[Pkg-octave-commit] [octave-ltfat] 01/01: Imported Upstream version 1.4.4

Rafael Laboissière rlaboiss-guest at moszumanska.debian.org
Sun May 4 23:23:39 UTC 2014


This is an automated email from the git hooks/post-receive script.

rlaboiss-guest pushed a commit to branch upstream
in repository octave-ltfat.

commit 1d02ada33d6541e4433fb0f65a15f200ad652722
Author: Rafael Laboissiere <rafael at laboissiere.net>
Date:   Sun May 4 15:08:50 2014 +0200

    Imported Upstream version 1.4.4
---
 CITATION                                           |   17 +
 COPYING                                            |  674 +++
 DESCRIPTION                                        |   16 +
 INDEX                                              |  365 ++
 NEWS                                               |   65 +
 PKG_ADD                                            |    6 +
 inst/AUTHORS                                       |    5 +
 inst/ChangeLog                                     |  377 ++
 inst/Contents.m                                    |   42 +
 inst/DESCRIPTION                                   |   16 +
 inst/INDEX                                         |  365 ++
 inst/INSTALL                                       |   23 +
 inst/INSTALL-Matlab                                |  116 +
 inst/INSTALL-Octave                                |   76 +
 inst/README                                        |   26 +
 inst/auditory/Contents.m                           |   47 +
 inst/auditory/audfiltbw.m                          |   59 +
 inst/auditory/auditoryinit.m                       |   26 +
 inst/auditory/audspace.m                           |   83 +
 inst/auditory/audspacebw.m                         |  113 +
 inst/auditory/audtofreq.m                          |   88 +
 inst/auditory/erbspace.m                           |   36 +
 inst/auditory/erbspacebw.m                         |   37 +
 inst/auditory/erbtofreq.m                          |   44 +
 inst/auditory/freqtoaud.m                          |  149 +
 inst/auditory/freqtoerb.m                          |   37 +
 inst/auditory/gammatonefir.m                       |  160 +
 inst/auditory/rangecompress.m                      |   83 +
 inst/auditory/rangeexpand.m                        |   69 +
 inst/auditory/semiaudplot.m                        |   86 +
 inst/blockproc/Contents.m                          |   48 +
 inst/blockproc/block.m                             |  457 ++
 inst/blockproc/block_fwt.m                         |  109 +
 inst/blockproc/block_ifwt.m                        |   74 +
 inst/blockproc/blockana.m                          |  238 ++
 inst/blockproc/blockdevices.m                      |   67 +
 inst/blockproc/blockdone.m                         |   54 +
 inst/blockproc/blockfigure.m                       |   96 +
 inst/blockproc/blockframeaccel.m                   |  140 +
 inst/blockproc/blockframepairaccel.m               |   83 +
 inst/blockproc/blockpanel.m                        |  121 +
 inst/blockproc/blockpanelget.m                     |   86 +
 inst/blockproc/blockplay.m                         |   42 +
 inst/blockproc/blockplot.m                         |   96 +
 inst/blockproc/blockprocinit.m                     |   69 +
 inst/blockproc/blockread.m                         |  262 ++
 inst/blockproc/blocksyn.m                          |  264 ++
 inst/blockproc/java/Makefile                       |   18 +
 inst/blockproc/java/blockproc.jar                  |  Bin 0 -> 32755 bytes
 .../java/net/sourceforge/ltfat/ContFrame.java      |  385 ++
 .../java/net/sourceforge/ltfat/SpectFrame.java     |  478 +++
 .../java/net/sourceforge/ltfat/Utils.java          |  199 +
 .../sourceforge/ltfat/thirdparty/JRangeSlider.java |  889 ++++
 inst/comp/arg_firwin.m                             |   35 +
 inst/comp/arg_freqtoaud.m                          |   29 +
 inst/comp/arg_fwt.m                                |   27 +
 inst/comp/arg_fwt2.m                               |   27 +
 inst/comp/arg_fwtcommon.m                          |   28 +
 inst/comp/arg_fwtext.m                             |   27 +
 inst/comp/arg_groupthresh.m                        |   29 +
 inst/comp/arg_ltfattranslate.m                     |   33 +
 inst/comp/arg_normalize.m                          |   30 +
 inst/comp/arg_pfilt.m                              |   29 +
 inst/comp/arg_plotfilterbank.m                     |   32 +
 inst/comp/arg_plotfwt.m                            |   35 +
 inst/comp/arg_tfplot.m                             |   36 +
 inst/comp/arg_thresh.m                             |   30 +
 inst/comp/arg_wfbtcommon.m                         |   29 +
 inst/comp/assert_L.m                               |   93 +
 inst/comp/assert_classname.m                       |   55 +
 inst/comp/assert_groworder.m                       |   45 +
 inst/comp/assert_sigreshape_post.m                 |   36 +
 inst/comp/assert_sigreshape_pre.m                  |  108 +
 inst/comp/assert_squarelat.m                       |   67 +
 inst/comp/block_interface.m                        |  176 +
 inst/comp/comp_atrousfilterbank_td.m               |   73 +
 inst/comp/comp_cellcoef2tf.m                       |   57 +
 inst/comp/comp_chirpzt.m                           |   89 +
 inst/comp/comp_col2diag.m                          |   49 +
 inst/comp/comp_dct.m                               |   90 +
 inst/comp/comp_dgt.m                               |   89 +
 inst/comp/comp_dgt_fb.m                            |  115 +
 inst/comp/comp_dgt_long.m                          |   65 +
 inst/comp/comp_dgt_ola.m                           |   79 +
 inst/comp/comp_dgt_walnut.m                        |  184 +
 inst/comp/comp_dgtreal.m                           |   70 +
 inst/comp/comp_dgtreal_fb.m                        |  121 +
 inst/comp/comp_dgtreal_long.m                      |   69 +
 inst/comp/comp_dgtreal_ola.m                       |   78 +
 inst/comp/comp_downs.m                             |  102 +
 inst/comp/comp_dst.m                               |  102 +
 inst/comp/comp_dwilt.m                             |   90 +
 inst/comp/comp_dwiltii.m                           |   58 +
 inst/comp/comp_dwiltiii.m                          |   56 +
 inst/comp/comp_dwiltiv.m                           |   44 +
 inst/comp/comp_edgt6.m                             |   37 +
 inst/comp/comp_extBoundary.m                       |  125 +
 inst/comp/comp_fftreal.m                           |   35 +
 inst/comp/comp_filterbank.m                        |   82 +
 inst/comp/comp_filterbank_a.m                      |   76 +
 inst/comp/comp_filterbank_fft.m                    |   39 +
 inst/comp/comp_filterbank_fftbl.m                  |   76 +
 inst/comp/comp_filterbank_pre.m                    |  119 +
 inst/comp/comp_filterbank_td.m                     |   88 +
 inst/comp/comp_filterbankresponse.m                |   54 +
 inst/comp/comp_fourierwindow.m                     |  142 +
 inst/comp/comp_framelength_fusion.m                |   39 +
 inst/comp/comp_framelength_tensor.m                |   27 +
 inst/comp/comp_frana_fusion.m                      |   35 +
 inst/comp/comp_frana_tensor.m                      |   33 +
 inst/comp/comp_frsyn_fusion.m                      |   37 +
 inst/comp/comp_frsyn_tensor.m                      |   33 +
 inst/comp/comp_fwt.m                               |   85 +
 inst/comp/comp_gabdual_long.m                      |   65 +
 inst/comp/comp_gabmixdual_fac.m                    |   75 +
 inst/comp/comp_gabreassign.m                       |   75 +
 inst/comp/comp_gabtight_long.m                     |   75 +
 inst/comp/comp_gdgt.m                              |   76 +
 inst/comp/comp_gfeigs.m                            |   81 +
 inst/comp/comp_gga.m                               |   65 +
 inst/comp/comp_hermite.m                           |   68 +
 inst/comp/comp_hermite_all.m                       |   66 +
 inst/comp/comp_iatrousfilterbank_td.m              |   70 +
 inst/comp/comp_idgt.m                              |   95 +
 inst/comp/comp_idgt_fac.m                          |  168 +
 inst/comp/comp_idgt_fb.m                           |  152 +
 inst/comp/comp_idgt_long.m                         |   60 +
 inst/comp/comp_idgtreal.m                          |   71 +
 inst/comp/comp_idgtreal_fac.m                      |  170 +
 inst/comp/comp_idgtreal_fb.m                       |  155 +
 inst/comp/comp_idgtreal_long.m                     |   66 +
 inst/comp/comp_idwilt.m                            |   81 +
 inst/comp/comp_idwiltii.m                          |   68 +
 inst/comp/comp_idwiltiii.m                         |   67 +
 inst/comp/comp_idwiltiv.m                          |   52 +
 inst/comp/comp_iedgt6.m                            |   44 +
 inst/comp/comp_ifftreal.m                          |   41 +
 inst/comp/comp_ifilterbank.m                       |  138 +
 inst/comp/comp_ifilterbank_fft.m                   |   38 +
 inst/comp/comp_ifilterbank_fftbl.m                 |   75 +
 inst/comp/comp_ifilterbank_td.m                    |   72 +
 inst/comp/comp_ifwt.m                              |   98 +
 inst/comp/comp_igdgt.m                             |   75 +
 inst/comp/comp_inonsepdgt.m                        |  138 +
 inst/comp/comp_inonsepdgt_shear.m                  |  132 +
 inst/comp/comp_inonsepdgtreal_quinqux.m            |   84 +
 inst/comp/comp_irdgt.m                             |   52 +
 inst/comp/comp_irdgtii.m                           |   51 +
 inst/comp/comp_irdgtiii.m                          |   54 +
 inst/comp/comp_isepdgt.m                           |   54 +
 inst/comp/comp_isepdgtreal.m                       |   54 +
 inst/comp/comp_iufilterbank_td.m                   |   74 +
 inst/comp/comp_iufwt.m                             |   66 +
 inst/comp/comp_iuwfbt.m                            |   82 +
 inst/comp/comp_iuwpfbt.m                           |   66 +
 inst/comp/comp_iwfac.m                             |   85 +
 inst/comp/comp_iwfbt.m                             |   75 +
 inst/comp/comp_iwpfbt.m                            |   69 +
 inst/comp/comp_nonsepdgt_multi.m                   |   60 +
 inst/comp/comp_nonsepdgt_shear.m                   |  154 +
 inst/comp/comp_nonsepdgtreal_quinqux.m             |   61 +
 inst/comp/comp_nonsepwin2multi.m                   |   37 +
 inst/comp/comp_pchirp.m                            |   41 +
 inst/comp/comp_pgauss.m                            |   73 +
 inst/comp/comp_sepdgt.m                            |   42 +
 inst/comp/comp_sepdgtreal.m                        |   47 +
 inst/comp/comp_sigreshape_post.m                   |   43 +
 inst/comp/comp_sigreshape_pre.m                    |   68 +
 inst/comp/comp_transferfunction.m                  |   63 +
 inst/comp/comp_ufilterbank_fft.m                   |   52 +
 inst/comp/comp_ufilterbank_td.m                    |   84 +
 inst/comp/comp_ufwt.m                              |   71 +
 inst/comp/comp_ups.m                               |  126 +
 inst/comp/comp_uwfbt.m                             |   74 +
 inst/comp/comp_uwpfbt.m                            |   81 +
 inst/comp/comp_warpedfoff.m                        |   27 +
 inst/comp/comp_warpedfreqresponse.m                |   90 +
 inst/comp/comp_wfac.m                              |  102 +
 inst/comp/comp_wfbt.m                              |   76 +
 inst/comp/comp_window.m                            |  190 +
 inst/comp/comp_wpfbt.m                             |   84 +
 inst/comp/compinit.m                               |   26 +
 inst/comp/complain_notposint.m                     |   29 +
 inst/comp/demo_blockproc_header.m                  |   45 +
 inst/comp/gabpars_from_window.m                    |   90 +
 inst/comp/gabpars_from_windowsignal.m              |   82 +
 inst/comp/nonsepgabpars_from_window.m              |   59 +
 inst/comp/vect2cell.m                              |   30 +
 inst/demos/Contents.m                              |   70 +
 inst/demos/demo_audiocompression.m                 |   96 +
 inst/demos/demo_audiodenoise.m                     |   91 +
 inst/demos/demo_audioshrink.m                      |  123 +
 inst/demos/demo_auditoryfilterbank.m               |  115 +
 inst/demos/demo_audscales.m                        |   62 +
 inst/demos/demo_blockproc_basicloop.m              |   54 +
 inst/demos/demo_blockproc_denoising.m              |   84 +
 inst/demos/demo_blockproc_dgtequalizer.m           |  101 +
 inst/demos/demo_blockproc_paramequalizer.m         |  264 ++
 inst/demos/demo_blockproc_pitchshift.m             |  101 +
 inst/demos/demo_blockproc_slidingcqt.m             |   98 +
 inst/demos/demo_blockproc_slidingerblets.m         |   85 +
 inst/demos/demo_blockproc_slidingsgram.m           |   82 +
 inst/demos/demo_dgt.m                              |  165 +
 inst/demos/demo_firwin.m                           |   37 +
 inst/demos/demo_framemul.m                         |  174 +
 inst/demos/demo_frsynabs.m                         |   68 +
 inst/demos/demo_gabfir.m                           |  237 ++
 inst/demos/demo_gablasso.m                         |   92 +
 inst/demos/demo_gabmixdual.m                       |  124 +
 inst/demos/demo_gabmulappr.m                       |  115 +
 inst/demos/demo_imagecompression.m                 |  108 +
 inst/demos/demo_nextfastfft.m                      |   71 +
 inst/demos/demo_nsdgt.m                            |  108 +
 inst/demos/demo_ofdm.m                             |  156 +
 inst/demos/demo_pbspline.m                         |  145 +
 inst/demos/demo_pgauss.m                           |  125 +
 inst/demos/demo_phaseplot.m                        |  134 +
 inst/demos/demosinit.m                             |   27 +
 inst/deprecated/Contents.m                         |   41 +
 inst/deprecated/deprecatedinit.m                   |   26 +
 inst/deprecated/framematrix.m                      |   96 +
 inst/deprecated/gabelitistlasso.m                  |  168 +
 inst/deprecated/gabgrouplasso.m                    |   44 +
 inst/deprecated/gablasso.m                         |   44 +
 inst/deprecated/gabmul.m                           |  120 +
 inst/deprecated/gabmuleigs.m                       |  219 +
 inst/deprecated/iufilterbank.m                     |   38 +
 inst/deprecated/iunsdgt.m                          |   64 +
 inst/deprecated/iunsdgtreal.m                      |   63 +
 inst/deprecated/tfmat.m                            |  235 +
 inst/filterbank/Contents.m                         |   57 +
 inst/filterbank/cqt.m                              |  327 ++
 inst/filterbank/cqtfilters.m                       |  333 ++
 inst/filterbank/erbfilters.m                       |  291 ++
 inst/filterbank/erblett.m                          |  211 +
 inst/filterbank/filterbank.m                       |   97 +
 inst/filterbank/filterbankbounds.m                 |  111 +
 inst/filterbank/filterbankdual.m                   |  134 +
 inst/filterbank/filterbankinit.m                   |   26 +
 inst/filterbank/filterbanklength.m                 |   64 +
 inst/filterbank/filterbanklengthcoef.m             |   65 +
 inst/filterbank/filterbankrealbounds.m             |  115 +
 inst/filterbank/filterbankrealdual.m               |  134 +
 inst/filterbank/filterbankrealtight.m              |  132 +
 inst/filterbank/filterbankresponse.m               |   86 +
 inst/filterbank/filterbanktight.m                  |  127 +
 inst/filterbank/filterbankwin.m                    |  190 +
 inst/filterbank/icqt.m                             |   70 +
 inst/filterbank/ierblett.m                         |   67 +
 inst/filterbank/ifilterbank.m                      |  100 +
 inst/filterbank/insdgfb.m                          |  117 +
 inst/filterbank/nonu2ufilterbank.m                 |   94 +
 inst/filterbank/plotfilterbank.m                   |  252 ++
 inst/filterbank/ufilterbank.m                      |   87 +
 inst/fourier/Contents.m                            |  101 +
 inst/fourier/blfilter.m                            |  185 +
 inst/fourier/ceil23.m                              |  109 +
 inst/fourier/ceil235.m                             |  112 +
 inst/fourier/chirpzt.m                             |  164 +
 inst/fourier/convolve.m                            |   73 +
 inst/fourier/dcti.m                                |  135 +
 inst/fourier/dctii.m                               |  129 +
 inst/fourier/dctiii.m                              |  130 +
 inst/fourier/dctiv.m                               |  118 +
 inst/fourier/dctresample.m                         |   65 +
 inst/fourier/dfracft.m                             |   87 +
 inst/fourier/dft.m                                 |   57 +
 inst/fourier/dsti.m                                |  111 +
 inst/fourier/dstii.m                               |  111 +
 inst/fourier/dstiii.m                              |  114 +
 inst/fourier/dstiv.m                               |  104 +
 inst/fourier/expwave.m                             |   53 +
 inst/fourier/ffracft.m                             |  144 +
 inst/fourier/fftindex.m                            |   55 +
 inst/fourier/fftreal.m                             |   66 +
 inst/fourier/fftresample.m                         |   63 +
 inst/fourier/fir2long.m                            |   64 +
 inst/fourier/firfilter.m                           |  117 +
 inst/fourier/firkaiser.m                           |  147 +
 inst/fourier/firwin.m                              |  384 ++
 inst/fourier/floor23.m                             |  118 +
 inst/fourier/floor235.m                            |  121 +
 inst/fourier/fourierinit.m                         |   27 +
 inst/fourier/gga.m                                 |  145 +
 inst/fourier/hermbasis.m                           |  162 +
 inst/fourier/idft.m                                |   57 +
 inst/fourier/ifftreal.m                            |   58 +
 inst/fourier/involute.m                            |   76 +
 inst/fourier/isevenfunction.m                      |   85 +
 inst/fourier/long2fir.m                            |   91 +
 inst/fourier/magresp.m                             |  195 +
 inst/fourier/middlepad.m                           |  189 +
 inst/fourier/modcent.m                             |   37 +
 inst/fourier/nextfastfft.m                         |  130 +
 inst/fourier/pbspline.m                            |  490 +++
 inst/fourier/pchirp.m                              |   90 +
 inst/fourier/pconv.m                               |   89 +
 inst/fourier/pderiv.m                              |   81 +
 inst/fourier/peven.m                               |   40 +
 inst/fourier/pfilt.m                               |   98 +
 inst/fourier/pgauss.m                              |  198 +
 inst/fourier/pheaviside.m                          |   63 +
 inst/fourier/pherm.m                               |  228 +
 inst/fourier/plotfft.m                             |  168 +
 inst/fourier/plotfftreal.m                         |  163 +
 inst/fourier/podd.m                                |   39 +
 inst/fourier/prect.m                               |   67 +
 inst/fourier/psech.m                               |  157 +
 inst/fourier/psinc.m                               |   62 +
 inst/fourier/pxcorr.m                              |   68 +
 inst/fourier/shah.m                                |   70 +
 inst/fourier/transferfunction.m                    |   37 +
 inst/fourier/warpedblfilter.m                      |  124 +
 inst/frames/Contents.m                             |   61 +
 inst/frames/frame.m                                |  477 +++
 inst/frames/frameaccel.m                           |  120 +
 inst/frames/framebounds.m                          |  215 +
 inst/frames/framecoef2native.m                     |   46 +
 inst/frames/framecoef2tf.m                         |   88 +
 inst/frames/framediag.m                            |   67 +
 inst/frames/framedual.m                            |   81 +
 inst/frames/framegram.m                            |   38 +
 inst/frames/framelength.m                          |   38 +
 inst/frames/framelengthcoef.m                      |   52 +
 inst/frames/framenative2coef.m                     |   42 +
 inst/frames/framepair.m                            |   81 +
 inst/frames/framered.m                             |   49 +
 inst/frames/framesinit.m                           |   25 +
 inst/frames/frametf2coef.m                         |   54 +
 inst/frames/frametight.m                           |   82 +
 inst/frames/frana.m                                |   91 +
 inst/frames/franagrouplasso.m                      |  210 +
 inst/frames/franaiter.m                            |  140 +
 inst/frames/franalasso.m                           |  194 +
 inst/frames/frsyn.m                                |   47 +
 inst/frames/frsynabs.m                             |  241 ++
 inst/frames/frsyniter.m                            |  171 +
 inst/frames/frsynmatrix.m                          |   95 +
 inst/frames/plotframe.m                            |  105 +
 inst/gabor/Contents.m                              |  107 +
 inst/gabor/col2diag.m                              |   55 +
 inst/gabor/constructphase.m                        |   66 +
 inst/gabor/dgt.m                                   |  221 +
 inst/gabor/dgt2.m                                  |  122 +
 inst/gabor/dgtlength.m                             |  125 +
 inst/gabor/dgtreal.m                               |  141 +
 inst/gabor/dsft.m                                  |   71 +
 inst/gabor/dwilt.m                                 |  193 +
 inst/gabor/dwilt2.m                                |  131 +
 inst/gabor/dwiltlength.m                           |   70 +
 inst/gabor/gabconvexopt.m                          |  683 +++
 inst/gabor/gabdual.m                               |  223 +
 inst/gabor/gabdualnorm.m                           |  152 +
 inst/gabor/gabfirdual.m                            |  147 +
 inst/gabor/gabfirtight.m                           |  142 +
 inst/gabor/gabframebounds.m                        |  151 +
 inst/gabor/gabframediag.m                          |   83 +
 inst/gabor/gabimagepars.m                          |   97 +
 inst/gabor/gabmixdual.m                            |  107 +
 inst/gabor/gaboptdual.m                            |  137 +
 inst/gabor/gabopttight.m                           |  156 +
 inst/gabor/gaborinit.m                             |   26 +
 inst/gabor/gabphasegrad.m                          |  320 ++
 inst/gabor/gabprojdual.m                           |  119 +
 inst/gabor/gabreassign.m                           |  112 +
 inst/gabor/gabrieszbounds.m                        |   82 +
 inst/gabor/gabtight.m                              |  253 ++
 inst/gabor/gabwin.m                                |  144 +
 inst/gabor/idgt.m                                  |  191 +
 inst/gabor/idgt2.m                                 |  186 +
 inst/gabor/idgtreal.m                              |  186 +
 inst/gabor/idwilt.m                                |   93 +
 inst/gabor/idwilt2.m                               |  130 +
 inst/gabor/instfreqplot.m                          |  211 +
 inst/gabor/isgram.m                                |  294 ++
 inst/gabor/isgramreal.m                            |  265 ++
 inst/gabor/iwmdct.m                                |  114 +
 inst/gabor/iwmdct2.m                               |  129 +
 inst/gabor/izak.m                                  |   63 +
 inst/gabor/latticetype2matrix.m                    |   54 +
 inst/gabor/longpar.m                               |   96 +
 inst/gabor/matrix2latticetype.m                    |  145 +
 inst/gabor/noshearlength.m                         |   62 +
 inst/gabor/phaselock.m                             |  103 +
 inst/gabor/phaseplot.m                             |  191 +
 inst/gabor/phaseunlock.m                           |   88 +
 inst/gabor/plotdgt.m                               |   76 +
 inst/gabor/plotdgtreal.m                           |   67 +
 inst/gabor/plotdwilt.m                             |   79 +
 inst/gabor/plotwmdct.m                             |   60 +
 inst/gabor/proj_dual.m                             |  117 +
 inst/gabor/projkern.m                              |   89 +
 inst/gabor/rect2wil.m                              |   58 +
 inst/gabor/resgram.m                               |  236 +
 inst/gabor/s0norm.m                                |   87 +
 inst/gabor/sgram.m                                 |  230 +
 inst/gabor/shearfind.m                             |  184 +
 inst/gabor/symphase.m                              |   79 +
 inst/gabor/tconv.m                                 |  108 +
 inst/gabor/tfplot.m                                |  205 +
 inst/gabor/wil2rect.m                              |   58 +
 inst/gabor/wilbounds.m                             |  103 +
 inst/gabor/wildual.m                               |  111 +
 inst/gabor/wilframediag.m                          |   50 +
 inst/gabor/wilorth.m                               |  146 +
 inst/gabor/wilwin.m                                |  263 ++
 inst/gabor/wmdct.m                                 |  186 +
 inst/gabor/wmdct2.m                                |  115 +
 inst/gabor/zak.m                                   |  116 +
 inst/isoctave.m                                    |   39 +
 inst/ltfat/DESCRIPTION                             |   16 +
 inst/ltfat/INDEX                                   |  365 ++
 inst/ltfat/PKG_ADD                                 |    6 +
 inst/ltfat/inst/CITATION                           |   17 +
 inst/ltfat_version                                 |    1 +
 inst/ltfatarghelper.m                              |  290 ++
 inst/ltfatbasepath.m                               |   36 +
 inst/ltfatgetdefaults.m                            |   43 +
 inst/ltfathelp.m                                   |  115 +
 inst/ltfatmex.m                                    |  526 +++
 inst/ltfatsetdefaults.m                            |   42 +
 inst/ltfatstart.m                                  |  212 +
 inst/ltfatstop.m                                   |   50 +
 inst/nonstatgab/Contents.m                         |   43 +
 inst/nonstatgab/insdgt.m                           |  113 +
 inst/nonstatgab/insdgtreal.m                       |  119 +
 inst/nonstatgab/nonstatgabinit.m                   |   26 +
 inst/nonstatgab/nsdgt.m                            |  169 +
 inst/nonstatgab/nsdgtlength.m                      |   58 +
 inst/nonstatgab/nsdgtreal.m                        |  187 +
 inst/nonstatgab/nsgabdual.m                        |  128 +
 inst/nonstatgab/nsgabframebounds.m                 |   75 +
 inst/nonstatgab/nsgabframediag.m                   |   67 +
 inst/nonstatgab/nsgabtight.m                       |  129 +
 inst/nonstatgab/nsgabwin.m                         |  138 +
 inst/nonstatgab/plotnsdgt.m                        |  112 +
 inst/nonstatgab/plotnsdgtreal.m                    |  104 +
 inst/nonstatgab/unsdgt.m                           |  146 +
 inst/nonstatgab/unsdgtreal.m                       |  166 +
 inst/operators/Contents.m                          |   49 +
 inst/operators/framemul.m                          |   92 +
 inst/operators/framemuladj.m                       |   59 +
 inst/operators/framemulappr.m                      |  122 +
 inst/operators/framemuleigs.m                      |  166 +
 inst/operators/gabmulappr.m                        |  162 +
 inst/operators/iframemul.m                         |  101 +
 inst/operators/ioperator.m                         |   53 +
 inst/operators/operator.m                          |   52 +
 inst/operators/operatoradj.m                       |   53 +
 inst/operators/operatorappr.m                      |   55 +
 inst/operators/operatoreigs.m                      |   77 +
 inst/operators/operatormatrix.m                    |   42 +
 inst/operators/operatornew.m                       |   82 +
 inst/operators/operatorsinit.m                     |   25 +
 inst/operators/spreadadj.m                         |  113 +
 inst/operators/spreadeigs.m                        |   62 +
 inst/operators/spreadfun.m                         |   48 +
 inst/operators/spreadinv.m                         |   68 +
 inst/operators/spreadop.m                          |  122 +
 inst/scalardistribute.m                            |   98 +
 inst/signals/Clar.wav                              |  Bin 0 -> 65580 bytes
 inst/signals/Contents.m                            |   53 +
 inst/signals/Piano2.wav                            |  Bin 0 -> 40492 bytes
 inst/signals/bat.asc                               |  400 ++
 inst/signals/bat.m                                 |   73 +
 inst/signals/batmask.asc                           |   40 +
 inst/signals/batmask.m                             |   50 +
 inst/signals/cameraman.m                           |   50 +
 inst/signals/cameraman.png                         |  Bin 0 -> 38267 bytes
 inst/signals/cocktailparty.m                       |   49 +
 inst/signals/cocktailparty.wav                     |  Bin 0 -> 726476 bytes
 inst/signals/ctestfun.m                            |   40 +
 inst/signals/expchirp.m                            |   65 +
 inst/signals/greasy.m                              |   79 +
 inst/signals/greasy.wav                            |  Bin 0 -> 11804 bytes
 inst/signals/gspi.m                                |   50 +
 inst/signals/gspi.wav                              |  Bin 0 -> 524332 bytes
 inst/signals/lichtenstein.m                        |   55 +
 inst/signals/lichtenstein.png                      |  Bin 0 -> 365198 bytes
 inst/signals/linus.m                               |   49 +
 inst/signals/linus.wav                             |  Bin 0 -> 82998 bytes
 inst/signals/ltfatlogo.m                           |   57 +
 inst/signals/ltfatlogo.wav                         |  Bin 0 -> 9644 bytes
 inst/signals/ltfattext.m                           |   56 +
 inst/signals/ltfattext.png                         |  Bin 0 -> 1712 bytes
 inst/signals/noise.m                               |  121 +
 inst/signals/otoclick.asc                          | 2210 ++++++++++
 inst/signals/otoclick.m                            |   52 +
 inst/signals/pinknoise.m                           |   44 +
 inst/signals/signalsinit.m                         |   27 +
 inst/signals/traindoppler.m                        |   51 +
 inst/signals/traindoppler.wav                      |  Bin 0 -> 314160 bytes
 inst/sigproc/Contents.m                            |   53 +
 inst/sigproc/crestfactor.m                         |   34 +
 inst/sigproc/dynlimit.m                            |   36 +
 inst/sigproc/elitistthresh.m                       |   97 +
 inst/sigproc/gaindb.m                              |   86 +
 inst/sigproc/groupthresh.m                         |  126 +
 inst/sigproc/iqam4.m                               |   64 +
 inst/sigproc/jpeg2rgb.m                            |   60 +
 inst/sigproc/largestn.m                            |   99 +
 inst/sigproc/largestr.m                            |   99 +
 inst/sigproc/normalize.m                           |  126 +
 inst/sigproc/qam4.m                                |   67 +
 inst/sigproc/rampdown.m                            |   48 +
 inst/sigproc/rampsignal.m                          |   96 +
 inst/sigproc/rampup.m                              |   47 +
 inst/sigproc/rgb2jpeg.m                            |   95 +
 inst/sigproc/rms.m                                 |   91 +
 inst/sigproc/sigprocinit.m                         |   26 +
 inst/sigproc/thresh.m                              |  180 +
 inst/sigproc/uquant.m                              |  107 +
 inst/wavelets/Contents.m                           |   86 +
 inst/wavelets/fwt.m                                |  207 +
 inst/wavelets/fwt2.m                               |  164 +
 inst/wavelets/fwt2filterbank.m                     |   57 +
 inst/wavelets/fwtbounds.m                          |   60 +
 inst/wavelets/fwtclength.m                         |   85 +
 inst/wavelets/fwtinit.m                            |  475 +++
 inst/wavelets/fwtlength.m                          |   55 +
 inst/wavelets/ifwt.m                               |  155 +
 inst/wavelets/ifwt2.m                              |  132 +
 inst/wavelets/iufwt.m                              |  107 +
 inst/wavelets/iuwfbt.m                             |   81 +
 inst/wavelets/iuwpfbt.m                            |   95 +
 inst/wavelets/iwfbt.m                              |  112 +
 inst/wavelets/iwpfbt.m                             |  115 +
 inst/wavelets/iwtfft.m                             |   72 +
 inst/wavelets/plotwavelets.m                       |  155 +
 inst/wavelets/ufwt.m                               |  123 +
 inst/wavelets/uwfbt.m                              |   93 +
 inst/wavelets/uwpfbt.m                             |   92 +
 inst/wavelets/wavcell2pack.m                       |   71 +
 inst/wavelets/waveletsinit.m                       |   28 +
 inst/wavelets/wavfun.m                             |  146 +
 inst/wavelets/wavpack2cell.m                       |   89 +
 inst/wavelets/wfbt.m                               |  134 +
 inst/wavelets/wfbt2filterbank.m                    |  102 +
 inst/wavelets/wfbtbounds.m                         |   71 +
 inst/wavelets/wfbtclength.m                        |   56 +
 inst/wavelets/wfbtinit.m                           |  189 +
 inst/wavelets/wfbtlength.m                         |   50 +
 inst/wavelets/wfbtmanip/deleteNode.m               |   56 +
 inst/wavelets/wfbtmanip/deleteSubtree.m            |   41 +
 inst/wavelets/wfbtmanip/depthIndex2NodeNo.m        |  122 +
 inst/wavelets/wfbtmanip/maxTreeSub.m               |   39 +
 inst/wavelets/wfbtmanip/nat2freqOrder.m            |   66 +
 inst/wavelets/wfbtmanip/noOfChildOutputs.m         |   36 +
 inst/wavelets/wfbtmanip/noOfNodeOutputs.m          |   61 +
 inst/wavelets/wfbtmanip/noOfOutputs.m              |   49 +
 inst/wavelets/wfbtmanip/noOfSubtreeOutputs.m       |   29 +
 inst/wavelets/wfbtmanip/nodeFiltUps.m              |   54 +
 inst/wavelets/wfbtmanip/nodeInLen.m                |   71 +
 inst/wavelets/wfbtmanip/nodeOutLen.m               |   70 +
 inst/wavelets/wfbtmanip/nodePredecesors.m          |   30 +
 inst/wavelets/wfbtmanip/nodeSub.m                  |   44 +
 inst/wavelets/wfbtmanip/nodeSubtreeBF.m            |   52 +
 inst/wavelets/wfbtmanip/nodeSubtreeDF.m            |   57 +
 inst/wavelets/wfbtmanip/nodesBForder.m             |   53 +
 inst/wavelets/wfbtmanip/nodesDForder.m             |   53 +
 inst/wavelets/wfbtmanip/nodesLevelsBForder.m       |   72 +
 inst/wavelets/wfbtmanip/nodesMultid.m              |  122 +
 inst/wavelets/wfbtmanip/rangeInLocalOutputs.m      |   85 +
 inst/wavelets/wfbtmanip/rangeInNodeOutputs.m       |   53 +
 inst/wavelets/wfbtmanip/rangeInOutputs.m           |  102 +
 inst/wavelets/wfbtmanip/rangeInWpOutputs.m         |   40 +
 inst/wavelets/wfbtmanip/rangeWpBF.m                |   51 +
 inst/wavelets/wfbtmanip/treeOutLen.m               |   45 +
 inst/wavelets/wfbtmanip/treeSub.m                  |   42 +
 inst/wavelets/wfbtput.m                            |  125 +
 inst/wavelets/wfbtremove.m                         |   98 +
 inst/wavelets/wfilt_algmband.m                     |   84 +
 inst/wavelets/wfilt_apr.m                          |   91 +
 inst/wavelets/wfilt_cmband.m                       |  112 +
 inst/wavelets/wfilt_db.m                           |  117 +
 inst/wavelets/wfilt_dden.m                         |  144 +
 inst/wavelets/wfilt_dgrid.m                        |   92 +
 inst/wavelets/wfilt_dtree.m                        |  103 +
 inst/wavelets/wfilt_hden.m                         |  134 +
 inst/wavelets/wfilt_lemarie.m                      |   73 +
 inst/wavelets/wfilt_matlabwtwrapper.m              |   49 +
 inst/wavelets/wfilt_maxflat.m                      |  163 +
 inst/wavelets/wfilt_mband.m                        |  128 +
 inst/wavelets/wfilt_optfs.m                        |  166 +
 inst/wavelets/wfilt_remez.m                        |  441 ++
 inst/wavelets/wfilt_spline.m                       |  275 ++
 inst/wavelets/wfilt_sym.m                          |  419 ++
 inst/wavelets/wfilt_symds.m                        |  235 +
 inst/wavelets/wfiltinfo.m                          |  139 +
 inst/wavelets/wfreq_lemarie.m                      |   74 +
 inst/wavelets/wpbest.m                             |  395 ++
 inst/wavelets/wpfbt.m                              |  115 +
 inst/wavelets/wpfbtclength.m                       |   56 +
 oct/Makefile_mac                                   |    1 +
 oct/Makefile_mingwoct                              |   32 +
 oct/Makefile_unix                                  |   32 +
 oct/comp_atrousfilterbank_td.cc                    |  110 +
 oct/comp_cellcoef2tf.cc                            |   64 +
 oct/comp_chirpzt.cc                                |   64 +
 oct/comp_col2diag.cc                               |   52 +
 oct/comp_dct.cc                                    |   88 +
 oct/comp_dgt_ola.cc                                |   64 +
 oct/comp_dgtreal_ola.cc                            |   63 +
 oct/comp_dst.cc                                    |   89 +
 oct/comp_dwilt.cc                                  |  123 +
 oct/comp_dwiltiii.cc                               |  118 +
 oct/comp_fftreal.cc                                |   51 +
 oct/comp_filterbank_fft.cc                         |   84 +
 oct/comp_filterbank_fftbl.cc                       |  105 +
 oct/comp_filterbank_td.cc                          |  117 +
 oct/comp_gabdual_long.cc                           |   69 +
 oct/comp_gabreassign.cc                            |   53 +
 oct/comp_gabtight_long.cc                          |   64 +
 oct/comp_gga.cc                                    |   74 +
 oct/comp_heapint.cc                                |   48 +
 oct/comp_iatrousfilterbank_td.cc                   |  102 +
 oct/comp_idwilt.cc                                 |  120 +
 oct/comp_idwiltiii.cc                              |  121 +
 oct/comp_ifftreal.cc                               |   47 +
 oct/comp_ifilterbank_fft.cc                        |   85 +
 oct/comp_ifilterbank_fftbl.cc                      |  104 +
 oct/comp_ifilterbank_td.cc                         |  112 +
 oct/comp_isepdgt.cc                                |   83 +
 oct/comp_isepdgtreal.cc                            |   80 +
 oct/comp_iwfac.cc                                  |   49 +
 oct/comp_nonsepdgt_multi.cc                        |   68 +
 oct/comp_nonsepdgt_shear.cc                        |   62 +
 oct/comp_nonsepwin2multi.cc                        |   59 +
 oct/comp_pchirp.cc                                 |   19 +
 oct/comp_pgauss.cc                                 |   29 +
 oct/comp_sepdgt.cc                                 |  117 +
 oct/comp_sepdgtreal.cc                             |   77 +
 oct/comp_ufilterbank_fft.cc                        |   59 +
 oct/comp_wfac.cc                                   |   79 +
 oct/config.h                                       |   13 +
 oct/ltfat_oct_template_helper.h                    |  348 ++
 oct/oct-memalloc.c                                 |   46 +
 oct/octinit.m                                      |   31 +
 src/Makefile.in                                    |   19 +
 src/Makefile_mac                                   |    1 +
 src/Makefile_mingw                                 |  100 +
 src/Makefile_mingwoct                              |   73 +
 src/Makefile_unix                                  |   75 +
 src/README                                         |   10 +
 src/autom4te.cache/output.0                        | 4490 ++++++++++++++++++++
 src/autom4te.cache/requests                        |   77 +
 src/autom4te.cache/traces.0                        |  231 +
 src/bootstrap                                      |    2 +
 src/c-safe-memalloc.c                              |   97 +
 src/ciutils.c                                      |  134 +
 src/ciutils.h                                      |   16 +
 src/config.h                                       |   75 +
 src/configure                                      | 4490 ++++++++++++++++++++
 src/configure.ac                                   |   45 +
 src/dct.c                                          |  128 +
 src/dct_ci.c                                       |   11 +
 src/dgt.c                                          |  112 +
 src/dgt_fac.c                                      |  120 +
 src/dgt_fb.c                                       |  529 +++
 src/dgt_long.h                                     |   47 +
 src/dgt_multi.c                                    |  132 +
 src/dgt_multi.h                                    |   50 +
 src/dgt_ola.c                                      |  280 ++
 src/dgt_shear.c                                    |  297 ++
 src/dgt_shear.h                                    |   53 +
 src/dgt_shearola.c                                 |  157 +
 src/dgt_walnut.c                                   |  672 +++
 src/dgtreal_fac.c                                  |   92 +
 src/drivers.c                                      |   78 +
 src/dst.c                                          |  114 +
 src/dst_ci.c                                       |   11 +
 src/dwilt.c                                        |  152 +
 src/fftreal.c                                      |   88 +
 src/filedefs.mk                                    |   12 +
 src/filterbank.c                                   |  396 ++
 src/gabdual.c                                      |   36 +
 src/gabdual_fac.c                                  |   99 +
 src/gabtight.c                                     |   36 +
 src/gabtight_fac.c                                 |  106 +
 src/goertzel.c                                     |  543 +++
 src/goertzel.h                                     |   67 +
 src/heapint.c                                      |  305 ++
 src/idgt.c                                         |   37 +
 src/idgt_fac.c                                     |  376 ++
 src/idgt_fb.c                                      |  406 ++
 src/idwilt.c                                       |  153 +
 src/ifilterbank.c                                  |  301 ++
 src/integer_manip.c                                |  279 ++
 src/iwfac.c                                        |  206 +
 src/iwmdct.c                                       |  163 +
 src/ltfat.h                                        |  181 +
 src/ltfat_blaslapack.c                             |  225 +
 src/ltfat_complexindependent.c                     |   25 +
 src/ltfat_complexindependent_bl.c                  |   23 +
 src/ltfat_typecomplexindependent.h                 |  101 +
 src/ltfat_typeindependent.h                        |  657 +++
 src/ltfat_types.h                                  |   81 +
 src/m4/ax_blas.m4                                  |  201 +
 src/m4/ax_lapack.m4                                |  131 +
 src/ostools.mk                                     |   26 +
 src/pfilt.c                                        |  104 +
 src/reassign.c                                     |   45 +
 src/spread.c                                       |   36 +
 src/thirdparty/cblas.h                             |  596 +++
 src/thirdparty/f77-fcn.h                           |  188 +
 src/thirdparty/fftw3.h                             |  331 ++
 src/thirdparty/portaudio.h                         | 1174 +++++
 src/wavelets.c                                     |  754 ++++
 src/wavelets.h                                     |  153 +
 src/wfac.c                                         |  200 +
 src/windows.c                                      |   88 +
 src/winmanip.c                                     |  187 +
 src/wmdct.c                                        |  173 +
 thirdparty/Playrec/Makefile_mac                    |   35 +
 thirdparty/Playrec/Makefile_macoct                 |    1 +
 thirdparty/Playrec/Makefile_mingw                  |   23 +
 thirdparty/Playrec/Makefile_mingwoct               |    4 +
 thirdparty/Playrec/Makefile_unix                   |   41 +
 thirdparty/Playrec/Makefile_unixoct                |   23 +
 thirdparty/Playrec/license.txt                     |    9 +
 thirdparty/Playrec/mex_dll_core.c                  |  653 +++
 thirdparty/Playrec/mex_dll_core.h                  |  165 +
 thirdparty/Playrec/pa_dll_playrec.c                | 4038 ++++++++++++++++++
 thirdparty/Playrec/pa_dll_playrec.h                |  244 ++
 724 files changed, 94949 insertions(+)

diff --git a/CITATION b/CITATION
new file mode 100644
index 0000000..04a3f56
--- /dev/null
+++ b/CITATION
@@ -0,0 +1,17 @@
+To cite LTFAT in publications please use:
+
+    Peter L. Søndergaard, Bruno Torrésani, Peter Balazs. The Linear Time-Frequency Analysis Toolbox.
+    International Journal of Wavelets, Multiresolution Analysis and Information Processing, 10(4), 2012.
+
+A BibTex entry for LaTex users:
+
+  @article{ltfatnote015,
+    author = "Peter L. S{\o}ndergaard and Bruno Torr\'esani and Peter Balazs",
+    title = {{The Linear Time Frequency Analysis Toolbox}},
+    journal = "International Journal of Wavelets, Multiresolution Analysis and Information Processing",
+    year = 2012,
+    volume = 10,
+    number = 4,
+    doi = "10.1142/S0219691312500324"
+  }
+ 
\ No newline at end of file
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..a8f59d9
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,16 @@
+Name: LTFAT
+Version: 1.4.4
+Date: 2014-3-20
+Author: Peter L. Soendergaard <soender at users.sourceforge.net>
+Maintainer: Zdenek Prusa
+Title: The Large Time-Frequency Analysis Toolbox
+Description: The Large Time/Frequency Analysis Toolbox (LTFAT) is a
+ Matlab/Octave toolbox for working with time-frequency analysis,
+ wavelets and signal processing. It is intended both as an educational
+ and a computational tool. The toolbox provides a large number of
+ linear transforms including Gabor and wavelet transforms along with
+ routines for constructing windows (filter prototypes) and routines
+ for manipulating coefficients.
+License: GPLv3+
+BuildRequires: fftw3, lapack, blas, portaudio 
+Url: http://ltfat.sourceforge.net/
diff --git a/INDEX b/INDEX
new file mode 100644
index 0000000..cab4e85
--- /dev/null
+++ b/INDEX
@@ -0,0 +1,365 @@
+ltfat >> Time-frequency analysis and Wavelets
+signals
+ ctestfun
+ noise
+ pinknoise
+ expchirp
+ bat
+ batmask
+ greasy
+ cocktailparty
+ gspi
+ linus
+ ltfatlogo
+ otoclick
+ traindoppler
+ cameraman
+ lichtenstein
+ ltfattext
+operators
+ operatornew
+ operator
+ ioperator
+ operatoradj
+ operatorappr
+ operatoreigs
+ operatormatrix
+ framemul
+ iframemul
+ framemuladj
+ framemulappr
+ framemuleigs
+ gabmulappr
+ spreadop
+ spreadinv
+ spreadadj
+ spreadfun
+ spreadeigs
+deprecated
+ gabelitistlasso
+ gabgrouplasso
+ gablasso
+ gabmuleigs
+ gabmul
+ framematrix
+ iufilterbank
+ iunsdgt
+ iunsdgtreal
+ tfmat
+sigproc
+ rms
+ normalize
+ gaindb
+ crestfactor
+ uquant
+ rampup
+ rampdown
+ rampsignal
+ thresh
+ largestr
+ largestn
+ dynlimit
+ groupthresh
+ rgb2jpeg
+ jpeg2rgb
+ qam4
+ iqam4
+gabor
+ tconv
+ dsft
+ zak
+ izak
+ col2diag
+ s0norm
+ dgt
+ idgt
+ isgram
+ isgramreal
+ dgt2
+ idgt2
+ dgtreal
+ idgtreal
+ gabwin
+ dgtlength
+ dwilt
+ idwilt
+ dwilt2
+ idwilt2
+ wmdct
+ iwmdct
+ wmdct2
+ iwmdct2
+ wil2rect
+ rect2wil
+ wilwin
+ dwiltlength
+ gabdual
+ gabtight
+ gabfirdual
+ gaboptdual
+ gabfirtight
+ gabopttight
+ gabconvexopt
+ gabprojdual
+ gabmixdual
+ wilorth
+ wildual
+ gabframebounds
+ gabrieszbounds
+ wilbounds
+ gabdualnorm
+ gabframediag
+ wilframediag
+ gabphasegrad
+ gabreassign
+ phaselock
+ phaseunlock
+ symphase
+ matrix2latticetype
+ latticetype2matrix
+ shearfind
+ noshearlength
+ tfplot
+ plotdgt
+ plotdgtreal
+ plotdwilt
+ plotwmdct
+ sgram
+ gabimagepars
+ resgram
+ instfreqplot
+ phaseplot
+blockproc
+ block
+ blockdevices
+ blockread
+ blockplay
+ blockpanel
+ blockpanelget
+ blockdone
+ blockframeaccel
+ blockframepairaccel
+ blockana
+ blocksyn
+ blockfigure
+ blockplot
+ block_fwt
+ block_ifwt
+demos
+ demo_dgt
+ demo_gabfir
+ demo_imagecompression
+ demo_audiocompression
+ demo_audiodenoise
+ demo_ofdm
+ demo_audioshrink
+ demo_gabmulappr
+ demo_nsdgt
+ demo_pgauss
+ demo_pbspline
+ demo_gabmixdual
+ demo_framemul
+ demo_phaseplot
+ demo_frsynabs
+ demo_nextfastfft
+ demo_audscales
+ demo_auditoryfilterbank
+ demo_blockproc_basicloop
+ demo_blockproc_paramequalizer
+ demo_blockproc_denoising
+ demo_blockproc_slidingsgram
+ demo_blockproc_slidingcqt
+ demo_blockproc_slidingerblets
+ demo_blockproc_pitchshift
+ demo_blockproc_dgtequalizer
+auditory
+ semiaudplot
+ audtofreq
+ freqtoaud
+ audspace
+ audspacebw
+ erbtofreq
+ freqtoerb
+ erbspace
+ erbspacebw
+ audfiltbw
+ rangecompress
+ rangeexpand
+ gammatonefir
+nonstatgab
+ nsdgt
+ unsdgt
+ insdgt
+ nsdgtreal
+ unsdgtreal
+ insdgtreal
+ nsgabdual
+ nsgabtight
+ nsgabframebounds
+ nsgabframediag
+ plotnsdgt
+ plotnsdgtreal
+wavelets
+ fwt
+ ifwt
+ fwt2
+ ifwt2
+ ufwt
+ iufwt
+ fwtlength
+ fwtclength
+ wfbt
+ iwfbt
+ uwfbt
+ iuwfbt
+ wpfbt
+ iwpfbt
+ uwpfbt
+ iuwpfbt
+ wpbest
+ wfbtlength
+ wfbtinit
+ wfbtput
+ wfbtremove
+ wfbt2filterbank
+ fwt2filterbank
+ fwtinit
+ plotwavelets
+ wfiltinfo
+ wavfun
+ wavcell2pack
+ wavpack2cell
+ wfilt_algmband
+ wfilt_apr
+ wfilt_db
+ wfilt_dden
+ wfilt_dgrid
+ wfilt_dtree
+ wfilt_hden
+ wfilt_lemarie
+ wfilt_matlabwtwrapper
+ wfilt_maxflat
+ wfilt_mband
+ wfilt_optfs
+ wfilt_remez
+ wfilt_symds
+ wfilt_spline
+ wfilt_sym
+ wfreq_lemarie
+filterbank
+ filterbank
+ ufilterbank
+ ifilterbank
+ filterbankwin
+ filterbanklength
+ filterbanklengthcoef
+ cqt
+ icqt
+ erblett
+ ierblett
+ insdgfb
+ cqtfilters
+ erbfilters
+ filterbankdual
+ filterbanktight
+ filterbankrealdual
+ filterbankrealtight
+ filterbankbounds
+ filterbankrealbounds
+ filterbankresponse
+ plotfilterbank
+fourier
+ fftindex
+ modcent
+ floor23
+ floor235
+ ceil23
+ ceil235
+ nextfastfft
+ dft
+ idft
+ fftreal
+ ifftreal
+ gga
+ chirpzt
+ plotfft
+ plotfftreal
+ involute
+ peven
+ podd
+ pconv
+ convolve
+ pxcorr
+ isevenfunction
+ middlepad
+ expwave
+ pchirp
+ shah
+ pheaviside
+ prect
+ psinc
+ pgauss
+ psech
+ pbspline
+ firwin
+ firkaiser
+ fir2long
+ long2fir
+ firfilter
+ blfilter
+ warpedblfilter
+ pfilt
+ magresp
+ transferfunction
+ pherm
+ hermbasis
+ dfracft
+ ffracft
+ fftresample
+ dctresample
+ pderiv
+ dcti
+ dctii
+ dctiii
+ dctiv
+ dsti
+ dstii
+ dstiii
+ dstiv
+frames
+ frame
+ framepair
+ framedual
+ frametight
+ frameaccel
+ frana
+ frsyn
+ frsynmatrix
+ framediag
+ franaiter
+ frsyniter
+ plotframe
+ framegram
+ framebounds
+ framered
+ framelength
+ framelengthcoef
+ framecoef2native
+ framenative2coef
+ framecoef2tf
+ frametf2coef
+ franalasso
+ franagrouplasso
+ frsynabs
+base
+ ltfatstart
+ ltfatstop
+ ltfathelp
+ ltfatmex
+ ltfatbasepath
+ isoctave
+ ltfatarghelper
+ ltfatgetdefaults
+ ltfatsetdefaults
+ scalardistribute
+ mulaclab
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..cccfb02
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,65 @@
+Version 1.4.4
+
+* New routines for calculating Gabor dual widows using convex optimization
+
+* New block processing demos: sliding CQT and Erblets
+
+
+Version 1.4.3
+
+* Added chirped Z-transform
+
+* Block processing demos now work in Octave (on Linux)
+
+* New zoomig features for blockplot
+
+Version 1.4.2
+
+* The filterbanks algorithms are now much faster because all the algorithms have been implemented in the C backend
+  
+* franalasso can now use the the FISTA algorithm
+
+* A generalization of the Goertzel algorithm "gga" has been added". 
+
+Version 1.4.1
+
+* Major change in the output format from the wfilt_ functions
+
+* Experimental filter backend added to handle filters defined on the
+  frequency side.
+
+* Bugs fixed for mex interfaces compilation on Mac
+
+---------- LTFAT 1.4 ------------------------------------------
+
+The major feature of the 1.4 series is that the backend now also works
+in single precision. Work on the wavelet toolbox is still ongoing.
+
+---------- LTFAT 1.3 ------------------------------------------
+
+This is a development release. It is fully backwards compatible with
+the LTFAT version 1.0 and 1.2 series and contain bugfixes, but the
+contents of the "wavelets" subdirectory is in development, and the
+interfaces described herein may change during the 1.3 development
+cycle.
+
+---------- LTFAT 1.2 ------------------------------------------
+
+Version 1.2 is backwards comptatible with the 1.0 series, but
+introduces the "frames" framework, which is an object-oriented
+interface to the various frames in LTFAT. It does not actually use the
+object oriented features in Octave / Matlab, instead it uses a simple
+struct to keep track of things.
+
+-------- LTFAT 1.0 ---------------------------
+
+The Linear Time-Frequency Analysis Toolbox (LTFAT) is a free software
+toolbox (GPLv3) written in the Matlab/Octave scripting language. It
+comprises more than 200 different functions in the area of Fourier
+analysis, signal processing and time-frequency analysis.
+
+The toolbox can be downloaded from http://ltfat.sourceforge.net.
+
+The toolbox can be used for both educational, research and
+computational purposes. It has a backend implemented in C, which can
+be compiled to speed up all computational intensive functions.
diff --git a/PKG_ADD b/PKG_ADD
new file mode 100644
index 0000000..f11ce42
--- /dev/null
+++ b/PKG_ADD
@@ -0,0 +1,6 @@
+# Only execute it if it exists on the path. PKG_ADD also gets called from the directory
+# where the binaries are installed, and here ltfatstart should not be called.
+if exist("ltfatstart","file")   
+  # Start ltfat quietly 
+  ltfatstart(0);
+end;
diff --git a/inst/AUTHORS b/inst/AUTHORS
new file mode 100644
index 0000000..239395c
--- /dev/null
+++ b/inst/AUTHORS
@@ -0,0 +1,5 @@
+Peter Soendergaard   <Peter.Soendergaard at oeaw.ac.at>
+Zdenek Prusa         <Zdenek.Prusa at oeaw.ac.at>
+Peter Balazs         <Peter.Balazs at oeaw.ac.at>
+Bruno Torresani      <Bruno.Torresani at univ-provence.fr>
+Hans G. Feichtinger  <hans.feichtinger at univie.ac.at>
diff --git a/inst/ChangeLog b/inst/ChangeLog
new file mode 100644
index 0000000..5df96e8
--- /dev/null
+++ b/inst/ChangeLog
@@ -0,0 +1,377 @@
+Version 1.4.4 25/2 2014
+	* Mostly bug fixes and doc updates. 
+
+	* Reworked build system on Linux and Mac OS.
+
+	* Most of the code moved from Mex/Oct interfaces to the backend.
+
+	* The C code was revised: consistence of argument naming and order,
+	                          introduced ltfatInt data type for array
+							  lengths.
+
+	* New block processing demos: real-time CQT and Erblets
+	  (fast enough only in Matlab).
+
+	* Added routines for calculating Gabor dual frames using convex optimization
+	  (requires UNLocBoX http://unlocbox.sourceforge.net/).
+
+	* Improved usability of the blockproc GUI: Added possibility to set initial 
+	  window positions, capturing Ctrl-C shortcut.
+
+	* Closed #22: Wilson and MDCT transforms are now completely implemented in C.
+
+	* Renamed framematrix to frsynmatrix
+
+
+Version 1.4.3 22/11 2013
+    * Fixed bug in nsgabframebounds.m
+
+    * Added chirped Z-transform
+
+    * Block processing demos now work in Octave (on Linux)
+
+    * Backend library now uses C99 complex number format only
+
+    * Faster block processing via block_interface MEX function
+
+    * New zoomig features for blockplot
+
+Version 1.4.2 17/9 2013
+	* Added mexExecuter to speed up cell array handling in the backends
+
+	* All filterbank algorithms are now in the backend
+
+	* franalasso now packs the FISTA algorithm
+
+	* More block processing demos: pitch shifting
+
+	* Added the generalized Goertzel algorithm
+
+Version 1.4.1 18/7 2013
+	* Major change in the output format from the wfilt_ functions. If
+	a wfilt_ function generates a tigth frames, its two outputs are
+	now identical.
+
+	* Close #67, #68, Mex compilation now works on Mac
+
+	* Experimental filter backend added to handle filters defined on
+	the frequency side and on the time side using structs and
+	anonymous functions
+
+	* Limited support for fractional downsampling in filters and filterbanks
+
+	* erbfilters routine added to generate Erb-spaced filterbanks
+
+	* Fixed bug #6, demo_audioshrink now works again
+
+	* All DCT and DST routines now call FFTW directly.
+
+	* Fixed bug #55, FWT on Octave can now handle complex values
+
+	* Added floor23, floor234, ceil23 and ceil235 to find the next
+	nice number. Useful for constructing downsampling rates in
+	filterbanks.
+
+Version 1.4.0 3/6 2013
+	* All routines calling the C backend now support single precision
+
+	* Frames framework has been rewritten for greater speed using
+	anonymous functions
+
+	* New "operators" directory for the comming inclusion of more
+	operator classes
+
+	* First alpha version of the block processing framework introduced
+	in "blocks"
+
+	* The noshearlength routine computes next efficient transform length
+	for a Gabor system on a non-separable lattice
+
+	* The frames framework now support non-stationary Gabor systems
+
+	* Compilation of functions calling BLAS and LAPACK has been fixed,
+	so gabdual and gabtight now works in C on all platforms
+
+	* Better speed when computing many Hermite functions, support for
+	orthonormalization in the sampled continous case
+
+	* Fast and discrete fractional Fourier transform added
+
+	* cqt and erblett transforms added
+
+Version 1.3.1 5/4 2013
+	* Fixed compilation on Unix
+
+	* Wavelets now works in Octave
+
+	* Improved firwin featuring all the windows from the Nuttall paper
+
+Version 1.3.0 20/3 2013
+	* This is the first full release of the wavelets. Too many changes
+	to list here, but the major features are listed below:
+
+	* fwt - Fast wavelet transform
+
+	* fwt2 - 2D FWT with different layouts
+
+	* ufwt - Undecimated FWT
+
+	* wfbt - Wavelet filter bank tree
+
+	* wpfbt - Wavelet packet filter bank tree
+
+	* wpbest - Best basis search of a wavelet packet tree
+
+	* wfilt_ functions defines a lot of different possible wavelet and
+	scaling functions.
+
+	* Mex compiled code is now supported for Windows 64 bit (Windows
+	Vista, 7). Support for Windows 32 has been dropped.
+
+	* Color test image, lichenstein, added and jpeg color model
+	support in rgb2jpeg
+
+	* frame multipliers added with the usual functions, framemul,
+	framemulinv, framemuladj, framemuleigs and framemulappr
+
+Version 1.2.0 13/12 2012
+	* Full support for non-separable Gabor lattices with support in
+	the C backend.
+
+	* Improved non-stationary Gabor systems: bugfixes for system with
+	odd-length shifts, tester has been extented to cover all these
+	cases.
+
+	* Iterative analysis and synthesis for frames: franaiter and
+	frsyniter uses the conjugate gradients algorithm.
+
+	* The "frames" framework has changed so that each frame object
+	only includes one frame. This means that you will need to create
+	two frames if you want to perform analysis/synthesis with a
+	bi-orthogonal / canonical dual system. On the other hand, a lot of
+	duplication was removed.
+
+	* Small bugfixes: idgt2, gabdualnorm
+
+Version 1.1.2 2/10 2012
+	* Almost full support for non-separable Gabor laticces
+
+	* Multi-win support re-enabled in gabdual and gabtight
+
+	* Demos finally converted to new documentation system
+
+Version 1.1.1 30/3 2012
+	* Initial inclusion of the frames framework
+
+	* New and more flexible groupthresh
+
+	* Much improved framelasso and framegrouplasso replaces the old
+	lasso methods
+
+Version 1.0.0 16/6 2011
+	* Auditory scales: Erb, bark, mel
+
+	* Gammatone filters.
+
+	* Filterbanks with a full set of support functions.
+
+	* non-stationary Gabor frames with a full set of support
+	functions.
+
+	* rangecompress and rangeexpand does ulaw and alaw.
+
+	* cocktailparty test signal replaces older 'greasylong'
+
+	* plot functions for visualizing coefficients of all transforms.
+
+	* C implementation improved: speedup in gabdual and gabtight,
+	implementation of dgtreal, pfilt and ufilterbank.
+
+	* nextfastfft computes next larger problem size with a fast FFT.
+
+	* isgramreal can use BFGS method, requires external software.
+
+Version 0.98.2 25/3 2011
+	* Added C code for IDGT using FIR filters.
+
+	* WinXP compilation now works without LCC.
+
+Version 0.98.1 25/2 2011
+	* New iterative spectrogram reconstruction featuring the word "LTFAT".
+
+	* Features added to ltfatarghelper to support importing definitions
+	from aux. functions.
+
+Version 0.98 28/1 2011
+
+	* The flags 'freqinv' and 'timeinv' can be passed to the DGT, IDGT,
+	DGTREAL and IDGTREAL to select a time- or frequency-invariant phase.
+
+	* Three new functions to ramp a signal (create a smooth transition
+	from 0 to 1), RAMPUP, RAMPDOWN and RAMPSIGNAL.
+
+	* nuttall window added to FIRWIN. General cleanup of FIRWIN. If is
+	now possible to taper the window in the middle.
+
+	* Support for different normalization of the function in all
+	window functions. This is done through the function NORMALIZE.
+
+	* PGAUSS takes options for shifting the center frequency and
+	specifying the bandwidth, in both samples or Hz.
+
+	* PINKNOISE: Pink noise generator.
+
+	* ISGRAM: Spectrogram reconstruction using the classical iterative
+	method by Griffin and Lim.
+
+	* ELITISTHRESH: Elitist LASSO thresholding.
+
+	* PRECT and PSINC: periodic rectangular and periodic Sinc function.
+
+Version 0.97.2:
+
+	* The GPC source code is now distributed with LTFAT. A popup
+	dialog has been added to mulaclab to explan the license
+	conditions.
+
+	* The algorithm for computing dgtreal with a FIR window is now
+          implemented in C.
+
+Version 0.97.1:
+
+	* Support for Octave on Windows XP.
+
+	* It is now possible to specify various targets and commands in
+	ltfatmex.
+
+Version 0.97
+
+	* Toolbox is now built upon a standalone C library.
+
+	* The 'mulaclab' is a graphical user interface for
+          manipulating the spectrogram of a signal. The gui works only
+          in Matlab.
+
+	* All functions in the LTFAT C library are now available in
+          both single and double precision
+
+	* Compilation and interfaces for both Matlab and Octave
+          interfaces now works on Windows XP.
+
+ 	* It is now possible to supply a window described by a text
+          string or a cell array to all relevant functions. See the
+          help on gabwin or wilwin for a description of the
+          possibilities.
+
+	* Much better support for optional arguments in functions, and
+          for setting default at startup. See the function
+          ltfatsetdefaults, ltfatgetdefaults and ltfatarghelper
+
+        * GABRIESZBOUNDS: compute Gabor Riesz bounds for a Gabor Riesz
+            sequence.
+
+	* WIL2RECT and RECT2WIL: arrange Wilson coefficients in a
+          rectangular shape (with holes) at the correct position in
+          the TF-plane.
+
+        * PEVEN and PODD extracts the even and odd part of a signal.
+
+Version 0.96 12/1 2009 svn no 728
+	* Matlab MEX compilation now works under Windows. See the
+	instructions in the INSTALL file.
+
+	* Speed optimizations in the C-code used by DGT, DWILT and MDCT
+	and their inverses.
+
+	* New functions DGTREAL and IDGTREAL works with the positive
+	frequencies of the DGT of real valued signals.
+
+	* New functions FFTREAL computes only the positive frequencies of
+	the FFT of a real valued input signal.
+
+	* More systematic naming of functions:
+		CANDUAL -> GABDUAL
+		CANTIGHT -> GABTIGHT
+		MIXDUAL -> GAMIXDUAL
+		PROJDUAL -> GABPROJDUAL
+		GFBOUNDS -> GABFRAMEBOUNDS and GABRIESZBOUNDS
+		TF_ADAPTLASSO -> GABELITISTLASSO
+		TF_GROUPLASSO -> GABGROUPLASSO
+
+	* Reassignment is a method for sharpening the spectrogram. Support
+	for reassignment is included in the new function REASSIGN and an
+	easy to use plot RESGRAM.
+
+	* Easy to use plot for plotting instantantaneous frequency:
+	INSTFREQPLOT
+
+	* Three different methos for computing instantaneous time and
+	frequency: INSTTFDGT, INSTTFPHASE and INSTTFABS.
+
+	* General speedup of many of the SPREAD* routines based on speedup
+	in COL2DIAG and more efficient algorithms for sparse matrices.
+
+	* COL2DIAG provides the basic coordinate change needed for
+	efficient implementation of spreading function methods. COL2DIAG
+	has a C-implementation.
+
+	* New function WIL2RECT converts Wilson coefficients from the
+	standard compact layout to a more loose layout, where the
+	coefficients are appropriatly placed on the TF-plane. The
+	rectangular format is welll suited for visualizing Wilson
+	coefficients.
+
+	* The functionality of GFBOUNDS was split into two methods
+	computing either frame bounds or Riesz basis bounds
+
+	* Dynamic range in SGRAM and RESGRAM is now specified by the
+	'dynrange' parameter instead of previously 'range'.
+
+	* greasylong and doppler signals added.
+
+	* Periodic Heaviside function added, PHEAVISIDE.
+
+	* Simple exponential wave added as EXPMODE.
+
+Version 0.95 6/3 2008 svn no. 595
+
+	* DCT based resampling function.
+
+Version 0.94 24/10 2007 svn no. 556
+
+	* Numerically stable computation of Hermite functions. Thanks to
+	Thomasz Hrycak.
+
+	* gabmulappr (approximation of an operator by a Gabor multiplier)
+	now works with fast algorithm.
+
+	* group lasso shrinkage and adaptive lasso shrinkage added with an
+	example (examp_audioshrink)
+
+	* Removed all support of lattices in the spreading operator
+	routines, as this is not practically usefull.
+
+	* Special support in candual for windows shorter than the number
+	of channels.
+
+	* The configure style system has been removed. Use ltfatmex instead.
+
+	* phaseplot now uses the phaselocked dgt by default.
+
+
+Version 0.93 10/8 2007 svn no. 504
+
+	* Easy compilation of Mex/Octave interfaces by 'ltfatmex' command
+
+	* Bug fixed for Wilson bases.
+
+	* Better support of choosing an alternative dimension for the
+	various transforms.
+
+	* fmax option added to sgram
+
+	* fftresample does Fourier interpolation 
+
+	* phaseplot changed to always do full STFT 
+
+	* moved to GPL v 3.0 license
diff --git a/inst/Contents.m b/inst/Contents.m
new file mode 100644
index 0000000..d0fdb11
--- /dev/null
+++ b/inst/Contents.m
@@ -0,0 +1,42 @@
+% LTFAT - Base routines
+%
+%  Peter L. Soendergaard, 2009 - 2014.
+%
+%  Basic routines
+%    LTFATSTART       -  Start the toolbox
+%    LTFATSTOP        -  Stop the toolbox
+%    LTFATHELP        -  Help
+%    LTFATMEX         -  Compile Mex/Oct interfaces
+%    LTFATBASEPATH    -  Return the base path
+%    ISOCTAVE         -  True if interpreter is Octave
+%
+%  Parameter handling
+%    LTFATARGHELPER   -  Handle optional parameters of functions
+%    LTFATGETDEFAULTS -  Get the default values for a function
+%    LTFATSETDEFAULTS -  Get the default values for a function
+%    SCALARDISTRIBUTE -  Expand parameters to common size
+%
+%  Graphical user interfaces
+%    MULACLAB         -  Short Time-Fourier transform modification in Matlab
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/DESCRIPTION b/inst/DESCRIPTION
new file mode 100644
index 0000000..a8f59d9
--- /dev/null
+++ b/inst/DESCRIPTION
@@ -0,0 +1,16 @@
+Name: LTFAT
+Version: 1.4.4
+Date: 2014-3-20
+Author: Peter L. Soendergaard <soender at users.sourceforge.net>
+Maintainer: Zdenek Prusa
+Title: The Large Time-Frequency Analysis Toolbox
+Description: The Large Time/Frequency Analysis Toolbox (LTFAT) is a
+ Matlab/Octave toolbox for working with time-frequency analysis,
+ wavelets and signal processing. It is intended both as an educational
+ and a computational tool. The toolbox provides a large number of
+ linear transforms including Gabor and wavelet transforms along with
+ routines for constructing windows (filter prototypes) and routines
+ for manipulating coefficients.
+License: GPLv3+
+BuildRequires: fftw3, lapack, blas, portaudio 
+Url: http://ltfat.sourceforge.net/
diff --git a/inst/INDEX b/inst/INDEX
new file mode 100644
index 0000000..cab4e85
--- /dev/null
+++ b/inst/INDEX
@@ -0,0 +1,365 @@
+ltfat >> Time-frequency analysis and Wavelets
+signals
+ ctestfun
+ noise
+ pinknoise
+ expchirp
+ bat
+ batmask
+ greasy
+ cocktailparty
+ gspi
+ linus
+ ltfatlogo
+ otoclick
+ traindoppler
+ cameraman
+ lichtenstein
+ ltfattext
+operators
+ operatornew
+ operator
+ ioperator
+ operatoradj
+ operatorappr
+ operatoreigs
+ operatormatrix
+ framemul
+ iframemul
+ framemuladj
+ framemulappr
+ framemuleigs
+ gabmulappr
+ spreadop
+ spreadinv
+ spreadadj
+ spreadfun
+ spreadeigs
+deprecated
+ gabelitistlasso
+ gabgrouplasso
+ gablasso
+ gabmuleigs
+ gabmul
+ framematrix
+ iufilterbank
+ iunsdgt
+ iunsdgtreal
+ tfmat
+sigproc
+ rms
+ normalize
+ gaindb
+ crestfactor
+ uquant
+ rampup
+ rampdown
+ rampsignal
+ thresh
+ largestr
+ largestn
+ dynlimit
+ groupthresh
+ rgb2jpeg
+ jpeg2rgb
+ qam4
+ iqam4
+gabor
+ tconv
+ dsft
+ zak
+ izak
+ col2diag
+ s0norm
+ dgt
+ idgt
+ isgram
+ isgramreal
+ dgt2
+ idgt2
+ dgtreal
+ idgtreal
+ gabwin
+ dgtlength
+ dwilt
+ idwilt
+ dwilt2
+ idwilt2
+ wmdct
+ iwmdct
+ wmdct2
+ iwmdct2
+ wil2rect
+ rect2wil
+ wilwin
+ dwiltlength
+ gabdual
+ gabtight
+ gabfirdual
+ gaboptdual
+ gabfirtight
+ gabopttight
+ gabconvexopt
+ gabprojdual
+ gabmixdual
+ wilorth
+ wildual
+ gabframebounds
+ gabrieszbounds
+ wilbounds
+ gabdualnorm
+ gabframediag
+ wilframediag
+ gabphasegrad
+ gabreassign
+ phaselock
+ phaseunlock
+ symphase
+ matrix2latticetype
+ latticetype2matrix
+ shearfind
+ noshearlength
+ tfplot
+ plotdgt
+ plotdgtreal
+ plotdwilt
+ plotwmdct
+ sgram
+ gabimagepars
+ resgram
+ instfreqplot
+ phaseplot
+blockproc
+ block
+ blockdevices
+ blockread
+ blockplay
+ blockpanel
+ blockpanelget
+ blockdone
+ blockframeaccel
+ blockframepairaccel
+ blockana
+ blocksyn
+ blockfigure
+ blockplot
+ block_fwt
+ block_ifwt
+demos
+ demo_dgt
+ demo_gabfir
+ demo_imagecompression
+ demo_audiocompression
+ demo_audiodenoise
+ demo_ofdm
+ demo_audioshrink
+ demo_gabmulappr
+ demo_nsdgt
+ demo_pgauss
+ demo_pbspline
+ demo_gabmixdual
+ demo_framemul
+ demo_phaseplot
+ demo_frsynabs
+ demo_nextfastfft
+ demo_audscales
+ demo_auditoryfilterbank
+ demo_blockproc_basicloop
+ demo_blockproc_paramequalizer
+ demo_blockproc_denoising
+ demo_blockproc_slidingsgram
+ demo_blockproc_slidingcqt
+ demo_blockproc_slidingerblets
+ demo_blockproc_pitchshift
+ demo_blockproc_dgtequalizer
+auditory
+ semiaudplot
+ audtofreq
+ freqtoaud
+ audspace
+ audspacebw
+ erbtofreq
+ freqtoerb
+ erbspace
+ erbspacebw
+ audfiltbw
+ rangecompress
+ rangeexpand
+ gammatonefir
+nonstatgab
+ nsdgt
+ unsdgt
+ insdgt
+ nsdgtreal
+ unsdgtreal
+ insdgtreal
+ nsgabdual
+ nsgabtight
+ nsgabframebounds
+ nsgabframediag
+ plotnsdgt
+ plotnsdgtreal
+wavelets
+ fwt
+ ifwt
+ fwt2
+ ifwt2
+ ufwt
+ iufwt
+ fwtlength
+ fwtclength
+ wfbt
+ iwfbt
+ uwfbt
+ iuwfbt
+ wpfbt
+ iwpfbt
+ uwpfbt
+ iuwpfbt
+ wpbest
+ wfbtlength
+ wfbtinit
+ wfbtput
+ wfbtremove
+ wfbt2filterbank
+ fwt2filterbank
+ fwtinit
+ plotwavelets
+ wfiltinfo
+ wavfun
+ wavcell2pack
+ wavpack2cell
+ wfilt_algmband
+ wfilt_apr
+ wfilt_db
+ wfilt_dden
+ wfilt_dgrid
+ wfilt_dtree
+ wfilt_hden
+ wfilt_lemarie
+ wfilt_matlabwtwrapper
+ wfilt_maxflat
+ wfilt_mband
+ wfilt_optfs
+ wfilt_remez
+ wfilt_symds
+ wfilt_spline
+ wfilt_sym
+ wfreq_lemarie
+filterbank
+ filterbank
+ ufilterbank
+ ifilterbank
+ filterbankwin
+ filterbanklength
+ filterbanklengthcoef
+ cqt
+ icqt
+ erblett
+ ierblett
+ insdgfb
+ cqtfilters
+ erbfilters
+ filterbankdual
+ filterbanktight
+ filterbankrealdual
+ filterbankrealtight
+ filterbankbounds
+ filterbankrealbounds
+ filterbankresponse
+ plotfilterbank
+fourier
+ fftindex
+ modcent
+ floor23
+ floor235
+ ceil23
+ ceil235
+ nextfastfft
+ dft
+ idft
+ fftreal
+ ifftreal
+ gga
+ chirpzt
+ plotfft
+ plotfftreal
+ involute
+ peven
+ podd
+ pconv
+ convolve
+ pxcorr
+ isevenfunction
+ middlepad
+ expwave
+ pchirp
+ shah
+ pheaviside
+ prect
+ psinc
+ pgauss
+ psech
+ pbspline
+ firwin
+ firkaiser
+ fir2long
+ long2fir
+ firfilter
+ blfilter
+ warpedblfilter
+ pfilt
+ magresp
+ transferfunction
+ pherm
+ hermbasis
+ dfracft
+ ffracft
+ fftresample
+ dctresample
+ pderiv
+ dcti
+ dctii
+ dctiii
+ dctiv
+ dsti
+ dstii
+ dstiii
+ dstiv
+frames
+ frame
+ framepair
+ framedual
+ frametight
+ frameaccel
+ frana
+ frsyn
+ frsynmatrix
+ framediag
+ franaiter
+ frsyniter
+ plotframe
+ framegram
+ framebounds
+ framered
+ framelength
+ framelengthcoef
+ framecoef2native
+ framenative2coef
+ framecoef2tf
+ frametf2coef
+ franalasso
+ franagrouplasso
+ frsynabs
+base
+ ltfatstart
+ ltfatstop
+ ltfathelp
+ ltfatmex
+ ltfatbasepath
+ isoctave
+ ltfatarghelper
+ ltfatgetdefaults
+ ltfatsetdefaults
+ scalardistribute
+ mulaclab
diff --git a/inst/INSTALL b/inst/INSTALL
new file mode 100644
index 0000000..e3874f5
--- /dev/null
+++ b/inst/INSTALL
@@ -0,0 +1,23 @@
+
+--------- Running the toolbox --------------------
+
+In Matlab or Octave type "ltfatstart" as the first command from the
+installation directory. This will set up the correct paths.
+
+In Octave you can put this command in your ~/.octaverc file. In Matlab
+you can put this command in your startup.m file. Your startup file of
+choice should contain some lines like this:
+
+addpath /path/to/ltfat
+ltfatstart;
+
+The ltfatstart command will add all the necessary subdirectories (so
+please don't add these manually), and it will print a statement
+telling you which backend you are currently using.
+
+-------- Compiling the toolbox ------- ------------
+
+- If you wish to use the toolbox with Matlab, see the file INSTALL-Matlab
+
+- If you wish to use the toolbox with Octave, see the file INSTALL-Octave
+
diff --git a/inst/INSTALL-Matlab b/inst/INSTALL-Matlab
new file mode 100644
index 0000000..8ddb1b3
--- /dev/null
+++ b/inst/INSTALL-Matlab
@@ -0,0 +1,116 @@
+-------- Compatibility ----------------------------------
+
+The toolbox should work and compile on all versions of Matlab later than 2009b.
+
+-------- What can be compiled -------------------------------
+
+- Static backend libraries libltfat.a, libltfatf.a
+                   OR
+  Shared backend libraries ltfat.dll, ltfatf.dll on Windows.
+
+- Fast Mex-interfaces linking to the backend libs.
+
+- Mex-interface PolygonClip using Generic Polygon Clipper
+
+Block processing framework (optional)
+
+- Mex-interface playrec
+
+- Java classes for blockproc GUI
+
+-------- Compiling backend libs and the MEX interfaces  ----------------
+
+LTFAT comes with C Mex interfaces to replace (shadow) all computationally
+intensitive functions in the toolbox.
+
+To compile the Mex-interfaces, type "ltfatmex" on the Matlab command
+prompt. This will compile the backend libraries and all the available
+mex-functions and also the PoligonClip mex function.
+
+If you have downloaded a binary release, everything is already
+compiled and you should not need to do anything else.
+
+The Mex-files and the backend libs links to certain additional libraries,
+which has to be present at your system. The library management varies between
+OS see below. 
+The depending libraries are:  FFTW3, BLAS, LAPACK
+
+--------- Compiling on MacOS -------------------------------------------
+
+On MacOS, you must have the gcc compiler and the FFTW libraries
+installed. Then just type "ltfatmex" and everything should work, because
+BLAS and LAPACK libraries are taken directly from Matlab.
+
+--------- Compiling on Microsoft Windows -------------------------------
+
+On Windows we rely on the MinGW compiler system: 
+
+- Install MinGW compiler system. The easiest is to download and install
+  TDM-GCC compiler suite from http://tdm-gcc.tdragon.net/download. 
+  After installation, ensure that the [MinGW]/bin directory is in the 
+  system PATH, where [MinGW] stands for installation directory.
+  
+- Manually install binaries of FFTW. The easiest way is to download 
+  them from http://www.fftw.org/install/windows.html. Copy all *.dll files
+  to the ltfat/mex directory.
+  
+- Run "ltfatmex".
+
+BLAS and LAPACK libraries are taken directly from the Matlab installation.
+Both 32bit and 64bit versions of Matlab are supported. Please use appropriate
+versions of FFTW and TDM-GCC.
+
+--------- Compiling on Linux ------------------------------------
+
+The dependencies are all standard packages in most Linux distributions.
+They have to be installed prior to running "ltfatmex".
+
+- On Redhat / Fedora, install the packages 'fftw-devel',
+  'lapack-devel' and 'blas-devel' and their dependcies.
+
+- On Debian / Ubuntu, install the packages 'libfftw3-dev',
+  'libblas-dev' and 'liblapack-dev'.
+
+
+--------- Compiling parts for block processing framework -----------
+
+Everything should be already compiled if you have downloaded the binary release.
+
+In order to get the block processing framework working from the source, one
+has to compile the MEX interface playrec and the JAVA GUI classes. This can be
+done by typing
+
+"ltfatmex playrec" and "ltfatmex java".
+
+Playrec MEX depends on the PORTAUDIO library, which has to be installed on your
+system prior running the commands. Compiling JAVA classes requires Java Development
+Kit to be installed.
+NOTE: Compiled Java classes (packed in blockproc.jar) are platform independent
+so compiling it and installing JDK can be avoided by taking the archive from any
+binary LTFAT package (from ltfat/blockproc/java).
+
+
+--------- Compiling on Mac ------------
+
+TBD.
+
+--------- Compiling on Microsoft Windows --------------------------
+
+Unfortunately, portaudio on Windows is not distributed in a binary package.
+One can follow instructions on http://www.portaudio.com/ to compile the library
+from the source with support for different sound APIs like DirectSound, MME,
+WASAPI, ASIO. Build a shared (dynamically linked) library (dll) and copy it to
+the ltfat/thirdparty/Playrec directory.
+
+Alternatively, when no such library is found in ltfat/thirdparty/Playrec, 
+ltfatmex attempts to link portaudio library shipped with Matlab. Expect much 
+worse audio performance in this case.
+
+--------- Compiling on Linux ------------------------------------
+
+- On Redhat / Fedora TBD
+
+- On Debian / Ubuntu, install the packages 'portaudio19-dev', 'openjdk-7-jdk' 
+
+Recent versions of Matlab already contain the portaudio lib so there is no need
+for installing it. 
diff --git a/inst/INSTALL-Octave b/inst/INSTALL-Octave
new file mode 100644
index 0000000..973d2a1
--- /dev/null
+++ b/inst/INSTALL-Octave
@@ -0,0 +1,76 @@
+-------- Compatibility ----------------------------------
+
+The toolbox should work and compile on all versions of Octave later
+than version 3.0, but it is generally recommended to upgrade to the
+latest stable release of Octave. For demos etc. to work, you will need
+to install some of the Octave-forge packages.
+
+LTFAT >=1.4.2 is also itself an Octave-forge package and the easiest
+way to install everything is by typing
+
+pkg install -forge ltfat
+
+on the octave prompt, which downloads ltfat directly from the 
+Octave-forge and compiles all. This however was tested only on Linux.
+Since you are reading this you have probably downloaded ltfat from
+elsewhere and you want to compile sources by yourself. 
+
+-------- What can be compiled -------------------------------
+
+- Static backend libraries libltfat.a, libltfatf.a
+
+- Fast Oct-interfaces linking to the backend libs.
+
+Block processing framework (optional, experimental, only on Linux)
+
+- Mex-interface playrec
+
+- Java classes for blockproc GUI
+
+-------- Compiling backend libs and the Octave interfaces  -------------
+
+LTFAT comes with C++ Octave interfaces to replace (shadow) all computationally
+intensitive functions in the toolbox.
+
+To compile the Octave interfaces, type "ltfatmex" on the Octave
+command prompt. This will compile the ltfat C library and all the
+available oct-functions.
+
+LTFAT backend lib and Oct-interfaces depends on the following
+libraries: FFTW3, BLAS, LAPACK, which are usually distributed with
+Octave itself, so there is no need for installing them separately.
+
+--------- Compiling on MacOS ------------------------------------------
+
+TBD
+
+--------- Compiling on Microsoft Windows ------------------------------
+
+Presently, Octave binary distribution for Windows comes in 32bit version only.
+We recommend using the package with the MinGW installer. It comes with the 32bit
+MinGW compiler system. It is important to add the following two entries to the PATH 
+variable:
+
+[OCTAVE]\bin\;[OCTAVE]\mingw\bin\; 
+
+where [OCTAVE] stands for the Octave installation directory.
+
+Then typing "ltfatmex" should compile the Oct-interfaces. 
+
+--------- Compiling on Linux ----------------------------------------
+
+To compile, you must have installed the Octave development package and
+all its dependencies (the 'mkoctfile' script must be available).
+This will also install all necessary libraries and header files needed
+for compilation.
+
+* On Fedora / Redhat this package is called "octave-devel"
+
+* On Debian / Ubuntu this package is called "octave-headers"
+
+Install the octave-forge packages to add extra toolboxes available for
+Octave.
+
+-------- Compiling parts for the block processing framework on Linux ----
+
+Please follow instructions in the INSTALL-Matlab.
diff --git a/inst/README b/inst/README
new file mode 100644
index 0000000..c25405f
--- /dev/null
+++ b/inst/README
@@ -0,0 +1,26 @@
+To use the toolbox, 'cd' to this directory and execute 'ltfatstart'.
+
+In Octave you can put this command in your ~/.octaverc file.
+
+Directory struture.
+
+The toolbox is organized in subdirectories as follows:
+
+  fourier     - Fourier analysis, DCT/DST transforms and filters.
+  gabor       - Gabor, Wilson and WMDCT analysis and synthesis functions.
+  filterbank  - Filter banks.
+  nonstatgab  - Non-stationary Gabor frames.
+  sparsereg   - Tools for sparse regression of Gabor and Wilson systems.
+  sigproc     - A collection of simple, signal processing tools.
+  auditory    - Auditory scales and common filters types.
+  demos       - Demos
+  signals     - Test signals for use with the examples.
+  comp        - Computational subroutines.
+                These should not be called directly.
+  src         - C implementation of the most computationally intensive
+               routines.
+  mex         - Mex files to speed up the toolbox (if compiled)
+  oct         - Octave C++-files to speed up the toolbox (if compiled)
+
+The file INSTALL contains instructions for compiling the C-library and 
+the Octave and Matlab interfaces.
\ No newline at end of file
diff --git a/inst/auditory/Contents.m b/inst/auditory/Contents.m
new file mode 100644
index 0000000..a3c26c2
--- /dev/null
+++ b/inst/auditory/Contents.m
@@ -0,0 +1,47 @@
+% LTFAT - Simple auditory processing
+%
+%  Peter L. Soendergaard, 2011 - 2014
+%
+%  Plots
+%     SEMIAUDPLOT      - 2D plot on auditory scale.
+%
+%  Auditory scales
+%     AUDTOFREQ        - Auditory unit to frequency conversion.
+%     FREQTOAUD        - Frequency to auditory unit conversion.
+%     AUDSPACE         - Auditory unit spaced vector
+%     AUDSPACEBW       - Auditory unit spaced vector by equal bandwidth.
+%     ERBTOFREQ        - Erb scale to frequency conversion.
+%     FREQTOERB        - Frequency to erb scale conversion.
+%     ERBSPACE         - Equidistant points on the erb scale.
+%     ERBSPACEBW       - Equidistant points by equal bandwidth.
+%     AUDFILTBW        - Bandwidth of audiory filters.
+%
+%  Range compression
+%     RANGECOMPRESS    - Compress range of signal (mu-law etc).
+%     RANGEEXPAND      - Expand range of signal.
+%
+%  Auditory filters
+%     GAMMATONEFIR     - Gammatone FIR approximation.
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/auditory/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
diff --git a/inst/auditory/audfiltbw.m b/inst/auditory/audfiltbw.m
new file mode 100644
index 0000000..e5b916c
--- /dev/null
+++ b/inst/auditory/audfiltbw.m
@@ -0,0 +1,59 @@
+function bw = audfiltbw(fc)
+%-*- texinfo -*-
+%@deftypefn {Function} audfiltbw
+%@verbatim
+%AUDFILTBW  Bandwidth of auditory filter
+%   Usage: bw = audfiltbw(fc)
+%
+%   AUDFILTBW(fc) returns the equivalent rectangular bandwidth of the
+%   auditory filter at center frequency fc. The function uses the
+%   relation
+%
+%      bw = 24.7 + fc/9.265
+%
+%   as estimated in Glasberg and Moore (1990)
+%
+%
+%   References:
+%     B. R. Glasberg and B. Moore. Derivation of auditory filter shapes from
+%     notched-noise data. Hearing Research, 47(1-2):103, 1990.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/audfiltbw.php}
+%@seealso{freqtoerb, erbspace}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+  
+% ------ Checking of input parameters ---------
+  
+error(nargchk(1,1,nargin));
+
+if ~isnumeric(fc) || any(fc(:)<0)
+  error('AUDFILTBW: fc must be non-negative.');
+end;
+
+% ------ Computation --------------------------
+
+% FIXME: What is the upper frequency for which the estimation is valid?
+
+bw = 24.7 + fc/9.265;
+
+
diff --git a/inst/auditory/auditoryinit.m b/inst/auditory/auditoryinit.m
new file mode 100644
index 0000000..acecdef
--- /dev/null
+++ b/inst/auditory/auditoryinit.m
@@ -0,0 +1,26 @@
+status=1;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} auditoryinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/auditoryinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/auditory/audspace.m b/inst/auditory/audspace.m
new file mode 100644
index 0000000..c0ca8b6
--- /dev/null
+++ b/inst/auditory/audspace.m
@@ -0,0 +1,83 @@
+function [y,bw] = audspace(flow,fhigh,n,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} audspace
+%@verbatim
+%AUDSPACE  Equidistantly spaced points on auditory scale
+%   Usage: y=audspace(scale,flow,fhigh,n);
+%
+%   AUDSPACE(flow,fhigh,n,scale) computes a vector of length n*
+%   containing values equidistantly scaled on the selected auditory scale
+%   between the frequencies flow and fhigh. All frequencies are
+%   specified in Hz.
+%
+%   See the help on FREQTOAUD to get a list of the supported values of the
+%   scale parameter.
+%  
+%   [y,bw]=AUDSPACE(...) does the same but outputs the bandwidth between
+%   each sample measured on the selected scale.
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/audspace.php}
+%@seealso{freqtoaud, audspacebw, audfiltbw}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+  
+%% ------ Checking of input parameters ---------
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+  
+% Default parameters.
+
+if ~isnumeric(flow) || ~isscalar(flow) 
+  error('%s: flow must be a scalar.',upper(mfilename));
+end;
+
+if ~isnumeric(fhigh) || ~isscalar(fhigh) 
+  error('%s: fhigh must be a scalar.',upper(mfilename));
+end;
+
+if ~isnumeric(n) || ~isscalar(n) || n<=0 || fix(n)~=n
+  error('%s: n must be a positive, integer scalar.',upper(mfilename));
+end;
+
+if flow>fhigh
+  error('%s: flow must be less than or equal to fhigh.',upper(mfilename));
+end;
+
+definput.import={'freqtoaud'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+
+%% ------ Computation --------------------------
+
+audlimits = freqtoaud([flow,fhigh],flags.audscale);
+
+y = audtofreq(linspace(audlimits(1),audlimits(2),n),flags.audscale);
+
+bw=(audlimits(2)-audlimits(1))/(n-1);
+
+% Set the endpoints to be exactly what the user specified, instead of the
+% calculated values
+y(1)=flow;
+y(end)=fhigh;
+
+
diff --git a/inst/auditory/audspacebw.m b/inst/auditory/audspacebw.m
new file mode 100644
index 0000000..67dc3b2
--- /dev/null
+++ b/inst/auditory/audspacebw.m
@@ -0,0 +1,113 @@
+function [y,n] = audspacebw(flow,fhigh,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} audspacebw
+%@verbatim
+%AUDSPACEBW  Auditory scale points specified by bandwidth
+%   Usage: y=audspacebw(flow,fhigh,bw,hitme);
+%          y=audspacebw(flow,fhigh,bw);
+%          y=audspacebw(flow,fhigh);
+%          [y,n]=audspacebw(...);
+%
+%   AUDSPACEBW(flow,fhigh,bw,scale) computes a vector containing values
+%   equistantly scaled between frequencies flow and fhigh on the
+%   selected auditory scale.  All frequencies are specified in Hz.The
+%   distance between two consecutive values is bw on the selected scale,
+%   and the points will be centered on the scale between flow and fhigh.
+%
+%   See the help on FREQTOAUD to get a list of the supported values of the
+%   scale parameter.
+%  
+%   AUDSPACEBW(flow,fhigh,bw,hitme,scale) will do as above, but one of
+%   the points is quaranteed to be the frequency hitme.
+%
+%   [y,n]=AUDSPACEBW(...) additionally returns the number of points n in
+%   the output vector y.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/audspacebw.php}
+%@seealso{freqtoaud, audspace, audfiltbw}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+  
+% ------ Checking of input parameters ---------
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(flow) || ~isscalar(flow) || flow<0
+  error('%s: flow must be a non-negative scalar.',upper(mfilename));
+end;
+
+if ~isnumeric(fhigh) || ~isscalar(fhigh) || fhigh<0
+  error('%s: fhigh must be a non-negative scalar.',upper(mfilename));
+end;
+
+if flow>fhigh
+  error('%s: flow must be less than or equal to fhigh.',upper(mfilename));
+end;
+
+definput.import={'freqtoaud'};
+definput.keyvals.hitme=[];
+definput.keyvals.bw=1;
+
+[flags,kv,bw]=ltfatarghelper({'bw','hitme'},definput,varargin);
+
+if ~isnumeric(bw) || ~isscalar(bw) || bw<=0 
+  error('%s: bw must be a positive scalar.',upper(mfilename));
+end;
+
+  
+%% ------ Computation --------------------------
+
+if isempty(kv.hitme)
+  % Convert the frequency limits to auds.
+  audlimits = freqtoaud([flow,fhigh],flags.audscale);
+  audrange  = audlimits(2)-audlimits(1);
+
+  % Calculate number of points, excluding final point
+  n         = floor(audrange/bw);
+
+  % The remainder is calculated in order to center the points
+  % correctly between flow and fhigh.
+  remainder = audrange-n*bw;
+
+  audpoints = audlimits(1)+(0:n)*bw+remainder/2;
+  
+  % Add the final point
+  n=n+1;  
+  
+else
+    
+  % Convert the frequency limits to auds.
+  audlimits    = freqtoaud([flow,fhigh,kv.hitme],flags.audscale);
+  audrangelow  = audlimits(3)-audlimits(1);
+  audrangehigh = audlimits(2)-audlimits(3);
+
+  % Calculate number of points, exluding final point.
+  nlow = floor(audrangelow/bw);
+  nhigh = floor(audrangehigh/bw);
+  
+  audpoints=(-nlow:nhigh)*bw+audlimits(3);
+  n=nlow+nhigh+1;
+end;
+
+y = audtofreq(audpoints,flags.audscale);
+
diff --git a/inst/auditory/audtofreq.m b/inst/auditory/audtofreq.m
new file mode 100644
index 0000000..bb070fc
--- /dev/null
+++ b/inst/auditory/audtofreq.m
@@ -0,0 +1,88 @@
+function freq = audtofreq(aud,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} audtofreq
+%@verbatim
+%AUDTOFREQ  Converts auditory units to frequency (Hz)
+%   Usage: freq = audtofreq(aud);
+%  
+%   AUDTOFREQ(aud,scale) converts values on the selected auditory scale to
+%   frequencies measured in Hz.
+%
+%   See the help on FREQTOAUD to get a list of the supported values of
+%   the scale parameter. If no scale is given, the erb-scale will be
+%   selected by default.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/audtofreq.php}
+%@seealso{freqtoaud, audspace, audfiltbw}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+
+%% ------ Checking of input parameters ---------
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+
+if ~isnumeric(aud) 
+  error('%s: aud must be a number.',upper(mfilename));
+end;
+
+definput.import={'freqtoaud'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+%% ------ Computation --------------------------
+  
+if flags.do_mel
+  freq = 700*sign(aud).*(exp(abs(aud)*log(17/7)/1000)-1);
+end;
+
+if flags.do_mel1000
+  freq = 1000*sign(aud).*(exp(abs(aud)*log(2)/1000)-1);
+end;
+
+if flags.do_erb
+  freq = (1/0.00437)*sign(aud).*(exp(abs(aud)/9.2645)-1);
+end;
+
+if flags.do_bark
+  % This one was found through http://www.ling.su.se/STAFF/hartmut/bark.htm
+  freq = sign(aud).*1960./(26.81./(abs(aud)+0.53)-1);
+end;
+
+if flags.do_erb83
+  freq = 14363./(1-exp(aud-43.0)/11.7)-14675;
+end;
+
+if flags.do_freq
+  freq=aud;
+end;
+
+if flags.do_log10
+   freq = 10^(aud);
+end
+
+if flags.do_semitone
+   freq = 10^(aud);
+end
+
+
+
diff --git a/inst/auditory/erbspace.m b/inst/auditory/erbspace.m
new file mode 100644
index 0000000..e35edb8
--- /dev/null
+++ b/inst/auditory/erbspace.m
@@ -0,0 +1,36 @@
+function [y,bw] = erbspace(flow,fhigh,n)
+%-*- texinfo -*-
+%@deftypefn {Function} erbspace
+%@verbatim
+%ERBSPACE  Equidistantly spaced points on erbscale
+%   Usage: y=erbspace(flow,fhigh,n);
+%
+%   This is a wrapper around AUDSPACE that selects the erb-scale. Please
+%   see the help on AUDSPACE for more information.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/erbspace.php}
+%@seealso{audspace, freqtoaud}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+  
+[y,bw] = audspace(flow,fhigh,n,'erb');
+
+
diff --git a/inst/auditory/erbspacebw.m b/inst/auditory/erbspacebw.m
new file mode 100644
index 0000000..7e26f30
--- /dev/null
+++ b/inst/auditory/erbspacebw.m
@@ -0,0 +1,37 @@
+function [y,n] = erbspacebw(flow,fhigh,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} erbspacebw
+%@verbatim
+%ERBSPACEBW  Erbscale points specified by bandwidth
+%   Usage: y=erbspacebw(flow,fhigh,bw,hitme);
+%          y=erbspacebw(flow,fhigh,bw);
+%          y=erbspacebw(flow,fhigh);
+%
+%   This is a wrapper around AUDSPACEBW that selects the erb-scale. Please
+%   see the help on AUDSPACEBW for more information.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/erbspacebw.php}
+%@seealso{audspacebw, freqtoaud}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+  
+[y,n] = audspacebw(flow,fhigh,varargin{:},'erb');
+
diff --git a/inst/auditory/erbtofreq.m b/inst/auditory/erbtofreq.m
new file mode 100644
index 0000000..922b513
--- /dev/null
+++ b/inst/auditory/erbtofreq.m
@@ -0,0 +1,44 @@
+function freq = erbtofreq(erb);
+%-*- texinfo -*-
+%@deftypefn {Function} erbtofreq
+%@verbatim
+%ERBTOFREQ  Converts erb units to frequency (Hz)
+%   Usage: freq = erbtofreq(erb);
+%  
+%   This is a wrapper around AUDTOFREQ that selects the erb-scale. Please
+%   see the help on AUDTOFREQ for more information.
+%
+%   The following figure shows the corresponding frequencies for erb
+%   values up to 31:
+%
+%     erbs=0:31;
+%     freqs=erbtofreq(erbs);
+%     plot(erbs,freqs);
+%     xlabel('Frequency / erb');
+%     ylabel('Frequency / Hz');
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/erbtofreq.php}
+%@seealso{audtofreq, freqtoaud}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+  
+freq = audtofreq(erb,'erb');
+
diff --git a/inst/auditory/freqtoaud.m b/inst/auditory/freqtoaud.m
new file mode 100644
index 0000000..cddfe3c
--- /dev/null
+++ b/inst/auditory/freqtoaud.m
@@ -0,0 +1,149 @@
+function aud = freqtoaud(freq,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} freqtoaud
+%@verbatim
+%FREQTOAUD  Converts frequencies (Hz) to auditory scale units
+%   Usage: aud = freqtoaud(freq,scale);
+%
+%   FREQTOAUD(freq,scale) converts values on the frequency scale (measured
+%   in Hz) to values on the selected auditory scale. The value of the
+%   parameter scale determines the auditory scale:
+%
+%     'erb'     A distance of 1 erb is equal to the equivalent rectangular
+%               bandwidth of the auditory filters at that point on the
+%               frequency scale. The scale is normalized such that 0 erbs
+%               corresponds to 0 Hz. The width of the auditory filters were
+%               determined by a notched-noise experiment. The erb scale is
+%               defined in Glasberg and Moore (1990). This is the default.
+%
+%     'mel'     The mel scale is a perceptual scale of pitches judged by
+%               listeners to be equal in distance from one another. The
+%               reference point between this scale and normal frequency
+%               measurement is defined by equating a 1000 Hz tone, 40 dB above
+%               the listener's threshold, with a pitch of 1000 mels.
+%               The mel-scale is defined in Stevens et. al (1937).
+%
+%     'mel1000'  Alternative definition of the mel scale using a break
+%                frequency of 1000 Hz. This scale was reported in Fant (1968). 
+%
+%     'bark'    The bark-scale is originally defined in Zwicker (1961). A
+%               distance of 1 on the bark scale is known as a critical
+%               band. The implementation provided in this function is
+%               described in Traunmuller (1990).
+%
+%     'erb83'   This is the original defintion of the erb scale given in
+%               Moore. et al. (1983).
+%
+%     'freq'    Return the frequency in Hz. 
+%
+%   If no flag is given, the erb-scale will be selected.
+%
+%
+%   References:
+%     S. Stevens, J. Volkmann, and E. Newman. A scale for the measurement of
+%     the psychological magnitude pitch. J. Acoust. Soc. Am., 8:185, 1937.
+%     
+%     E. Zwicker. Subdivision of the audible frequency range into critical
+%     bands (frequenzgruppen). J. Acoust. Soc. Am., 33(2):248-248, 1961.
+%     [1]http ]
+%     
+%     G. Fant. Analysis and synthesis of speech processes. In B. Malmberg,
+%     editor, Manual of phonetics. North-Holland, 1968.
+%     
+%     B. R. Glasberg and B. Moore. Derivation of auditory filter shapes from
+%     notched-noise data. Hearing Research, 47(1-2):103, 1990.
+%     
+%     H. Traunmuller. Analytical expressions for the tonotopic sensory scale.
+%     J. Acoust. Soc. Am., 88:97, 1990.
+%     
+%     B. Moore and B. Glasberg. Suggested formulae for calculating
+%     auditory-filter bandwidths and excitation patterns. J. Acoust. Soc.
+%     Am., 74:750, 1983.
+%     
+%     References
+%     
+%     1. http://link.aip.org/link/?JAS/33/248/1
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/freqtoaud.php}
+%@seealso{freqtoaud, audspace, audfiltbw}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+
+%% ------ Checking of input parameters ---------
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(freq) 
+  error('%s: freq must be number.',upper(mfilename));
+end;
+
+definput.import={'freqtoaud'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+%% ------ Computation --------------------------
+
+
+if flags.do_mel
+  aud = 1000/log(17/7)*sign(freq).*log(1+abs(freq)/700);
+end;
+
+if flags.do_mel1000
+  aud = 1000/log(2)*sign(freq).*log(1+abs(freq)/1000);
+end;
+
+if flags.do_erb
+  % There is a round-off error in the Glasberg & Moore paper, as
+  % 1000/(24.7*4.37)*log(10) = 21.332 and not 21.4 as they state.
+  % The error is tiny, but may be confusing.
+  % On page 37 of the paper, there is Fortran code with yet another set
+  % of constants:
+  %     2302.6/(24.673*4.368)*log10(1+freq*0.004368);
+  aud = 9.2645*sign(freq).*log(1+abs(freq)*0.00437);
+end;
+
+if flags.do_bark
+  % The bark scale seems to have several different approximations available.
+  
+  % This one was found through http://www.ling.su.se/STAFF/hartmut/bark.htm
+  aud = sign(freq).*((26.81./(1+1960./abs(freq)))-0.53);
+  
+  % The one below was found on Wikipedia.
+  %aud = 13*atan(0.00076*freq)+3.5*atan((freq/7500).^2);
+end;
+
+if flags.do_erb83
+  aud = sign(freq).*(11.17*log((abs(freq)+312)./(abs(freq)+14675))+43.0);
+end;
+
+if flags.do_freq
+  aud = freq;
+end;
+
+if flags.do_log10
+   aud = log10(freq);
+end
+
+if flags.do_semitone
+   aud = log10(freq);
+end
+
diff --git a/inst/auditory/freqtoerb.m b/inst/auditory/freqtoerb.m
new file mode 100644
index 0000000..b83454b
--- /dev/null
+++ b/inst/auditory/freqtoerb.m
@@ -0,0 +1,37 @@
+function erb = freqtoerb(freq);
+%-*- texinfo -*-
+%@deftypefn {Function} freqtoerb
+%@verbatim
+%FREQTOERB  Converts frequencies (Hz) to erbs
+%   Usage: erb = freqtoerb(freq);
+%
+%   This is a wrapper around FREQTOAUD that selects the erb-scale. Please
+%   see the help on FREQTOAUD for more information.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/freqtoerb.php}
+%@seealso{freqtoaud, demo_audscales}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+
+erb = freqtoaud(freq,'erb');
+
+
diff --git a/inst/auditory/gammatonefir.m b/inst/auditory/gammatonefir.m
new file mode 100644
index 0000000..89bdb85
--- /dev/null
+++ b/inst/auditory/gammatonefir.m
@@ -0,0 +1,160 @@
+function b=gammatonefir(fc,fs,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} gammatonefir
+%@verbatim
+%GAMMATONEFIR  Gammatone filter coefficients
+%   Usage: b = gammatonefir(fc,fs,n,betamul);
+%          b = gammatonefir(fc,fs,n);
+%          b = gammatonefir(fc,fs);
+%
+%   Input parameters:
+%      fc    :  center frequency in Hz.
+%      fs    :  sampling rate in Hz.
+%      n     :  filter order.
+%      beta  :  bandwidth of the filter.
+%
+%   Output parameters:
+%      b     :  FIR filters as an cell-array of structs.
+%
+%   GAMMATONEFIR(fc,fs,n,betamul) computes the filter coefficients of a
+%   digital FIR gammatone filter of length n with center frequency fc,
+%   4th order rising slope, sampling rate fs and bandwith determined by
+%   betamul. The bandwidth beta of each filter is determined as betamul*
+%   times AUDFILTBW of the center frequency of corresponding filter.
+%
+%   GAMMATONEFIR(fc,fs,n) will do the same but choose a filter bandwidth
+%   according to Glasberg and Moore (1990).  betamul is choosen to be 1.0183.
+%
+%   GAMMATONEFIR(fc,fs) will do as above and choose a sufficiently long
+%   filter to accurately represent the lowest subband channel.
+%
+%   If fc is a vector, each entry of fc is considered as one center
+%   frequency, and the corresponding coefficients are returned as column
+%   vectors in the output.
+%
+%   The inpulse response of the gammatone filter is given by
+%
+%       g(t) = a*t^(n-1)*cos(2*pi*fc*t)*exp(-2*pi*beta*t)
+%
+%   The gammatone filters as implemented by this function generate
+%   complex valued output, because the filters are modulated by the
+%   exponential function. Using real on the output will give the
+%   coefficients of the corresponding cosine modulated filters.
+%
+%   To create the filter coefficients of a 1-erb spaced filter bank using
+%   gammatone filters use the following construction:
+%
+%     g = gammatonefir(erbspacebw(flow,fhigh),fs);
+%
+%
+%  
+%   References:
+%     A. Aertsen and P. Johannesma. Spectro-temporal receptive fields of
+%     auditory neurons in the grassfrog. I. Characterization of tonal and
+%     natural stimuli. Biol. Cybern, 38:223-234, 1980.
+%     
+%     B. R. Glasberg and B. Moore. Derivation of auditory filter shapes from
+%     notched-noise data. Hearing Research, 47(1-2):103, 1990.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/gammatonefir.php}
+%@seealso{erbspace, audspace, audfiltbw, demo_auditoryfilterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+
+% ------ Checking of input parameters ---------
+
+if nargin<2
+  error('Too few input arguments.');
+end;
+
+if ~isnumeric(fs) || ~isscalar(fs) || fs<=0
+  error('%s: fs must be a positive scalar.',upper(mfilename));
+end;
+
+if ~isnumeric(fc) || ~isvector(fc) || any(fc<0) || any(fc>fs/2)
+  error(['%s: fc must be a vector of positive values that are less than half ' ...
+         'the sampling rate.'],upper(mfilename));
+end;
+
+definput.import={'normalize'};
+definput.importdefaults={'null'};
+definput.flags.real={'complex','real'};
+definput.keyvals.n=[];
+definput.flags.phase={'causalphase','peakphase'};
+
+definput.keyvals.betamul=1.0183;
+
+[flags,keyvals,n,betamul]  = ltfatarghelper({'n','betamul'},definput,varargin);
+
+nchannels = length(fc);
+
+% ourbeta is used in order not to mask the beta function.
+
+ourbeta = betamul*audfiltbw(fc);
+
+if isempty(n)
+  % Calculate a good value for n
+  % FIXME actually do this
+  n=5000;
+end;
+
+b=cell(nchannels,1);
+
+for ii = 1:nchannels
+
+  delay = 3/(2*pi*ourbeta(ii));
+  
+  scalconst = 2*(2*pi*ourbeta(ii))^4/factorial(4-1)/fs;
+  
+  nfirst = ceil(fs*delay);
+  
+  if nfirst>n/2
+    error(['%s: The desired filter length is too short to accomodate the ' ...
+           'beginning of the filter. Please choose a filter length of ' ...
+           'at least %i samples.'],upper(mfilename),nfirst*2);
+  end;
+  
+  nlast = floor(n/2);
+
+  t=[(0:nfirst-1)/fs-nfirst/fs+delay,(0:nlast-1)/fs+delay].';  
+
+  % g(t) = a*t^(n-1)*cos(2*pi*fc*t)*exp(-2*pi*beta*t)
+  if flags.do_real
+    bwork = scalconst*t.^(4-1).*cos(2*pi*fc(ii)*t).*exp(-2*pi* ...
+                                                      ourbeta(ii)*t);
+  else
+    bwork = scalconst*t.^(4-1).*exp(2*pi*i*fc(ii)*t).*exp(-2*pi* ...
+                                                      ourbeta(ii)*t);
+  end;
+
+  if flags.do_peakphase
+    bwork=bwork*exp(-2*pi*i*fc(ii)*delay);
+  end;
+
+  
+  % Insert zeros before the start of the signal.
+  %bwork = fftshift([bwork(1:nlast);zeros(n-nlast-nfirst,1);bwork(nlast+1:nlast+nfirst)]);
+    
+  bwork = normalize(bwork,flags.norm);  
+  b{ii} = struct('h',bwork,'offset',-nfirst,'realonly',0);
+end;
+
+
diff --git a/inst/auditory/rangecompress.m b/inst/auditory/rangecompress.m
new file mode 100644
index 0000000..4a50126
--- /dev/null
+++ b/inst/auditory/rangecompress.m
@@ -0,0 +1,83 @@
+function [outsig, sigweight] = rangecompress(insig,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} rangecompress
+%@verbatim
+%RANGECOMPRESS   Compress the dynamic range of a signal 
+%   Usage: [outsig, sigweight] = rangecompress(insig,mu);
+%   
+%   [outsig, sigweight]=RANGECOMPRESS(insig,mu) range-compresss the input
+%   signal insig using mu-law range-compression with parameter mu.
+%
+%   RANGECOMPRESS takes the following optional arguments:
+%
+%     'mulaw'  Do mu-law compression, this is the default.
+%
+%     'alaw'   Do A-law compression.
+%
+%     'mu',mu  mu-law parameter. Default value is 255.
+%
+%     'A',A    A-law parameter. Default value is 87.7.
+%
+%   The following plot shows how the output range is compressed for input
+%   values between 0 and 1:
+%
+%     x=linspace(0,1,100);
+%     xc=rangecompress(x);
+%     plot(x,xc);
+%     xlabel('input');
+%     ylabel('output');
+%     title('mu-law compression');
+%  
+%   References:
+%     S. Jayant and P. Noll. Digital Coding of Waveforms: Principles and
+%     Applications to Speech and Video. Prentice Hall, 1990.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/rangecompress.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR: Bruno Torresani and Peter L. Soendergaard
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.flags.method={'mulaw','alaw'};
+definput.keyvals.mu=255;
+definput.keyvals.A=87.7;
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_mulaw
+  tmp = log(1+kv.mu);
+  
+  sigweight = max(abs(insig(:)));
+  outsig = sign(insig) .* log(1+kv.mu*abs(insig))/tmp;
+
+end;
+
+if flags.do_alaw
+  absx=abs(insig);
+  tmp=1+log(kv.A);
+  mask=absx<1/kv.A;
+
+  outsig = sign(insig).*(mask.*kv.A.*absx./tmp+(1-mask).*(1+log(kv.A*absx))/tmp);
+end;
+
+
diff --git a/inst/auditory/rangeexpand.m b/inst/auditory/rangeexpand.m
new file mode 100644
index 0000000..dafdb95
--- /dev/null
+++ b/inst/auditory/rangeexpand.m
@@ -0,0 +1,69 @@
+function outsig = rangeexpand(insig,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} rangeexpand
+%@verbatim
+%RANGEEXPAND  Expand the dynamic range of a signal
+%   Usage:  sig = rangeexpand(insig,mu,sigweight);
+%
+%   RANGEEXPAND(insig,mu,sigweight) inverts a previously
+%   applied mu-law companding to the signal insig. The parameters
+%   mu and sigweight must match those from the call to RANGECOMPRESS
+%
+%   RANGEEXPAND takes the following optional arguments:
+%
+%     'mulaw'   Do mu-law compression, this is the default.
+%
+%     'alaw'    Do A-law compression.
+%
+%     'mu',mu   mu-law parameter. Default value is 255.
+%  
+%   References:
+%     S. Jayant and P. Noll. Digital Coding of Waveforms: Principles and
+%     Applications to Speech and Video. Prentice Hall, 1990.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/rangeexpand.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR: Bruno Torresani and Peter L. Soendergaard
+
+definput.flags.method={'mulaw','alaw'};
+definput.keyvals.mu=255;
+definput.keyvals.A=87.7;
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_mulaw
+
+  cst = (1+kv.mu);
+  outsig = cst.^(abs(insig));
+  outsig = sign(insig) .* (outsig-1);
+  outsig = outsig/kv.mu;
+
+end;
+
+if flags.do_alaw
+  absx=abs(insig);
+  tmp=1+log(kv.A);
+  mask=absx<1/tmp;
+
+  outsig = sign(insig).*(mask.*(absx*tmp/kv.A)+(1-mask).*exp(absx*tmp-1)/kv.A);
+end;
+
+
diff --git a/inst/auditory/semiaudplot.m b/inst/auditory/semiaudplot.m
new file mode 100644
index 0000000..a3cb56b
--- /dev/null
+++ b/inst/auditory/semiaudplot.m
@@ -0,0 +1,86 @@
+function h=semiaudplot(x,y,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} semiaudplot
+%@verbatim
+%SEMIAUDPLOT  2D plot on auditory scale
+%   Usage: h=semiaudplot(x,y);
+%
+%   SEMIAUDPLOT(x,y) plots the data (x,y) on an auditory scale. By
+%   default the values of the x-axis will be shown on the Erb-scale.
+%
+%   SEMIAUDPLOT takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'x'       Make the x-axis use the auditory scale. This is the default.
+%
+%     'y'       Make the y-axis use the auditory scale.
+%
+%     'opts',c  Pass options stored in a cell array onto the plot
+%               function.
+%
+%   In addition to these parameters, the auditory scale can be
+%   specified. All scales supported by FREQTOAUD are supported. The default
+%   is to use the erb-scale.     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/auditory/semiaudplot.php}
+%@seealso{freqtoaud}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import       = {'ltfattranslate','freqtoaud'};
+definput.flags.plotdir= {'x','y'};
+definput.keyvals.tick = [0,100,250,500,1000,2000,4000,8000,16000];
+definput.keyvals.res  = 500;
+definput.keyvals.opts = {};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+n=500;
+tickpos=freqtoaud(kv.tick,flags.audscale);
+    
+if flags.do_x
+  xmin=min(x);
+  xmax=max(x);
+  audminmax=freqtoaud([xmin,xmax],flags.audscale);
+  
+  plotval=spline(x,y,audspace(xmin,xmax,n,flags.audscale));
+  plot(linspace(audminmax(1),audminmax(2),n),plotval,kv.opts{:});
+  set(gca,'XTick',tickpos);
+  set(gca,'XTickLabel',num2str(kv.tick(:)));
+  xlabel(sprintf('%s (Hz)',kv.frequency));
+ 
+end;
+
+if flags.do_y
+  ymin=min(y);
+  ymax=max(y);
+  audminmax=freqtoaud([ymin,ymax],flags.audscale);
+  
+  plot(x,freqtoerb(y),kv.opts{:});
+  set(gca,'YTick',tickpos);
+  set(gca,'YTickLabel',num2str(tick(:)));
+  
+  ylabel(sprintf('%s (Hz)',kv.frequency));
+end;
+
+
diff --git a/inst/blockproc/Contents.m b/inst/blockproc/Contents.m
new file mode 100644
index 0000000..a6da3f8
--- /dev/null
+++ b/inst/blockproc/Contents.m
@@ -0,0 +1,48 @@
+% LTFAT - Block processing
+%
+%  Zdenek Prusa, 2013 - 2014.
+%
+%  Basic methods
+%    BLOCK          - Setup a new block-stream
+%    BLOCKDEVICES   - List available audio I/O devices
+%    BLOCKREAD      - Read samples from file/device
+%    BLOCKPLAY      - Play block (sound output)
+%    BLOCKPANEL     - Block-stream control GUI
+%    BLOCKPANELGET   - Obtain parameter(s) from GUI
+%    BLOCKDONE      - Closes block-stream and frees resources
+%
+%  Block-adapted transforms
+%    BLOCKFRAMEACCEL     - Prepare a frame for a block-stream processing
+%    BLOCKFRAMEPAIRACCEL - Prepare a pair of frames for a block-stream processing
+%    BLOCKANA            - Block analysis
+%    BLOCKSYN            - Block synthesis
+%
+%  Running visualisation
+%    BLOCKFIGURE   - Initialize figure for redrawing
+%    BLOCKPLOT     - Append coefficients to the running plot
+%
+%  Helper functions
+%    BLOCK_FWT      - FWT processing
+%    BLOCK_IFWT     - IFWT processing
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/blockproc/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/blockproc/block.m b/inst/blockproc/block.m
new file mode 100644
index 0000000..0b4d5dc
--- /dev/null
+++ b/inst/blockproc/block.m
@@ -0,0 +1,457 @@
+function [fs,classid] = block(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} block
+%@verbatim
+%BLOCK  Initialize block stream
+%   Usage: block(source);
+%
+%   Input parameters:
+%      source    : Block stream input.
+%      fs        : Sampling rate.
+%   Output parameters:
+%      fs        : Sampling rate.
+%      classid   : Data type.
+%
+%   BLOCK(source) initializes block data stream from source which
+%   can be one of the following (the letter-case is ignored for strings):
+%
+%      'file.wav'      name of a wav file
+%
+%      'dialog'        shows the file dialog to choose a wav file.
+%
+%      'rec'           input is taken from a microphone/auxilary input
+%
+%      'playrec'       loopbacks the input to the output
+%
+%      data            input data as columns of a matrix for each input 
+%                        channel
+%
+%   BLOCK accepts the following optional flags and key-value pairs
+%
+%      'L',L                Block length - default is 1024. Specifying L
+%                             fixes the buffer length, which cannot be
+%                             changed in the loop.
+%
+%      'devid',dev          Whenever more input/output devices are present
+%                             in your system, 'devid' can be used to 
+%                             specify one. For the 'playrec' option the 
+%                             devId should be a two element vector 
+%                             [playDevid, recDevid]. List of the installed
+%                             devices and their IDs can be obtained by 
+%                             BLOCKDEVICES.
+%      
+%      'playch',playch      If device supports more output channels, 'playch'
+%                             can be used to specify which should be used. E.g.
+%                             for two channel device, [1,2] is used to specify 
+%                             both channels. 
+%
+%      'recch',recch        If device supports more input channels, 'recch'
+%                             can be used to specify which should be used.
+%
+%      'outfile','file.wav' Processed sound data is stored in a new wav
+%                             file. NOT IMPLEMENTED YET!
+%
+%      'nbuf',nbuf          Max number of buffers to be preloaded. Helps
+%                             avoiding glitches, but increases delay.
+%
+%
+%      'loadind',loadind    How to show the load indicator. loadind can 
+%                             be the following
+%              
+%                              'nobar'   Suppresses any load display.
+%          
+%                              'bar'     Displays ascii load bar in command
+%                                        line (Does not work in Octave).
+%
+%                              obj       Java object which have a public
+%                                        method updateBar(double).  
+%
+%   Optional flag groups
+%
+%      'noloop', 'loop'     Plays the input in a loop. 
+%
+%      'single', 'double'   Data type to be used.
+%
+%      'online', 'offline'  Allows offline processing for data or wav
+%                           inputs. NOT IMPELMENTED YET!
+%
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/block.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+definput.keyvals.devid=[];
+definput.keyvals.nbuf=[];
+definput.keyvals.fs=[];
+definput.keyvals.playch=[];
+definput.keyvals.recch=[];
+definput.keyvals.outfile=[];
+definput.keyvals.L=[];
+definput.keyvals.loadind= 'nobar';
+definput.flags.fmt={'single','double'};
+definput.flags.loop={'noloop','loop'};
+definput.flags.onoff={'online','offline'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Octave version check
+skipLoadin = 0;
+if isoctave
+    octs=strsplit(version,'.');
+    octN=str2num(octs{1})*1000+str2num(octs{2});
+    if octN<3007
+      warning('%s: Using Octave < 3.7. Disabling load indicator.',mfilename);
+      skipLoadin = 1; 
+    end
+end
+
+
+if ~skipLoadin
+   if ischar(kv.loadind)
+      if ~strcmpi(kv.loadind,'bar') && ~strcmpi(kv.loadind,'nobar')
+         error('%s: Incorrect value parameter for the key ''loadin''.',upper(mfilename));
+      end
+   elseif isjava(kv.loadind)
+      try
+         javaMethod('updateBar',kv.loadind,0);
+      catch
+         error('%s: Java object does not contain updateBar method.',upper(mfilename))
+      end
+% Instead of this:
+%      if ~any(cellfun(@(mEl)~isempty(strfind(mEl,'updateBar(double)')),methods(kv.loadind,'-full')))
+%         error('%s: The Java object does not contain the updateBar(double) method.',upper(mfilename));
+%      end
+   end
+end
+
+
+playChannels = 0;
+recChannels = 0;
+play = 0;
+record = 0;
+% Here we can define priority list of the host APIs.
+% If none of the preferred API devices is present, the first one is taken.
+hostAPIpriorityList = {};
+% Force portaudio to use buffer of the following size
+pa_bufLen = -1;
+
+if ~isempty(kv.outfile)
+   error('%s: TO DO: Writing to the output wav file is not supported yet.',upper(mfielname));
+end
+
+if ischar(source)
+   if isempty(kv.fs)
+      kv.fs = 44100;
+   end
+   if(strcmpi(source,'rec'))
+      recChannels = 1;
+      record = 1;
+      if isempty(kv.nbuf)
+         kv.nbuf = 3;
+      end
+   elseif strcmpi(source,'playrec')
+      playChannels = 2;
+      recChannels = 1;
+      record = 1;   
+      play = 1;
+      if isempty(kv.nbuf)
+         kv.nbuf = 1;
+      end
+   elseif strcmpi(source,'dialog')
+      [fileName,pathName] = uigetfile('*.wav','Select the *.wav file'); 
+      if fileName == 0
+         error('%s: No file chosen.',upper(mfilename));
+      end
+      source = fullfile(pathName,fileName);
+      [fs,classid] = block(source,varargin{:});
+      return;
+   elseif(numel(source)>4)
+      if(strcmpi(source(end-3:end),'.wav'))
+         if exist(source,'file')~=2
+            error('%s: File "%s" does not exist.',upper(mfilename),source);
+         end
+         if isoctave
+            warning('off','Octave:fopen-file-in-path');
+         end
+         [~, kv.fs] = wavread(source, [1,1]);
+         playChannels = 2;
+         play = 1;
+      else
+         error('%s: "%s" is not valid wav filename.',upper(mfilename),source);
+      end
+      if isempty(kv.nbuf)
+         kv.nbuf = 3;
+      end
+   else
+      error('%s: Unrecognized command "%s".',upper(mfilename),source);
+   end
+elseif(isnumeric(source))
+    if isempty(kv.fs)
+      kv.fs = 44100;
+      warning('%s: Sampling rate not specified. Using default value %i Hz.',upper(mfilename),kv.fs); 
+   end
+   playChannels = 2;
+   play = 1;
+   if isempty(kv.nbuf)
+      kv.nbuf = 3;
+   end
+else
+   error('%s: Unrecognized input.',upper(mfilename));
+end
+
+isPlayrecInit = 0;
+try 
+   isPlayrecInit = playrec('isInitialised');
+catch
+   err = lasterror;
+   if ~isempty(strfind(err.message,'The specified module could not be found'))
+      error('%s: playrec found but portaudio cannot be found.', upper(mfilename));
+   end
+    if ~isempty(strfind(err.message,'Undefined function'))
+      error('%s: playrec could not be found.', upper(mfilename));
+    end
+   error('%s: Error loading playrec.',upper(mfilename));
+end
+
+if isPlayrecInit
+   playrec('reset');
+end
+
+if isempty(kv.playch)
+  kv.playch = 1:playChannels; 
+end
+
+if isempty(kv.recch)
+  kv.recch = 1:recChannels; 
+end
+
+devs = playrec('getDevices');
+if isempty(devs)
+   error('%s: No sound devices available. portaudio lib is probably incorrectly built.',upper(mfilename));
+end
+
+block_interface('reset');
+
+prioriryPlayID = -1;
+priorityRecID = -1;
+
+% Get all installed play devices
+playDevStructs = devs(arrayfun(@(dEl) dEl.outputChans,devs)>0);
+
+% Search for priority play device
+for ii=1:numel(hostAPIpriorityList)
+   hostAPI = hostAPIpriorityList{ii};
+   priorityHostNo = find(arrayfun(@(dEl) ~isempty(strfind(lower(dEl.hostAPI),lower(hostAPI))),playDevStructs)>0);
+   if ~isempty(priorityHostNo)
+      prioriryPlayID = playDevStructs(priorityHostNo(1)).deviceID;
+      break;
+   end
+end
+
+% Get IDs of all play devices
+playDevIds = arrayfun(@(dEl) dEl.deviceID, playDevStructs);
+
+% Get all installed recording devices
+recDevStructs = devs(arrayfun(@(dEl) dEl.inputChans,devs)>0);
+% Search for priority rec device
+for ii=1:numel(hostAPIpriorityList)
+   hostAPI = hostAPIpriorityList{ii};
+   priorityHostNo = find(arrayfun(@(dEl) ~isempty(strfind(lower(dEl.hostAPI),lower(hostAPI))),recDevStructs)>0);
+   if ~isempty(priorityHostNo)
+      priorityRecID = recDevStructs(priorityHostNo(1)).deviceID;
+      break;
+   end
+end
+
+% Get IDs of all rec devices
+recDevIds = arrayfun(@(dEl) dEl.deviceID,recDevStructs);
+
+if play && record
+   if ~isempty(kv.devid)
+      if(numel(kv.devid)~=2)
+         error('%s: devid should be 2 element vector.',upper(mfilename));
+      end
+      if ~any(playDevIds==kv.devid(1))
+         error('%s: There is no play device with id = %i.',upper(mfilename),kv.devid(1));
+      end
+      if ~any(recDevIds==kv.devid(2))
+         error('%s: There is no rec device with id = %i.',upper(mfilename),kv.devid(2));
+      end
+   else
+      % Use asio device if present
+      if prioriryPlayID~=-1 && priorityRecID~=-1
+         kv.devid = [prioriryPlayID, priorityRecID];
+      else
+         kv.devid = [playDevIds(1), recDevIds(1)];
+      end
+   end
+   if pa_bufLen~=-1
+      playrec('init', kv.fs, kv.devid(1), kv.devid(2), max(kv.playch),max(kv.recch),pa_bufLen);
+   else
+      playrec('init', kv.fs, kv.devid(1), kv.devid(2));
+   end
+   if numel(kv.recch) >1 && numel(kv.recch) ~= numel(kv.playch)
+      error('%s: Using more than one input channel.',upper(mfilename));
+   end
+   block_interface('setPlayChanList',kv.playch);
+   block_interface('setRecChanList',kv.recch);
+elseif play && ~record
+   if ~isempty(kv.devid)
+      if numel(kv.devid) >1
+         error('%s: devid should be scalar.',upper(mfilename));
+      end
+      if ~any(playDevIds==kv.devid)
+         error('%s: There is no play device with id = %i.',upper(mfilename),kv.devid);
+      end
+   else
+      % Use prefered device if present
+      if prioriryPlayID~=-1
+         kv.devid = prioriryPlayID;
+      else
+         % Use the first (hopefully default) device
+         kv.devid = playDevIds(1);
+      end
+   end
+   if pa_bufLen~=-1
+      playrec('init', kv.fs, kv.devid, -1,max(kv.playch),-1,pa_bufLen);
+   else
+      playrec('init', kv.fs, kv.devid, -1);
+   end
+   block_interface('setPlayChanList',kv.playch);
+   if(playrec('getPlayMaxChannel')<numel(kv.playch))
+       error ('%s: Selected device does not support %d output channels.\n',upper(mfilename), max(chanList));
+   end
+elseif ~play && record
+   if ~isempty(kv.devid)
+      if ~any(recDevIds==kv.devid)
+         error('%s: There is no rec device with id = %i.',upper(mfilename),kv.devid);
+      end
+   else
+      % Use asio device if present
+      if priorityRecID~=-1
+         kv.devid = priorityRecID;
+      else
+         % Use the first (hopefully default) device
+         kv.devid = recDevIds(1);
+      end
+   end
+   if pa_bufLen~=-1
+      playrec('init', kv.fs, -1, kv.devid,-1,max(kv.recch),pa_bufLen);
+   else
+      playrec('init', kv.fs, -1, kv.devid);
+   end
+   block_interface('setRecChanList',kv.recch);
+else
+   error('%s: Play or record should have been set.',upper(mfilename));
+end
+
+% From the playrec author:
+% This slight delay is included because if a dialog box pops up during
+% initialisation (eg MOTU telling you there are no MOTU devices
+% attached) then without the delay Ctrl+C to stop playback sometimes
+% doesn't work.
+pause(0.1);   
+
+if(~playrec('isInitialised'))
+    error ('%s: Unable to initialise playrec correctly.',upper(mfilename));
+end
+
+
+if(playrec('pause'))
+    %fprintf('Playrec was paused - clearing all previous pages and unpausing.\n');
+    playrec('delPage');
+    playrec('pause', 0);
+end
+
+% Reset skipped samples
+playrec('resetSkippedSampleCount');
+
+% Store data
+block_interface('setSource',source);
+block_interface('setBufCount',kv.nbuf);
+block_interface('setClassId',flags.fmt);
+
+
+% Return parameters
+classid = flags.fmt;
+fs = kv.fs;
+
+if play
+chanString = sprintf('%d,',kv.playch);
+dev = devs(find(arrayfun(@(dEl) dEl.deviceID==kv.devid(1),devs)));
+%fssup = sprintf('%d, ',dev.supportedSampleRates);
+%fssup = ['Supported sampling frequencies [',fssup(1:end-2),'].\n' ];
+fprintf('Play device: ID=%d, name=%s, API=%s, channels=%s, default latency: %d--%d ms\n',...
+        dev.deviceID,dev.name,dev.hostAPI,chanString(1:end-1),floor(1000*dev.defaultLowOutputLatency),...
+        floor(1000*dev.defaultHighOutputLatency));
+%fprintf(fssup);
+end
+
+if record
+chanString = sprintf('%d,',kv.recch);
+dev = devs(find(arrayfun(@(dEl) dEl.deviceID==kv.devid(end),devs)));
+fprintf('Rec. device: ID=%d, name=%s, API=%s, channels=%s, default latency: %d--%d ms\n',...
+        dev.deviceID,dev.name,dev.hostAPI,chanString(1:end-1),floor(1000*dev.defaultLowInputLatency),...
+        floor(1000*dev.defaultHighInputLatency));
+end
+
+
+% Store option for displaying the load bar
+block_interface('setDispLoad',kv.loadind);
+
+% Store option for displaying the loop playback
+block_interface('setIsLoop',flags.do_loop);
+
+% Set block length
+if isempty(kv.L)
+   block_interface('setBufLen',-1);
+else
+   if kv.L<256
+      error('%s: Minimum buffer length is 256.',upper(mfilename))
+   end
+   block_interface('setBufLen',kv.L);
+end
+
+% Handle sources with known input length
+if ischar(source) && numel(source)>4 && strcmpi(source(end-3:end),'.wav') 
+   Ls = wavread(source, 'size');
+   tmpf = wavread(source,[1,1]); % Workaround for Octave
+   block_interface('setLs',[Ls(1),size(tmpf,2)]);
+   block_interface('setSource',@(pos,endSample) cast(wavread(source,[pos, endSample]),block_interface('getClassId')) );
+elseif isnumeric(source)
+   block_interface('setLs',size(source));
+   block_interface('setSource',@(pos,endSample) cast(source(pos:endSample,:),block_interface('getClassId')) );
+end
+
+% Another slight delay to allow printing all messages prior to the playback
+% starts. 
+pause(0.1); 
+
+   
+
+      
+   
+   
+   
+   
+   
+   
+   
+   
+
diff --git a/inst/blockproc/block_fwt.m b/inst/blockproc/block_fwt.m
new file mode 100644
index 0000000..752db75
--- /dev/null
+++ b/inst/blockproc/block_fwt.m
@@ -0,0 +1,109 @@
+function c = block_fwt( f, w, J)
+%-*- texinfo -*-
+%@deftypefn {Function} block_fwt
+%@verbatim
+%BLOCK_FWT FWT func. wrapper for a block processing
+%   Usage: c = block_fwt( f, h, J);
+%
+%   Input parameters:
+%         f     : Input data.
+%         h     : Analysis Wavelet Filterbank. 
+%         J     : Number of filterbank iterations.
+%
+%   Output parameters:
+%         c      : Coefficient vector.
+%
+%   c = BLOCK_FWT(f,h,J) acceppts suitably extended block of data f*
+%   and produces correct coefficients. f is expected to be a collumn vector
+%   or a matrix and the processing is done column-wise.
+%
+%   Function should be independent of block_interface.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/block_fwt.php}
+%@seealso{block, blockread, blockplay}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% Initialize the wavelet filters structure
+%h = fwtinit(h,'ana');
+
+if any(w.a~=w.a(1))
+   error('%s: Non-equal subsampling factors are not supported.',upper(mfilename));
+end
+
+w = fwtinit(w);
+% Extended block length 
+Ls = size(f,1);
+% Low-pass filter length
+m = numel(w.h{1}.h);
+% Low-pass subsampling factor
+a = w.a(1);
+% Extension length
+rred = (a^J-1)/(a-1)*(m-a);
+% Block boundaries
+blocksize=w.a(1)^J;
+% Input signal samples to be processed
+L=rred+floor((Ls-rred)/blocksize)*blocksize;
+
+levelLen = L;
+filtNo = length(w.h);
+subbNo = (filtNo-1)*J+1;
+Lc = zeros(subbNo,1);
+runPtr = 0; 
+for jj=1:J
+   for ff=filtNo:-1:2
+      Lc(end-runPtr) = floor((levelLen-m-1)/w.a(ff));
+      runPtr = runPtr + 1;
+   end
+   levelLen = floor((levelLen-m-1)/w.a(1));
+end
+Lc(1)=levelLen; 
+
+% 
+%[Lc, L] = fwtclength(Ls,h,J,'valid');
+
+% Crop to the right length
+if(Ls>L)
+   f=postpad(f,L); 
+end
+
+if Ls<rred+a^J
+   error('%s: Insufficient input signal length for the %s flag. Minimum is %i.',upper(mfilename),'''valid''',rred+a^J);
+end
+
+c = comp_fwt(f,w.h,J,w.a,Lc,'valid');
+
+% Do the cropping 
+runPtr = 0; 
+for jj=1:J-1
+   for ff=filtNo:-1:2
+      cstart = (a^(J-jj)-1)/(a-1)*(m-a);
+      c{end-runPtr} = c{end-runPtr}(cstart+1:end,:);
+      runPtr = runPtr + 1;
+   end
+end 
+
+% To the pack format
+c = cell2mat(c);
+
diff --git a/inst/blockproc/block_ifwt.m b/inst/blockproc/block_ifwt.m
new file mode 100644
index 0000000..d47657c
--- /dev/null
+++ b/inst/blockproc/block_ifwt.m
@@ -0,0 +1,74 @@
+function f = block_ifwt(c,w,J,Lb)
+%-*- texinfo -*-
+%@deftypefn {Function} block_ifwt
+%@verbatim
+%BLOCK_IFWT IFWT wrapper for blockstream processing
+%   Usage: f=block_ifwt(c,g,J,Lb);
+%
+%   f = BLOCK_IFWT(c,g,J,Lb)
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/block_ifwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<4
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+
+w = fwtinit(w);
+
+%Lc = fwtclength(Lb,g,J,'per');
+filtNo = length(w.g);
+subbNo = (filtNo-1)*J+1;
+Lc = zeros(subbNo,1);
+runPtr = 0; 
+levelLen = Lb;
+  for jj=1:J
+     for ff=filtNo:-1:2
+        Lc(end-runPtr) = floor(levelLen/w.a(ff));
+        runPtr = runPtr + 1;
+     end
+     levelLen = ceil(levelLen/w.a(1));
+  end
+Lc(1)=levelLen; 
+c = mat2cell(c,Lc);
+
+m = numel(w.g{1}.h);
+a = w.a(1);
+% Do the extension 
+cstartZeros = zeros(numel(Lc),1);
+filtNo = length(w.g);
+runPtr = 0; 
+for jj=1:J-1
+   for ff=filtNo:-1:2
+      cstartZeros(end-runPtr) = (a^(J-jj)-1)/(a-1)*(m-a);
+      runPtr = runPtr + 1;
+   end
+end 
+
+% Pad with zeros ()
+cext = cellfun(@(cEl,cZEl) zeros(size(cEl,1)+cZEl,size(cEl,2)),c,num2cell(cstartZeros),'UniformOutput',0);
+for jj=1:numel(cext)
+   cext{jj}(end+1-size(c{jj},1):end,:) = c{jj};
+end
+
+Ls = Lb + (a^(J)-1)/(a-1)*(m-a);
+
+%% ----- Run computation 
+f = comp_ifwt(cext,w.g,J,w.a,Ls,'valid');
diff --git a/inst/blockproc/blockana.m b/inst/blockproc/blockana.m
new file mode 100644
index 0000000..35c478a
--- /dev/null
+++ b/inst/blockproc/blockana.m
@@ -0,0 +1,238 @@
+function [c, fola] = blockana(F, f, fola)
+%-*- texinfo -*-
+%@deftypefn {Function} blockana
+%@verbatim
+%BLOCKANA Blockwise analysis interface
+%   Usage: c=blockana(F, f)
+%
+%   Input parameters:
+%      Fa   : Analysis frame object.    
+%      f    : Block of signal.
+%      fola : Explicitly defined overlap
+%   Output parameters:
+%      c    : Block coefficients.
+%      fola : Stored overlap
+%
+%   c=BLOCKANA(Fa,f) calculates the coefficients c of the signal block f using 
+%   the frame defined by F. The block overlaps are handled according to the 
+%   F.blokalg. Assuming BLOCKANA is called in the loop only once, fola*
+%   can be omitted and the overlaps are handled in the background
+%   automatically.    
+%
+%
+%   References:
+%     N. Holighaus, M. Doerfler, G. A. Velasco, and T. Grill. A framework for
+%     invertible, real-time constant-Q transforms. IEEE Transactions on
+%     Audio, Speech and Language Processing, 21(4):775 -785, 2013.
+%     
+%     Z. Průša. Segmentwise Discrete Wavelet Transform. PhD thesis, Brno
+%     University of Technology, Brno, 2012.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockana.php}
+%@seealso{block, blocksyn, blockplay}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+    if nargin<2
+        error('%s: Too few input parameters.',upper(mfilename));
+    end;
+    
+    if ~isstruct(F)
+        error('%s: First agument must be a frame definition structure.',upper(mfilename));
+    end;
+    
+    if nargin<3
+       fola = [];
+    end
+    
+    if ~isfield(F,'blockalg')
+        F.blockalg = 'naive';
+    end
+    
+    % Block length
+    Lb = size(f,1);
+    % Next block index start (from a global point of view, starting with zero)
+    nextSb = block_interface('getPos');
+    % Block index start (from a global point of view, starting with zero)
+    Sb = nextSb-Lb;
+    
+    do_sliced = strcmp(F.blockalg,'sliced');
+    do_segola = strcmp(F.blockalg,'segola');
+    
+    if strcmp(F.blockalg,'naive')
+       % Most general. Should work for anything.
+       % Produces awful block artifacts when coefficients are altered.
+       f = [f; zeros(F.L-size(f,1),size(f,2))];
+       c = F.frana(f);
+    elseif do_sliced || do_segola
+
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       %% STEP 1) Determine overlap lengths 
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       if do_sliced
+          % Sliced real-time block processing
+          % Equal block length assumtion
+          Sbolen = Lb;
+          nextSbolen = Lb;
+       else
+             if ~isfield(F,'winLen') 
+                error('%s: Frame does not have FIR windows.',upper(mfilename));
+             end
+             % Window length
+             Lw = F.winLen;
+          switch(F.type)
+             case 'fwt'
+                J = F.J;
+                w = F.g;
+                m = numel(w.h{1}.h);
+                a = w.a(1);
+                if Lb<a^J
+                   error('%s: Minimum block length is %i.',upper(mfilename),a^J);
+                end
+                rred = (a^J-1)/(a-1)*(m-a);
+                Sbolen = rred + mod(Sb,a^J);
+                nextSbolen = rred + mod(nextSb,a^J);
+             case {'dgtreal','dgt','dwilt','wmdct'}
+                a = F.a; 
+                Sbolen = ceil((Lw-1)/a)*a + mod(Sb,a);
+                nextSbolen = ceil((Lw-1)/a)*a + mod(nextSb,a);
+             case {'filterbank','filterbankreal','ufilterbank','ufilterbankreal'}
+                a = F.lcma;
+                if Lw-1 < a
+                   Sbolen = mod(Sb,a);
+                   nextSbolen = mod(nextSb,a);
+                else
+                   Sbolen = ceil((Lw-1)/a)*a + mod(Sb,a);
+                   nextSbolen = ceil((Lw-1)/a)*a + mod(nextSb,a);
+                end
+                %Sbolen = ceil((Lw-1)/a)*a + mod(Sb,a);
+                %nextSbolen = ceil((Lw-1)/a)*a + mod(nextSb,a);
+             otherwise
+                error('%s: Unsupported frame.',upper(mfilename));
+          end
+       end
+       
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       %% STEP 2) Common overlap handling 
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       % Append the previous block
+       fext = [loadOverlap(Sbolen,size(f,2),fola);f];
+       % Save the current block
+       if nargout>1
+          fola = storeOverlap(fext,nextSbolen);
+       else
+          storeOverlap(fext,nextSbolen);
+       end
+       
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       %% STEP 3) Do the rest
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       if do_sliced
+          % Multiply by the slicing window (all channels)
+          fwin = bsxfun(@times,F.sliwin,fext);
+          % If some padding is necessary, do it symmetrically
+          pad = F.L-size(fwin,1);
+          W = size(fwin,2);
+          fwin = [zeros(floor(pad/2),W);...
+                  fwin;...
+                  zeros(ceil(pad/2),W)];
+          % Apply transform
+          c = F.frana(fwin);
+       else
+          switch(F.type)
+             case 'fwt'
+                c = block_fwt(fext,w,J);
+             case {'dgtreal','dgt','dwilt','wmdct'}
+                Lwl = floor(Lw/2);
+                Lext = Sbolen + Lb - nextSbolen + Lwl;
+                startc = ceil(Lwl/a)+1;
+                endc = ceil((Lext)/a);
+                % Pad with zeros to comply with the frame requirements
+                fext = [fext; zeros(F.L-size(fext,1),size(fext,2))];
+                c = F.frana(fext(1:F.L,:));
+                % Pick just valid coefficients
+                cc = F.coef2native(c,size(c));
+                cc = cc(:,startc:endc,:);
+                c = F.native2coef(cc);
+             case {'filterbank','filterbankreal'}
+                % Subsampling factors
+                a = F.a(:,1);
+                % Filter lengths
+                gl = F.g_info.gl;
+                % Filter offsets
+                Lwl = max(gl+F.g_info.offset-1);
+                Lext = Sbolen + Lb - nextSbolen + Lwl;
+                startc = ceil(Lwl./a)+1;
+                endc = ceil((Lext)./a);
+                
+                fext = [fext; zeros(F.L-size(fext,1),size(fext,2))];
+                c = F.frana(fext(1:F.L,:));
+                cc = F.coef2native(c,size(c));
+                cc = cellfun(@(cEl,sEl,eEl) cEl(sEl:eEl,:),cc,num2cell(startc),num2cell(endc),'UniformOutput',0);
+                c = F.native2coef(cc);
+          end
+       end
+    else
+       error('%s: Frame was not created with blockaccel.',upper(mfilename));
+    end
+
+end % BLOCKANA
+
+function overlap = loadOverlap(L,chan,overlap)
+%LOADOVERLAP Loads overlap
+%
+%
+    if isempty(overlap)
+       overlap = block_interface('getAnaOverlap');
+    end
+
+    % Supply zeros if it is empty
+    if isempty(overlap)
+        overlap = zeros(L,chan,block_interface('getClassId'));
+    end
+    Lo = size(overlap,1);
+    if nargin<1
+        L = Lo;
+    end
+    % If required more than stored, do zero padding
+    if L>Lo
+        oTmp = zeros(L,size(overlap,2));
+        oTmp(end-Lo+1:end) = oTmp(end-Lo+1:end)+overlap;
+        overlap = oTmp;
+    else
+        overlap = overlap(end-L+1:end,:);
+    end
+    
+end % LOADOVERLAP
+
+function overlap = storeOverlap(fext,L)
+%STOREOVERLAP Stores overlap
+%
+%
+    if L>size(fext,1)
+        error('%s: Storing more samples than passed.',upper(mfilename));
+    end
+    overlap = fext(end-L+1:end,:);
+    
+    if nargout<1
+       block_interface('setAnaOverlap',overlap); 
+    end
+end % STOREOVERLAP
+
+
diff --git a/inst/blockproc/blockdevices.m b/inst/blockproc/blockdevices.m
new file mode 100644
index 0000000..612a5e2
--- /dev/null
+++ b/inst/blockproc/blockdevices.m
@@ -0,0 +1,67 @@
+function devs = blockdevices()
+%-*- texinfo -*-
+%@deftypefn {Function} blockdevices
+%@verbatim
+%BLOCKDEVICES Lists audio devices
+%   Usage: devs = blockdevices();
+%
+%   BLOCKDEVICES lists the available audio input and output devices. The
+%   ID can be used in the BLOCK function to specify which device should
+%   be used.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockdevices.php}
+%@seealso{block}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+devs = playrec('getDevices');
+
+fprintf('\nAvailable output devices:\n');
+
+for k=1:length(devs)
+    if(devs(k).outputChans)
+        fs = sprintf('%d, ',devs(k).supportedSampleRates);
+        fs = ['[',fs(1:end-2),']' ];
+        fprintf(['ID =%2d: %s (%s) %d chan., latency %d--%d ms,'...
+                 ' fs %s\n'], ...
+            devs(k).deviceID, devs(k).name, ...
+            devs(k).hostAPI, devs(k).outputChans,...
+            floor(1000*devs(k).defaultLowOutputLatency),...
+            floor(1000*devs(k).defaultHighOutputLatency),...
+            fs);
+
+    end
+end
+
+fprintf('\nAvailable input devices:\n');
+
+for k=1:length(devs)
+    if(devs(k).inputChans)
+        fs = sprintf('%d, ',devs(k).supportedSampleRates);
+        fs = ['[',fs(1:end-2),']' ];
+        fprintf(['ID =%2d: %s (%s) %d chan., latency %d--%d ms,'...
+                 ' fs %s\n'], ...
+            devs(k).deviceID, devs(k).name, ...
+            devs(k).hostAPI, devs(k).inputChans,...
+            floor(1000*devs(k).defaultLowInputLatency),...
+            floor(1000*devs(k).defaultHighInputLatency),fs);
+
+    end
+end
diff --git a/inst/blockproc/blockdone.m b/inst/blockproc/blockdone.m
new file mode 100644
index 0000000..cf4da14
--- /dev/null
+++ b/inst/blockproc/blockdone.m
@@ -0,0 +1,54 @@
+function blockdone(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blockdone
+%@verbatim
+%BLOCKDONE  Destroy the current blockstream
+%   Usage: blockdone();
+%
+%   BLOCKDONE() closes the current blockstream. The function resets
+%   the playrec tool and clear all buffers in block_interface.
+%
+%   BLOCKDONE(p1,p2,...) in addition tries to call close methods on
+%   all input arguments which are JAVA objects (which are passed by reference).
+%   
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockdone.php}
+%@seealso{block}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% TO DO: Process additional zeros to compensate for the delay 
+
+block_interface('clearAll');
+playrec('reset');
+
+for ii=1:numel(varargin)
+   p = varargin{ii};
+   if isjava(p)
+      try
+         javaMethod('close',p);
+      catch
+         warning(sprintf('%s: Object %i does not have a close method.',...
+         upper(mfilename),ii));
+      end
+   elseif isstruct(p) && isfield(p,'destructor') &&...
+          isa(p.destructor,'function_handle')
+      p.destructor();
+   end
+end
diff --git a/inst/blockproc/blockfigure.m b/inst/blockproc/blockfigure.m
new file mode 100644
index 0000000..c0b1952
--- /dev/null
+++ b/inst/blockproc/blockfigure.m
@@ -0,0 +1,96 @@
+function p = blockfigure(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blockfigure
+%@verbatim
+%BLOCKFIGURE Block figure object
+%   Usage: p=blockfigure();
+%          p=blockfigure('cm',cmaps);
+%
+%   Output parameters:
+%         p     : JAVA object of the class net.sourceforge.ltfat.SpectFrame
+%
+%   p=BLOCKFIGURE() initializes a JAVA object for the BLOCKPLOT
+%   routine. 
+%
+%   Optional key-value pairs:
+%
+%      'cm',cmaps   : Custom colormap (a L x3 matrix) or colormaps
+%                       (cell array of matrixes).
+%
+%   The function takes in the additional optional arguments:
+%
+%       'location',location:   Window inital position. location
+%                                has to be 2 element row vector [x,y]
+%                                defining distance from the top-left
+%                                corner of the screen. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockfigure.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+definput.keyvals.cm=[];
+definput.keyvals.location=[50,120];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+p = [];
+try
+p = javaObject('net.sourceforge.ltfat.SpectFrame');
+javaMethod('setLocation',p,kv.location(1),kv.location(2));
+catch% err
+   error(['%s: Could not load net.sourceforge.ltfat.SpectFrame. It is not ',...
+          'compiled or it is not in Matlab classpath. In the latter case, ',...
+          'ltfatstart should do the trick.'],upper(mfilename));
+end
+
+if ~isvector(kv.location) || any(size(kv.location)~=[1,2]) ||...
+    any(kv.location<0) || ~isreal(kv.location)
+   error(['%s: Location has to be a 2 element row vector of ',...
+         ' positive numbers.'],upper(mfilename));  
+end
+
+
+% Gives p time to be correctly initialized. Otherwise, calling methods
+% of the object can fail.
+pause(0.1);
+
+
+if isempty(kv.cm)
+   % Create a default colormap.
+   kv.cm = {jet(256)};
+elseif isnumeric(kv.cm)
+   % Enclose the colormap to a single element cell array.
+   kv.cm = {kv.cm};
+elseif iscell(kv.cm)
+   if numel(kv.cm)>1
+      error('%s: TO DO: More than one colormap is not supported yet.',upper(mfilename));
+   end
+end
+
+% Set the colormap.
+if isoctave
+   javaMethod('setColormap',p,kv.cm{1}(:),size(kv.cm{1},1),size(kv.cm{1},2));
+else
+   javaMethod('setColormap',p,kv.cm{1});
+end
+
+javaMethod('show',p);
+
+
+
+
+
diff --git a/inst/blockproc/blockframeaccel.m b/inst/blockproc/blockframeaccel.m
new file mode 100644
index 0000000..9743303
--- /dev/null
+++ b/inst/blockproc/blockframeaccel.m
@@ -0,0 +1,140 @@
+function Fo = blockframeaccel(F, Lb, varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blockframeaccel
+%@verbatim
+%BLOCKFRAMEACCEL Precompute structures for block processing
+%   Usage: F = blockframeaccel(F,Lb);
+%
+%   F=BLOCKFRAMEACCEL(F,Lb) has to be called for each frame object prior to
+%   entering the main loop where BLOCKANA and BLOCKSYN are called.
+%   The function works entirely like FRAMEACCEL but in addition, it prepares
+%   structures for the processing of a consecutive stream of blocks.
+%
+%      'sliwin',sliwin   : Slicing window. sliwin have to be a window
+%                            of length 2Lb or a string accepted
+%                            by the FIRWIN function. It is used only in
+%                            the slicing window approach. The default is 
+%                            'hann'.
+%
+%      'zpad',zpad   : Number of zero samples the block will be padded
+%                        after it is windowed by a slicing window.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockframeaccel.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
+definput.flags.blockalg = {'naive','sliced','segola'};
+definput.keyvals.sliwin = [];
+definput.keyvals.zpad = 0;
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+isSliProp = ~isempty(kv.sliwin) || kv.zpad~=0;
+assert(~(~flags.do_sliced && isSliProp),...
+   sprintf(['%s: Definig slicing window properties without setting the',...
+            ' ''sliced'' flag.'], mfilename));
+
+if flags.do_sliced 
+   if isempty(kv.sliwin)
+      kv.sliwin = 'hann';
+   end
+  
+   if ~isnumeric(kv.sliwin)
+      kv.sliwin = fftshift(sqrt(firwin(kv.sliwin,2*Lb)));
+   end
+
+   Fo = frameaccel(F,2*Lb+2*kv.zpad);
+   Fo.sliwin = kv.sliwin;
+   Fo.zpad = kv.zpad;
+elseif flags.do_segola
+   % Determine window length without calling frameaccel
+   % Fo = frameaccel(F,Lb);
+   winLen = framefirlen(F);
+
+   if winLen==-1
+      error(['%s: Segment overlap cannot be used with this frame.,'...
+             ' It does not have FIR windows.'],upper(mfilename));
+   end
+    
+   switch(F.type) 
+      case {'dgt','dgtreal'}
+         Fo = frameaccel(F,Lb+winLen-1+F.a);
+      case {'filterbank','filterbankreal','ufilterbank','ufilterbankreal'}
+         lcma =  filterbanklength(1,F.a(:,1));
+         Fo = frameaccel(F,Lb+winLen-1+lcma);
+         assert(all(Fo.a(:,2)==1), '%s: Fractional subsampling is not supported',upper(mfilename) );
+         Fo.lcma =  lcma;
+      case {'dwilt'}
+         Fo = frameaccel(F,Lb+winLen-1+2*F.M);
+         Fo.a = 2*Fo.M;
+      case {'wmdct'}
+         Fo = frameaccel(F,Lb+winLen-1+F.M);
+         Fo.a = Fo.M;
+      otherwise
+	 error('%s: Unsupported frame for segola.',upper(mfilename));
+   end
+   
+   % This is important otherwise we would get 0 coefficients for some
+   % blocks.
+   assert(max(Fo.a(:,1)) <= Lb ,sprintf(['%s: Time step %i is bigger than the',...
+      ' block length %i.'],upper(mfilename),Fo.a,Lb));
+   
+   Fo.winLen = winLen;
+
+
+elseif flags.do_naive
+   Fo = frameaccel(F,Lb);
+end
+
+Fo.blockalg = flags.blockalg;
+
+function winLen = framefirlen(F)
+%FRAMEFIRLEN Frame window/filter length
+%
+%   Function returns length of the longest FIR window/filter. The function
+%   returns -1 if the frame does not have FIR windows.
+
+winLen = -1;
+info = [];
+switch(F.type)
+      case {'dgt','dgtreal'}
+        [~, info] =  gabwin(F.g,F.a,F.M,[],F.kv.lt);
+      case {'dwilt','wmdct'}
+        [~, info] = wilwin(F.g,F.M,[],upper(mfilename));
+      case {'filterbank','ufilterbank'}
+        [~, info]  = filterbankwin(F.g,F.a);
+      case {'filterbankreal','ufilterbankreal'}
+        [~, info]  = filterbankwin(F.g,F.a,'real');
+      case 'fwt' 
+        winLen = (F.g.a(1)^F.J-1)/(F.g.a(1)-1)*(numel(F.g.g{1}.h)-1)+1; 
+end;
+
+  
+if ~isempty(info) && isfield(info,'isfir') && info.isfir
+   if isfield(info,'longestfilter')
+      winLen = info.longestfilter;
+   else
+      winLen = max(info.gl);
+   end
+end
+
+
+
+
+
diff --git a/inst/blockproc/blockframepairaccel.m b/inst/blockproc/blockframepairaccel.m
new file mode 100644
index 0000000..10a3e4f
--- /dev/null
+++ b/inst/blockproc/blockframepairaccel.m
@@ -0,0 +1,83 @@
+function [Fao,Fso] = blockframepairaccel(Fa, Fs, Lb, varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blockframepairaccel
+%@verbatim
+%BLOCKFRAMEPAIRACCEL Precompute structures for block processing
+%   Usage: F = blockframepairaccel(Fa,Fs,Lb);
+%
+%   [Fao,Fso]=BLOCKFRAMEPAIRACCEL(Fa,Fs,Lb) works similar to 
+%   BLOCKFRAMEACCEL with a pair of frames. The only difference from
+%   calling BLOCKFRAMEACCEL separatelly for each frame is correct
+%   default choice of the slicing windows. Frame objects Fa,Fs will be
+%   accelerated for length 2*Lb.
+%
+%   The following optional arguments are recognized:
+%
+%      'anasliwin',anasliwin  : Analysis slicing window. sliwin have to
+%                                 be a window of length 2Lb or a string 
+%                                 accepted by the FIRWIN function. It is
+%                                 used only in the slicing window approach.
+%                                 The default is 'hann'.
+%
+%      'synsliwin',synsliwin  : Synthesis slicing window. The same as the
+%                                 previous one holds. The default is 'rect'.
+%
+%      'zpad',zpad   : Number of zero samples the block will be padded
+%                        after it is windowed by a slicing window. Note the
+%                        frames will be accelerated for length
+%                        2*Lb+2*kv.zpad. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockframepairaccel.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+definput.flags.blockalg = {'naive','sliced','segola'};
+definput.keyvals.anasliwin = [];
+definput.keyvals.synsliwin = [];
+definput.keyvals.zpad = 0;
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+isSliProp = ~isempty(kv.anasliwin) || ~isempty(kv.synsliwin) || kv.zpad~=0;
+assert(~(~flags.do_sliced && isSliProp),...
+   sprintf(['%s: Definig slicing window properties without setting the',...
+            ' ''sliced'' flag.'], mfilename));
+
+if flags.do_sliced 
+   if isempty(kv.anasliwin)
+      kv.anasliwin = 'hann';
+   end
+   
+   if isempty(kv.synsliwin)
+      kv.synsliwin = 'hann';
+   end
+
+   Fao = blockframeaccel(Fa,Lb,'sliced','sliwin',kv.anasliwin,...
+                         'zpad',kv.zpad);
+   Fso = blockframeaccel(Fs,Lb,'sliced','sliwin',kv.synsliwin,...
+                         'zpad',kv.zpad);
+else
+   Fao = blockframeaccel(Fa,Lb,flags.blockalg);
+   Fso = blockframeaccel(Fs,Lb,flags.blockalg);
+end
+
+
+
+
+
diff --git a/inst/blockproc/blockpanel.m b/inst/blockproc/blockpanel.m
new file mode 100644
index 0000000..283ec05
--- /dev/null
+++ b/inst/blockproc/blockpanel.m
@@ -0,0 +1,121 @@
+function p = blockpanel(params,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blockpanel
+%@verbatim
+%BLOCKPANEL Control panel
+%   Usage: blockpanel(params)
+%
+%   Input parameters:
+%      params: Cell-array of parameters specifications.
+%
+%   Output parameters:
+%      p : Control panel Java object
+%
+%   BLOCKPANEL(params) creates a Java object containing GUI for changing
+%   parameters during the playback. params should be a cell-array, whose 
+%   elements are another cell array of the following format:
+%
+%      {'var','label',minVal,maxVal,defVal,valCount}
+%
+%   Example:
+%
+%   params = {
+%               {'G','Gain',-20,20,0,21}
+%            }
+% 
+%   The function takes in the additional optional arguments:
+%
+%       'location',location:   Window initial position. location
+%                                has to be 2 element row vector [x,y]
+%                                defining distance from the top-left
+%                                corner of the screen. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockpanel.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<1
+    error('%s: Too few input parameters.',upper(mfilename));
+end
+
+definput.keyvals.location=[50,50];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if ~isvector(kv.location) || any(size(kv.location)~=[1,2]) ||...
+    any(kv.location<0) || ~isreal(kv.location)
+   error(['%s: Location has to be a 2 element row vector of ',...
+         ' positive numbers.'],upper(mfilename));  
+end
+
+if ~iscell(params) || isempty(params)
+    error('%s: Input should be a nonempty cell array.',upper(mfilename));
+end
+
+if ~iscell(params{1})
+    params = {params};
+end
+
+try
+  p = javaObject('net.sourceforge.ltfat.ContFrame');
+catch% err
+   error(['%s: Could not load net.sourceforge.ltfat.ContFrame. It is not ',...
+          'compiled or it is not in Matlab classpath. In the latter case, ',...
+          'ltfatstart should do the trick.'],upper(mfilename));
+end
+
+% Using Java LinkedList class for passing the cell-array
+% (since there is no way how to pass the cell-array directly)
+paramList = javaObject('java.util.LinkedList');
+    
+
+for ii = 1:numel(params)
+   param = params{ii};
+   if numel(param)<6
+      error('%s: Parameter %i is not in format {''var'',''label'',minVal,maxVal,defVal,valCount}.',upper(mfilename),ii);
+   end
+   if param{3}>=param{4}
+      error('%s: In parameter %i: minVal cannot be greater or equal to maxVal.',upper(mfilename),ii);
+   end
+   
+   if param{5}<param{3} || param{5}>param{4}
+      error('%s: In parameter %i: defVal is not in range minVal-maxVal.',upper(mfilename),ii);
+   end
+   
+   if param{6}<=1
+      error('%s: In parameter %i: valCount has to be >=2.',upper(mfilename),ii);
+   end
+   
+   % Each element of the linked list paramList is again a linked list
+   paramListEl = javaObject('java.util.LinkedList');
+   for jj=1:numel(param)
+        javaMethod('add',paramListEl,param{jj});
+   end
+   javaMethod('add',paramList,paramListEl);
+    
+   
+end
+
+% Pass the data
+javaMethod('addControlElements',p,paramList);
+
+javaMethod('setLocation',p,kv.location(1),kv.location(2));
+ 
+% Give the object time to initialize properly.
+pause(0.1);
+ 
+
diff --git a/inst/blockproc/blockpanelget.m b/inst/blockproc/blockpanelget.m
new file mode 100644
index 0000000..83d1b9e
--- /dev/null
+++ b/inst/blockproc/blockpanelget.m
@@ -0,0 +1,86 @@
+function [par,varargout] = blockpanelget(p,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blockpanelget
+%@verbatim
+%BLOCKPANELGET Get parameters from GUI
+%   Usage: [par,...] = blockpanelget(p,spar,...)
+%
+%   Input parameters:
+%         p    : JAVA object
+%         spar : String. Name of the parameter.
+%
+%   Output parameters:
+%         par  : Single value or vector of parameters.
+%
+%   par = BLOCKPANELGET(p,'spar') gets a current value of the parameter
+%   'spar' from the GUI specified in p. 
+%   par = BLOCKPANELGET(p,'spar1','spar2','spar3') gets current values
+%   of the parameters 'spar1', 'spar2' and 'spar3' from the GUI and
+%   stores them in a vector p.
+%   [par1,par2,par3] = BLOCKPANELGET(p,'spar1','spar2','spar3') gets 
+%   current values of the parameters 'spar1', 'spar2' and 'spar3' 
+%   from the GUI and stores them in the separate variables par1,par2
+%   and par3. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockpanelget.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+nout = nargout();
+
+if nargin<1
+   error('%s: Too few input arguments.',upper(mfilename));
+end
+
+if nout~=1 && nargin==1
+   error(['%s: Ambiguous output. When no parameter is explicitly defined,',...
+    ' the function cannot return more tha one output parameter.'],mfilename);
+end
+
+
+if nargin>1 
+   if nout~=1 && nout ~= numel(varargin)
+      error('%s: Number of inputs does not match with number of outputs.',upper(mfilename));
+   end
+
+   res = javaMethod('getParams',p,varargin);
+
+   if nout == 1
+      if numel(res)==1
+         par = res(1);
+      else
+         par = res;
+      end
+   else
+      par = res(1);
+      varargout = num2cell(res(2:end));
+   end
+else
+   par = javaMethod('getParams',p);
+   if isoctave
+      parTmp = par; 
+      par = zeros(numel(parTmp),1);
+      for ii=1:numel(parTmp)
+          par(ii) = parTmp(ii);
+      end
+   end
+end
+   
+
+
diff --git a/inst/blockproc/blockplay.m b/inst/blockproc/blockplay.m
new file mode 100644
index 0000000..fff915f
--- /dev/null
+++ b/inst/blockproc/blockplay.m
@@ -0,0 +1,42 @@
+function blockplay(f)
+%-*- texinfo -*-
+%@deftypefn {Function} blockplay
+%@verbatim
+%BLOCKPLAY Schedules block to be played
+%   Usage: blockplay(L)
+%       
+%   Input parameters:
+%      f    : Samples.
+%
+%   Function schedules samples in f to be played. Since playrec handles
+%   playing and recording in a single command, the actual relay of samples
+%   to playrec is done in the next call of BLOCKREAD.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockplay.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+source = block_interface('getSource');
+
+if strcmp(source,'rec')
+   error('%s: Blocks cannot be played in the rec only mode.',upper(mfilename));
+end
+
+block_interface('setToPlay',f);
+
diff --git a/inst/blockproc/blockplot.m b/inst/blockproc/blockplot.m
new file mode 100644
index 0000000..b5238c0
--- /dev/null
+++ b/inst/blockproc/blockplot.m
@@ -0,0 +1,96 @@
+function cola=blockplot(p,F,c,cola)
+%-*- texinfo -*-
+%@deftypefn {Function} blockplot
+%@verbatim
+%BLOCKPLOT Plot block coefficients
+%   Usage: blockplot(p,F,c);
+%
+%   Input parameters:
+%         p     : JAVA object of the class net.sourceforge.ltfat.SpectFrame.
+%         F     : Frame object.
+%         c     : Block coefficients.
+%         cola  : (Optional) overlap from previous block.
+%
+%   Output parameters:
+%         cola  : Overlap to the next block.
+%
+%   BLOCKPLOT(p,F,c) appends the block coefficients c to the running 
+%   coefficient plot in p. The coefficients must have been obtained by
+%   c=blockana(F,...). The format of c is changed to a rectangular 
+%   layout according to the type of F.
+%
+%   BLOCKPLOT(p,[],c) does the same, but expects c to be already
+%   formatted matrix of real numbers. The matrix dimensions are not
+%   restricted, but it will be shrinked or expanded to a vertical
+%   strip in the sliding image.
+%
+%   cola=BLOCKPLOT(p,F,c,cola) does the same, but adds cola to the 
+%   first respective coefficients in c and returns last coefficients from
+%   c. This is only relevant for the sliced window blocking approach.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockplot.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
+if ~isempty(F)
+    ctf = framecoef2tf(F,c(:,1));
+    
+    if size(c,2)>1
+        error('%s: Only one channel input is supported.',upper(mfilename));
+    end
+
+    if strcmp(F.blockalg,'sliced')
+       % DO the coefficient overlapping or cropping
+       %ctf = ctf(:,floor(end*3/8):floor(end*5/8)+1);
+
+       if nargin>3 
+          olLen = ceil(size(ctf,2)/2);
+          if isempty(cola)
+             cola = zeros(size(ctf,1),olLen,class(ctf));
+          end
+
+          ctf(:,1:olLen) = ctf(:,1:olLen) + cola;
+          cola = ctf(:,end+1-olLen:end);
+          ctf = ctf(:,1:olLen);
+       end
+    end
+    
+    ctf = abs(ctf);
+else
+    if ~isreal(c)
+        error('%s: Complex values are not supported',upper(mfilename));
+    end
+    ctf = c;
+end
+
+
+if isoctave
+   % The JAVA 2D-array handling is row-major
+   ctf = cast(ctf,'double').';
+   javaMethod('append',p,ctf(:),size(ctf,2),size(ctf,1));
+else
+   % Matlab casts correctly
+   ctf = cast(ctf,'single');
+   javaMethod('append',p,ctf);
+end
+
+
+
diff --git a/inst/blockproc/blockprocinit.m b/inst/blockproc/blockprocinit.m
new file mode 100644
index 0000000..c5ca394
--- /dev/null
+++ b/inst/blockproc/blockprocinit.m
@@ -0,0 +1,69 @@
+status=1;
+
+%-*- texinfo -*-
+%@deftypefn {Function} blockprocinit
+%@verbatim
+% Add entry to the dynamic classpath if JVM is present.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockprocinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+if ~isempty(which('javaaddpath')) 
+   try
+      % Here it gets somewhat confusing. This script is called in
+      % ltfatstart, but the jar is created in ltfatmex. It prints nasty
+      % warning, if it cannot find the jar. Adding a folder to the classpath,
+      % which is then filled with compiled classes by ltfatmex is fine. 
+      %
+      % Moreover, according to the Matlab documentation:
+      %
+      % MATLAB calls the 'clear java' command whenever you change the dynamic path. 
+      % It clears definition of all Java classes defined by files on the dynamic class path,
+      % removes all variables from the base workspace, and removes all compiled scripts, functions,
+      % and MEX-functions from memory.
+
+      jarFile = 'blockproc.jar';
+      javaDirPath = [basepath,filesep,'blockproc',filesep,'java'];
+      jarPath = [javaDirPath,filesep,jarFile];
+      
+      if exist(jarPath,'file')
+         if any(cellfun(@(cpEl)strcmp(cpEl,javaDirPath),javaclasspath))
+            javarmpath(javaDirPath);
+         end
+         % Adding a jar file. Once added to the classpath, it cannot be
+         % deleted. Removing it from the classpath issues again the 'clear
+         % java' command, but the jar cannot be removed while Matlab is
+         % running at all.
+         % http://www.mathworks.com/support/solutions/en/data/1-37JYLQ/?product=ML&solution=1-37JYLQ
+         javaaddpath([basepath,filesep,'blockproc',filesep,'java',filesep,jarFile]);
+      else
+         % Adding directory with *.class files. Does not block.
+         javaaddpath([basepath,filesep,'blockproc',filesep,'java']);
+      end
+   catch 
+       % Use lasterr for Octave compatibility
+       err=lasterr;
+       if ltfatstartprint
+           warning('%s: JVM support not present.',upper(mfilename));
+       end;
+   end
+else
+    if ltfatstartprint
+        warning('%s: Java toolbox not present.',upper(mfilename));
+    end;
+end
diff --git a/inst/blockproc/blockread.m b/inst/blockproc/blockread.m
new file mode 100644
index 0000000..45a54d9
--- /dev/null
+++ b/inst/blockproc/blockread.m
@@ -0,0 +1,262 @@
+function [f,valid] = blockread(L)
+%-*- texinfo -*-
+%@deftypefn {Function} blockread
+%@verbatim
+%BLOCKREAD Read one block from input
+%   Usage: blockread(L)
+%       
+%   Input parameters:
+%      L    : Number of samples.
+%   Output parameters:
+%      f     : Samples.
+%      valid : Input data valid flag.
+%
+%   Function also control the playback, so it does not have to rely on
+%   whether the user called BLOCKPLAY.
+% 
+%   Block streaming uses several buffers to compensate for the processing
+%   delay variation. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blockread.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+persistent Lwav;
+persistent clearStr;
+persistent readTime;
+persistent t1;
+persistent t2;
+%global delayLog;
+%global delayLog2;
+
+Lbuf = block_interface('getBufLen'); 
+if nargin==1
+   if Lbuf>0 && Lbuf~=L
+      error('%s: Buffer length was fixed to %i, but now requiring %i.',...
+            upper(mfilename),Lbuf,L);
+   end
+   if L<256
+      error('%s: Minimum buffer length is 256.',upper(mfilename));
+   end
+else
+   if Lbuf<0
+      L = 1024;
+   else
+      L = Lbuf;
+   end
+end
+
+do_updateGUI = 0;
+do_updateBAR = 0;
+
+loadind = block_interface('getDispLoad');
+
+if ischar(loadind)
+   if strcmp('bar',loadind)
+      do_updateBAR = 1;
+   end
+elseif isjava(loadind)
+   do_updateGUI = 1;
+else
+   error('%s: Something went wrong. Should not ever get here.',upper(mfilename));
+end
+
+if do_updateBAR || do_updateGUI 
+   if block_interface('getPageNo')>0
+      procTime = toc(t1);
+      res = 2;
+
+      fs= playrec('getSampleRate');
+      load = floor(100*(procTime+readTime)/(L/fs));
+      
+      if do_updateBAR
+         msg = sprintf(['Load : |',repmat('*',1,ceil(min([load,100])/res)),repmat(' ',1,floor((100-min([load,100]))/res)),'| \n']);
+         droppedStr = sprintf('Dropped samples: %i\n',playrec('getSkippedSampleCount'));
+         fprintf([clearStr,msg,droppedStr]);
+         clearStr = repmat(sprintf('\b'), 1, length(msg)+length(droppedStr));
+      elseif do_updateGUI
+         javaMethod('updateBar',loadind,load);
+      else
+         error('%s: Something went wrong. Should not ever get here.',upper(mfilename));
+      end
+   
+      block_interface('setSkipped',playrec('getSkippedSampleCount'));
+      if playrec('getSkippedSampleCount') > block_interface('getSkipped')
+         block_interface('setSkipped',playrec('getSkippedSampleCount'));
+      end
+
+   else
+      clearStr = '';
+      %delayLog = [];
+      %delayLog2 = [0];
+      procTime = 0;
+   end
+   t2 = tic;
+end
+
+valid = 1;
+source = block_interface('getSource');
+pos = block_interface('getPos') +1; % convert to the Matlab indexing
+block_interface('incPageNo');
+pageNo = block_interface('getPageNo');
+classid = block_interface('getClassId');
+
+% Update sample counter
+block_interface('setPos',pos+L-1); % convert back the Matlab indexing
+
+%%%
+%% REC, source is a mic/aux, no loopback
+%
+if strcmp(source,'rec')
+   recChanList = block_interface('getRecChanList');
+   
+   if do_updateBAR || do_updateGUI
+      readTime = toc(t2);
+   end
+   % Issue reading buffers up to max
+   while block_interface('getEnqBufCount') <= block_interface('getBufCount')
+      block_interface('pushPage', playrec('rec', L, recChanList));
+   end
+   pageList = block_interface('getPageList');
+   % Block until the first page is loaded
+   while(playrec('isFinished', pageList(1)) == 0)
+   end
+   % Read the data. Cast to the specified type
+   f = cast(playrec('getRec',pageList(1)),classid);
+   % Delete page
+   playrec('delPage', pageList(1));
+   % Throw away the page id
+   block_interface('popPage');
+   
+%%%   
+%% PLAYREC, source is a mic, loopback to an output
+%
+elseif strcmp(source,'playrec')
+   recChanList = block_interface('getRecChanList');
+   if pageNo<=1
+      blockplay(zeros(L,numel(recChanList),classid));
+   end
+   
+   % Enqueue already processed
+   fhat = block_interface('getToPlay');
+   if isempty(fhat)
+      fhat = zeros(L,numel(recChanList),classid);
+   end
+   chanList = block_interface('getPlayChanList');
+
+   % Copy input channel to all output chanels.
+   if size(fhat,2)==1
+      fhat = repmat(fhat,1,numel(chanList));
+   end
+   % Play and record
+   block_interface('pushPage',playrec('playrec', fhat, chanList, -1, recChanList));
+   
+   if do_updateBAR || do_updateGUI
+      readTime = toc(t2);
+   end
+   pageList = block_interface('getPageList');
+   % Playback is block_interface('getBufCount') behind the input
+   if block_interface('getPageNo') <= block_interface('getBufCount')
+      f = zeros(L,numel(recChanList),classid);
+   else
+      % Block until the first page is loaded
+      while(playrec('isFinished', pageList(1)) == 0)
+      end
+      % Read the data
+      f = cast(playrec('getRec',pageList(1)),classid);
+      playrec('delPage', pageList(1));
+      % Throw away the page id
+      block_interface('popPage');
+   end
+
+%%%   
+%% PLAY: Source is a *.wav file
+%
+elseif isa(source,'function_handle')
+   % Get play channel list (could be chached) 
+   chanList = block_interface('getPlayChanList');
+   % Get already processed (from blockplay)
+   fhat = block_interface('getToPlay');
+
+   % Create something if blockplay was not called
+   if isempty(fhat)
+      fhat = zeros(L,numel(chanList),classid);
+   end
+
+   % Broadcast single input channel to all output chanels.
+   if size(fhat,2)==1
+      fhat = repmat(fhat,1,numel(chanList));
+   end
+
+   % Number of wav samples (is chached, since it is disk read operation)
+   Lwav = block_interface('getLs');
+
+
+   % Determine valid samples
+   endSample = min(pos + L - 1, Lwav(1));
+   %f = cast(wavread(source,[pos, endSample]),block_interface('getClassId'));
+   f = source(pos,endSample);
+   % Pad with zeros if some samples are missing
+   if (pos + L - 1) >= Lwav(1)
+      ftmp = zeros(L,Lwav(2),classid);
+      ftmp(1:size(f,1),:) = f;
+      f = ftmp;
+      % Rewind if loop option was set.
+      if block_interface('getIsLoop')
+         block_interface('setPos',0);
+         % Throw away stored overlaps.
+         if ~isempty(block_interface('getAnaOverlap'))
+            block_interface('setAnaOverlap',[]);
+         end
+         if ~isempty(block_interface('getSynOverlap'))
+            block_interface('setSynOverlap',[]);
+         end
+      else
+         valid = 0;
+      end
+   end
+
+
+   % playrec('play',... - enques fhat to be played
+   % block_interface('pushPage', - stores page number in an inner FIFO
+   % queue
+   block_interface('pushPage', playrec('play', fhat, chanList));
+
+   if do_updateBAR || do_updateGUI
+      readTime = toc(t2);
+   end
+   % If enough buffers are enqued, block the execution here until the 
+   % first one is finished.
+   if block_interface('getEnqBufCount') > block_interface('getBufCount')
+      pageId = block_interface('popPage');
+      % "Aggresive" chceking if page was played.
+      % Another (supposedly slower) option is:
+      % playrec('block',pageId);
+      while(playrec('isFinished', pageId) == 0), end;
+   end
+end
+
+if pageNo<=1
+   playrec('resetSkippedSampleCount');
+end
+
+if do_updateBAR || do_updateGUI
+   t1=tic;
+end
+
+
diff --git a/inst/blockproc/blocksyn.m b/inst/blockproc/blocksyn.m
new file mode 100644
index 0000000..c2be54d
--- /dev/null
+++ b/inst/blockproc/blocksyn.m
@@ -0,0 +1,264 @@
+function [fhat, fola] = blocksyn(F, c , Lb, fola)
+%-*- texinfo -*-
+%@deftypefn {Function} blocksyn
+%@verbatim
+%BLOCKSYN Blockwise synthesis interface
+%   Usage: blocksyn(F, c, Lb)
+%
+%   Input parameters:
+%      F    : Synthesis frame object.
+%      c    : Coefficients of a block.
+%      Lb   : Length of the block.
+%      fola : Explicitly defined overlap.
+%   Output parameters:
+%      fhat : Reconstructed block of signal.
+%      fola : Stored overlap.
+%
+%   fhat=BLOCKSYN(F,c,Lb) reconstructs the signal block fhat from the
+%   coefficients c using the frame defined by F. If some overlap is used,
+%   it is stored internally using BLOCK_INTERFACE. Nothe that the function is 
+%   capable of handling overlaps internally only for a single call
+%   to the function in the blockproc. loop.%   
+%
+%   [fhat,fola]=BLOCKSYN(F,c,Lb,fola) does the same, but the block algorithm
+%   uses fola to read and store overlap explicitly. fola can be empty.
+%
+%   *Note:* To get perfect reconstruction, the synthesis frame F must
+%   be a dual frame of the analysis frame used in BLOCKANA.
+%
+%
+%   References:
+%     N. Holighaus, M. Doerfler, G. A. Velasco, and T. Grill. A framework for
+%     invertible, real-time constant-Q transforms. IEEE Transactions on
+%     Audio, Speech and Language Processing, 21(4):775 -785, 2013.
+%     
+%     Z. Průša. Segmentwise Discrete Wavelet Transform. PhD thesis, Brno
+%     University of Technology, Brno, 2012.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/blockproc/blocksyn.php}
+%@seealso{block, blockana, framedual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+    if nargin<3
+        error('%s: Too few input parameters.',upper(mfilename));
+    end;
+    
+    if ~isstruct(F)
+        error('%s: First argument must be a frame definition structure.',upper(mfilename));
+    end;
+    
+    if ~isfield(F,'blockalg')
+        F.blockalg = 'naive';
+    end
+    
+    if nargin<4
+       fola = [];
+    end
+    
+    % Next block index start (from a global point of view, starting with zero)
+    nextSb = block_interface('getPos');
+    % Block index start (from a global point of view, starting with zero)
+    Sb = nextSb-Lb;
+    
+    if strcmp(F.blockalg,'naive')
+       % Most general. Should work for anything.
+       % Produces awful block artifacts when coefficients are altered.
+       fhat = F.frsyn(c);
+       fhat = fhat(1:Lb,:);
+    elseif strcmp(F.blockalg,'sliced')
+        % General processing
+        % Equal block length assumption
+        % Reconstruct
+        f = F.frsyn(c);
+        % If the transform length differs from the 2*Lb,
+        % Pick the correct part from the result
+        pad = size(f,1) - 2*Lb;
+        sIdx = floor(pad/2);
+        % Result should not be longer than 2*Lb
+        f = f(1+sIdx:sIdx+2*Lb,:);
+        % Multiply by a slicing window
+        f = bsxfun(@times,F.sliwin,f);
+        % Load and add overlap (first half)
+        ol = loadOverlap(Lb,size(f,2),fola);
+        olLen = size(ol,1);
+        f(1:olLen,:) = f(1:olLen,:) + ol;
+        % Store overlap (second half)
+        if nargout>1
+           fola=storeOverlap(f,Lb);
+        else
+           storeOverlap(f,Lb);
+        end
+        % Return first half
+        fhat = f(1:Lb,:);
+    elseif strcmp(F.blockalg,'segola')
+       if ~isfield(F,'winLen') 
+          error('%s: Frame does not have FIR windows.',upper(mfilename));
+       end
+       Lw = F.winLen;
+       switch(F.type)
+         case 'fwt'
+           % The SegDWT algorithm
+           J = F.J;
+           w = F.g;
+           m = numel(w.g{1}.h);
+           a = w.a(1);
+           blocksize = a^J;
+           r = (a^J-1)/(a-1)*(m-1);
+           Lbrec = (floor(nextSb/blocksize) - floor(Sb/blocksize))*blocksize;
+           rSb = (a^J-1)/(a-1)*(m-a) + mod(Sb,a^J);
+           over = r - rSb;
+           f = block_ifwt(c,w,J,Lbrec);
+           ol = loadOverlap(r-mod(Sb, a^J),size(c,2),fola);
+           olLen = size(ol,1);
+           f(1:olLen-over,:) = f(1:olLen-over,:) + ol(1+over:end,:);
+           f = [ol(1:over,:);f];
+           if nargout>1
+              fola=storeOverlap(f,r-mod(nextSb, a^J));
+           else
+              storeOverlap(f,r-mod(nextSb, a^J));
+           end
+           fhat = f(1:Lb,:);
+          case {'dgt','dgtreal','dwilt','wmdct'}
+           % Time step 
+           a = F.a; 
+           % Length of the left half of the window
+           Lwl = floor(Lw/2);
+
+           Sbonelmax =  ceil((Lw-1)/a)*a + a-1;
+           Sbolen = ceil((Lw-1)/a)*a + mod(Sb,a);
+           % Next block overlap length
+           nextSbolen = ceil((Lw-1)/a)*a + mod(nextSb,a);
+           Lext = Sbolen + Lb - mod(nextSb,a);
+           Lextc = Sbolen + Lb - nextSbolen + Lwl;
+           
+           startc = ceil(Lwl/a)+1;
+           endc = ceil((Lextc)/a);
+           
+           cc = F.coef2native(c,size(c));
+           chat = zeros(size(cc,1),ceil(F.L/a),size(cc,3),class(cc));
+           chat(:,startc:endc,:) = cc;
+           chat = F.native2coef(chat); 
+           f = F.frsyn(chat);
+           f = f(1:Lext,:);
+           over = Sbonelmax - Sbolen;
+           
+           ol = loadOverlap(Sbonelmax-mod(Sb,a),size(c,2),fola);
+           olLen = size(ol,1);
+           f(1:olLen-over,:) = f(1:olLen-over,:) + ol(1+over:end,:);
+           f = [ol(1:over,:);f];
+           if nargout>1
+              fola=storeOverlap(f,Sbonelmax-mod(nextSb,a));
+           else
+              storeOverlap(f,Sbonelmax-mod(nextSb,a));
+           end
+           fhat = f(1:Lb,:);
+          case {'filterbank','filterbankreal'} 
+           lcma = F.lcma;
+           % Time step 
+           a = F.a(:,1); 
+           % Length of the left half of the window
+           Lwl = max(-F.g_info.offset);
+           
+                if Lw-1 < a
+           Sbonelmax =   lcma-1;
+           Sbolen =  mod(Sb,lcma);
+           nextSbolen = mod(nextSb,lcma);
+                else
+           Sbonelmax =  ceil((Lw-1)/lcma)*lcma + lcma-1;
+           Sbolen = ceil((Lw-1)/lcma)*lcma + mod(Sb,lcma);
+           nextSbolen = ceil((Lw-1)/lcma)*lcma + mod(nextSb,lcma);
+                end
+
+
+           Lext = Sbolen + Lb - mod(nextSb,lcma);
+           Lextc = Sbolen + Lb - nextSbolen + Lwl;
+           
+           startc = ceil(Lwl./a)+1;
+           endc = ceil((Lextc)./a);
+           
+           cc = F.coef2native(c,size(c));
+           
+           chat = cell(numel(cc),1);
+           for ii=1:numel(cc)
+              chat{ii} = zeros(ceil(F.L./a(ii)),size(cc{ii},2));
+              chat{ii}(startc(ii):endc(ii),:) = cc{ii};
+           end
+           
+           chat = F.native2coef(chat); 
+           f = F.frsyn(chat);
+           f = f(1:Lext,:);
+           over = Sbonelmax - Sbolen;
+           
+           
+           ol = loadOverlap(Sbonelmax-mod(Sb,lcma),size(c,2),fola);
+           olLen = size(ol,1);
+           f(1:olLen-over,:) = f(1:olLen-over,:) + ol(1+over:end,:);
+           f = [ol(1:over,:);f];
+           if nargout>1
+              fola=storeOverlap(f,Sbonelmax-mod(nextSb,lcma));
+           else
+              storeOverlap(f,Sbonelmax-mod(nextSb,lcma));
+           end
+           fhat = f(1:Lb,:);             
+          otherwise
+           error('%s: Unsupported frame.',upper(mfilename));
+        end
+
+    else
+       error('%s: Frame was not created with blockaccel.',upper(mfilename));
+    end
+
+end
+
+function overlap = loadOverlap(L,chan,overlap)
+%LOADOVERLAP Loads overlap
+%
+%
+   if isempty(overlap)
+      overlap = block_interface('getSynOverlap');
+   end
+   
+   if isempty(overlap)
+     overlap = zeros(L,chan,block_interface('getClassId'));
+   end
+   Lo = size(overlap,1);
+   if nargin<1
+      L = Lo;
+   end
+   if L>Lo
+      error('%s: Required more samples than stored.',upper(mfilename));
+   end
+   overlap = overlap(end-L+1:end,:);
+end
+
+function overlap = storeOverlap(fext,L)
+%STOREOVERLAP Stores overlap
+%
+%
+    if L>size(fext,1)
+        error('%s: Storing more samples than passed.',upper(mfilename));
+    end
+    overlap = fext(end-L+1:end,:);
+    
+    if nargout<1
+       block_interface('setSynOverlap',overlap); 
+    end
+end % STOREOVERLAP
+
diff --git a/inst/blockproc/java/Makefile b/inst/blockproc/java/Makefile
new file mode 100644
index 0000000..d511631
--- /dev/null
+++ b/inst/blockproc/java/Makefile
@@ -0,0 +1,18 @@
+# Use Make to process this file. 
+
+JC=javac
+
+FLAGS=-source 1.6 -target 1.6
+include ../../src/ostools.mk
+
+default:
+	$(JC) $(FLAGS) net/sourceforge/ltfat/*.java net/sourceforge/ltfat/thirdparty/*.java
+	jar cf blockproc.jar net/sourceforge/ltfat/*.class net/sourceforge/ltfat/thirdparty/*.class
+
+clean: classclean
+	$(RM)  *.jar
+
+classclean:
+	$(RM) net$(PS)sourceforge$(PS)ltfat$(PS)*.class
+	$(RM) net$(PS)sourceforge$(PS)ltfat$(PS)thirdparty$(PS)*.class
+
diff --git a/inst/blockproc/java/blockproc.jar b/inst/blockproc/java/blockproc.jar
new file mode 100644
index 0000000..e87c4ff
Binary files /dev/null and b/inst/blockproc/java/blockproc.jar differ
diff --git a/inst/blockproc/java/net/sourceforge/ltfat/ContFrame.java b/inst/blockproc/java/net/sourceforge/ltfat/ContFrame.java
new file mode 100644
index 0000000..f6a206f
--- /dev/null
+++ b/inst/blockproc/java/net/sourceforge/ltfat/ContFrame.java
@@ -0,0 +1,385 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.sourceforge.ltfat;
+
+import java.awt.*;
+import javax.swing.*;
+import java.awt.KeyEventDispatcher;
+import java.awt.KeyboardFocusManager;
+import java.util.List;
+import java.awt.event.KeyEvent;
+import java.lang.Override;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.lang.Throwable;
+
+/**
+ *
+ * @author zprusa
+ */
+public class ContFrame {
+    volatile private boolean showLoadInd = false;
+    private JFrame jf = null;
+    private Map paramMap = null;
+    private Map sliderParamMap = null;
+    private Map sliderBoundsMap = null;
+    public double flag = 1;
+    private ExecutorService executor = Executors.newSingleThreadExecutor();
+    
+    JLabel loadLabel;
+    JProgressBar loadBar;
+    JLabel loadTxt;
+    
+    // Components
+    private int defXPad = 3;
+    private int defYPad = 10;
+    private int namePrefferedSize = 70;
+    private int sliderPrefferedSize = 170;
+    private int valuePrefferedSize = 30;
+
+    /*
+    Sanity check.
+    Attempt to close the window if there was an exeption in the Matlab code
+     */
+
+  @Override
+    public void finalize() throws Throwable{
+      //System.out.println("Finalize called on ContFrame");
+        try{
+            this.close();
+        }
+        catch(Throwable t){
+            throw t;
+        }
+        finally {
+            super.finalize();
+        }
+
+    }
+
+
+
+    public double getParam(String key) throws NoSuchFieldException {
+       if(paramMap == null)
+           return 0;
+
+       Double d = (Double) paramMap.get(key);
+       if(d==null){
+          throw new NoSuchFieldException("Parameter "+key+" not found."); 
+       }
+       return (Double)paramMap.get(key);
+    }
+    
+     public double[] getParams(String... key) throws NoSuchFieldException {
+       int keyLen = key.length;
+       double[] out = new double[keyLen]; 
+       for(int ii=0;ii<keyLen;ii++){
+          try{ 
+             out[ii]=getParam(key[ii]); 
+          }
+          catch(NoSuchFieldException err){
+              throw(err);
+          }
+       }
+       return out;
+    }
+     
+     public double[] getParams() {
+       int outLen = paramMap.size();
+       if(outLen==0){
+          throw new NullPointerException("Parameter map is empty");
+       }
+       Iterator it = paramMap.entrySet().iterator();
+       double[] out = new double[outLen]; 
+       int ii=0;
+       while (it.hasNext()) {
+          Map.Entry act = (Map.Entry) it.next(); 
+          out[ii++] = (Double) act.getValue();
+       }
+       return out;
+     } 
+
+    public void addControlElements(final List params) {
+        // Ensure everything is done in the EDT
+        runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                paramMap = new LinkedHashMap<String,Double>();
+                sliderParamMap = new HashMap<JSlider,String>();
+                sliderBoundsMap = new HashMap<JSlider,SliderBounds>();
+                initFrameComponents(params);
+                jf.pack();
+                jf.validate();
+                jf.setVisible(true);
+            }
+        });
+    }
+
+    public void close() {
+        if (jf != null) {
+            jf.setVisible(false);
+            jf.dispose();
+        }
+    }
+
+    private void runInEDT(Runnable r){
+        if (SwingUtilities.isEventDispatchThread()) {
+            //   System.out.println("We are on on EDT. Strange....");
+            try{
+                r.run();
+            }
+            catch(Exception e){}
+            catch(Throwable t){}
+        } else {
+            try{
+                SwingUtilities.invokeLater(r);
+            }
+            catch(Exception e){}
+            catch(Throwable t){}
+        }
+    }
+
+    private void runInPool(Runnable r){
+        if (SwingUtilities.isEventDispatchThread()) {
+            System.out.println("Warning! We are on on EDT. Strange....");
+        }
+        try{
+            executor.execute(r);
+        }
+        catch(Exception e){}
+        catch(Throwable t){}
+    }
+
+    public void updateBar(final double val) {
+       runInPool( new Runnable() {
+           public void run() {
+               if(loadLabel==null||loadBar==null||loadTxt==null)
+                   return;
+               
+               if(!showLoadInd){
+                   loadLabel.setVisible(true);
+                   loadBar.setVisible(true); 
+                   loadTxt.setVisible(true);
+               }
+               loadBar.setValue((int)val);
+               loadTxt.setText(String.format(" %d%%",((int)val)));
+               if((int)val>80){
+                   loadTxt.setForeground(Color.red);
+               }
+               else{
+                   loadTxt.setForeground(Color.black);
+               }
+               
+               showLoadInd = true;
+               loadBar.repaint();
+               loadTxt.repaint();
+           }
+       });
+
+   }
+
+    public ContFrame() {
+        runInEDT( new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    // Set System L&F
+                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+                } catch (UnsupportedLookAndFeelException e) {
+                    // handle exception
+                } catch (ClassNotFoundException e) {
+                    // handle exception
+                } catch (InstantiationException e) {
+                    // handle exception
+                } catch (IllegalAccessException e) {
+                    // handle exception
+                }
+
+                jf = initFrame();
+            }
+        });
+
+    }
+
+    public void setLocation(final double x, final double y){
+        runInEDT( new Runnable() {
+            @Override
+            public void run() {
+                    jf.setLocation((int)x,(int)y);
+            }
+        });
+    }
+
+
+    private JFrame initFrame() {
+        final JFrame buildJF = new JFrame("LTFAT Control Panel");
+        buildJF.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+        buildJF.addWindowListener(new java.awt.event.WindowAdapter() {
+            @Override
+            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
+                flag = 0;
+                close();
+            }
+        });
+
+        // Add a global Ctrc-C keyboard shortcut listener
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        kfm.addKeyEventDispatcher(new KeyEventDispatcher() {
+            @Override
+            public boolean dispatchKeyEvent(KeyEvent e) {
+                if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_C &&
+                   e.getID()==KeyEvent.KEY_PRESSED){
+                    // Ctrl-C does not hide the
+                    flag = 0;
+                }
+                // The Ctrl-C is consumed here. It is not passed further.
+                return false;
+            }
+        });
+
+        return buildJF;
+    }
+    
+    private void initFrameComponents(List<List> params){
+       GridBagLayout gl =  new GridBagLayout();
+       jf.setLayout(gl); 
+       GridBagConstraints labelConst = new GridBagConstraints();
+       GridBagConstraints sliderConst = new GridBagConstraints();
+       GridBagConstraints valConst = new GridBagConstraints();
+       
+       labelConst.gridx = 0;
+       labelConst.gridy = 0;
+       labelConst.fill = GridBagConstraints.VERTICAL;
+       labelConst.ipadx = defXPad;
+       labelConst.ipady = defYPad;
+       labelConst.anchor = GridBagConstraints.CENTER;
+       labelConst.weightx = 0.2;
+       labelConst.weighty = 1.0/params.size();
+    
+       sliderConst.gridx = 1;
+       sliderConst.gridy = 0;
+       sliderConst.fill = GridBagConstraints.HORIZONTAL;
+       sliderConst.ipadx = defXPad;
+       sliderConst.ipady = defYPad;
+       sliderConst.anchor = GridBagConstraints.CENTER;
+       sliderConst.weightx = 0.7;
+       sliderConst.weighty = 1.0/params.size();
+       
+       valConst.gridx = 2;
+       valConst.gridy = 0;
+       valConst.fill = GridBagConstraints.BOTH;
+       valConst.ipadx = defXPad;
+       valConst.ipady = defYPad;
+       valConst.anchor = GridBagConstraints.LINE_START;
+       valConst.weightx = 0.1;
+       valConst.weighty = 1.0/params.size();
+       valConst.insets = new Insets(10, 0, 0, 0);
+       
+       
+       
+        
+       for(List lEl: params){
+           String name= new String("noname");
+           String label= new String("nolabel");
+           Object labelObj = lEl.get(1);
+           if(labelObj instanceof Character){
+              label = ((Character)labelObj).toString();
+           }
+           else if(labelObj instanceof String){
+              label = (String)labelObj;
+           }
+           Object nameObj = lEl.get(0);
+           if(nameObj instanceof Character){
+              name = ((Character)nameObj).toString();
+           }
+           else if(nameObj instanceof String){
+              name = (String)nameObj;
+           }
+           
+           Double minVal = (Double) lEl.get(2);
+           Double maxVal = (Double)lEl.get(3);
+           Double defaultVal = (Double)lEl.get(4);
+           int noVal = ((Double)lEl.get(5)).intValue();
+           int defValSlider = val2slider(defaultVal,minVal,maxVal,noVal);
+           
+           JLabel jname = new JLabel(label);
+           JSlider jval = new JSlider(0, noVal-1, defValSlider);
+           final JLabel jvalTxt = new JLabel(String.format("%.3g    ",slider2val(jval.getValue(),minVal,maxVal,noVal)));
+           jvalTxt.setPreferredSize(new Dimension(50, 15));
+           jval.addChangeListener(new ChangeListener() {
+               @Override
+               public void stateChanged(ChangeEvent e) {
+                  JSlider jslider = (JSlider) e.getSource();
+                  int sliIntVal = jslider.getValue();
+                  double sliMinVal = ((SliderBounds)sliderBoundsMap.get(jslider)).getMinVal();
+                  double sliMaxVal = ((SliderBounds)sliderBoundsMap.get(jslider)).getMaxVal();
+                  double sliVal = slider2val(sliIntVal, sliMinVal, sliMaxVal, jslider.getMaximum()+1);
+                  
+                  final Dimension jvalTxtDim = jvalTxt.getPreferredSize();
+                  jvalTxt.setMinimumSize(jvalTxtDim);
+                  jvalTxt.setMaximumSize(jvalTxtDim);
+                  jvalTxt.setText(String.format("%.3g",sliVal));
+                  paramMap.put(sliderParamMap.get(jslider), sliVal );
+               }
+           });
+           
+           
+           jf.add(jname,labelConst);
+           labelConst.gridy += 1;
+           jf.add(jval,sliderConst);
+           sliderConst.gridy += 1;
+           jf.add(jvalTxt,valConst);
+           valConst.gridy += 1;
+           
+           
+           paramMap.put(name, defaultVal);
+           sliderParamMap.put(jval, name);
+           sliderBoundsMap.put(jval, new SliderBounds(minVal,maxVal));
+       }
+       
+
+       loadTxt = new JLabel("0%");
+       loadTxt.setPreferredSize(new Dimension(50, 15));
+       loadLabel = new JLabel("Load:");
+       loadBar = new JProgressBar();
+
+       jf.add(loadLabel,labelConst);
+       jf.add(loadBar,sliderConst);
+       jf.add(loadTxt,valConst);
+       loadLabel.setVisible(false);
+       loadBar.setVisible(false);
+       loadTxt.setVisible(false);
+    }
+    
+    private int val2slider(double val, double minVal, double maxVal, int noVal){
+       int retVal = (int)Math.round((val-minVal)/(maxVal-minVal)*(noVal-1));
+       return Math.min(Math.max(retVal, 0),noVal);
+    }
+    
+    private double slider2val(int slider, double minVal, double maxVal, int noVal){
+       double retVal = ((double)slider)/(noVal-1)*(maxVal-minVal) + minVal;
+       return Math.min(Math.max(retVal, minVal),maxVal);
+    }
+    
+    private class SliderBounds{
+        private double minVal = 0.0;
+        private double maxVal = 0.0;
+        SliderBounds(double minVal,double maxVal){
+            this.minVal = minVal;
+            this.maxVal = maxVal;
+        }
+        
+        double getMaxVal(){
+          return maxVal;
+        }
+        
+        double getMinVal(){
+          return minVal;
+        }
+    }
+}
diff --git a/inst/blockproc/java/net/sourceforge/ltfat/SpectFrame.java b/inst/blockproc/java/net/sourceforge/ltfat/SpectFrame.java
new file mode 100644
index 0000000..7a8bb1b
--- /dev/null
+++ b/inst/blockproc/java/net/sourceforge/ltfat/SpectFrame.java
@@ -0,0 +1,478 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.sourceforge.ltfat;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.IndexColorModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.lang.Override;
+import java.lang.Runnable;
+import java.lang.Throwable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JSlider;
+import javax.swing.SwingUtilities;
+import javax.swing.Timer;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import net.sourceforge.ltfat.thirdparty.JRangeSlider;
+
+/**
+ *
+ * @author zprusa
+ */
+public class SpectFrame {
+    // Default image dimensions
+    static final int defWidth = 800;
+    static final int defHeight = 400;
+    static final int heightRed = 4;
+    // Actual image dimensions
+    private int height = defHeight;
+    private int width = defWidth;
+    private JFrame jf = null;
+    // Spectrogram has its own pannel
+    SpectPanel spectPanel = null;
+    private ExecutorService executor=Executors.newSingleThreadExecutor();
+    // Default colormap length
+    private int cmapLen = 256; 
+    private byte[] colormap = null;
+    IndexColorModel cm = null;
+    private int sidx = 0;
+    private int srunPos = 0;
+    private int defSpeed = 2;
+    private int spectStep = defSpeed*width/800;
+    private String popupName = "LTFAT plot";
+    private double climMax = 20;
+    private double climMin = -70;
+    private String climUnit = "dB";
+    private final Object graphicsLock = new Object();
+
+        /*
+    Sanity check.
+    Attempt to close the window if there was an exeption in the Matlab code
+     */
+
+    @Override
+    public void finalize() throws Throwable{
+        //System.out.println("Finalize called on SpectFrame");
+        try{
+            this.close();
+        }
+        catch(Throwable t){
+            throw t;
+        }
+        finally {
+            super.finalize();
+        }
+
+    }
+
+    public SpectFrame(){
+        this(defWidth,defHeight);
+    }
+   
+    public SpectFrame(final int width, final int height) {
+        
+      colormap = new byte[cmapLen*3];  
+      for(int yy=0;yy<cmapLen;yy++){
+         colormap[3*yy] = (byte) yy;
+         colormap[3*yy+1] = (byte) yy;
+         colormap[3*yy+2] = (byte) yy;
+      }
+      cm = new IndexColorModel(8, cmapLen, colormap, 0, false);  
+      
+      runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    // Set System L&F
+                    UIManager.setLookAndFeel(
+                            UIManager.getSystemLookAndFeelClassName());
+                } catch (UnsupportedLookAndFeelException e) {
+                    // handle exception
+                } catch (ClassNotFoundException e) {
+                    // handle exception
+                } catch (InstantiationException e) {
+                    // handle exception
+                } catch (IllegalAccessException e) {
+                    // handle exception
+                }
+
+                //setColormap(cm);
+                jf = initFrame(width,height);
+                jf.pack();
+            }
+        });
+    }
+
+    public void setLocation(final double x, final double y){
+        runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                if(jf != null){
+                    jf.setLocation((int)x,(int)y);
+                }
+            }
+        });
+    }
+
+    public void show(){
+        runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                if(jf!=null)
+                    jf.setVisible(true);
+            }
+        });
+
+    }
+
+
+    /* Octave version */
+    public void setColormap(double[] cmMat, double cMatLen, double cols){
+    if (colormap==null ){
+       colormap = new byte[cmapLen*3];   
+    }
+    int cmIdx = 0;
+    float ratio = ((float)cMatLen)/((float)cmapLen);
+    for(int yy=0;yy<cmapLen;yy++){
+          for(int xx=0;xx<cols;xx++){
+             double tmpVal = 255.0*cmMat[(int)(Math.floor(yy*ratio)+cMatLen*xx)];
+             tmpVal = Math.min(tmpVal, 255.0);
+             tmpVal = Math.max(tmpVal, 0.0);
+             colormap[cmIdx++] = (byte) tmpVal;
+          }
+    }
+        cm = new IndexColorModel(8, cmapLen, colormap, 0, false);
+    }
+    
+    /* Matlab version */
+    public void setColormap(double[][] cmMat){
+    if (colormap==null ){
+       colormap = new byte[cmapLen*3];   
+    }
+    int cmIdx = 0;
+    int cMatLen = cmMat.length;
+    float ratio = cMatLen/((float)cmapLen);
+    for(int yy=0;yy<cmapLen;yy++){
+          for(int xx=0;xx<cmMat[0].length;xx++){
+             double tmpVal = 255.0*cmMat[(int)Math.floor(yy*ratio)][xx];
+             tmpVal = Math.min(tmpVal, 255.0);
+             tmpVal = Math.max(tmpVal, 0.0);
+             colormap[cmIdx++] = (byte) tmpVal;
+          }
+    }
+    
+    cm = new IndexColorModel(8, cmapLen, colormap, 0, false);
+    }
+    
+    public void close() {
+        if (jf != null) {
+            jf.setVisible(false);
+            jf.dispose();
+        }
+        if( executor != null ){
+           executor.shutdown();
+        }
+    }
+
+    
+    private JFrame initFrame(int width, int height){
+        this.height = height;
+        this.width = width;
+        JFrame buildJF = new JFrame("LTFAT Plot Panel");
+        buildJF.setLayout(new BorderLayout());
+        spectPanel = new SpectPanel(width,height);
+        
+        buildJF.add(spectPanel);
+        spectPanel.addWheelListener();
+        
+        
+        JPopupMenu jpm = new JPopupMenu(popupName);
+        
+        JSlider speedSlider = new JSlider(JSlider.HORIZONTAL, 1, 10, defSpeed);
+        speedSlider.addChangeListener(new ChangeListener() {
+
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JSlider source = (JSlider)e.getSource();
+                spectStep = source.getValue()*defWidth/800;
+            }
+        });
+        
+        JRangeSlider climSlider = new JRangeSlider((int)climMin, (int)climMax, (int)climMin,(int) climMax, JRangeSlider.HORIZONTAL);
+        climSlider.addChangeListener(new ChangeListener() {
+
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JRangeSlider source = (JRangeSlider)e.getSource();
+                climMin = source.getLowValue();
+                climMax = source.getHighValue();
+            }
+        });
+        
+         
+        JLabel speedTxt = new JLabel("Speed:");
+        JPanel speedPanel = new JPanel();
+        speedPanel.add(speedTxt);
+        speedPanel.add(speedSlider);
+        speedSlider.setPreferredSize(new Dimension(100,speedSlider.getPreferredSize().height));
+        jpm.add(speedPanel);
+        
+        JLabel climTxt = new JLabel("Limits:");
+        JPanel climPanel = new JPanel();
+        climPanel.add(climTxt);
+        climPanel.add(climSlider);
+        climSlider.setPreferredSize(new Dimension(100,climSlider.getPreferredSize().height));
+        jpm.add(climPanel);
+        
+        
+        spectPanel.addPopupMenu(jpm);
+        return buildJF;
+    }
+
+    public int getHeight() {
+      return this.height;
+    }
+
+    
+    
+    /*
+     * Col is passed by value from Matlab
+     */
+      public void append(final double[] col, final double colHeight, final double colWidth) {
+
+
+       runInPool(new Runnable() {
+            @Override
+            public void run() {
+               if(spectPanel==null){
+                  return;
+	       }
+
+	       Utils.pow(col);
+               Utils.db(col);
+               Float mindb = new Float(climMin);
+               Float maxdb = new Float(climMax);
+               Utils.clipToRange(col, mindb, maxdb);
+               byte[] pixels = new byte[col.length];
+               Utils.toByte(col, pixels, mindb, maxdb);
+
+              //System.out.println(pixels);
+               DataBuffer dbuf = new DataBufferByte(pixels, col.length, 0);
+               SampleModel smod = new MultiPixelPackedSampleModel( DataBuffer.TYPE_BYTE,(int) colWidth,(int)colHeight, 8);
+               WritableRaster raster = Raster.createWritableRaster(smod, dbuf, null);
+               BufferedImage image = new BufferedImage(cm, raster, false, null);
+           
+             
+               Graphics2D g2 = (Graphics2D) spectPanel.getGraphics2D();
+               g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+               //g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+               g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+               synchronized(graphicsLock)
+               {
+                  int startsrunPos = srunPos;
+                  srunPos += spectStep;
+
+                  if(srunPos>width){
+                     g2.drawImage(image,startsrunPos,heightRed*height, width,0,0,0,(int)colWidth,(int)colHeight, null);
+                     srunPos -= width;
+                     startsrunPos = 0;
+                  }
+                  g2.drawImage(image,startsrunPos,heightRed*height, srunPos,0,0,0,(int)colWidth,(int)colHeight, null);
+               }
+              
+               spectPanel.repaint();
+            }
+        });
+    }
+    
+    
+    public void append(final float[][] col) {
+
+       final int colWidth = col[0].length;
+       final int colHeight = col.length;
+
+       runInPool(new Runnable() {
+            @Override
+            public void run() {
+               Utils.pow(col);
+               Utils.db(col);
+               Float mindb = new Float(climMin);
+               Float maxdb = new Float(climMax);
+               Utils.clipToRange(col, mindb, maxdb);
+               byte[] pixels = new byte[colWidth*colHeight];
+               Utils.toByte(col, pixels, mindb, maxdb);
+
+              //System.out.println(pixels);
+               DataBuffer dbuf = new DataBufferByte(pixels, colWidth*colHeight, 0);
+               SampleModel smod = new MultiPixelPackedSampleModel( DataBuffer.TYPE_BYTE, colWidth,colHeight, 8);
+               WritableRaster raster = Raster.createWritableRaster(smod, dbuf, null);
+               BufferedImage image = new BufferedImage(cm, raster, false, null);
+           
+             
+               Graphics2D g2 = (Graphics2D) spectPanel.getGraphics2D();
+               g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+               g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+               g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+               synchronized(graphicsLock)
+               {
+                  int startsrunPos = srunPos;
+                  srunPos += spectStep;
+
+                  if(srunPos>width){
+                     g2.drawImage(image,startsrunPos,heightRed*height, width,0,0,0,colWidth,colHeight, null);
+                     srunPos -= width;
+                     startsrunPos = 0;
+                  }
+                  g2.drawImage(image,startsrunPos,heightRed*height, srunPos,0,0,0,colWidth,colHeight, null);
+               }
+               spectPanel.repaint();
+            }
+        });
+    }
+    
+    public void append(double[][] col) {
+      // System.out.println("Jessss"+col.length);
+    }
+
+     private void runInEDT(Runnable r){
+        if (SwingUtilities.isEventDispatchThread()) {
+            //   System.out.println("We are on on EDT. Strange....");
+            try{
+                r.run();
+            }
+            catch(Exception e){}
+            catch(Throwable t){}
+        } else {
+            try{
+                SwingUtilities.invokeLater(r);
+            }
+            catch(Exception e){}
+            catch(Throwable t){}
+        }
+    }
+     
+     private void runInPool(Runnable r){
+        if (SwingUtilities.isEventDispatchThread()) {
+            System.out.println("Warning! We are on on EDT. Strange....");
+        }
+        try{
+            executor.execute(r);
+        }
+        catch(Exception e){}
+        catch(Throwable t){}
+    } 
+     
+    private class SpectPanel extends JPanel{
+        private BufferedImage spectbf = null;
+        private float zoom = 1.0f;
+
+        public void addWheelListener(){
+        
+            this.addMouseWheelListener(new MouseWheelListener() {
+
+                @Override
+                public void mouseWheelMoved(MouseWheelEvent e) {
+                    if(e.getWheelRotation()>0){
+                       zoom+=0.05;
+                       zoom = Math.min(zoom,1.0f);
+                    }
+                    else{
+                       zoom-=0.05;
+                       zoom = Math.max(zoom,0.05f);
+                    }
+                        
+                }
+            });
+        
+        }
+
+        public void addPopupMenu(JPopupMenu jpm){
+            this.setComponentPopupMenu(jpm);
+        }
+
+
+        public SpectPanel(int width, int height) {
+            Dimension dim = new Dimension(width, height);
+            setSize(dim);
+            setPreferredSize(dim);
+            spectbf = new BufferedImage(width, heightRed*height, BufferedImage.TYPE_4BYTE_ABGR);
+
+            Graphics2D bfGraphics = (Graphics2D) spectbf.getGraphics();
+            bfGraphics.setColor(Color.LIGHT_GRAY);
+            bfGraphics.fillRect(0, 0, width, heightRed*height);
+            
+        }
+        
+        public void setImage(BufferedImage bf){
+          spectbf = bf;
+        }
+        
+        protected void setZoom(float zoom)
+        {
+            this.zoom = zoom;
+        }
+
+        @Override
+        public void paintComponent(Graphics g) {
+            //super.paint(g);
+            Dimension thisSize = this.getSize();
+            Graphics2D g2d = (Graphics2D) g;
+            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
+            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
+            
+            if (spectbf != null) {
+               //synchronized(bfLock){
+               synchronized(graphicsLock)
+               { 
+                   
+                  int winIdx = (int) (thisSize.width * srunPos/((float)spectbf.getWidth()));
+                  int sbfH=(int)((1.0f-zoom)*spectbf.getHeight());
+                  g2d.drawImage(spectbf,thisSize.width-winIdx,0,thisSize.width,thisSize.height,
+                                        0,sbfH, srunPos,spectbf.getHeight(), null);
+                  g2d.drawImage(spectbf,0,0,thisSize.width-winIdx,thisSize.height,
+                                        srunPos,sbfH,spectbf.getWidth() , spectbf.getHeight(), null);
+               }
+
+            }
+        }
+        
+        public Graphics2D getGraphics2D(){
+           return (Graphics2D) spectbf.getGraphics();
+        }
+        
+   
+
+        
+    
+    }
+    
+    
+
+}
diff --git a/inst/blockproc/java/net/sourceforge/ltfat/Utils.java b/inst/blockproc/java/net/sourceforge/ltfat/Utils.java
new file mode 100644
index 0000000..20ab7e7
--- /dev/null
+++ b/inst/blockproc/java/net/sourceforge/ltfat/Utils.java
@@ -0,0 +1,199 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.sourceforge.ltfat;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferFloat;
+
+/**
+ *
+ * @author zprusa
+ */
+public class Utils {
+    public static void abs(float[][] in)
+    {
+       int width = in[0].length;
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+             in[yy][xx] = Math.abs(in[yy][xx]);
+          }
+       }
+    }
+    public static void pow(float[][] in)
+    {
+       int width = in[0].length;
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+             in[yy][xx] = in[yy][xx]*in[yy][xx];
+          }
+       }
+    }
+    public static void db(float[][] in)
+    {
+       int width = in[0].length;
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+             in[yy][xx] = (float) (20*Math.log10(in[yy][xx]+1e-10));
+          }
+       }
+    }
+    public static void abs(float[] in)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             in[yy] = Math.abs(in[yy]);
+       }
+    }
+    public static void pow(float[] in)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             in[yy] = in[yy]*in[yy];
+       }
+    }
+    public static void db(float[] in)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             in[yy] = (float) (20*Math.log10(in[yy]+1e-10));
+       }
+    }
+    public static void dynrange(float[][] in,int db, Float omin, Float omax)
+    {
+       omax = max(in);
+       omin = omax - db;
+       clipToRange(in, omin, omax);
+    }
+    public static float max(float[][] in)
+    {
+       float max = in[0][0];
+       int width = in[0].length;
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+             if(in[yy][xx]>max){
+                max = in[yy][xx];
+             }
+          }
+       }
+       return max;
+    }
+    
+    public static void clipToRange(float[][] in, float min, float max)
+    {
+       int width = in[0].length;
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+             if(in[yy][xx]>max){
+                in[yy][xx]=max;
+             }
+             if(in[yy][xx]<min){
+                in[yy][xx]=min;
+             }
+          }
+       }
+    }
+    
+    public static void toByte(float[][] in, byte[] out, float min, float max )
+    {
+       int width = in[0].length;
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+             out[yy*width+xx] = (byte) (255*(in[yy][xx]-min)/(max-min));
+          }
+       }
+    }
+    
+    public static void clipToRange(float[] in, float min, float max)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             if(in[yy]>max){
+                in[yy]=max;
+             }
+             if(in[yy]<min){
+                in[yy]=min;
+             }
+       }
+    }
+    
+    public static void toByte(float[] in, byte[] out, float min, float max )
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             out[yy] = (byte) (255*(in[yy]-min)/(max-min));
+       }
+    }
+    
+    
+    public static float inColormap(float[][] in, float min, float max, float[][] colormap, BufferedImage b)
+    {
+       int width = in[0].length;
+       int height = in.length;
+       int cvals = colormap.length;
+       float[] bData = ((DataBufferFloat) b.getRaster().getDataBuffer()).getData();
+       
+       for(int yy=0;yy<height;yy++){
+          for(int xx=0;xx<width;xx++){
+            int cmapIdx = (int)(cvals*(in[yy][xx]-min)/max);
+            bData[yy*width+xx] = colormap[cmapIdx][0];
+            bData[yy*width+xx+1] = colormap[cmapIdx][1];
+            bData[yy*width+xx+2] = colormap[cmapIdx][2];
+          }
+       }
+       return max;
+    }
+    
+    
+    
+    public static void abs(double[] in)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             in[yy] = Math.abs(in[yy]);
+       }
+    }
+    public static void pow(double[] in)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             in[yy] = in[yy]*in[yy];
+       }
+    }
+    public static void db(double[] in)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             in[yy] = 20.0*Math.log10(in[yy]+1e-10);
+       }
+    }
+    
+    
+    public static void clipToRange(double[] in, float min, float max)
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             if(in[yy]>max){
+                in[yy]=max;
+             }
+             if(in[yy]<min){
+                in[yy]=min;
+             }
+       }
+    }
+    
+    public static void toByte(double[] in, byte[] out, float min, float max )
+    {
+       int height = in.length;
+       for(int yy=0;yy<height;yy++){
+             out[yy] = (byte) (255*(in[yy]-min)/(max-min));
+       }
+    }
+}
diff --git a/inst/blockproc/java/net/sourceforge/ltfat/thirdparty/JRangeSlider.java b/inst/blockproc/java/net/sourceforge/ltfat/thirdparty/JRangeSlider.java
new file mode 100644
index 0000000..86647dd
--- /dev/null
+++ b/inst/blockproc/java/net/sourceforge/ltfat/thirdparty/JRangeSlider.java
@@ -0,0 +1,889 @@
+package net.sourceforge.ltfat.thirdparty;
+
+/*
+  This code is part of the prefuse project: http://prefuse.org/, which
+  is distributed under BSD licence.
+
+  Copyright (c) 2004-2011 Regents of the University of California.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+  3. Neither the name of the University nor the names of its contributors
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
+ 
+ */
+
+
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.swing.BoundedRangeModel;
+import javax.swing.DefaultBoundedRangeModel;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ * <p>Implements a Swing-based Range slider, which allows the user to enter a 
+ * range (minimum and maximum) value.</p>
+ * 
+ * @author Ben Bederson
+ * @author Jesse Grosjean
+ * @author Jon Meyer
+ * @author Lance Good
+ * @author jeffrey heer
+ * @author Colin Combe
+ */
+public class JRangeSlider extends JComponent 
+    implements MouseListener, MouseMotionListener, KeyListener
+{   
+    /*
+     * NOTE: This is a modified version of the original class distributed by
+     * Ben Bederson, Jesse Grosjean, and Jon Meyer as part of an HCIL Tech
+     * Report.  It is modified to allow both vertical and horitonal modes.
+     * It also fixes a bug with offset on the buttons. Also fixed a bug with
+     * rendering using (x,y) instead of (0,0) as origin.  Also modified to
+     * render arrows as a series of lines rather than as a GeneralPath.
+     * Also modified to fix rounding errors on toLocal and toScreen.
+     * 
+     * With inclusion in prefuse, this class has been further modified to use a
+     * bounded range model, support keyboard commands and more extensize
+     * parameterization of rendering/appearance options. Furthermore, a stub
+     * method has been introduced to allow subclasses to perform custom
+     * rendering within the slider through.
+     */
+    
+    final public static int VERTICAL = 0;
+    final public static int HORIZONTAL = 1;
+    final public static int LEFTRIGHT_TOPBOTTOM = 0;
+    final public static int RIGHTLEFT_BOTTOMTOP = 1;
+    
+    public static int PREFERRED_BREADTH = 16;
+    public static int PREFERRED_LENGTH = 80;
+    final protected static int ARROW_SZ = 16;
+    final protected static int ARROW_WIDTH = 8;
+    final protected static int ARROW_HEIGHT = 4;
+
+    protected BoundedRangeModel model;
+    protected int orientation;
+    protected int direction;
+    protected boolean empty;
+    protected int increment = 1;
+    protected int minExtent = 0; // min extent, in pixels
+    
+    protected ArrayList listeners = new ArrayList();
+    protected ChangeEvent changeEvent = null;
+    protected ChangeListener lstnr;
+ 
+    protected Color thumbColor = new Color(150,180,220);
+    
+    // ------------------------------------------------------------------------
+
+    /** 
+     * Create a new range slider. 
+     *
+     * @param minimum - the minimum value of the range.
+     * @param maximum - the maximum value of the range.
+     * @param lowValue - the current low value shown by the range slider's bar.
+     * @param highValue - the current high value shown by the range slider's bar.
+     * @param orientation - construct a horizontal or vertical slider?
+     */
+    public JRangeSlider(int minimum, int maximum, int lowValue, int highValue, int orientation) {
+        this(new DefaultBoundedRangeModel(lowValue, highValue - lowValue, minimum, maximum),
+                orientation,LEFTRIGHT_TOPBOTTOM);
+    }
+
+    /** 
+     * Create a new range slider. 
+     *
+     * @param minimum - the minimum value of the range.
+     * @param maximum - the maximum value of the range.
+     * @param lowValue - the current low value shown by the range slider's bar.
+     * @param highValue - the current high value shown by the range slider's bar.
+     * @param orientation - construct a horizontal or vertical slider?
+     * @param direction - Is the slider left-to-right/top-to-bottom or right-to-left/bottom-to-top
+     */
+    public JRangeSlider(int minimum, int maximum, int lowValue, int highValue, int orientation, int direction) {
+        this(new DefaultBoundedRangeModel(lowValue, highValue - lowValue, minimum, maximum), 
+                orientation, direction);
+    }
+    
+    /** 
+     * Create a new range slider. 
+     *
+     * @param model - a BoundedRangeModel specifying the slider's range
+     * @param orientation - construct a horizontal or vertical slider?
+     * @param direction - Is the slider left-to-right/top-to-bottom or right-to-left/bottom-to-top
+     */
+    public JRangeSlider(BoundedRangeModel model, int orientation, int direction) {
+        super.setFocusable(true);
+        this.model = model;
+        this.orientation = orientation;     
+        this.direction = direction;
+        
+        setForeground(Color.LIGHT_GRAY);
+        
+        this.lstnr = createListener();
+        model.addChangeListener(lstnr);
+        
+        addMouseListener(this);
+        addMouseMotionListener(this);
+        addKeyListener(this);
+    }
+    
+    /**
+     * Create a listener to relay change events from the bounded range model.
+     * @return a ChangeListener to relay events from the range model
+     */
+    protected ChangeListener createListener() {
+        return new RangeSliderChangeListener();
+    }
+    
+    /**
+     * Listener that fires a change event when it receives  change event from
+     * the slider list model.
+     */
+    protected class RangeSliderChangeListener implements ChangeListener {
+        public void stateChanged(ChangeEvent e) {
+            fireChangeEvent();
+        }
+    }
+    
+    /** 
+     * Returns the current "low" value shown by the range slider's bar. The low
+     * value meets the constraint minimum <= lowValue <= highValue <= maximum. 
+     */
+    public int getLowValue() {
+        return model.getValue();
+    }
+
+    /** 
+     * Sets the low value shown by this range slider. This causes the range slider to be
+     * repainted and a ChangeEvent to be fired.
+     * @param lowValue the low value to use
+     */
+    public void setLowValue(int lowValue) {
+        int e = (model.getValue()-lowValue)+model.getExtent();
+        model.setRangeProperties(lowValue, e,
+            model.getMinimum(), model.getMaximum(), false);
+        model.setValue(lowValue);
+    }
+
+    /** 
+     * Returns the current "high" value shown by the range slider's bar. The high
+     * value meets the constraint minimum <= lowValue <= highValue <= maximum. 
+     */
+    public int getHighValue() {
+        return model.getValue()+model.getExtent();
+    }
+
+    /** 
+     * Sets the high value shown by this range slider. This causes the range slider to be
+     * repainted and a ChangeEvent to be fired.
+     * @param highValue the high value to use
+     */
+    public void setHighValue(int highValue) {
+        model.setExtent(highValue-model.getValue());
+    }
+    
+    /**
+     * Set the slider range span.
+     * @param lowValue the low value of the slider range
+     * @param highValue the high value of the slider range
+     */
+    public void setRange(int lowValue, int highValue) {
+        model.setRangeProperties(lowValue, highValue-lowValue,
+                model.getMinimum(), model.getMaximum(), false);
+    }
+
+    /**
+     * Gets the minimum possible value for either the low value or the high value.
+     * @return the minimum possible range value
+     */
+    public int getMinimum() {
+        return model.getMinimum();
+    }
+
+    /**
+     * Sets the minimum possible value for either the low value or the high value.
+     * @param minimum the minimum possible range value
+     */
+    public void setMinimum(int minimum) {
+        model.setMinimum(minimum);
+    }
+
+    /**
+     * Gets the maximum possible value for either the low value or the high value.
+     * @return the maximum possible range value
+     */
+    public int getMaximum() {
+        return model.getMaximum();
+    }
+
+    /**
+     * Sets the maximum possible value for either the low value or the high value.
+     * @param maximum the maximum possible range value
+     */
+    public void setMaximum(int maximum) {
+        model.setMaximum(maximum);
+    }
+
+    /**
+     * Sets the minimum extent (difference between low and high values).
+     * This method <strong>does not</strong> change the current state of the
+     * model, but can affect all subsequent interaction.
+     * @param minExtent the minimum extent allowed in subsequent interaction
+     */
+    public void setMinExtent(int minExtent) {
+        this.minExtent = minExtent;
+    }
+    
+    /**
+     * Sets whether this slider is empty.
+     * @param empty true if set to empty, false otherwise
+     */
+    public void setEmpty(boolean empty) {
+        this.empty = empty;
+        repaint();
+    }
+
+    /**
+     * Get the slider thumb color. This is the part of the slider between
+     * the range resize buttons.
+     * @return the slider thumb color
+     */
+    public Color getThumbColor() {
+        return thumbColor;
+    }
+    
+    /**
+     * Set the slider thumb color. This is the part of the slider between
+     * the range resize buttons.
+     * @param thumbColor the slider thumb color
+     */
+    public void setThumbColor(Color thumbColor) {
+        this.thumbColor = thumbColor;
+    }
+    
+    /**
+     * Get the BoundedRangeModel backing this slider.
+     * @return the slider's range model
+     */
+    public BoundedRangeModel getModel() {
+        return model;
+    }
+    
+    /**
+     * Set the BoundedRangeModel backing this slider.
+     * @param brm the slider range model to use
+     */
+    public void setModel(BoundedRangeModel brm) {
+        model.removeChangeListener(lstnr);
+        model = brm;
+        model.addChangeListener(lstnr);
+        repaint();
+    }
+    
+    /** 
+     * Registers a listener for ChangeEvents.
+     * @param cl the ChangeListener to add
+     */
+    public void addChangeListener(ChangeListener cl) {
+        if ( !listeners.contains(cl) )
+            listeners.add(cl);
+    }
+
+    /** 
+     * Removes a listener for ChangeEvents.
+     * @param cl the ChangeListener to remove
+     */
+    public void removeChangeListener(ChangeListener cl) {
+        listeners.remove(cl);
+    }
+    
+    /**
+     * Fire a change event to all listeners.
+     */
+    protected void fireChangeEvent() {
+        repaint();
+        if ( changeEvent == null )
+            changeEvent = new ChangeEvent(this);
+        Iterator iter = listeners.iterator();
+        while ( iter.hasNext() )
+            ((ChangeListener)iter.next()).stateChanged(changeEvent);
+    }
+
+    /**
+     * @see java.awt.Component#getPreferredSize()
+     */
+    public Dimension getPreferredSize() {
+        if (orientation == VERTICAL) {
+            return new Dimension(PREFERRED_BREADTH, PREFERRED_LENGTH);
+        }
+        else {
+            return new Dimension(PREFERRED_LENGTH, PREFERRED_BREADTH);
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // Rendering
+
+    /**
+     * Override this method to perform custom painting of the slider trough.
+     * @param g a Graphics2D context for rendering
+     * @param width the width of the slider trough
+     * @param height the height of the slider trough
+     */
+    protected void customPaint(Graphics2D g, int width, int height) {
+        // does nothing in this class
+        // subclasses can override to perform custom painting
+    }
+    
+    /**
+     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
+     */
+    public void paintComponent(Graphics g) {        
+        Rectangle bounds = getBounds();
+        int width = (int)bounds.getWidth() - 1;
+        int height = (int)bounds.getHeight() - 1;
+
+        int min = toScreen(getLowValue());
+        int max = toScreen(getHighValue());
+
+        // Paint the full slider if the slider is marked as empty
+        if (empty) {
+            if (direction == LEFTRIGHT_TOPBOTTOM) {
+                min = ARROW_SZ;
+                max = (orientation == VERTICAL) ? height-ARROW_SZ : width-ARROW_SZ;
+            }
+            else {
+                min = (orientation == VERTICAL) ? height-ARROW_SZ : width-ARROW_SZ;
+                max = ARROW_SZ;                 
+            }
+        }
+
+        Graphics2D g2 = (Graphics2D)g;
+        g2.setColor(getBackground());
+        g2.fillRect(0, 0, width, height);
+        g2.setColor(getForeground());
+        g2.drawRect(0, 0, width, height);
+
+        customPaint(g2, width, height);
+        
+        // Draw arrow and thumb backgrounds
+        g2.setStroke(new BasicStroke(1));
+        if (orientation == VERTICAL) {  
+            if (direction == LEFTRIGHT_TOPBOTTOM) {
+                g2.setColor(getForeground());
+                g2.fillRect(0, min - ARROW_SZ, width, ARROW_SZ-1);
+                paint3DRectLighting(g2,0,min-ARROW_SZ,width,ARROW_SZ-1);
+            
+                if ( thumbColor != null ) {
+                    g2.setColor(thumbColor);
+                    g2.fillRect(0, min, width, max - min-1);
+                    paint3DRectLighting(g2,0,min,width,max-min-1);
+                }
+                
+                g2.setColor(getForeground());
+                g2.fillRect(0, max, width, ARROW_SZ-1);
+                paint3DRectLighting(g2,0,max,width,ARROW_SZ-1);
+            
+                // Draw arrows          
+                g2.setColor(Color.black);
+                paintArrow(g2, (width-ARROW_WIDTH) / 2.0, min - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, true);
+                paintArrow(g2, (width-ARROW_WIDTH) / 2.0, max + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, false);
+            }
+            else {
+                g2.setColor(getForeground());
+                g2.fillRect(0, min, width, ARROW_SZ-1);
+                paint3DRectLighting(g2,0,min,width,ARROW_SZ-1);
+            
+                if ( thumbColor != null ) {
+                    g2.setColor(thumbColor);
+                    g2.fillRect(0, max, width, min-max-1);
+                    paint3DRectLighting(g2,0,max,width,min-max-1);
+                }
+            
+                g2.setColor(getForeground());
+                g2.fillRect(0, max-ARROW_SZ, width, ARROW_SZ-1);
+                paint3DRectLighting(g2,0,max-ARROW_SZ,width,ARROW_SZ-1);
+            
+                // Draw arrows          
+                g2.setColor(Color.black);
+                paintArrow(g2, (width-ARROW_WIDTH) / 2.0, min + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, false);
+                paintArrow(g2, (width-ARROW_WIDTH) / 2.0, max - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, true);             
+            }
+        }
+        else {
+            if (direction == LEFTRIGHT_TOPBOTTOM) {
+                g2.setColor(getForeground());
+                g2.fillRect(min - ARROW_SZ, 0, ARROW_SZ-1, height);
+                paint3DRectLighting(g2,min-ARROW_SZ,0,ARROW_SZ-1,height);
+            
+                if ( thumbColor != null ) {
+                    g2.setColor(thumbColor);
+                    g2.fillRect(min, 0, max - min - 1, height);
+                    paint3DRectLighting(g2,min,0,max-min-1,height);
+                }
+
+                g2.setColor(getForeground());
+                g2.fillRect(max, 0, ARROW_SZ-1, height);
+                paint3DRectLighting(g2,max,0,ARROW_SZ-1,height);
+            
+                // Draw arrows          
+                g2.setColor(Color.black);
+                paintArrow(g2, min - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, true);
+                paintArrow(g2, max + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, false);
+            }
+            else {
+                g2.setColor(getForeground());
+                g2.fillRect(min, 0, ARROW_SZ - 1, height);
+                paint3DRectLighting(g2,min,0,ARROW_SZ-1,height);
+                
+                if ( thumbColor != null ) {
+                    g2.setColor(thumbColor);
+                    g2.fillRect(max, 0, min - max - 1, height);
+                    paint3DRectLighting(g2,max,0,min-max-1,height); 
+                }
+                
+                g2.setColor(getForeground());
+                g2.fillRect(max-ARROW_SZ, 0, ARROW_SZ-1, height);
+                paint3DRectLighting(g2,max-ARROW_SZ,0,ARROW_SZ-1,height); 
+            
+                // Draw arrows          
+                g2.setColor(Color.black);
+                paintArrow(g2, min + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, true);
+                paintArrow(g2, max - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, false);                   
+            }
+        }               
+    }
+
+    /**
+     * This draws an arrow as a series of lines within the specified box.
+     * The last boolean specifies whether the point should be at the 
+     * right/bottom or left/top. 
+     */
+    protected void paintArrow(Graphics2D g2, double x, double y, int w, int h,
+                              boolean topDown)
+    {
+        int intX = (int)(x+0.5);
+        int intY = (int)(y+0.5);
+        
+        if (orientation == VERTICAL) {
+            if (w % 2 == 0) {
+                w = w - 1;
+            }
+            
+            if (topDown) {
+                for(int i=0; i<(w/2+1); i++) {
+                    g2.drawLine(intX+i,intY+i,intX+w-i-1,intY+i);
+                }
+            }
+            else {
+                for(int i=0; i<(w/2+1); i++) {
+                    g2.drawLine(intX+w/2-i,intY+i,intX+w-w/2+i-1,intY+i);
+                }               
+            }
+        }
+        else {
+            if (h % 2 == 0) {
+                h = h - 1;
+            }
+                        
+            if (topDown) {
+                for(int i=0; i<(h/2+1); i++) {
+                    g2.drawLine(intX+i,intY+i,intX+i,intY+h-i-1);
+                }
+            }
+            else {
+                for(int i=0; i<(h/2+1); i++) {
+                    g2.drawLine(intX+i,intY+h/2-i,intX+i,intY+h-h/2+i-1);
+                }               
+            }           
+        }
+    }
+    
+    /**
+     * Adds Windows2K type 3D lighting effects
+     */
+    protected void paint3DRectLighting(Graphics2D g2, int x, int y,
+                                       int width, int height)
+    {
+        g2.setColor(Color.white);
+        g2.drawLine(x+1,y+1,x+1,y+height-1);
+        g2.drawLine(x+1,y+1,x+width-1,y+1);
+        g2.setColor(Color.gray);
+        g2.drawLine(x+1,y+height-1,x+width-1,y+height-1);
+        g2.drawLine(x+width-1,y+1,x+width-1,y+height-1);
+        g2.setColor(Color.darkGray);
+        g2.drawLine(x,y+height,x+width,y+height);
+        g2.drawLine(x+width,y,x+width,y+height);        
+    }
+
+    /**
+     * Converts from screen coordinates to a range value.
+     */
+    protected int toLocal(int xOrY) {
+        Dimension sz = getSize();
+        int min = getMinimum();
+        double scale;
+        if (orientation == VERTICAL) {
+            scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() - min);           
+        }
+        else {
+            scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
+        }
+
+        if (direction == LEFTRIGHT_TOPBOTTOM) {
+            return (int) (((xOrY - ARROW_SZ) / scale) + min + 0.5);         
+        }
+        else {
+            if (orientation == VERTICAL) {
+                return (int) ((sz.height - xOrY - ARROW_SZ) / scale + min + 0.5);
+            }
+            else {
+                return (int) ((sz.width - xOrY - ARROW_SZ) / scale + min + 0.5);
+            }
+        }
+    }
+
+    /**
+     * Converts from a range value to screen coordinates.
+     */
+    protected int toScreen(int xOrY) {
+        Dimension sz = getSize();
+        int min = getMinimum();
+        double scale;
+        if (orientation == VERTICAL) {
+            scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() - min);           
+        }
+        else {
+            scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
+        }
+
+        // If the direction is left/right_top/bottom then we subtract the min and multiply times scale
+        // Otherwise, we have to invert the number by subtracting the value from the height
+        if (direction == LEFTRIGHT_TOPBOTTOM) {
+            return (int)(ARROW_SZ + ((xOrY - min) * scale) + 0.5);
+        }
+        else {
+            if (orientation == VERTICAL) {
+                return (int)(sz.height-(xOrY - min) * scale - ARROW_SZ + 0.5);
+            }
+            else {
+                return (int)(sz.width-(xOrY - min) * scale - ARROW_SZ + 0.5);
+            }
+        }
+    }
+
+    /**
+     * Converts from a range value to screen coordinates.
+     */
+    protected double toScreenDouble(int xOrY) {
+        Dimension sz = getSize();
+        int min = getMinimum();
+        double scale;
+        if (orientation == VERTICAL) {
+            scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum()+1 - min);         
+        }
+        else {
+            scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum()+1 - min);
+        }
+
+        // If the direction is left/right_top/bottom then we subtract the min and multiply times scale
+        // Otherwise, we have to invert the number by subtracting the value from the height
+        if (direction == LEFTRIGHT_TOPBOTTOM) {
+            return ARROW_SZ + ((xOrY - min) * scale);
+        }
+        else {
+            if (orientation == VERTICAL) {
+                return sz.height-(xOrY - min) * scale - ARROW_SZ;
+            }
+            else {
+                return sz.width-(xOrY - min) * scale - ARROW_SZ;
+            }
+        }
+    }
+
+    
+    // ------------------------------------------------------------------------
+    // Event Handling
+
+    static final int PICK_NONE = 0;
+    static final int PICK_LEFT_OR_TOP = 1;
+    static final int PICK_THUMB = 2;
+    static final int PICK_RIGHT_OR_BOTTOM = 3;
+    int pick;
+    int pickOffsetLow;
+    int pickOffsetHigh;
+    int mouse;
+
+    private int pickHandle(int xOrY) {
+        int min = toScreen(getLowValue());
+        int max = toScreen(getHighValue());
+        int pick = PICK_NONE;
+        
+        if (direction == LEFTRIGHT_TOPBOTTOM) {
+            if ((xOrY > (min - ARROW_SZ)) && (xOrY < min)) {
+                pick = PICK_LEFT_OR_TOP;
+            } else if ((xOrY >= min) && (xOrY <= max)) {
+                pick = PICK_THUMB;
+            } else if ((xOrY > max) && (xOrY < (max + ARROW_SZ))) {
+                pick = PICK_RIGHT_OR_BOTTOM;
+            }
+        }
+        else {
+            if ((xOrY > min) && (xOrY < (min + ARROW_SZ))) {
+                pick = PICK_LEFT_OR_TOP;
+            } else if ((xOrY <= min) && (xOrY >= max)) {
+                pick = PICK_THUMB;
+            } else if ((xOrY > (max - ARROW_SZ) && (xOrY < max))) {
+                pick = PICK_RIGHT_OR_BOTTOM;
+            }           
+        }
+        
+        return pick;
+    }
+
+    private void offset(int dxOrDy) {
+        model.setValue(model.getValue()+dxOrDy);
+    }
+
+    /**
+     * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
+     */
+    public void mousePressed(MouseEvent e) {        
+        if (orientation == VERTICAL) {
+            pick = pickHandle(e.getY());
+            pickOffsetLow = e.getY() - toScreen(getLowValue());
+            pickOffsetHigh = e.getY() - toScreen(getHighValue());
+            mouse = e.getY();
+        }
+        else {
+            pick = pickHandle(e.getX());
+            pickOffsetLow = e.getX() - toScreen(getLowValue());
+            pickOffsetHigh = e.getX() - toScreen(getHighValue());
+            mouse = e.getX();           
+        }
+        repaint();
+    }
+
+    /**
+     * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
+     */
+    public void mouseDragged(MouseEvent e) {
+        requestFocus();
+        int value = (orientation == VERTICAL) ? e.getY() : e.getX();
+        
+        int minimum = getMinimum();
+        int maximum = getMaximum();
+        int lowValue = getLowValue();
+        int highValue = getHighValue();
+        
+        switch (pick) {
+            case PICK_LEFT_OR_TOP:
+                int low = toLocal(value-pickOffsetLow);
+            
+                if (low < minimum) {
+                    low = minimum;
+                }
+                if (low > maximum - minExtent) {
+                    low = maximum - minExtent;
+                }
+                if (low > highValue-minExtent) {
+                    setRange(low, low + minExtent);
+                }
+                else
+                    setLowValue(low);
+                break;
+
+            case PICK_RIGHT_OR_BOTTOM:
+                int high = toLocal(value-pickOffsetHigh);
+                
+                if (high < minimum + minExtent) {
+                    high = minimum + minExtent;
+                }
+                if (high > maximum) {
+                    high = maximum;
+                }
+                if (high < lowValue+minExtent) {
+                    setRange(high - minExtent, high);
+                }
+                else
+                    setHighValue(high);
+                break;
+
+            case PICK_THUMB:
+                int dxOrDy = toLocal(value - pickOffsetLow) - lowValue;
+                if ((dxOrDy < 0) && ((lowValue + dxOrDy) < minimum)) {
+                    dxOrDy = minimum - lowValue;
+                }
+                if ((dxOrDy > 0) && ((highValue + dxOrDy) > maximum)) {
+                    dxOrDy = maximum - highValue;
+                }
+                if (dxOrDy != 0) {
+                    offset(dxOrDy);
+                }
+                break;
+        }
+    }
+
+    /**
+     * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
+     */
+    public void mouseReleased(MouseEvent e) {
+        pick = PICK_NONE;
+        repaint();
+    }
+
+    /**
+     * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
+     */
+    public void mouseMoved(MouseEvent e) {
+        if (orientation == VERTICAL) {
+            switch (pickHandle(e.getY())) {
+                case PICK_LEFT_OR_TOP:
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+                case PICK_RIGHT_OR_BOTTOM:
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+                case PICK_THUMB:
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+                case PICK_NONE :
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+            }
+        }
+        else {
+            switch (pickHandle(e.getX())) {
+                case PICK_LEFT_OR_TOP:
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+                case PICK_RIGHT_OR_BOTTOM:
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+                case PICK_THUMB:
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+                case PICK_NONE :
+                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    break;
+            }           
+        }
+    }
+
+    /**
+     * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
+     */
+    public void mouseClicked(MouseEvent e) {
+    }
+    /**
+     * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
+     */
+    public void mouseEntered(MouseEvent e) {
+    }
+    /**
+     * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
+     */
+    public void mouseExited(MouseEvent e) {
+    }
+
+    private void grow(int increment) {
+        model.setRangeProperties(model.getValue()-increment,
+            model.getExtent()+2*increment, 
+            model.getMinimum(), model.getMaximum(), false);
+    }
+    
+    /**
+     * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
+     */
+    public void keyPressed(KeyEvent e) {
+        int kc = e.getKeyCode();
+        boolean v = (orientation == VERTICAL);
+        boolean d = (kc == KeyEvent.VK_DOWN);
+        boolean u = (kc == KeyEvent.VK_UP);
+        boolean l = (kc == KeyEvent.VK_LEFT);
+        boolean r = (kc == KeyEvent.VK_RIGHT);
+        
+        int minimum = getMinimum();
+        int maximum = getMaximum();
+        int lowValue = getLowValue();
+        int highValue = getHighValue();
+        
+        if ( v&&r || !v&&u ) {
+            if ( lowValue-increment >= minimum &&
+                 highValue+increment <= maximum ) {
+                grow(increment);
+            }
+        } else if ( v&&l || !v&&d ) { 
+            if ( highValue-lowValue >= 2*increment ) {
+                grow(-1*increment);
+            }
+        } else if ( v&&d || !v&&l ) {
+            if ( lowValue-increment >= minimum ) {
+                offset(-increment);
+            }
+        } else if ( v&&u || !v&&r ) {
+            if ( highValue+increment <= maximum ) {
+                offset(increment);
+            }
+        }
+    }
+    
+    /**
+     * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
+     */
+    public void keyReleased(KeyEvent e) {
+    }
+    /**
+     * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
+     */
+    public void keyTyped(KeyEvent e) {
+    }
+    
+    @Override
+    public void setPreferredSize(Dimension dim){
+        PREFERRED_BREADTH = dim.height;
+        PREFERRED_LENGTH = dim.width;
+    }
+    
+} // end of class JRangeSlider
+
diff --git a/inst/comp/arg_firwin.m b/inst/comp/arg_firwin.m
new file mode 100644
index 0000000..e18eb7e
--- /dev/null
+++ b/inst/comp/arg_firwin.m
@@ -0,0 +1,35 @@
+function definput=arg_firwin(definput)
+  
+  definput.flags.wintype={ 'hanning','hann','sine','cosine','sqrthan', ...
+                      'sqrthann','hamming', 'hammingacc','sqrtham','square','rect', ...
+                      'sqrtsquare','sqrtrect', 'tria','bartlett', ...
+                      'triangular','sqrttria','blackman','blackman2', ...
+                      'nuttall','nuttall10','nuttall01','nuttall20', ...
+                      'nuttall11','nuttall03', 'nuttall12','nuttall21', ...
+                      'nuttall30', 'ogg','itersine'};
+  
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_firwin
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_firwin.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_freqtoaud.m b/inst/comp/arg_freqtoaud.m
new file mode 100644
index 0000000..5c4d6ed
--- /dev/null
+++ b/inst/comp/arg_freqtoaud.m
@@ -0,0 +1,29 @@
+function definput=arg_freqtoaud(definput)
+  
+  definput.flags.audscale={'erb','mel','mel1000','bark','erb83','freq','log10','semitone'};
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_freqtoaud
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_freqtoaud.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_fwt.m b/inst/comp/arg_fwt.m
new file mode 100644
index 0000000..08e5053
--- /dev/null
+++ b/inst/comp/arg_fwt.m
@@ -0,0 +1,27 @@
+function definput = arg_fwt(definput)
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_fwt
+%@verbatim
+%definput.flags.ext=  {'per','zpd','sym','symw','asym','asymw','ppd','sp0'};
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_fwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+definput.flags.ext = {'per','zero','even','odd'};
+
diff --git a/inst/comp/arg_fwt2.m b/inst/comp/arg_fwt2.m
new file mode 100644
index 0000000..5efc6c1
--- /dev/null
+++ b/inst/comp/arg_fwt2.m
@@ -0,0 +1,27 @@
+function definput = arg_fwt2(definput)
+
+definput.flags.type2d = {'standard','tensor'};
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_fwt2
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_fwt2.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_fwtcommon.m b/inst/comp/arg_fwtcommon.m
new file mode 100644
index 0000000..22b0d7c
--- /dev/null
+++ b/inst/comp/arg_fwtcommon.m
@@ -0,0 +1,28 @@
+function definput = arg_fwtcommon(definput)
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_fwtcommon
+%@verbatim
+%definput.flags.ansy = {'syn','ana'};
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_fwtcommon.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+definput.keyvals.a = [];
+
diff --git a/inst/comp/arg_fwtext.m b/inst/comp/arg_fwtext.m
new file mode 100644
index 0000000..2fe58a2
--- /dev/null
+++ b/inst/comp/arg_fwtext.m
@@ -0,0 +1,27 @@
+function definput = arg_fwtext(definput)
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_fwtext
+%@verbatim
+%definput.flags.ext=  {'per','zpd','sym','symw','asym','asymw','ppd','sp0'};
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_fwtext.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+definput.flags.ext = {'per','zero','even','odd','valid'};
+
diff --git a/inst/comp/arg_groupthresh.m b/inst/comp/arg_groupthresh.m
new file mode 100644
index 0000000..5982719
--- /dev/null
+++ b/inst/comp/arg_groupthresh.m
@@ -0,0 +1,29 @@
+function definput=arg_groupthresh(definput)
+
+  definput.flags.grouptype={'group','elite'};
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_groupthresh
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_groupthresh.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_ltfattranslate.m b/inst/comp/arg_ltfattranslate.m
new file mode 100644
index 0000000..aeef094
--- /dev/null
+++ b/inst/comp/arg_ltfattranslate.m
@@ -0,0 +1,33 @@
+function definput=arg_ltfattranslate(definput)
+
+  definput.keyvals.frequency='Frequency';
+  definput.keyvals.time='Time';
+  definput.keyvals.samples='samples';
+  definput.keyvals.normalized='normalized';
+  definput.keyvals.magnitude='Magnitude';
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_ltfattranslate
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_ltfattranslate.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_normalize.m b/inst/comp/arg_normalize.m
new file mode 100644
index 0000000..d1dbd94
--- /dev/null
+++ b/inst/comp/arg_normalize.m
@@ -0,0 +1,30 @@
+function definput=arg_normalize(definput)
+  
+  definput.flags.norm={'2','1','inf','area','energy','peak',...
+                       's0','rms','null','wav'};
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_normalize
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_normalize.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_pfilt.m b/inst/comp/arg_pfilt.m
new file mode 100644
index 0000000..5e08ad5
--- /dev/null
+++ b/inst/comp/arg_pfilt.m
@@ -0,0 +1,29 @@
+function definput=arg_pfilt(definput)
+  
+  definput.keyvals.crossover=120;
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_pfilt
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_pfilt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_plotfilterbank.m b/inst/comp/arg_plotfilterbank.m
new file mode 100644
index 0000000..b8201b6
--- /dev/null
+++ b/inst/comp/arg_plotfilterbank.m
@@ -0,0 +1,32 @@
+function definput=arg_plotfilterbank(definput)
+
+  definput.keyvals.fc=[];
+  definput.keyvals.ntickpos=10;
+  definput.keyvals.tick=[];
+  definput.groups.audtick={'tick',[0,100,250,500,1000,2000,4000,8000,16000,32000]};
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_plotfilterbank
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_plotfilterbank.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_plotfwt.m b/inst/comp/arg_plotfwt.m
new file mode 100644
index 0000000..33dc6f5
--- /dev/null
+++ b/inst/comp/arg_plotfwt.m
@@ -0,0 +1,35 @@
+function definput=arg_plotfwt(definput)
+
+  definput.flags.frqbands = {'uni', 'dyad'};
+  definput.flags.wavplottype = {'image', 'stem', 'surf','waterfall'};
+  definput.keyvals.fc=[];
+  definput.keyvals.ntickpos=10;
+  definput.keyvals.tick=[];
+  
+  definput.groups.audtick={'tick',[0,100,250,500,1000,2000,4000,8000,16000,32000]};
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_plotfwt
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_plotfwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_tfplot.m b/inst/comp/arg_tfplot.m
new file mode 100644
index 0000000..c62e8fc
--- /dev/null
+++ b/inst/comp/arg_tfplot.m
@@ -0,0 +1,36 @@
+function definput=arg_tfplot(definput)
+  
+  definput.flags.tc={'notc','tc'};
+  definput.flags.plottype={'image','contour','surf','pcolor'};  
+  definput.flags.log={'db','dbsq','lin','linsq','linabs'};
+  definput.flags.colorbar={'colorbar','nocolorbar'};
+  definput.flags.display={'display','nodisplay'};
+
+  definput.keyvals.fontsize=14;  
+  definput.keyvals.fs=[];
+  definput.keyvals.clim=[];
+  definput.keyvals.dynrange=[];  
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_tfplot
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_tfplot.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_thresh.m b/inst/comp/arg_thresh.m
new file mode 100644
index 0000000..af6c45c
--- /dev/null
+++ b/inst/comp/arg_thresh.m
@@ -0,0 +1,30 @@
+function definput=arg_thresh(definput)
+  
+  definput.flags.iofun={'hard','soft','wiener'};
+  definput.flags.outclass={'full','sparse'};
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_thresh
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_thresh.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/arg_wfbtcommon.m b/inst/comp/arg_wfbtcommon.m
new file mode 100644
index 0000000..e6170ee
--- /dev/null
+++ b/inst/comp/arg_wfbtcommon.m
@@ -0,0 +1,29 @@
+function definput = arg_wfbtcommon(definput)
+
+%-*- texinfo -*-
+%@deftypefn {Function} arg_wfbtcommon
+%@verbatim
+% definput.keyvals.J = 1;
+% definput.flags.treetype = {'full','dwt'};
+% Frequency vs. natral ordering of the output subbands
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/arg_wfbtcommon.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+definput.flags.forder = {'freq','nat'};
+
diff --git a/inst/comp/assert_L.m b/inst/comp/assert_L.m
new file mode 100644
index 0000000..ab9bf42
--- /dev/null
+++ b/inst/comp/assert_L.m
@@ -0,0 +1,93 @@
+function [b,N,L]=assert_L(Ls,Lwindow,L,a,M,callfun)
+%-*- texinfo -*-
+%@deftypefn {Function} assert_L
+%@verbatim
+%ASSERT_L  Validate lattice and window size.
+%   Usage:  [b,N,L]=assert_L(Ls,Lwindow,L,a,M,callfun);
+%
+%   Input parameters:
+%         Ls      : Length of signal (see below).
+%         Lwindow : Length of window.
+%         L       : Specified length of transform (may be [])
+%         a       : Length of time shift.
+%         M       : Number of modulations.
+%         callfun : Name of calling function.
+%   Output parameters:
+%         b       : Length of frequency shift.
+%         N       : Number of translations.
+%         L       : Transform length.         
+%
+%  Calculate a minimal transform length, or verify a user specified
+%  input length.
+%
+%  The routine assumes that a and M has already been checked. use
+%  assert_squarelat for this.
+%
+%  If the window length is not yet determined, it is safe to pass Lwindow=0
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/assert_L.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if ~isempty(L)
+  if (prod(size(L))~=1 || ~isnumeric(L))
+    error([callfun,': L must be a scalar']);
+  end;
+  
+  if rem(L,1)~=0
+    error([callfun,': L must be an integer']);
+  end;
+end;
+
+% Length of window must be dividable by M.
+if rem(Lwindow,M)~=0
+    error('%s: Length of window must be dividable by M = %i.',...
+          callfun,M);
+end;
+
+if isempty(L)
+  % Smallest length transform.
+  Lsmallest=lcm(a,M);
+
+  % Choose a transform length larger than both the length of the
+  % signal and the window.
+  % The ",1" is to always get a transform of at least Lsmallest
+  L=ceil(max([Ls,Lwindow,1])/Lsmallest)*Lsmallest;
+else
+
+  if rem(L,M)~=0
+    error('%s: The length of the transform must be divisable by M = %i',...
+          callfun,M);
+  end;
+
+  if rem(L,a)~=0
+    error('%s: The length of the transform must be divisable by a = %i',...
+          callfun,a);
+  end;
+
+  if L<Lwindow
+    error('%s: Window is too long.',callfun);
+  end;
+
+end;
+
+b=L/M;
+N=L/a;
+
+
+
diff --git a/inst/comp/assert_classname.m b/inst/comp/assert_classname.m
new file mode 100644
index 0000000..1f6593f
--- /dev/null
+++ b/inst/comp/assert_classname.m
@@ -0,0 +1,55 @@
+function classname = assert_classname(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} assert_classname
+%@verbatim
+% ASSERT_CLASSNAME 
+%
+% Returns name of the least "simplest" common data type.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/assert_classname.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Array of data types to be checked. Ordered from the "simplest" to the
+% most "complex".
+typesToTest = {'single','double'}; 
+
+if nargin==0 || isempty(varargin)
+   classname = 'double';
+   return;
+end
+
+if ~all(cellfun(@(vEl) isnumeric(vEl),varargin))
+   error('%s: Parameters are not numeric types. ',upper(mfilename));
+end
+
+% Shortcut to double
+if all(cellfun(@(vEl) isa(vEl,'double'),varargin))
+   classname = 'double';
+   return;
+end
+
+% Go trough all the types, halt if any of the inputs is of the specified
+% type.
+for ii=1:numel(typesToTest)
+   if any(cellfun(@(vEl) isa(vEl,typesToTest{ii}),varargin))
+      classname = typesToTest{ii};
+      return;
+   end
+end
+
diff --git a/inst/comp/assert_groworder.m b/inst/comp/assert_groworder.m
new file mode 100644
index 0000000..95919d0
--- /dev/null
+++ b/inst/comp/assert_groworder.m
@@ -0,0 +1,45 @@
+function order=assert_groworder(order)
+%-*- texinfo -*-
+%@deftypefn {Function} assert_groworder
+%@verbatim
+%ASSERT_GROWORDER  Grow the order parameter
+%
+%   ASSERT_GROWORDER is meant to be used in conjunction with
+%   assert_sigreshape_pre and assert_sigreshape_post. It is used to
+%   modify the order parameter in between calls in order to expand the
+%   processed dimension by 1, i.e. for use in a routine that creates 2D
+%   output from 1D input, for instance in dgt or filterbank.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/assert_groworder.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if numel(order)>1
+  % We only need to handle the non-trivial order, where dim>1
+  
+  p=order(1);
+  
+  % Shift orders higher that the working dimension by 1, to make room for
+  % the new dimension, but leave lower dimensions untouched.
+  order(order>p)=order(order>p)+1;
+  
+  order=[p,p+1,order(2:end)];
+end;
+
+
+
diff --git a/inst/comp/assert_sigreshape_post.m b/inst/comp/assert_sigreshape_post.m
new file mode 100644
index 0000000..3fff698
--- /dev/null
+++ b/inst/comp/assert_sigreshape_post.m
@@ -0,0 +1,36 @@
+function f=assert_sigreshape_post(f,dim,permutedsize,order)
+
+%-*- texinfo -*-
+%@deftypefn {Function} assert_sigreshape_post
+%@verbatim
+% Restore the original, permuted shape.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/assert_sigreshape_post.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+f=reshape(f,permutedsize);
+
+if dim>1
+  % Undo the permutation.
+  f=ipermute(f,order);
+end;
+
+
+
+
+
diff --git a/inst/comp/assert_sigreshape_pre.m b/inst/comp/assert_sigreshape_pre.m
new file mode 100644
index 0000000..59f1ddb
--- /dev/null
+++ b/inst/comp/assert_sigreshape_pre.m
@@ -0,0 +1,108 @@
+function [f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,callfun)
+%-*- texinfo -*-
+%@deftypefn {Function} assert_sigreshape_pre
+%@verbatim
+%ASSERT_SIGRESHAPE_PRE  Preprocess and handle dimension input.
+%
+%   Input parameters:
+%      f            : signal, possibly ND-array
+%      L            : L parameter
+%      dim          : dim parameter
+%      callfun      : Name of calling function
+%   Output parameters:
+%      f            : Input signal as matrix
+%      L            : Verified L
+%      Ls           : Length of signal along dimension to be processed
+%      W            : Number of transforms to do.
+%      dim          : Verified dim
+%      permutedsize : pass to assert_sigreshape_post
+%      order        : pass to assert_sigreshape_post
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/assert_sigreshape_pre.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+  
+if ~isnumeric(f)
+  error('%s: The input must be numeric.',callfun);
+end;
+
+D=ndims(f);
+
+% Dummy assignment.
+order=1;
+
+if isempty(dim)
+  dim=1;
+
+  if sum(size(f)>1)==1
+    % We have a vector, find the dimension where it lives.
+    dim=find(size(f)>1);
+  end;
+
+else
+  if (numel(dim)~=1 || ~isnumeric(dim))
+    error('%s: dim must be a scalar.',callfun);
+  end;
+  if rem(dim,1)~=0
+    error('%s: dim must be an integer.',callfun);
+  end;
+  if (dim<1) || (dim>D)
+    error('%s: dim must be in the range from 1 to %d.',callfun,D);
+  end;  
+
+end;
+
+if (numel(L)>1 || ~isnumeric(L))
+  error('%s: L must be a scalar.',callfun);
+end;
+if (~isempty(L) && rem(L,1)~=0)
+  error('%s: L must be an integer.',callfun);
+end;
+
+
+if dim>1
+  order=[dim, 1:dim-1,dim+1:D];
+
+  % Put the desired dimension first.
+  f=permute(f,order);
+
+end;
+
+Ls=size(f,1);
+
+% If L is empty it is set to be the length of the transform.
+if isempty(L)
+  L=Ls;
+end;  
+
+% Remember the exact size for later and modify it for the new length
+permutedsize=size(f);
+permutedsize(1)=L;
+  
+% Reshape f to a matrix.
+if ~isempty(f)
+  f=reshape(f,size(f,1),numel(f)/size(f,1));
+end;
+W=size(f,2);
+
+
+
+
+
+
diff --git a/inst/comp/assert_squarelat.m b/inst/comp/assert_squarelat.m
new file mode 100644
index 0000000..76dba88
--- /dev/null
+++ b/inst/comp/assert_squarelat.m
@@ -0,0 +1,67 @@
+function assert_squarelat(a,M,R,callfun,flag)
+%-*- texinfo -*-
+%@deftypefn {Function} assert_squarelat
+%@verbatim
+%ASSERT_SQUARELAT  Validate lattice and window size.
+%   Usage:  assert_squarelat(a,M,R,callfun,flag);
+%
+%   Input parameters:
+%         a       : Length of time shift.
+%         M       : Number of modulations.
+%         R       : Number of multiwindows.
+%         callfun : Name of calling function.
+%         flag    : See below.
+%         
+%  if flag>0 test if system is at least critically sampled.
+%
+%  This routine deliberately checks the validity of M before a, such
+%  that it can be used for DWILT etc., where you just pass a=M.
+%
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/assert_squarelat.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+if nargin==4
+  flag=0;
+end;
+
+if  (prod(size(M))~=1 || ~isnumeric(M))
+  error('%s: M must be a scalar',callfun);
+end;
+
+if (prod(size(a))~=1 || ~isnumeric(a))
+  error('%s: a must be a scalar',callfun);
+end;
+
+if rem(M,1)~=0
+  error('%s: M must be an integer',callfun);
+end;
+
+if rem(a,1)~=0
+  error('%s: a must be an integer',callfun);
+end;
+
+if flag>0
+  if a>M*R
+    error('%s: The lattice must not be undersampled',callfun);
+  end;
+end;
+
+
+
diff --git a/inst/comp/block_interface.m b/inst/comp/block_interface.m
new file mode 100644
index 0000000..dde57dd
--- /dev/null
+++ b/inst/comp/block_interface.m
@@ -0,0 +1,176 @@
+function  varargout = block_interface(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} block_interface
+%@verbatim
+%BLOCK_INTERFACE Common block processing backend
+%
+%
+%
+%
+%
+%
+%  Object-like interface for sharing data between block handling
+%  functions. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/block_interface.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<1
+     error('%s: Too few input parameters.',upper(mfilename));
+end
+
+% Persistent data
+persistent pos;
+persistent pageNo;
+persistent sourceName;
+persistent maxBufCount;
+persistent pageList;
+persistent playChanList;
+persistent recChanList;
+persistent skipCounter;
+
+persistent classid;
+persistent toPlayBlock;
+persistent anaOverlap;
+persistent synOverlap;
+persistent dispLoad;
+
+persistent Ls;
+
+persistent loop;
+
+% DEFAULTS
+persistent bufLen;
+
+
+
+command = varargin{1};
+
+
+
+switch command
+   case {'reset','clearAll'}
+      pos = 0; 
+      sourceName = [];
+      maxBufCount = 3;
+      pageList = [];
+      playChanList = [];
+      recChanList = [];
+      pageNo = 0;
+      skipCounter = 0;
+      classid = 'double';
+      anaOverlap = [];
+      synOverlap = [];
+      toPlayBlock = [];
+      dispLoad = 1;
+      loop = 0;
+      Ls = -1;
+      bufLen = 1024;
+%% SETTERS %%%
+   case 'setLs'
+      Ls = varargin{2};
+   case 'setPos'
+      pos = varargin{2};
+   case 'setBufCount'
+      maxBufCount = varargin{2};
+   case 'setPlayChanList'
+      playChanList = varargin{2};
+   case 'setRecChanList'
+      recChanList = varargin{2};
+   case 'setPageNo'
+      pos = varargin{2};
+   case 'setSkipped'
+      skipCounter = varargin{2};
+   case 'setBufLen'
+      bufLen = varargin{2}; 
+   case 'setClassId'
+      classid = varargin{2};
+   case 'setAnaOverlap'
+      anaOverlap = varargin{2};
+   case 'setSynOverlap'
+      synOverlap = varargin{2};
+   case 'setDispLoad'
+      dispLoad = varargin{2};
+   case 'setToPlay'
+      toPlayBlock=varargin{2};
+   case 'setIsLoop'
+      loop = varargin{2};
+   case 'setSource'
+      sourceName = varargin{2};
+%% GETTERS %%%
+   case 'getLs'
+      varargout{1}=Ls;
+   case 'getPos'
+      varargout{1}=pos;
+   case 'getBufCount'
+      varargout{1}= maxBufCount;
+   case 'getPlayChanList'
+      varargout{1}=playChanList;
+   case 'getRecChanList'
+      varargout{1}=recChanList; 
+   case 'getPageList'
+      varargout{1}=pageList; 
+   case 'getPageNo'
+      varargout{1}=pageNo; 
+   case 'getSkipped'
+      varargout{1}=skipCounter; 
+   case 'getBufLen'
+      varargout{1}=bufLen; 
+   case 'getClassId'
+      varargout{1}=classid; 
+   case 'getAnaOverlap'
+      varargout{1}=anaOverlap;
+   case 'getSynOverlap'
+      varargout{1}=synOverlap;
+   case 'getDispLoad'
+      varargout{1}=dispLoad;
+   case 'getToPlay'
+      varargout{1}=toPlayBlock; 
+      toPlayBlock = [];
+   case 'getIsLoop'
+      varargout{1}=loop;
+   case 'getSource'
+      if isnumeric(sourceName)
+         varargout{1}='numeric';
+      else
+         varargout{1}=sourceName;
+      end
+   case 'getEnqBufCount'
+      varargout{1}= numel(pageList);
+
+%% OTHER %%%
+   case 'incPageNo'
+      pageNo = pageNo +1;
+   case 'popPage'
+      varargout{1}=pageList(1);
+      pageList = pageList(2:end);
+   case 'pushPage'
+      pageList = [pageList, varargin{2}];   
+
+
+%   case 'incSkipped'
+%      skipCounter = skipCounter + varargin{2};
+%   case 'readNumericBlock'
+%      L = varargin{2};
+%      varargout{1}=sourceName(pos+1:pos+1+L,:); 
+   otherwise
+      error('%s: Unrecognized command.',upper(mfilename));
+end
+
+
diff --git a/inst/comp/comp_atrousfilterbank_td.m b/inst/comp/comp_atrousfilterbank_td.m
new file mode 100644
index 0000000..ec84483
--- /dev/null
+++ b/inst/comp/comp_atrousfilterbank_td.m
@@ -0,0 +1,73 @@
+function c=comp_atrousfilterbank_td(f,g,a,offset)  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_atrousfilterbank_td
+%@verbatim
+%COMP_ATROUSFILTERBANK_TD   Uniform filterbank by conv2
+%   Usage:  c=comp_atrousfilterbank_fft(f,g,a,skip);
+%
+%   Input parameters:
+%         f   : Input data - L*W array.
+%         g   : Filterbank filters - filtLen*M array. 
+%         a   : Filter upsampling factor - scalar.
+%         offset: Delay of the filters - scalar or array of length M. 
+%
+%   Output parameters:
+%         c  : L*M*W array of coefficients
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_atrousfilterbank_td.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%input data length
+L=size(f,1);
+%input channel number
+W=size(f,2);
+%filter number
+M=size(g,2);
+g = comp_ups(g,a,1);
+
+%length of filters
+filtLen = size(g,1);
+skip = -offset;
+% Allow filter delay only in the filter support range
+if(all(skip>=filtLen) || all(skip<0))
+  error('%s: The filter zero index position outside of the filter support.', upper(mfilename));  
+end
+
+if(numel(skip)==1)
+    skip = skip*ones(M,1);
+end
+
+% Output memory allocation
+c=zeros(L,M,W,assert_classname(f,g));
+
+% Explicitly extend the input. length(fext) = length(f) + 2*(filtLen-1)
+fext = comp_extBoundary(f,filtLen-1,'per','dim',1);
+% CONV2 does 2-D linear convolution. 'valid' option crops tails
+% length(fextconv2) = length(f) + (filtLen-1)
+% length(c(:,m,:)) = N
+% W channels done simultaneously by conv2
+for m=1:M
+  c(:,m,:) = comp_downs(conv2(fext,g(:,m),'valid'),1,skip(m),L); 
+end;
+
+ 
+
+
diff --git a/inst/comp/comp_cellcoef2tf.m b/inst/comp/comp_cellcoef2tf.m
new file mode 100644
index 0000000..4f8a95b
--- /dev/null
+++ b/inst/comp/comp_cellcoef2tf.m
@@ -0,0 +1,57 @@
+function coef = comp_cellcoef2tf(coef,maxLen)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_cellcoef2tf
+%@verbatim
+%COMP_CELLCOEF2TF Cell to a tf-layout
+%   Usage: coef = comp_cellcoef2tf(coef,dim)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_cellcoef2tf.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
+
+coefLenMax = max(cellfun(@(cEl)size(cEl,1),coef));
+
+if nargin>1
+   coefLenMax = min([coefLenMax,maxLen]);
+end
+
+coefTmp = zeros(coefLenMax,numel(coef),size(coef{1},2),class(coef{1}));
+
+for ii=1:numel(coef)
+   if size(coef{ii},1) == 1
+      coefTmp(:,ii) = coef{ii};
+      continue;
+   end
+   if ~isoctave
+       coefTmp(:,ii) = interp1(coef{ii},linspace(1,size(coef{ii},1),...
+                       coefLenMax),'nearest');
+   else
+       coefRe = interp1(real(coef{ii}),linspace(1,size(coef{ii},1),...
+                       coefLenMax),'nearest');
+                   
+        coefIm = interp1(imag(coef{ii}),linspace(1,size(coef{ii},1),...
+                       coefLenMax),'nearest');  
+                   
+        coefTmp(:,ii) = coefRe + 1i*coefIm;
+   end
+end
+coef = coefTmp';
diff --git a/inst/comp/comp_chirpzt.m b/inst/comp/comp_chirpzt.m
new file mode 100644
index 0000000..c21026e
--- /dev/null
+++ b/inst/comp/comp_chirpzt.m
@@ -0,0 +1,89 @@
+function c = comp_chirpzt(f,K,deltao,o)
+
+
+Ls = size(f,1);
+W = size(f,2);
+
+q = 1;
+if 0
+    %Use the decimation scheme
+    % q fft of length
+    q = ceil(Ls/K);
+    Lfft = 2^nextpow2(2*K-1);
+    
+    fext = zeros(q*W,K);
+    for w=0:W-1
+       fext(1+w*q*K:w*q*K+Ls) = f(:,w+1);
+    end
+    f = fext.';
+    Ls = K;
+    k = (0:K-1).';
+    
+    W2 = exp(-1i*q*deltao*(k.^2)./2);
+    
+    preChirp = W2(1:K).*exp(-1i*k*q*o);
+    postChirp = zeros(K,q);
+    for jj=0:q-1
+       postChirp(:,jj+1) = exp(-1i*jj*(k*deltao+o)).*W2(1:K);
+    end
+else
+   %Reference: fft of the following length
+   Lfft = nextfastfft(Ls+K-1);
+
+   n = (0:max([Ls,K])-1).';
+   W2 = exp(-1i*deltao*(n.^2)./2);
+
+   preChirp = W2(1:Ls).*exp(-1i*o*(0:Ls-1).');
+   postChirp = W2(1:K);
+end
+
+
+chirpFilt = zeros(Lfft,1);
+chirpFilt(1:K) = conj(W2(1:K));
+chirpFilt(end:-1:end-Ls+2) = conj(W2(2:Ls));
+chirpFilt = fft(chirpFilt);
+
+ff = bsxfun(@times,f,preChirp);
+c = ifft(bsxfun(@times,fft(ff,Lfft),chirpFilt));
+
+
+
+if q>1
+   ctmp = c;
+   c = zeros(K,W,assert_classname(f));
+   for w=0:W-1
+      c(:,w+1) = sum(ctmp(1:K,1+w*q:(w+1)*q).*postChirp,2);
+   end
+else
+   c = bsxfun(@times,c(1:K,:),postChirp);
+end
+   
+   
+   
+   
+   
+   
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_chirpzt
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_chirpzt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/comp_col2diag.m b/inst/comp/comp_col2diag.m
new file mode 100644
index 0000000..794cbe6
--- /dev/null
+++ b/inst/comp/comp_col2diag.m
@@ -0,0 +1,49 @@
+function cout=comp_col2diag(cin);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_col2diag
+%@verbatim
+%COMP_COL2DIAG  transforms columns to diagonals (in a special way)
+%
+%  This function transforms the first column to the main diagonal. The
+%  second column to the first side-diagonal below the main diagonal and so
+%  on. 
+% 
+%  This way fits well the connection of matrix and spreading function, see
+%  spreadfun.
+%
+%  This function is its own inverse.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_col2diag.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+L=size(cin,1);
+cout=zeros(L,assert_classname(cin));
+
+jj=(0:L-1).';
+for ii=0:L-1
+  cout(ii+1,:)=cin(ii+1,mod(ii-jj,L)+1);
+end;
+
+
+
+
diff --git a/inst/comp/comp_dct.m b/inst/comp/comp_dct.m
new file mode 100644
index 0000000..b4ff956
--- /dev/null
+++ b/inst/comp/comp_dct.m
@@ -0,0 +1,90 @@
+function c = comp_dct(f,type)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dct
+%@verbatim
+%COMP_DCT Calculates DCT
+%   Input parameters:
+%         f     : Input data.
+%         type  : DCT version.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dct.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+[L,W] = size(f);
+
+
+switch type
+   case 1
+      c=zeros(L,W,assert_classname(f));
+      f2=[f;flipud(f(2:L-1,:))]/sqrt(2);
+      f2(1,:)=f2(1,:)*sqrt(2);
+      f2(L,:)=f2(L,:)*sqrt(2);
+  
+      s1=fft(f2)/sqrt(2*L-2);
+
+      c=s1(1:L,:)+[zeros(1,W);s1(2*L-2:-1:L+1,:);zeros(1,W)];
+
+      c(2:L-1,:)=c(2:L-1,:)/sqrt(2);
+   case 2
+      c=zeros(L,W,assert_classname(f));
+      m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+      m1(1)=1;
+
+      m2=1/sqrt(2)*exp((1:L-1)*pi*i/(2*L)).';
+
+      s1=fft([f;flipud(f)]);
+
+      c=bsxfun(@times,s1(1:L,:),m1)+[zeros(1,W);bsxfun(@times,s1(2*L:-1:L+2,:),m2)];
+
+      c=c/sqrt(L)/2;
+   case 3
+      c=zeros(2*L,W,assert_classname(f));
+
+      m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+      m1(1)=1;
+  
+      m2=1/sqrt(2)*exp((L-1:-1:1)*pi*i/(2*L)).';
+
+      c=[bsxfun(@times,m1,f);zeros(1,W);bsxfun(@times,m2,f(L:-1:2,:))];
+
+      c=fft(c)/sqrt(L);
+
+      c=c(1:L,:);
+   case 4
+      s1=zeros(2*L,W,assert_classname(f));
+      c=zeros(L,W,assert_classname(f));
+
+      m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+      m2=1/sqrt(2)*exp((1:L)*pi*i/(2*L)).';
+
+      s1=[bsxfun(@times,m1,f);bsxfun(@times,flipud(m2),f(L:-1:1,:))];
+  
+      s1=exp(-pi*i/(4*L))*fft(s1)/sqrt(2*L);
+
+      c=bsxfun(@times,s1(1:L,:),m1)+bsxfun(@times,s1(2*L:-1:L+1,:),m2);
+   otherwise
+      error('%s: Type not supported.',upper(mfilename));
+end
+
+
+if isreal(f)
+   c=real(c);
+end;
diff --git a/inst/comp/comp_dgt.m b/inst/comp/comp_dgt.m
new file mode 100644
index 0000000..ee8a0fe
--- /dev/null
+++ b/inst/comp/comp_dgt.m
@@ -0,0 +1,89 @@
+function c=comp_dgt(f,g,a,M,lt,phasetype,algfir,algns)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgt
+%@verbatim
+%COMP_DGT  Compute a DGT
+%   Usage:  c=comp_dgt(f,g,a,M,L,phasetype);
+%
+%   Input parameters:
+%         f     : Input data
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         L     : Length of transform to do.
+%         lt    : Lattice type
+%         phasetype : Type of phase
+%         algtype : Select algorithm
+%   Output parameters:
+%         c     : M*N*W array of coefficients.
+%
+%   If phasetype is zero, a freq-invariant transform is computed. If
+%   phase-type is one, a time-invariant transform is computed.
+%
+%   The algorithm chooser do the following:
+%
+%       algfir=0 : Default value, automatically choose the fastest
+%        algorithm.
+%       
+%       algfir=1 : Choose the algorithm depending on the input.
+%
+%       algns=0  : Default value, automatically choose the fastest
+%        algorithm.
+%
+%       algns=1  : Always choose multiwindow.
+%
+%       algns=2  : Always choose shear
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+      
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+L=size(f,1);
+
+if lt(2)==1
+        c=comp_sepdgt(f,g,a,M);
+else
+        
+    g=fir2long(g,L);
+    
+    if  (algns==0 && lt(2)<=2) || (algns==1)
+        
+        c=comp_nonsepdgt_multi(f,g,a,M,lt);
+        
+    else
+        
+        [s0,s1,br] = shearfind(L,a,M,lt);
+        
+        c=comp_nonsepdgt_shear(f,g,a,M,s0,s1,br);
+        
+    end;
+
+end;
+
+% FIXME : Calls non-comp function 
+if phasetype==1
+  c=phaselock(c,a,'lt',lt);
+end;
+
+
+
diff --git a/inst/comp/comp_dgt_fb.m b/inst/comp/comp_dgt_fb.m
new file mode 100644
index 0000000..6fe8add
--- /dev/null
+++ b/inst/comp/comp_dgt_fb.m
@@ -0,0 +1,115 @@
+function [coef]=comp_dgt_fb(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgt_fb
+%@verbatim
+%COMP_DGT_FB  Filter bank DGT
+%   Usage:  c=comp_dgt_fb(f,g,a,M);
+%  
+%   This is a computational routine. Do not call it directly.
+%
+%   See help on DGT.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgt_fb.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+% Calculate the parameters that was not specified.
+L=size(f,1);
+N=L/a;
+gl=length(g);
+W=size(f,2);      % Number of columns to apply the transform to.
+glh=floor(gl/2);  % gl-half
+
+
+% Conjugate the window here.
+g=conj(fftshift(g));
+
+coef=zeros(M,N,W,assert_classname(f,g));
+
+% ----- Handle the first boundary using periodic boundary conditions. ---
+for n=0:ceil(glh/a)-1
+
+    % Periodic boundary condition.
+    fpart=[f(L-(glh-n*a)+1:L,:);...
+           f(1:gl-(glh-n*a),:)];
+    
+    fg=bsxfun(@times,fpart,g);
+    
+    % Do the sum (decimation in frequency, Poisson summation)
+    coef(:,n+1,:)=sum(reshape(fg,M,gl/M,W),2);
+      
+end;
+
+% ----- Handle the middle case. ---------------------
+for n=ceil(glh/a):floor((L-ceil(gl/2))/a)
+  
+  fg=bsxfun(@times,f(n*a-glh+1:n*a-glh+gl,:),g);
+  
+  % Do the sum (decimation in frequency, Poisson summation)
+  coef(:,n+1,:)=sum(reshape(fg,M,gl/M,W),2);
+end;
+
+% ----- Handle the last boundary using periodic boundary conditions. ---
+for n=floor((L-ceil(gl/2))/a)+1:N-1
+
+    % Periodic boundary condition.
+    fpart=[f((n*a-glh)+1:L,:);... %   L-n*a+glh elements
+           f(1:n*a-glh+gl-L,:)];  %  gl-L+n*a-glh elements      
+    
+    fg=bsxfun(@times,fpart,g);
+    
+    % Do the sum (decimation in frequency, Poisson summation)
+    coef(:,n+1,:)=sum(reshape(fg,M,gl/M,W),2);      
+end;
+
+% --- Shift back again to make it a frequency-invariant system. ---
+for n=0:N-1
+  coef(:,n+1,:)=circshift(coef(:,n+1,:),n*a-glh);
+end;
+
+
+coef=fft(coef);
+
+
+
+% Simple code using a lot of circshifts.
+% Move f initially so it lines up with the initial fftshift of the
+% window
+%f=circshift(f,glh);
+%for n=0:N-1
+  % Do the inner product.
+  %fg=circshift(f,-n*a)(1:gl,:).*gw;
+  
+  % Periodize it.
+  %fpp=zeros(M,W);
+  %for ii=0:gl/M-1
+    %  fpp=fpp+fg(ii*M+1:(ii+1)*M,:);
+    %end;
+%  fpp=sum(reshape(fg,M,gl/M,W),2);
+  
+  % Shift back again.
+%  coef(:,n+1,:)=circshift(fpp,n*a-glh); %),M,1,W);
+  
+%end;
+
+
+
+
+
diff --git a/inst/comp/comp_dgt_long.m b/inst/comp/comp_dgt_long.m
new file mode 100644
index 0000000..04b5a0c
--- /dev/null
+++ b/inst/comp/comp_dgt_long.m
@@ -0,0 +1,65 @@
+function cout=comp_dgt_long(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgt_long
+%@verbatim
+%COMP_DGT_LONG  Gabor transform using long windows.
+%   Usage:  c=comp_dgt_long(f,g,a,M);
+%
+%   Input parameters:
+%         f      : Factored input data
+%         g      : Window.
+%         a      : Length of time shift.
+%         M      : Number of channels.
+%   Output parameters:
+%         c      : M x N*W*R array of coefficients, where N=L/a
+%
+%   Do not call this function directly, use DGT instead.
+%   This function does not check input parameters!
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgt_long.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+gf=comp_wfac(g,a,M);
+  
+% Compute the window application
+cout=comp_dgt_walnut(f,gf,a,M);
+
+% Apply dft modulation.
+cout=fft(cout)/sqrt(M);
+
+% Change to the right shape
+L=size(f,1);
+W=size(f,2);
+N=L/a;
+cout=reshape(cout,M,N,W);
+
+
+
diff --git a/inst/comp/comp_dgt_ola.m b/inst/comp/comp_dgt_ola.m
new file mode 100644
index 0000000..8a72b3c
--- /dev/null
+++ b/inst/comp/comp_dgt_ola.m
@@ -0,0 +1,79 @@
+function coef=comp_dgt_ola(f,g,a,M,Lb)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgt_ola
+%@verbatim
+%
+%  This function implements periodic convolution using overlap-add. The
+%  window g is supposed to be extended by fir2iir.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgt_ola.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+[L W]=size(f);
+gl=length(g);
+  
+N=L/a;
+
+% Length of extended block and padded g
+Lext=Lb+gl;
+
+% Number of blocks
+Nb=L/Lb;
+
+% Number of time positions per block
+Nblock   = Lb/a;
+Next = Lext/a;
+
+if rem(Nblock,1)~=0
+  error('The length of the time shift must devide the block length.');
+end;
+
+% Number of time positions in half extension
+b2 = gl/2/a;
+
+if rem(b2,1)~=0
+  error(['The length of the time shift must devide the window length by ' ...
+         'an even number.'])
+end;
+
+% Extend window to length of extended block.
+gpad=fir2long(g,Lext);
+
+coef=zeros(M,N,W,assert_classname(f,g));
+
+for ii=0:Nb-1
+  
+  block=comp_dgt_long(postpad(f(ii*Lb+1:(ii+1)*Lb,:),Lext),gpad,a,M);
+  block=reshape(block,M,Next,W);
+
+  % Large block
+  coef(:,ii*Nblock+1:(ii+1)*Nblock,:) = coef(:,ii*Nblock+1:(ii+1)*Nblock,:)+block(:,1:Nblock,:);  
+  
+  % Small block +
+  s_ii=mod(ii+1,Nb);
+  coef(:,s_ii*Nblock+1   :s_ii*Nblock+b2,:) = coef(:,s_ii*Nblock+1 ...
+                                                   :s_ii*Nblock+b2,:)+ block(:,Nblock+1:Nblock+b2,:); 
+
+  % Small block -
+  s_ii=mod(ii-1,Nb)+1;
+  coef(:,s_ii*Nblock-b2+1:s_ii*Nblock,:) =coef(:,s_ii*Nblock-b2+1:s_ii*Nblock,:)+ block(:,Nblock+b2+1:Nblock+2*b2,:);
+
+end;
+
+
diff --git a/inst/comp/comp_dgt_walnut.m b/inst/comp/comp_dgt_walnut.m
new file mode 100644
index 0000000..0b6898e
--- /dev/null
+++ b/inst/comp/comp_dgt_walnut.m
@@ -0,0 +1,184 @@
+function cout=comp_dgt_walnut(f,gf,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgt_walnut
+%@verbatim
+%COMP_DGT_WALNUT  First step of full-window factorization of a Gabor matrix.
+%   Usage:  c=comp_dgt_walnut(f,gf,a,M);
+%
+%   Input parameters:
+%         f      : Factored input data
+%         gf     : Factorization of window (from facgabm).
+%         a      : Length of time shift.
+%         M      : Number of channels.
+%   Output parameters:
+%         c      : M x N*W*R array of coefficients, where N=L/a
+%
+%   Do not call this function directly, use DGT instead.
+%   This function does not check input parameters!
+%
+%   The length of f and gamma must match.
+%
+%   If input is a matrix, the transformation is applied to
+%   each column.
+%
+%   This function does not handle the multidim case. Take care before
+%   calling this.
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgt_walnut.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+L=size(f,1);
+W=size(f,2);
+LR=numel(gf);
+R=LR/L;
+
+N=L/a;
+
+[c,h_a,h_m]=gcd(a,M);
+h_a=-h_a;
+p=a/c;
+q=M/c;
+d=N/q;
+
+ff=zeros(p,q*W,c,d,assert_classname(f,gf));
+
+if p==1
+  % --- integer oversampling ---
+
+  if (c==1) && (d==1) && (W==1) && (R==1)
+    % --- Short time Fourier transform of single signal ---
+    % This is used for spectrograms of short signals.      
+      ff(1,:,1,1)=f(:);
+  else
+    for s=0:d-1
+      for r=0:c-1    
+	for l=0:q-1
+	  ff(1,l+1:q:W*q,r+1,s+1)=f(r+s*M+l*c+1,:);
+	end;
+      end;
+    end;    
+  end;
+
+else
+  % --- rational oversampling ---
+  % Set up the small matrices
+  % The r-loop (runs up to c) has been vectorized
+  for w=0:W-1
+    for s=0:d-1
+      for l=0:q-1
+	for k=0:p-1	    	  
+	  ff(k+1,l+1+w*q,:,s+1)=f((1:c)+mod(k*M+s*p*M-l*h_a*a,L),w+1);
+	end;
+      end;
+    end;
+  end;
+end;
+
+% This version uses matrix-vector products and ffts
+
+% fft them
+if d>1
+  ff=fft(ff,[],4);
+end;
+
+C=zeros(q*R,q*W,c,d,assert_classname(f,gf));
+
+for r=0:c-1    
+  for s=0:d-1
+    GM=reshape(gf(:,r+s*c+1),p,q*R);
+    FM=reshape(ff(:,:,r+1,s+1),p,q*W);
+    
+    C(:,:,r+1,s+1)=GM'*FM;
+  end;
+end;
+
+% Inverse fft
+if d>1
+  C=ifft(C,[],4);
+end;
+
+% Place the result
+
+cout=zeros(M,N,R,W,assert_classname(f,gf));
+
+if p==1
+  % --- integer oversampling ---
+
+  if (c==1) && (d==1) && (W==1) && (R==1)
+    
+    % --- Short time Fourier transform of single signal ---
+    % This is used for spectrograms of short signals.      
+    for l=0:q-1
+      cout(l+1,mod((0:q-1)+l,N)+1,1,1)=C(:,l+1,1,1);
+    end;
+    
+  else
+
+    % The r-loop (runs up to c) has been vectorized
+    for rw=0:R-1
+      for w=0:W-1    
+	for s=0:d-1
+	  for l=0:q-1
+	    for u=0:q-1
+	      cout((1:c)+l*c,mod(u+s*q+l,N)+1,rw+1,w+1)=C(u+1+rw*q,l+1+w*q,:,s+1);
+	    end;
+	  end;
+	end;
+      end; 
+    end;
+  end;
+
+else
+
+  % Rational oversampling
+  % The r-loop (runs up to c) has been vectorized
+  for rw=0:R-1
+    for w=0:W-1    
+      for s=0:d-1
+	for l=0:q-1
+	  for u=0:q-1
+	    cout((1:c)+l*c,mod(u+s*q-l*h_a,N)+1,rw+1,w+1)=C(u+1+rw*q,l+1+w*q,:,s+1);
+	  end;
+	end;
+      end;
+    end; 
+  end;
+
+end;
+
+cout=reshape(cout,M,N*W*R);
+
+
+
+
+
diff --git a/inst/comp/comp_dgtreal.m b/inst/comp/comp_dgtreal.m
new file mode 100644
index 0000000..c357e5f
--- /dev/null
+++ b/inst/comp/comp_dgtreal.m
@@ -0,0 +1,70 @@
+function c=comp_dgtreal(f,g,a,M,lt,phasetype)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgtreal
+%@verbatim
+%COMP_DGTREAL  Compute a DGTREAL
+%   Usage:  c=comp_dgt_real(f,g,a,M,lt,phasetype);
+%
+%   Input parameters:
+%         f     : Input data
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         L     : Length of transform to do.
+%   Output parameters:
+%         c     : M*N array of coefficients.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgtreal.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+L=size(f,1);
+
+W=size(f,2);
+N=L/a;
+
+M2=floor(M/2)+1;
+
+if lt(2)==1
+
+    c = comp_sepdgtreal(f,g,a,M);
+    
+    if phasetype==1
+        
+        TimeInd = (0:(N-1))*a;
+        FreqInd = (0:(M2-1))/M;
+        
+        phase = FreqInd'*TimeInd;
+        phase = exp(2*i*pi*phase);
+    
+        c=bsxfun(@times,c,phase);
+        
+    end;
+    
+else
+    % Quinqux lattice
+    c=comp_nonsepdgtreal_quinqux(f,g,a,M);            
+end;
+
+
+
+
+
diff --git a/inst/comp/comp_dgtreal_fb.m b/inst/comp/comp_dgtreal_fb.m
new file mode 100644
index 0000000..6d22212
--- /dev/null
+++ b/inst/comp/comp_dgtreal_fb.m
@@ -0,0 +1,121 @@
+function [coef]=comp_dgtreal_fb(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgtreal_fb
+%@verbatim
+%COMP_DGTREAL_FB  Filter bank DGT
+%   Usage:  c=comp_dgt_fb(f,g,a,M,boundary);
+%  
+%   This is a computational routine. Do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgtreal_fb.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   See help on DGT.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+% Calculate the parameters that was not specified.
+L=size(f,1);
+N=L/a;
+gl=length(g);
+W=size(f,2);      % Number of columns to apply the transform to.
+glh=floor(gl/2);  % gl-half
+M2=floor(M/2)+1;
+
+
+% Conjugate the window here.
+g=conj(fftshift(g));
+
+coef=zeros(M,N,W,assert_classname(f,g));
+
+% Replicate g when multiple columns should be transformed.
+gw=repmat(g,1,W);
+
+% ----- Handle the first boundary using periodic boundary conditions. ---
+for n=0:ceil(glh/a)-1
+
+    % Periodic boundary condition.
+    fpart=[f(L-(glh-n*a)+1:L,:);...
+           f(1:gl-(glh-n*a),:)];
+
+  fg=fpart.*gw;
+  
+  % Do the sum (decimation in frequency, Poisson summation)
+  coef(:,n+1,:)=sum(reshape(fg,M,gl/M,W),2);
+      
+end;
+
+% ----- Handle the middle case. ---------------------
+for n=ceil(glh/a):floor((L-ceil(gl/2))/a)
+  
+  fg=f(n*a-glh+1:n*a-glh+gl,:).*gw;
+  
+  % Do the sum (decimation in frequency, Poisson summation)
+  coef(:,n+1,:)=sum(reshape(fg,M,gl/M,W),2);
+end;
+
+% ----- Handle the last boundary using periodic boundary conditions. ---
+for n=floor((L-ceil(gl/2))/a)+1:N-1
+
+    % Periodic boundary condition.
+    fpart=[f((n*a-glh)+1:L,:);... %   L-n*a+glh elements
+           f(1:n*a-glh+gl-L,:)];  %  gl-L+n*a-glh elements
+
+    fg=fpart.*gw;
+    
+    % Do the sum (decimation in frequency, Poisson summation)
+    coef(:,n+1,:)=sum(reshape(fg,M,gl/M,W),2);      
+end;
+
+% --- Shift back again to make it a frequency-invariant system. ---
+for n=0:N-1
+  coef(:,n+1,:)=circshift(coef(:,n+1,:),n*a-glh);
+end;
+
+coef=fftreal(coef);
+coef=reshape(coef,M2,N,W);
+
+%c=c(1:M2,:);
+
+
+
+% Simple code using a lot of circshifts.
+% Move f initially so it lines up with the initial fftshift of the
+% window
+%f=circshift(f,glh);
+%for n=0:N-1
+  % Do the inner product.
+  %fg=circshift(f,-n*a)(1:gl,:).*gw;
+  
+  % Periodize it.
+  %fpp=zeros(M,W);
+  %for ii=0:gl/M-1
+    %  fpp=fpp+fg(ii*M+1:(ii+1)*M,:);
+    %end;
+%  fpp=sum(reshape(fg,M,gl/M,W),2);
+  
+  % Shift back again.
+%  coef(:,n+1,:)=circshift(fpp,n*a-glh); %),M,1,W);
+  
+%end;
+
+
+
+
+
diff --git a/inst/comp/comp_dgtreal_long.m b/inst/comp/comp_dgtreal_long.m
new file mode 100644
index 0000000..2c5d729
--- /dev/null
+++ b/inst/comp/comp_dgtreal_long.m
@@ -0,0 +1,69 @@
+function cout=comp_dgtreal_long(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgtreal_long
+%@verbatim
+%COMP_DGTREAL_LONG  Full-window factorization of a Gabor matrix.
+%   Usage:  c=comp_dgtreal_long(f,g,a,M);
+%
+%   Input parameters:
+%         f      : Factored input data
+%         g      : Window
+%         a      : Length of time shift.
+%         M      : Number of channels.
+%   Output parameters:
+%         c      : M x N*W*R array of coefficients, where N=L/a
+%
+%   Do not call this function directly, use DGT instead.
+%   This function does not check input parameters!
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgtreal_long.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR    : Peter L. Soendergaard.
+%   TESTING   : TEST_DGT
+%   REFERENCE : OK 
+  
+L=size(f,1);
+W=size(f,2);
+N=L/a;
+M2=floor(M/2)+1;
+  
+gf=comp_wfac(g,a,M);
+
+% Compute the window application
+% We know the output is real, but comp_dgt_walnut cannot detect this, so
+% we force the output to be real.
+cout=real(comp_dgt_walnut(f,gf,a,M));
+
+% FFT with only positive frequencies
+cout=fftreal(cout)/sqrt(M);
+cout=reshape(cout,M2,N,W);
+
+
+
diff --git a/inst/comp/comp_dgtreal_ola.m b/inst/comp/comp_dgtreal_ola.m
new file mode 100644
index 0000000..b56440e
--- /dev/null
+++ b/inst/comp/comp_dgtreal_ola.m
@@ -0,0 +1,78 @@
+function coef=comp_dgtreal_ola(f,g,a,M,Lb)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dgtreal_ola
+%@verbatim
+%
+%  This function implements periodic convolution using overlap-add. The
+%  window g is supposed to be extended by fir2iir.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dgtreal_ola.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+[L W]=size(f);
+gl=length(g);
+  
+N=L/a;
+M2=floor(M/2)+1;
+
+% Length of extended block and padded g
+Lext=Lb+gl;
+
+% Number of blocks
+Nb=L/Lb;
+
+% Number of time positions per block
+Nblock   = Lb/a;
+
+if rem(Nblock,1)~=0
+  error('The length of the time shift must devide the block length.');
+end;
+
+% Number of time positions in half extension
+b2 = gl/2/a;
+
+if rem(b2,1)~=0
+  error(['The length of the time shift must devide the window length by ' ...
+         'an even number.'])
+end;
+
+% Extend window to length of extended block.
+gpad=fir2long(g,Lext);
+
+coef=zeros(M2,N,W,assert_classname(f,g));
+
+for ii=0:Nb-1
+  
+  block=dgtreal(postpad(f(ii*Lb+1:(ii+1)*Lb,:),Lext),gpad,a,M);
+
+  % Large block
+  coef(:,ii*Nblock+1:(ii+1)*Nblock,:) = coef(:,ii*Nblock+1:(ii+1)*Nblock,:)+block(:,1:Nblock,:);  
+  
+  % Small block +
+  s_ii=mod(ii+1,Nb);
+  coef(:,s_ii*Nblock+1   :s_ii*Nblock+b2,:) = coef(:,s_ii*Nblock+1 ...
+                                                   :s_ii*Nblock+b2,:)+ block(:,Nblock+1:Nblock+b2,:); 
+
+  % Small block -
+  s_ii=mod(ii-1,Nb)+1;
+  coef(:,s_ii*Nblock-b2+1:s_ii*Nblock,:) =coef(:,s_ii*Nblock-b2+1:s_ii*Nblock,:)+ block(:,Nblock+b2+1:Nblock+2*b2,:);
+
+end;
+
+
diff --git a/inst/comp/comp_downs.m b/inst/comp/comp_downs.m
new file mode 100644
index 0000000..55bb292
--- /dev/null
+++ b/inst/comp/comp_downs.m
@@ -0,0 +1,102 @@
+function fdowns = comp_downs(f,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_downs
+%@verbatim
+%COMP_DOWNS Downsampling
+%   Usage: fdowns = comp_downs(f,a) 
+%          fdowns = comp_downs(f,a,skip,L,'dim',dim) 
+%   
+%   Input parameters:
+%         f     : Input vector/matrix.
+%         a     : Downsampling factor.
+%         skip  : Skipped initial samples.
+%         L     : Length of the portion of the input to be used.
+%         dim   : Direction of downsampling.
+%   Output parameters:
+%         fdowns  : Downsampled vector/matrix.
+%
+%   Downsamples input f by a factor a (leaves every a*th sample) along
+%   dimension dim. If dim is not specified, first non-singleton
+%   dimension is used. Parameter skip (integer) specifies how
+%   many samples to skip from the beginning and L defines how many
+%   elements of the input data are to be used starting at index 1+skip. 
+%
+%   Examples:
+%   ---------
+%
+%   The default behavior is equal to the subsampling performed
+%   in the frequency domain using reshape and sum:
+%
+%      f = 1:9;
+%      a = 3;
+%      fupsTD = comp_downs(f,a)
+%      fupsFD = real(ifft(sum(reshape(fft(f),length(f)/a,a),2).'))/a
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_downs.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<2)
+    error('%s: Too few input parameters.',upper(mfilename));
+end
+
+definput.keyvals.dim = [];
+definput.keyvals.skip = 0;
+definput.keyvals.L = [];
+[flags,kv,skip,L]=ltfatarghelper({'skip','L','dim'},definput,varargin);
+
+% a have to be a positive integer
+if(a<1)
+    a = 1;
+end
+if(a<0 || rem(a,1)~=0)
+    error('%s: Parameter *a* have to be a positive integer.',upper(mfilename));
+end
+
+% supported type are [0--a-1]
+% if(type<0||type>(a-1))
+%     error('%s: Unsupported downsampling type.',upper(mfilename));
+% end
+
+if(ndims(f)>2)
+    error('%s: Multidimensional signals (d>2) are not supported.',upper(mfilename));
+end
+
+% ----- Verify f and determine its length -------
+[f,Lreq,Ls,~,dim,permutedsize,order]=assert_sigreshape_pre(f,L,kv.dim,upper(mfilename));
+
+if(skip>=Ls)
+    error('%s: Parameter *skip* have to be less than the input length.',upper(mfilename));
+end
+
+if(~isempty(L))
+   if(Lreq+skip>Ls)
+       error('%s: Input length is less than required samples count: L+skip>Ls.',upper(mfilename)); 
+   end 
+   Ls = Lreq+skip;
+end
+
+
+% Actual computation
+fdowns = f(1+skip:a:Ls,:);   
+
+
+permutedSizeAlt = size(fdowns);
+fdowns=assert_sigreshape_post(fdowns,dim,permutedSizeAlt,order);
diff --git a/inst/comp/comp_dst.m b/inst/comp/comp_dst.m
new file mode 100644
index 0000000..cb74077
--- /dev/null
+++ b/inst/comp/comp_dst.m
@@ -0,0 +1,102 @@
+function c = comp_dst(f,type)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dst
+%@verbatim
+%COMP_DST Calculates DST
+%   Input parameters:
+%         f     : Input data.
+%         type  : DST version.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dst.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+[L,W] = size(f);
+
+
+switch type
+   case 1
+      c=zeros(L,W,assert_classname(f));
+
+      s1=dft([zeros(1,W,assert_classname(f));...
+	           f;...
+	           zeros(1,W,assert_classname(f));...
+	           -flipud(f)]);
+
+
+      % This could be done by a repmat instead.
+      for w=1:W
+         c(:,w)=s1(2:L+1,w)-s1(2*L+2:-1:L+3,w);
+      end;
+
+      c=c*1i/2;
+   case 2
+      c=zeros(L,W,assert_classname(f));
+
+      m1=1/sqrt(2)*exp(-(1:L)*pi*i/(2*L)).';
+      m1(L)=-i;
+  
+      m2=-1/sqrt(2)*exp((1:L-1)*pi*i/(2*L)).';
+
+      s1=i*fft([f;-flipud(f)])/sqrt(L)/2;
+
+      % This could be done by a repmat instead.
+      for w=1:W
+        c(:,w)=s1(2:L+1,w).*m1+[s1(2*L:-1:L+2,w).*m2;0];
+      end;
+   case 3
+      c=zeros(2*L,W,assert_classname(f));
+
+      m1=1/sqrt(2)*exp((1:L)*pi*i/(2*L)).';
+      m1(L)=i;
+
+      m2=-1/sqrt(2)*exp(-(L-1:-1:1)*pi*i/(2*L)).';
+
+      for w=1:W
+        c(:,w)=[0;m1.*f(:,w);m2.*f(L-1:-1:1,w)];
+      end;
+
+      c=-sqrt(L)*2*i*ifft(c);
+      c=c(1:L,:);
+   case 4
+      s1=zeros(2*L,W,assert_classname(f));
+      c=zeros(L,W,assert_classname(f));
+
+      m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+      m2=-1/sqrt(2)*exp((1:L)*pi*i/(2*L)).';
+
+      for w=1:W
+        s1(:,w)=[m1.*f(:,w);flipud(m2).*f(L:-1:1,w)];
+      end;
+
+      s1=i*exp(-pi*i/(4*L))*fft(s1)/sqrt(2*L);
+
+      % This could be done by a repmat instead.
+      for w=1:W
+        c(:,w)=s1(1:L,w).*m1+s1(2*L:-1:L+1,w).*m2;
+      end;
+   otherwise
+      error('%s: Type not supported.',upper(mfilename));
+end
+
+
+if isreal(f)
+   c=real(c);
+end;
diff --git a/inst/comp/comp_dwilt.m b/inst/comp/comp_dwilt.m
new file mode 100644
index 0000000..1517f9d
--- /dev/null
+++ b/inst/comp/comp_dwilt.m
@@ -0,0 +1,90 @@
+function [coef]=comp_dwilt(f,g,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dwilt
+%@verbatim
+%COMP_DWILT  Compute Discrete Wilson transform.
+%   
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dwilt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+L = size(f,1);
+a=M;
+N=L/a;
+W=size(f,2);
+
+
+coef=zeros(2*M,N/2,W,assert_classname(f,g));
+
+coef2=comp_sepdgt(f,g,a,2*M);
+
+if (isreal(f) && isreal(g))
+
+    % If the input coefficients are real, the calculations can be
+  % be simplified. The complex case code also works for the real case.
+
+  % Unmodulated case.
+  coef(1,:,:)=coef2(1,1:2:N,:);
+
+  % cosine, first column.
+  coef(3:2:M,:,:)=sqrt(2)*real(coef2(3:2:M,1:2:N,:));
+  
+  % sine, second column
+  coef(M+3:2:2*M,:,:)=-sqrt(2)*imag(coef2(3:2:M,2:2:N,:));
+  
+  % sine, first column.
+  coef(2:2:M,:,:)=-sqrt(2)*imag(coef2(2:2:M,1:2:N,:));
+  
+  % cosine, second column
+  coef(M+2:2:2*M,:,:)=sqrt(2)*real(coef2(2:2:M,2:2:N,:));
+
+  % Nyquest case
+  if mod(M,2)==0
+    coef(M+1,:,:) = coef2(M+1,1:2:N,:);
+  else
+    coef(M+1,:,:) = coef2(M+1,2:2:N,:);
+  end;
+
+
+else
+  % Complex valued case
+  
+
+  % Unmodulated case.
+  coef(1,:,:)=coef2(1,1:2:N,:);
+
+  % odd value of m
+  coef(2:2:M,:,:)=1/sqrt(2)*i*(coef2(2:2:M,1:2:N,:)-coef2(2*M:-2:M+2,1:2:N,:));
+  coef(M+2:2:2*M,:,:)=1/sqrt(2)*(coef2(2:2:M,2:2:N,:)+coef2(2*M:-2:M+2,2:2:N,:));
+
+  % even value of m
+  coef(3:2:M,:,:)=1/sqrt(2)*(coef2(3:2:M,1:2:N,:)+coef2(2*M-1:-2:M+2,1:2:N,:));
+  coef(M+3:2:2*M,:,:)=1/sqrt(2)*i*(coef2(3:2:M,2:2:N,:)-coef2(2*M-1:-2:M+2,2:2:N,:));
+
+  % Nyquest case
+  if mod(M,2)==0
+    coef(M+1,:,:) = coef2(M+1,1:2:N,:);
+  else
+    coef(M+1,:,:) = coef2(M+1,2:2:N,:);
+  end;
+
+end;
+
+
+
diff --git a/inst/comp/comp_dwiltii.m b/inst/comp/comp_dwiltii.m
new file mode 100644
index 0000000..a10d9d1
--- /dev/null
+++ b/inst/comp/comp_dwiltii.m
@@ -0,0 +1,58 @@
+function [coef]=comp_dwiltii(coef2,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dwiltii
+%@verbatim
+%COMP_DWILT  Compute Discrete Wilson transform.
+%   
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dwiltii.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M=size(coef2,1)/2;
+N=size(coef2,2);
+W=size(coef2,3);
+L=N*a;
+
+coef=zeros(2*M,N/2,W,assert_classname(coef2));
+
+
+% ---- m is zero ---------
+coef(1,:,:)=coef2(1,1:2:N,:);
+
+% --- m is odd ----------
+coef(2:2:M,:,:)    = i/sqrt(2)*(coef2(2:2:M,1:2:N,:)+coef2(2*M:-2:M+2,1:2:N,:));
+coef(M+2:2:2*M,:,:)= 1/sqrt(2)*(coef2(2:2:M,2:2:N,:)-coef2(2*M:-2:M+2,2:2:N,:));
+
+% --- m is even ---------
+coef(3:2:M,:,:)=     1/sqrt(2)*(coef2(3:2:M,1:2:N,:)-coef2(2*M-1:-2:M+2,1:2:N,:));
+coef(M+3:2:2*M,:,:)= i/sqrt(2)*(coef2(3:2:M,2:2:N,:)+coef2(2*M-1:-2:M+2,2:2:N,:));
+
+% --- m is nyquest ------
+if mod(M,2)==0
+  coef(M+1,:,:) = i*coef2(M+1,2:2:N,:);
+else
+  coef(M+1,:,:) = i*coef2(M+1,1:2:N,:);
+end;
+
+coef=reshape(coef,M*N,W);
+
+
+
+
+
diff --git a/inst/comp/comp_dwiltiii.m b/inst/comp/comp_dwiltiii.m
new file mode 100644
index 0000000..ee5d5e2
--- /dev/null
+++ b/inst/comp/comp_dwiltiii.m
@@ -0,0 +1,56 @@
+function [coef]=comp_dwiltiii(f,g,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dwiltiii
+%@verbatim
+%COMP_DWILTIII  Compute Discrete Wilson transform type III.
+%   
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dwiltiii.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+L = size(f,1);
+a=M;
+N=L/a;
+W=size(f,2);
+
+fwasreal = isreal(f);
+coef=zeros(M,N,W,assert_classname(f,g));
+
+halfmod=exp(-pi*i*(0:L-1).'/(2*M));
+f=f.*repmat(halfmod,1,W);
+
+coef2=comp_sepdgt(f,g,a,2*M);
+  
+if (isreal(g) && fwasreal)
+   % --- m is even ---------
+   coef(1:2:M,1:2:N,:)= real(coef2(1:2:M,1:2:N,:)) + imag(coef2(1:2:M,1:2:N,:));
+   coef(1:2:M,2:2:N,:)= real(coef2(1:2:M,2:2:N,:)) - imag(coef2(1:2:M,2:2:N,:));
+
+   % --- m is odd ----------
+   coef(2:2:M,1:2:N,:)= real(coef2(2:2:M,1:2:N,:)) - imag(coef2(2:2:M,1:2:N,:));
+   coef(2:2:M,2:2:N,:)= real(coef2(2:2:M,2:2:N,:)) + imag(coef2(2:2:M,2:2:N,:));    
+else
+   % --- m is even ---------
+   coef(1:2:M,1:2:N,:)= 1/sqrt(2)*(exp(-i*pi/4)*coef2(1:2:M,1:2:N,:)+exp(i*pi/4)*coef2(2*M:-2:M+1,1:2:N,:));
+   coef(1:2:M,2:2:N,:)= 1/sqrt(2)*(exp(i*pi/4)*coef2(1:2:M,2:2:N,:)+exp(-i*pi/4)*coef2(2*M:-2:M+1,2:2:N,:));
+
+   % --- m is odd ----------
+   coef(2:2:M,1:2:N,:)= 1/sqrt(2)*(exp(i*pi/4)*coef2(2:2:M,1:2:N,:)+exp(-i*pi/4)*coef2(2*M-1:-2:M+1,1:2:N,:));
+   coef(2:2:M,2:2:N,:)= 1/sqrt(2)*(exp(-i*pi/4)*coef2(2:2:M,2:2:N,:)+exp(i*pi/4)*coef2(2*M-1:-2:M+1,2:2:N,:));
+end
diff --git a/inst/comp/comp_dwiltiv.m b/inst/comp/comp_dwiltiv.m
new file mode 100644
index 0000000..ff4defc
--- /dev/null
+++ b/inst/comp/comp_dwiltiv.m
@@ -0,0 +1,44 @@
+function [coef]=comp_dwiltiv(coef2,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_dwiltiv
+%@verbatim
+%COMP_DWILTIV  Compute Discrete Wilson transform type IV.
+%   
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_dwiltiv.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M=size(coef2,1)/2;
+N=size(coef2,2);
+W=size(coef2,3);
+L=N*a;
+
+coef=zeros(M,N,W,assert_classname(coef2));
+
+% --- m is even ---------
+coef(1:2:M,1:2:N,:)= 1/sqrt(2)*(exp(-i*pi/4)*coef2(1:2:M,1:2:N,:)+exp(-i*pi*3/4)*coef2(2*M:-2:M+1,1:2:N,:));
+coef(1:2:M,2:2:N,:)= 1/sqrt(2)*(exp(i*pi/4)*coef2(1:2:M,2:2:N,:)+exp(i*pi*3/4)*coef2(2*M:-2:M+1,2:2:N,:));
+
+% --- m is odd ----------
+coef(2:2:M,1:2:N,:)= 1/sqrt(2)*(exp(i*pi/4)*coef2(2:2:M,1:2:N,:)+exp(i*pi*3/4)*coef2(2*M-1:-2:M+1,1:2:N,:));
+coef(2:2:M,2:2:N,:)= 1/sqrt(2)*(exp(-i*pi/4)*coef2(2:2:M,2:2:N,:)+exp(-i*pi*3/4)*coef2(2*M-1:-2:M+1,2:2:N,:));
+
+coef=reshape(coef,M*N,W);
+
+
diff --git a/inst/comp/comp_edgt6.m b/inst/comp/comp_edgt6.m
new file mode 100644
index 0000000..b0c09c1
--- /dev/null
+++ b/inst/comp/comp_edgt6.m
@@ -0,0 +1,37 @@
+function cout=comp_edgt6(cin,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_edgt6
+%@verbatim
+%COMP_EDGT6   Compute Even DGT type 6
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_edgt6.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M=size(cin,1);
+N=size(cin,2)/2;
+W=size(cin,3);
+
+cout=zeros(M,N,W,assert_classname(cin));
+
+cout=cin(:,1:N,:);
+
+cout=reshape(cout,M*N,W);
+
+
diff --git a/inst/comp/comp_extBoundary.m b/inst/comp/comp_extBoundary.m
new file mode 100644
index 0000000..7d1fedb
--- /dev/null
+++ b/inst/comp/comp_extBoundary.m
@@ -0,0 +1,125 @@
+function fout = comp_extBoundary(f,extLen,ext,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_extBoundary
+%@verbatim
+%EXTENDBOUNDARY Extends collumns
+%    Usage: fout = comp_extBoundary(f,extLen,ext); 
+%           fout = comp_extBoundary(f,extLen,ext,'dim',dim);
+%
+%   Input parameters:
+%         f          : Input collumn vector/matrix
+%         extLen     : Length of extensions
+%         ext        : Type of extensions
+%   Output parameters:
+%         fout       : Extended collumn vector/matrix
+%
+%   Extends input collumn vector or matrix f at top and bottom by 
+%   extLen elements/rows. Extended values are determined from the input
+%   according to the type of extension ext.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_extBoundary.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+ if(ndims(f)>2)
+     error('%s: Multidimensional signals (d>2) are not supported.',upper(mfilename));
+ end
+
+definput.flags.ext = {'per','ppd','perdec','odd','even','sym','asym',...
+                      'symw','asymw','zero','zpd','sp0'};
+definput.keyvals.a = 2;
+definput.keyvals.dim = [];
+[flags,kv,a]=ltfatarghelper({'a'},definput,varargin);
+
+% How slow is this?
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim,upper(mfilename));
+
+
+fout = zeros(size(f,1) + 2*extLen,size(f,2),assert_classname(f));
+fout(extLen+1:end-extLen,:) = f;
+
+legalExtLen = min([size(f,1),extLen]);
+timesExtLen = floor(extLen/size(f,1));
+moduloExtLen = mod(extLen,size(f,1));
+
+% zero padding by default
+% ext: 'per','zpd','sym','symw','asym','asymw','ppd','sp0'
+if(strcmp(ext,'perdec')) % possible last samples replications
+    moda = mod(size(f,1),a);
+    repl = a-moda;
+    if(moda)
+        % version with replicated last sample
+        fout(end-extLen+1:end-extLen+repl,:) = f(end,:);
+        fRepRange = 1+extLen:extLen+length(f)+repl;
+        fRep = fout(fRepRange,:);
+        fRepLen = length(fRepRange);
+        timesExtLen = floor(extLen/fRepLen);
+        moduloExtLen = mod(extLen,fRepLen);
+
+        fout(1+extLen-timesExtLen*fRepLen:extLen,:) = repmat(fRep,timesExtLen,1);
+        fout(1:moduloExtLen,:) = fRep(end-moduloExtLen+1:end,:);
+        
+        timesExtLen = floor((extLen-repl)/fRepLen);
+        moduloExtLen = mod((extLen-repl),fRepLen);
+        fout(end-extLen+repl+1:end-extLen+repl+timesExtLen*fRepLen,:) = repmat(fRep,timesExtLen,1);
+        fout(end-moduloExtLen+1:end,:) = f(1:moduloExtLen,:);
+        
+        %fout(rightStartIdx:end-extLen+timesExtLen*length(f)) = repmat(f(:),timesExtLen,1);
+        %fout(1+extLen-legalExtLen:extLen-repl)= f(end-legalExtLen+1+repl:end);
+    else
+        fout = comp_extBoundary(f,extLen,'per',varargin{:});
+       % fout(1+extLen-legalExtLen:extLen) = f(end-legalExtLen+1:end);
+       % fout(1:extLen-legalExtLen) = f(end-(extLen-legalExtLen)+1:end);
+       % fout(end-extLen+1:end-extLen+legalExtLen) = f(1:legalExtLen);
+    end
+elseif(strcmp(ext,'per') || strcmp(ext,'ppd'))
+       % if ext > length(f)
+       fout(1+extLen-timesExtLen*size(f,1):extLen,:) = repmat(f,timesExtLen,1);
+       fout(end-extLen+1:end-extLen+timesExtLen*size(f,1),:) = repmat(f,timesExtLen,1);
+       %  mod(extLen,length(f)) samples are the rest
+       fout(1:moduloExtLen,:) = f(end-moduloExtLen+1:end,:);
+       fout(end-moduloExtLen+1:end,:) = f(1:moduloExtLen,:);
+elseif(strcmp(ext,'sym')||strcmp(ext,'even'))
+    fout(1+extLen-legalExtLen:extLen,:) = f(legalExtLen:-1:1,:);
+    fout(end-extLen+1:end-extLen+legalExtLen,:) = f(end:-1:end-legalExtLen+1,:);
+elseif(strcmp(ext,'symw'))
+    legalExtLen = min([size(f,1)-1,extLen]);
+    fout(1+extLen-legalExtLen:extLen,:) = f(legalExtLen+1:-1:2,:);
+    fout(end-extLen+1:end-extLen+legalExtLen,:) = f(end-1:-1:end-legalExtLen,:);
+elseif(strcmp(ext,'asym')||strcmp(ext,'odd'))
+    fout(1+extLen-legalExtLen:extLen,:) = -f(legalExtLen:-1:1,:);
+    fout(end-extLen+1:end-extLen+legalExtLen,:) = -f(end:-1:end-legalExtLen+1,:);
+elseif(strcmp(ext,'asymw'))
+    legalExtLen = min([size(f,1)-1,extLen]);
+    fout(1+extLen-legalExtLen:extLen,:) = -f(legalExtLen+1:-1:2,:);
+    fout(end-extLen+1:end-extLen+legalExtLen,:) = -f(end-1:-1:end-legalExtLen,:);
+elseif(strcmp(ext,'sp0'))
+    fout(1:extLen,:) = f(1,:);
+    fout(end-extLen+1:end,:) = f(end,:);
+elseif(strcmp(ext,'zpd')||strcmp(ext,'zero')||strcmp(ext,'valid'))
+    % do nothing
+else
+    error('%s: Unsupported flag.',upper(mfilename));
+end
+
+% Reshape back according to the dim.
+permutedsizeAlt = size(fout);
+fout=assert_sigreshape_post(fout,dim,permutedsizeAlt,order);
diff --git a/inst/comp/comp_fftreal.m b/inst/comp/comp_fftreal.m
new file mode 100644
index 0000000..7b28a11
--- /dev/null
+++ b/inst/comp/comp_fftreal.m
@@ -0,0 +1,35 @@
+function f=comp_fftreal(f)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_fftreal
+%@verbatim
+%COMP_FFTREAL  Compute an FFTREAL
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_fftreal.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+N=size(f,1);
+N2=floor(N/2)+1;
+
+% Force FFT along dimension 1, since we have permuted the dimensions
+% manually
+f=fft(f,N,1);
+f=f(1:N2,:);
+
+
+
diff --git a/inst/comp/comp_filterbank.m b/inst/comp/comp_filterbank.m
new file mode 100644
index 0000000..934fe48
--- /dev/null
+++ b/inst/comp/comp_filterbank.m
@@ -0,0 +1,82 @@
+function c=comp_filterbank(f,g,a);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbank
+%@verbatim
+%COMP_FILTERBANK  Compute filtering
+%
+%   Function groups filters in g according to a presence of .h and .H
+%   fields. If .H is present, it is further decided whether it is a full
+%   frequency response or a band-limited freq. resp.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbank.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+[L,W]=size(f);
+M=numel(g);
+c = cell(M,1);
+
+% Divide filters into time domain and frequency domain groups
+mFreq = 1:M;
+mTime = mFreq(cellfun(@(gEl) isfield(gEl,'h') ,g)>0); 
+mFreq(mTime) = [];
+
+if ~isempty(mTime)
+   % Pick imp. resp.
+   gtime = cellfun(@(gEl) gEl.h, g(mTime),'UniformOutput',0);
+
+   % Call the routine
+   gskip = cellfun(@(gEl) gEl.offset ,g(mTime));
+   c(mTime) = comp_filterbank_td(f,gtime,a(mTime),gskip,'per');
+end
+
+if ~isempty(mFreq)
+   % Filtering in the frequency domain
+   F=fft(f);
+   % Pick frequency domain filters
+   gfreq = g(mFreq);
+   % Divide filters into the full-length and band-limited groups
+   mFreqFullL = 1:numel(gfreq);
+   amFreqCell = mat2cell(a(mFreq,:).',size(a,2),ones(1,numel(mFreq)));
+   mFreqBL = mFreqFullL(cellfun(@(gEl,aEl) numel(gEl.H)~=L || (numel(aEl)>1 && aEl(2) ~=1), gfreq(:),amFreqCell(:))>0);
+   mFreqFullL(mFreqBL) = [];
+   
+   mFreqFullL = mFreq(mFreqFullL);
+   mFreqBL = mFreq(mFreqBL);
+   
+   if ~isempty(mFreqFullL)
+      G = cellfun(@(gEl) gEl.H, g(mFreqFullL),'UniformOutput',0);
+      c(mFreqFullL) = comp_filterbank_fft(F,G,a(mFreqFullL));
+   end
+   
+   if ~isempty(mFreqBL)
+      G = cellfun(@(gEl) gEl.H, g(mFreqBL),'UniformOutput',0);
+      foff = cellfun(@(gEl) gEl.foff, g(mFreqBL));
+      % Cast from logical to double.
+      realonly = cellfun(@(gEl) cast(isfield(gEl,'realonly') && gEl.realonly,'double'), g(mFreqBL));
+      c(mFreqBL) = comp_filterbank_fftbl(F,G,foff,a(mFreqBL,:),realonly);
+   end
+end
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_filterbank_a.m b/inst/comp/comp_filterbank_a.m
new file mode 100644
index 0000000..14f7bc3
--- /dev/null
+++ b/inst/comp/comp_filterbank_a.m
@@ -0,0 +1,76 @@
+function [a,info]=comp_filterbank_a(a,M,info)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbank_a
+%@verbatim
+%COMP_FILTERBANK_A  Return sanitized a
+%   Usage:  [a,info]=comp_filterbank_a(a,M);
+%   
+%   [a,info]=COMP_FILTERBANK_A(a,M) returns a sanitized version of a*
+%   expand to a Mx2 matrix, and update the information in info.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbank_a.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% FIXME: Not sufficiently safe in the case where there is only one
+% channel, or when attempting to specify a uniform filterbank with
+% fractional downsampling.
+%
+
+
+info.isfractional=0;
+info.isuniform=0;
+
+if M==1 && size(a,1)~=1
+   error('%s: One channel, but more a.',upper(mfilename));
+end
+
+if M==1 && size(a,2)<2
+   a = [a,1];
+end
+
+if isvector(a) && M~=1 && size(a,2)<2
+    [a,~]=scalardistribute(a(:),ones(M,1));
+    
+    if all(a==a(1))
+        info.isuniform=1;
+    end;
+
+    a=[a,ones(M,1)];
+else
+    % We need to check against the case where this routine has already
+    % been run
+    if isequal(a(:,2),ones(M,1))
+        if all(a(:,1)==a(1))
+            info.isuniform=1;
+        end;        
+    else
+        info.isfractional=1;
+    end;
+    
+    % If the filterbank uses fractional downsampling, it cannot be
+    % treated by the uniform algorithms, even though the sampling rate is uniform.
+    
+    % FIXME: Fractional, uniform filterbanks are not handled, they are
+    % not allowed.
+
+end;
+
+info.a=a;
+
+
diff --git a/inst/comp/comp_filterbank_fft.m b/inst/comp/comp_filterbank_fft.m
new file mode 100644
index 0000000..0f5d73f
--- /dev/null
+++ b/inst/comp/comp_filterbank_fft.m
@@ -0,0 +1,39 @@
+function c=comp_filterbank_fft(F,G,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbank_fft
+%@verbatim
+%COMP_FILTERBANK_FFT  Compute filtering in FD
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbank_fft.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M = numel(G);
+[L,W] = size(F);
+c = cell(M,1);
+N = L./a;
+
+for m=1:M
+    c{m}=zeros(N(m),W,assert_classname(F,G{m}));
+    for w=1:W
+        c{m}(:,w)=ifft(sum(reshape(F(:,w).*G{m},N(m),a(m)),2))/a(m);
+    end;
+end
+
diff --git a/inst/comp/comp_filterbank_fftbl.m b/inst/comp/comp_filterbank_fftbl.m
new file mode 100644
index 0000000..8d73a80
--- /dev/null
+++ b/inst/comp/comp_filterbank_fftbl.m
@@ -0,0 +1,76 @@
+function c=comp_filterbank_fftbl(F,G,foff,a,realonly)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbank_fftbl
+%@verbatim
+%COMP_FILTERBANK_FFTBL  Compute filtering in FD
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbank_fftbl.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M = numel(G);
+[L,W] = size(F);
+c = cell(M,1);
+if size(a,2)>1
+   afrac=a(:,1)./a(:,2);
+else
+   afrac = a(:,1);
+end
+
+N = L./afrac;
+assert(all(rem(N,1))<1e-6,'%s: Bad output length. \n',upper(mfilename));
+N = round(N);
+
+fsuppRangeSmall = cellfun(@(fEl,GEl) mod([fEl:fEl+numel(GEl)-1].',L)+1 ,num2cell(foff),G,'UniformOutput',0);
+
+
+for m=1:M
+    c{m}=zeros(N(m),W,assert_classname(F,G{m}));
+
+    for w=1:W
+        Ftmp = F(fsuppRangeSmall{m},w).*G{m};
+        postpadL = ceil(max([N(m),numel(G{m})])/N(m))*N(m);
+        Ftmp = postpad(Ftmp,postpadL);
+        
+        Ftmp = sum(reshape(Ftmp,N(m),numel(Ftmp)/N(m)),2);
+        
+        Ftmp = circshift(Ftmp,foff(m));
+        
+        c{m}(:,w)=ifft(Ftmp)/afrac(m);
+    end;
+end
+
+
+% Handle the real only as a separate filter using recursion
+realonlyRange = 1:M;
+realonlyRange = realonlyRange(realonly>0);
+
+if ~isempty(realonlyRange)
+   Gconj = cellfun(@(gEl) conj(gEl(end:-1:1)),G(realonlyRange),'UniformOutput',0);
+   LG = cellfun(@(gEl) numel(gEl),Gconj);
+   foffconj = mod(L-foff(realonlyRange)-LG,L)+1;
+   aconj = a(realonlyRange,:);
+
+   cconj = comp_filterbank_fftbl(F,Gconj,foffconj,aconj,0);
+   for ii=1:numel(cconj)
+      c{realonlyRange(ii)} = (c{realonlyRange(ii)} + cconj{ii})/2;
+   end
+end
+
diff --git a/inst/comp/comp_filterbank_pre.m b/inst/comp/comp_filterbank_pre.m
new file mode 100644
index 0000000..0825fa1
--- /dev/null
+++ b/inst/comp/comp_filterbank_pre.m
@@ -0,0 +1,119 @@
+function g = comp_filterbank_pre(g,a,L,crossover)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbank_pre
+%@verbatim
+%COMP_FILTERBANK_PRE Return sanitized filterbank
+%
+%   The purpose of this function is to evauate all parameters of the
+%   filters, which can be evaluated knowing L.
+%
+%   This function ensures that g will be in the following format:
+%
+%      If g has field .h and it is a vector with length < crossover:
+%         Impulse response is modulated.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbank_pre.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<4
+   crossover = 0; 
+end
+
+M=numel(g);
+
+% Divide filters to time domain and frequency domain groups
+mFreq = 1:M;
+mTime = mFreq(cellfun(@(gEl,aEl) isfield(gEl,'h') && numel(gEl.h)<=crossover,g(:),num2cell(a(:,1)))>0); 
+mFreq(mTime) = [];
+
+% Prepare time-domain filters
+for mId=1:numel(mTime)
+   m = mTime(mId);
+   
+   % Handle .fc parameter
+   if isfield(g{m},'fc') && g{m}.fc~=0
+      l = (g{m}.offset:g{m}.offset+numel(g{m}.h)-1).'/L;
+      g{m}.h = g{m}.h.*exp(2*pi*1i*round(g{m}.fc*L/2)*l);
+      g{m}.fc = 0;
+   end
+
+   if isfield(g{m},'realonly') && g{m}.realonly
+      g{m}.h = real(g{m}.h);
+      g{m}.realonly = 0;
+   end
+   
+   % Do zero padding when the offset is big enough so the initial imp. resp.
+   % support no longer intersects with zero
+   if g{m}.offset > 0
+      g{m}.h = [zeros(g{m}.offset,1);g{m}.h(:)];
+      g{m}.offset = 0;
+   end
+   
+   if g{m}.offset < -(numel(g{m}.h)-1)
+      g{m}.h = [g{m}.h(:);zeros(-g{m}.offset-numel(g{m}.h)+1,1)];
+      g{m}.offset = -(numel(g{m}.h)-1);
+   end
+   
+end
+
+% Prepare frequency-domain filters
+%l=(0:L-1).'/L;
+for m=mFreq
+
+    if isfield(g{m},'h')
+       g{m}.H=comp_transferfunction(g{m},L);
+       g{m}=rmfield(g{m},'h');
+       g{m}=rmfield(g{m},'offset');
+       if isfield(g{m},'fc'), g{m}=rmfield(g{m},'fc'); end;
+       % The following parameters have to be set to zeros, because they
+       % have already been incorporated in the freq. resp. calculation.
+       g{m}.foff = 0;
+    elseif isfield(g{m},'H') && ~isnumeric(g{m}.H)
+       g{m}.H=g{m}.H(L);
+       g{m}.foff=g{m}.foff(L);
+    end
+    
+    if isfield(g{m},'H') && isfield(g{m},'delay') && g{m}.delay~=0
+       % handle .delay parameter
+       lrange = mod(g{m}.foff:g{m}.foff+numel(g{m}.H)-1,L).'/L;
+       g{m}.H=g{m}.H.*exp(-2*pi*1i*round(g{m}.delay)*lrange); 
+       g{m}.delay = 0;
+    end
+
+    % Treat full-length .H
+    if numel(g{m}.H)==L
+       if isfield(g{m},'foff') && g{m}.foff~=0 
+          % handle .foff parameter for full-length freq. resp.
+          g{m}.H = circshift(g{m}.H,g{m}.foff);
+          % to avoid any other moving
+          g{m}.foff = 0;
+       end
+
+       if isfield(g{m},'realonly') && g{m}.realonly
+          % handle .realonly parameter for full-length freq. resp.
+          g{m}.H=(g{m}.H+involute(g{m}.H))/2;
+          g{m}.realonly = 0;
+       end;
+    end
+end;
+
+
+
+
+
diff --git a/inst/comp/comp_filterbank_td.m b/inst/comp/comp_filterbank_td.m
new file mode 100644
index 0000000..4a52acf
--- /dev/null
+++ b/inst/comp/comp_filterbank_td.m
@@ -0,0 +1,88 @@
+function c=comp_filterbank_td(f,g,a,offset,ext)  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbank_td
+%@verbatim
+%COMP_FILTERBANK_TD   Non-uniform filterbank by conv2
+%   Usage:  c=comp_filterbank_td(f,g,a,skip,ext);
+%
+%   Input parameters:
+%         f     : Input data - L*W array.
+%         g     : Filterbank filters - length M cell-array of vectors of lengths filtLen(m).
+%         a     : Subsampling factors - array of length M.
+%         offset: Offset of the filters - scalar or array of length M. 
+%         ext   : Border exension technique.
+%
+%   Output parameters:
+%         c  : Cell array of length M. Each element is N(m)*W array.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbank_td.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%input data length
+L=size(f,1);
+%input channel number
+W=size(f,2);
+%filter number
+M=numel(g);
+%filter lengths
+filtLen = cellfun(@(x) numel(x),g(:));
+skip = -offset;
+% Allow filter delay only in the filter support range
+if any(skip(:)>=filtLen) || any(skip<0)
+  error('%s: The filter zero index position outside of the filter support.', upper(mfilename));  
+end
+
+
+% Determine output lengths
+% Lext -- length of the signal after convolution before subsampling
+% N -- after subsampling
+if strcmp(ext,'per')
+   Lext = L;
+   N = ceil(Lext./a);
+elseif strcmp(ext,'valid')
+   Lext = L-(filtLen-1);
+   N = ceil(Lext./a);
+else
+   Lext = (L+filtLen-1);
+   N = ceil((Lext-skip)./a); 
+end
+N = N(:);
+Lreq = a(:).*(N-1) + 1;
+
+% Output cell allocation
+c=cell(M,1);
+
+% for m=1:M
+%   c{m}=zeros(N(m),W,assert_classname(f));
+% end;
+
+% Explicitly extend the input. length(fext) = length(f) + 2*(filtLen-1)
+% CONV2 with 'valid' does 2-D linear convolution and crops (filtLen-1) samples from both ends.  
+% length(fextconv2) = length(f) + (filtLen-1)
+% length(c{m}) = N(m)
+% W channels are done simultaneously
+for m=1:M
+   fext = comp_extBoundary(f,filtLen(m)-1,ext,'dim',1);
+   c{m} = comp_downs(conv2(fext,g{m}(:),'valid'),a(m),skip(m),Lreq(m)); 
+end
+
+
+ 
+
+
diff --git a/inst/comp/comp_filterbankresponse.m b/inst/comp/comp_filterbankresponse.m
new file mode 100644
index 0000000..73cfd28
--- /dev/null
+++ b/inst/comp/comp_filterbankresponse.m
@@ -0,0 +1,54 @@
+function gf=comp_filterbankresponse(g,a,L,do_real)
+
+M=numel(g);
+
+if size(a,2)>1
+    % G1 is done this way just so that we can determine the data type.
+    G1=comp_transferfunction(g{1},L);
+    gf=abs(G1).^2*(L/a(1,1)*a(1,2));    
+    
+    for m=2:M
+        gf=gf+abs(comp_transferfunction(g{m},L)).^2*(L/a(m,1)*a(m,2));
+    end;
+    
+else
+    % G1 is done this way just so that we can determine the data type.
+    G1=comp_transferfunction(g{1},L);
+    gf=abs(G1).^2*(L/a(1));    
+    
+    for m=2:M
+        gf=gf+abs(comp_transferfunction(g{m},L)).^2*(L/a(m));
+    end;
+    
+end;
+    
+if do_real
+    gf=gf+involute(gf);   
+end;
+
+gf=gf/L;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_filterbankresponse
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_filterbankresponse.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/comp_fourierwindow.m b/inst/comp/comp_fourierwindow.m
new file mode 100644
index 0000000..d793d7d
--- /dev/null
+++ b/inst/comp/comp_fourierwindow.m
@@ -0,0 +1,142 @@
+function [g,info] = comp_fourierwindow(g,L,callfun);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_fourierwindow
+%@verbatim
+%COMP_FOURIERWINDOW  Compute the window from numeric, text or cell array.
+%   Usage: [g,info] = comp_fourierwindow(g,a,M,L,wilson,callfun);
+%
+%   [g,info]=COMP_FOURIERWINDOW(g,L,callfun) will compute the window
+%   from a text description or a cell array containing additional
+%   parameters.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_fourierwindow.php}
+%@seealso{gabwin, wilwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+% Basic discovery: Some windows depend on L, and some windows help define
+% L, so the calculation of L is window dependant.
+  
+% Default values.
+info.gauss=0;
+info.isfir=0;
+
+% Manually get the list of window names
+definput=arg_firwin(struct);
+firwinnames =  definput.flags.wintype;
+
+% Create window if string was given as input.
+if ischar(g)
+  winname=lower(g);
+  switch(winname)
+   case {'pgauss','gauss'}
+    complain_L(L,callfun);
+    g=comp_pgauss(L,1,0,0);
+    info.gauss=1;
+    info.tfr=1;
+   case {'psech','sech'}
+    complain_L(L,callfun);
+    g=psech(L,1);
+    info.tfr=1;
+   otherwise
+    error('%s: Unknown window type: %s',callfun,winname);
+  end;
+end;
+
+if iscell(g)
+  if isempty(g) || ~ischar(g{1})
+    error('First element of window cell array must be a character string.');
+  end;
+  
+  winname=lower(g{1});
+  
+  switch(winname)
+   case {'pgauss','gauss'}
+    complain_L(L,callfun);
+    [g,info.tfr]=pgauss(L,g{2:end});
+    info.gauss=1;
+   case {'psech','sech'}
+    complain_L(L,callfun);
+    [g,info.tfr]=psech(L,g{2:end});    
+   case firwinnames
+    g=firwin(winname,g{2:end});
+    info.isfir=1;
+   otherwise
+    error('Unsupported window type.');
+  end;
+end;
+
+if isnumeric(g)
+  if size(g,2)>1
+    if size(g,1)>1
+      error('g must be a vector');
+    else
+      % g was a row vector.
+      g=g(:);
+    end;
+  end;
+  g_time=g;
+  g=struct();
+  g.h=fftshift(g_time);
+  info.gl=numel(g_time);
+  g.offset=-floor(info.gl/2);  
+  g.fc=0;
+  g.realonly=0;
+  info.wasreal=isreal(g.h);
+else
+
+    if isstruct(g)
+        if isfield(g,'h')
+            info.wasreal=isreal(g.h);
+            info.gl=length(g.h);
+            info.isfir=1;
+        else
+            info.wasreal=g.realonly;
+            info.gl=[];
+            
+            if ~isempty(L)
+                if ~isnumeric(g.H)
+                    g.H=g.H(L);
+                    g.foff=g.foff(L);
+                end;
+            end;
+        end;
+    else
+        % Information to be determined post creation.
+        info.wasreal = isreal(g);
+        info.gl      = length(g);
+        
+        if (~isempty(L) && (info.gl<L))
+            info.isfir=1;
+        end;
+            
+    end;
+    
+end;
+    
+function complain_L(L,callfun)
+  
+  if isempty(L)
+    error(['%s: You must specify a length L if a window is represented as a ' ...
+           'text string or cell array.'],callfun);
+  end;
+
+
+
diff --git a/inst/comp/comp_framelength_fusion.m b/inst/comp/comp_framelength_fusion.m
new file mode 100644
index 0000000..594785a
--- /dev/null
+++ b/inst/comp/comp_framelength_fusion.m
@@ -0,0 +1,39 @@
+function L=comp_framelength_fusion(F,Ls);
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_framelength_fusion
+%@verbatim
+% This is highly tricky: Get the minimal transform length for each
+% subframe, and set the length as the lcm of that.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_framelength_fusion.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+Lsmallest=1;
+for ii=1:F.Nframes
+    Lsmallest=lcm(Lsmallest,framelength(F.frames{ii},1));
+end;
+L=ceil(Ls/Lsmallest)*Lsmallest;
+
+% Verify that we did not screw up the assumptions.
+for ii=1:F.Nframes
+    if L~=framelength(F.frames{ii},L)
+        error(['%s: Cannot determine a frame length. Frame no. %i does ' ...
+               'not support a length of L=%i.'],upper(mfilename),ii,L);
+    end;
+end;
diff --git a/inst/comp/comp_framelength_tensor.m b/inst/comp/comp_framelength_tensor.m
new file mode 100644
index 0000000..681c881
--- /dev/null
+++ b/inst/comp/comp_framelength_tensor.m
@@ -0,0 +1,27 @@
+function L=comp_framelength_tensor(F,Ls);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_framelength_tensor
+%@verbatim
+%COMP_FRAMELENGTH_TENSOR  Helper function for the Tensor frame
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_framelength_tensor.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+error(['For the tensor product frame, call framelength for the ', ...
+       'individual subframes']);
diff --git a/inst/comp/comp_frana_fusion.m b/inst/comp/comp_frana_fusion.m
new file mode 100644
index 0000000..9d4ff83
--- /dev/null
+++ b/inst/comp/comp_frana_fusion.m
@@ -0,0 +1,35 @@
+function outsig=comp_frana_fusion(F,insig)
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_frana_fusion
+%@verbatim
+% All frames must use the same length signal.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_frana_fusion.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+L=F.length(size(insig,1));
+insig=postpad(insig,L);
+
+coefs = cell(F.Nframes,1);
+for ii=1:F.Nframes
+    coefs(ii)={F.w(ii)*frana(F.frames{ii},insig)};
+end;
+outsig=cell2mat(coefs);
+
+
diff --git a/inst/comp/comp_frana_tensor.m b/inst/comp/comp_frana_tensor.m
new file mode 100644
index 0000000..fe87344
--- /dev/null
+++ b/inst/comp/comp_frana_tensor.m
@@ -0,0 +1,33 @@
+outsig = comp_frana_tensor(F,insig)
+
+outsig=frsyn(F.frames{1},insig);
+perm=circshift((1:F.Nframes).',-1);
+for ii=2:F.Nframes
+    outsig=permute(outsig,perm);
+    outsig=frsyn(F.frames{ii},outsig);
+end;
+outsig=permute(outsig,perm);
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_frana_tensor
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_frana_tensor.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/comp_frsyn_fusion.m b/inst/comp/comp_frsyn_fusion.m
new file mode 100644
index 0000000..fb4075d
--- /dev/null
+++ b/inst/comp/comp_frsyn_fusion.m
@@ -0,0 +1,37 @@
+function outsig=comp_frsyn_fusion(F,insig)
+
+W=size(insig,2);
+L=size(insig,1)/framered(F);
+
+outsig=zeros(L,W);
+
+idx=0;    
+for ii=1:F.Nframes
+    coeflen=L*framered(F.frames{ii});
+    outsig=outsig+frsyn(F.frames{ii},insig(idx+1:idx+coeflen,:))*F.w(ii);
+    idx=idx+coeflen;
+end;
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_frsyn_fusion
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_frsyn_fusion.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/comp_frsyn_tensor.m b/inst/comp/comp_frsyn_tensor.m
new file mode 100644
index 0000000..94d5248
--- /dev/null
+++ b/inst/comp/comp_frsyn_tensor.m
@@ -0,0 +1,33 @@
+function outsig=comp_frsyn_tensor(F,insig)
+
+outsig=frsyn(F.frames{1},insig);
+perm=circshift((1:F.Nframes).',-1);
+for ii=2:F.Nframes
+    outsig=permute(outsig,perm);
+    outsig=frsyn(F.frames{ii},outsig);
+end;
+outsig=permute(outsig,perm);
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_frsyn_tensor
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_frsyn_tensor.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/comp_fwt.m b/inst/comp/comp_fwt.m
new file mode 100644
index 0000000..0eb6085
--- /dev/null
+++ b/inst/comp/comp_fwt.m
@@ -0,0 +1,85 @@
+function c = comp_fwt(f,h,J,a,ext)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_fwt
+%@verbatim
+%COMP_FWT Compute DWT using FWT
+%   Usage:  c=comp_fwt(f,h,J,a,Lc,ext);
+%
+%   Input parameters:
+%         f     : Input data - L*W array.
+%         h     : Analysis Wavelet filters - cell-array of length filtNo.
+%         J     : Number of filterbank iterations.
+%         a     : Subsampling factors - array of length filtNo. 
+%         ext   : 'per','zero','even','odd' Type of the forward transform boundary handling.
+%
+%   Output parameters:
+%         c     : Cell array of length M. Each element is Lc(m)*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_fwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% This could be removed with some effort. The question is, are there such
+% wavelet filters? If your filterbank has different subsampling factors following the first two filters, please send a feature request.
+assert(a(1)==a(2),'First two elements of *a* are not equal. Such wavelet filterbank is not suported.');
+
+% Time-reversed, complex conjugate impulse responses.
+filtNo = length(h);
+hCell = cellfun(@(hEl) conj(flipud(hEl.h(:))),h,'UniformOutput',0);
+
+if(strcmp(ext,'per'))
+   % Initial shift of the filter to compensate for it's delay.
+   % "Zero" delay transform is produced
+   offset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,h); 
+elseif strcmp(ext,'valid')
+   offset = -cellfun(@(hEl) numel(hEl.h)-1,h);
+else
+   % No compensation for the filter delay (filters are made causal with respect to the output sequences).
+   % This creates relative shift between levels of coefficients.
+   % Initial shift determines type of subsampling. 
+   % This is even subsampling. e.g. subs. [1,2,3,4,5,6] by a factor 3 becomes [3,6]
+   % The number of output coefficients depends on it.
+   offset = -(a-1);
+   % For odd subsampling skip = 0; but it requires slight touches
+   % elsewhere.
+end
+
+M = (filtNo-1)*J+1;
+c = cell(M,1);
+runPtr = M-filtNo+2;
+ctmp = f;
+for jj=1:J
+    % Run filterbank
+    ctmp = comp_filterbank_td(ctmp,hCell,a,offset,ext);
+    % Bookkeeping
+    c(runPtr:runPtr+filtNo-2) = ctmp(2:end);
+    ctmp = ctmp{1};
+    runPtr = runPtr - (filtNo - 1);
+end
+% Save final approximation coefficients
+c{1} = ctmp;
+
+
+
+
+       
+
+
+
+
diff --git a/inst/comp/comp_gabdual_long.m b/inst/comp/comp_gabdual_long.m
new file mode 100644
index 0000000..8651e2c
--- /dev/null
+++ b/inst/comp/comp_gabdual_long.m
@@ -0,0 +1,65 @@
+function gd=comp_gabdual_long(g,a,M);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gabdual_long
+%@verbatim
+%COMP_GABDUAL_LONG  Compute dual window
+%
+%  This is a computational subroutine, do not call it directly, use
+%  GABDUAL instead.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gabdual_long.php}
+%@seealso{gabdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+L=length(g);
+R=size(g,2);
+
+gf=comp_wfac(g,a,M);
+
+b=L/M;
+N=L/a;
+
+c=gcd(a,M);
+d=gcd(b,N);
+  
+p=b/d;
+q=N/d;
+
+gdf=zeros(p*q*R,c*d,assert_classname(g));
+
+G=zeros(p,q*R,assert_classname(g));
+for ii=1:c*d
+  % This essentially computes pinv of each block.
+
+  G(:)=gf(:,ii);
+  S=G*G';
+  Gpinv=(S\G);
+
+  gdf(:,ii)=Gpinv(:);
+end;
+
+gd=comp_iwfac(gdf,L,a,M);
+
+if isreal(g)
+  gd=real(gd);
+end;
+
+
+
diff --git a/inst/comp/comp_gabmixdual_fac.m b/inst/comp/comp_gabmixdual_fac.m
new file mode 100644
index 0000000..9db6fa2
--- /dev/null
+++ b/inst/comp/comp_gabmixdual_fac.m
@@ -0,0 +1,75 @@
+function gammaf=comp_gabmixdual_fac(gf1,gf2,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gabmixdual_fac
+%@verbatim
+%COMP_GABMIXDUAL_FAC  Computes factorization of mix-dual.
+%   Usage:  gammaf=comp_gabmixdual_fac(gf1,gf2,a,M)
+%
+%   Input parameters:
+%      gf1    : Factorization of first window
+%      gf2    : Factorization of second window
+%      L      : Length of window.
+%      a      : Length of time shift.
+%      M      : Number of channels.
+%
+%   Output parameters:
+%      gammaf : Factorization of mix-dual
+%
+%   GAMMAF is a factorization of a dual window of gf1
+%
+%   This function does not verify input parameters, call
+%   GABMIXDUAL instead
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gabmixdual_fac.php}
+%@seealso{gabmixdual, comp_fac, compute_ifac}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+LR=prod(size(gf1));
+R=LR/L;
+
+b=L/M;
+N=L/a;
+
+c=gcd(a,M);
+d=gcd(b,N);
+  
+p=b/d;
+q=N/d;
+
+gammaf=zeros(p*q*R,c*d,assert_classname(gf1,gf2));
+
+G1=zeros(p,q*R,assert_classname(gf1,gf2));
+G2=zeros(p,q*R,assert_classname(gf1,gf2));
+for ii=1:c*d
+
+  G1(:)=gf1(:,ii);
+  G2(:)=gf2(:,ii);
+  S=G2*G1';
+  Gpinv=M*S\G2;
+
+  gammaf(:,ii)=Gpinv(:);
+end;
+
+
+
diff --git a/inst/comp/comp_gabreassign.m b/inst/comp/comp_gabreassign.m
new file mode 100644
index 0000000..d5ec10d
--- /dev/null
+++ b/inst/comp/comp_gabreassign.m
@@ -0,0 +1,75 @@
+function sr=comp_gabreassign(s,tgrad,fgrad,a);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gabreassign
+%@verbatim
+%COMP_GABREASSIGN  Reassign time-frequency distribution.
+%   Usage:  sr = comp_gabreassign(s,tgrad,fgrad,a);
+%
+%   COMP_GABREASSIGN(s,tgrad,fgrad,a) will reassign the values of the positive
+%   time-frequency distribution s using the instantaneous time and frequency
+%   fgrad and ifdummy. The lattice is determined by the time shift a and
+%   the number of channels deduced from the size of s.
+%
+%
+%   References:
+%     F. Auger and P. Flandrin. Improving the readability of time-frequency
+%     and time-scale representations by the reassignment method. IEEE Trans.
+%     Signal Process., 43(5):1068-1089, 1995.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gabreassign.php}
+%@seealso{gabreassign}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+[M,N,W]=size(s);
+L=N*a;
+b=L/M;
+
+freqpos=fftindex(M);  
+tgrad=bsxfun(@plus,tgrad/b,freqpos);
+
+timepos=fftindex(N);
+fgrad=bsxfun(@plus,fgrad/a,timepos.');
+
+tgrad=round(tgrad);
+fgrad=round(fgrad);
+
+tgrad=mod(tgrad,M);
+fgrad=mod(fgrad,N);  
+  
+sr=zeros(M,N,W,assert_classname(s,tgrad,fgrad));
+
+fgrad=fgrad+1;
+tgrad=tgrad+1;
+
+for w=1:W
+    for ii=1:M
+        for jj=1:N      
+            sr(tgrad(ii,jj),fgrad(ii,jj),w) = sr(tgrad(ii,jj),fgrad(ii,jj),w)+s(ii,jj,w);
+        end;
+    end;  
+end;
+
+
+
+
diff --git a/inst/comp/comp_gabtight_long.m b/inst/comp/comp_gabtight_long.m
new file mode 100644
index 0000000..b712764
--- /dev/null
+++ b/inst/comp/comp_gabtight_long.m
@@ -0,0 +1,75 @@
+function gt=comp_gabtight_long(g,a,M);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gabtight_long
+%@verbatim
+%COMP_GABTIGHT_LONG  Compute tight window
+%
+%  This is a computational subroutine, do not call it directly, use
+%  GABTIGHT instead.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gabtight_long.php}
+%@seealso{gabtight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+L=length(g);
+R=size(g,2);
+
+gf=comp_wfac(g,a,M);
+
+b=L/M;
+N=L/a;
+
+c=gcd(a,M);
+d=gcd(b,N);
+  
+p=b/d;
+q=N/d;
+
+G=zeros(p,q*R,assert_classname(g));
+
+
+
+if p==1
+  % Integer oversampling, including Wilson basis.
+  for ii=1:c*d
+    gf(:,ii)=gf(:,ii)/norm(gf(:,ii));
+  end;
+else
+  for ii=1:c*d
+    
+    G(:)=gf(:,ii);
+    
+    % Compute thin SVD
+    [U,sv,V] = svd(G,'econ');
+    
+    Gtight=U*V';  
+    
+    gf(:,ii)=Gtight(:);
+  end;
+end;
+
+gt=comp_iwfac(gf,L,a,M);
+
+if isreal(g)
+  gt=real(gt);
+end;
+
+
+
diff --git a/inst/comp/comp_gdgt.m b/inst/comp/comp_gdgt.m
new file mode 100644
index 0000000..4c245dc
--- /dev/null
+++ b/inst/comp/comp_gdgt.m
@@ -0,0 +1,76 @@
+function [c,Ls]=comp_gdgt(f,g,a,M,L,c_t,c_f,c_w,timeinv)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gdgt
+%@verbatim
+%COMP_GDGT  Compute generalized DGT
+%   Usage:  c=comp_gdgt(f,g,a,M,L,c_t,c_f,c_w,timeinv);
+%
+%   Input parameters:
+%         f       : Input data
+%         g       : Window function.
+%         a       : Length of time shift.
+%         M       : Number of modulations.
+%         L       : Length of transform to do.
+%         c_t     : Centering in time of modulation.
+%         c_f     : Centering in frequency of modulation.
+%         c_w     : Centering in time of window.
+%         timeinv : Should we compute a time invariant Gabor system.
+%   Output parameters:
+%         c       : M*N array of coefficients.
+%         Ls      : Length of input signal.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gdgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+Lwindow=size(g,1);
+
+W=size(f,2);
+N=L/a;
+
+% Preprocess to handle c_f different from 0.
+if (c_f~=0)
+  halfmod=exp(-2*pi*i*c_f*(0:L-1).'/M);
+  f=f.*repmat(halfmod,1,W);
+end;
+
+c=comp_dgt(f,g,a,M,L,0);
+
+if timeinv
+  c=phaselock(c,a);
+end;
+
+% Post-process if c_t is different from 0.
+if (c_t~=0)
+
+  % The following is necessary because REPMAT does not work for
+  % 3D arrays.
+  halfmod=reshape(repmat(exp(-2*pi*i*c_t*((0:M-1)+c_f).'/M),1,N*W),M,N,W);
+  
+  c=c.*halfmod;
+end;
+
+c=reshape(c,M,N,W);
+
+
+
+
+
diff --git a/inst/comp/comp_gfeigs.m b/inst/comp/comp_gfeigs.m
new file mode 100644
index 0000000..6013792
--- /dev/null
+++ b/inst/comp/comp_gfeigs.m
@@ -0,0 +1,81 @@
+function lambdas=comp_gfeigs(gf,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gfeigs
+%@verbatim
+%COMP_GFEIGS_SEP
+%   Usage:  lambdas=comp_gfeigs(gf,a,M);
+%
+%   Compute Eigenvalues of a Gabor frame operator in
+%   the separable case.
+%
+%   This is a computational routine, do not call it directly.
+%
+%   See help on GFBOUNDS
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gfeigs.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+LR=prod(size(gf));
+R=LR/L;
+
+b=L/M;
+N=L/a;
+
+c=gcd(a,M);
+d=gcd(b,N);
+p=b/d;
+q=N/d;
+
+% Initialize eigenvalues
+AF=Inf;
+BF=0;
+
+% Holds subsubmatrix.
+C=zeros(p,q*R,assert_classname(gf));
+
+lambdas=zeros(p,c*d,assert_classname(gf));
+
+% Iterate through all the subsubmatrices.
+for k=0:c*d-1
+  % Extract p x q*R matrix of array.
+  C(:)=gf(:,k+1);
+  
+  % Get eigenvalues of 'squared' subsubmatrix.
+  lambdas(:,1+k)=eig(C*C');
+    
+end;
+
+% Clean eigenvalues, they are real, and
+% scale them correctly.
+lambdas=real(lambdas);
+
+% Reshape and sort.
+lambdas=sort(lambdas(:));
+
+
+
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_gga.m b/inst/comp/comp_gga.m
new file mode 100644
index 0000000..dfe7326
--- /dev/null
+++ b/inst/comp/comp_gga.m
@@ -0,0 +1,65 @@
+function c = comp_gga(f,indvec)
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} comp_gga
+%@verbatim
+%% Initialization
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_gga.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+L = size(f,1);
+W = size(f,2);
+no_freq = length(indvec); %number of frequencies to compute
+classname = assert_classname(f);
+c = zeros(no_freq,W,classname); %memory allocation for the output coefficients
+
+%% Computation via second-order system
+% loop over the particular frequencies
+
+for cnt_freq = 1:no_freq
+    
+    %for a single frequency:
+    %a/ precompute the constants
+    pik_term = 2*pi*(indvec(cnt_freq))/(L);
+    cos_pik_term2 = cos(pik_term) * 2;
+    cc = exp(-1i*pik_term); % complex constant
+    for w=1:W
+    %b/ state variables
+       s0 = 0; 
+       s1 = 0;
+       s2 = 0;
+       %c/ 'main' loop
+       for ind = 1:L-1 %number of iterations is (by one) less than the length of signal
+          %new state
+          s0 = f(ind,w) + cos_pik_term2 * s1 - s2;  % (*)
+          %shifting the state variables
+          s2 = s1;
+          s1 = s0;
+       end
+       %d/ final computations
+       s0 = f(L,w) + cos_pik_term2 * s1 - s2; %correspond to one extra performing of (*)
+       c(cnt_freq,w) = s0 - s1*cc; %resultant complex coefficient
+    
+       %complex multiplication substituting the last iteration
+       %and correcting the phase for (potentially) non-integer valued
+       %frequencies at the same time
+       c(cnt_freq,w) = c(cnt_freq,w) * exp(-1i*pik_term*(L-1));
+    end
+end
diff --git a/inst/comp/comp_hermite.m b/inst/comp/comp_hermite.m
new file mode 100644
index 0000000..d18868b
--- /dev/null
+++ b/inst/comp/comp_hermite.m
@@ -0,0 +1,68 @@
+function y = comp_hermite(n, x);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_hermite
+%@verbatim
+%COMP_HERMITE   Compute sampling of continuous Hermite function.
+%   Usage:  y = comp_hermite(n, x);
+%
+%   COMP_HERMITE(n, x) evaluates the n-th Hermite function at the vector x.
+%   The function is normalized to have the L^2(-inf,inf) norm equal to one.
+%
+%   A minimal effort is made to avoid underflow in recursion.
+%   If used to evaluate the Hermite quadratures, it works for n <= 2400
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_hermite.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR:
+%   T. Hrycak, Oct 5, 2005
+%   Last modified July 17, 2007
+
+
+rt = 1 / sqrt(sqrt(pi));
+
+if n == 0
+  y = rt * exp(-0.5 * x.^2);
+end
+if n == 1
+  y = rt * sqrt(2) * x .* exp(-0.5 * x.^2);
+end
+
+%     
+%     if n > 2, conducting the recursion.
+%
+
+if n >= 2
+  ef = exp(-0.5 * (x.^2) / (n+1));
+  tmp1 = rt * ef;
+  tmp2 = rt * sqrt(2) * x .* (ef.^2);
+  for k = 2:n
+    y = sqrt(2)*x.*tmp2 - sqrt(k-1)*tmp1 .* ef;
+    y = ef .* y / sqrt(k);
+    tmp1 = tmp2;
+    tmp2 = y;
+  end
+end
+  
+
+
+
+
+
diff --git a/inst/comp/comp_hermite_all.m b/inst/comp/comp_hermite_all.m
new file mode 100644
index 0000000..bb55ccb
--- /dev/null
+++ b/inst/comp/comp_hermite_all.m
@@ -0,0 +1,66 @@
+function y = comp_hermite_all(n, x)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_hermite_all
+%@verbatim
+%COMP_HERMITE_ALL  Compute all Hermite functions up to an order
+%   Usage:  y = hermite_fun_all(n, x);
+%
+%   This function evaluates the Hermite functions
+%   of degree 0 through n-1 at the vector x.
+%   The functions are normalized to have the L^2 norm
+%   on (-inf,inf) equal to one. No effort is made to 
+%   avoid unerflow during recursion.	
+%   
+%   Input parameters: 
+%     n     : the number of Hermite functions
+%     x     : the vector of arguments
+%
+%   Output parameters:
+%     y     : the values of the first n Hermite functions at 
+%             the nodes x
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_hermite_all.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%   T. Hrycak, Mar. 22, 2006
+%   Last modified   July 17, 2007
+%
+%
+%       
+
+rt = 1 / sqrt(sqrt(pi));
+
+%     
+%     conducting the recursion.
+%
+
+y = zeros(length(x), n);
+
+y(:, 1) = rt * exp(-0.5 * x.^2);
+if n > 1
+   y(:, 2) = rt * sqrt(2) * x .* exp(-0.5 * x.^2);
+end
+for k = 2:n-1
+        y(:, k+1) = sqrt(2)*x.*y(:, k) - sqrt(k-1)*y(:, k-1);
+        y(:, k+1) = y(:, k+1)/sqrt(k);
+end
+
+
+
diff --git a/inst/comp/comp_iatrousfilterbank_td.m b/inst/comp/comp_iatrousfilterbank_td.m
new file mode 100644
index 0000000..2ce3fe0
--- /dev/null
+++ b/inst/comp/comp_iatrousfilterbank_td.m
@@ -0,0 +1,70 @@
+function f=comp_iatrousfilterbank_td(c,g,a,offset)  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iatrousfilterbank_td
+%@verbatim
+%COMP_IATROUSFILTERBANK_TD   Synthesis Uniform filterbank by conv2
+%   Usage:  f=comp_iatrousfilterbank_td(c,g,a,skip);
+%
+%   Input parameters:
+%         c    : L*M*W array of coefficients.
+%         g    : Filterbank filters - filtLen*M array. 
+%         a    : Filters upsampling factor - scalar.
+%         skip : Delay of the filters - scalar or array of length M.
+%
+%   Output parameters:
+%         f  : Output L*W array. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iatrousfilterbank_td.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%input channel number
+W=size(c,3);
+%filter number
+M=size(g,2);
+g = comp_ups(g,a,1);
+%length of filters
+filtLen = size(g,1);
+L=size(c,1);
+skip = -offset;
+% Allow filter delay only in the filter support range
+if(all(skip>=filtLen) || all(skip<0))
+  error('%s: The filter zero index position outside of the filter support.', upper(mfilename));  
+end
+
+if(numel(skip)==1)
+    skip = skip*ones(M,1);
+end
+
+% Output memory allocation
+f=zeros(L,W,assert_classname(c,g));
+
+skipOut = (filtLen-1)+skip;
+
+% W channels are done simultaneously
+for m=1:M
+   cext = comp_extBoundary(squeeze(c(:,m,:)),filtLen-1,'per','dim',1); 
+   ftmp = conv2(g(:,m),cext);
+   f = f + ftmp(1+skipOut(m):L+skipOut(m),:); 
+end
+
+
+ 
+
+
diff --git a/inst/comp/comp_idgt.m b/inst/comp/comp_idgt.m
new file mode 100644
index 0000000..d1b5fc5
--- /dev/null
+++ b/inst/comp/comp_idgt.m
@@ -0,0 +1,95 @@
+function f=comp_idgt(coef,g,a,lt,phasetype,algns)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgt
+%@verbatim
+%COMP_IDGT  Compute IDGT
+%   Usage:  f=comp_idgt(c,g,a,lt,phasetype);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         lt    : Lattice type
+%         phasetype : Type of phase
+%   Output parameters:
+%         f     : Signal.
+%
+%   Value of the algorithm chooser
+%
+%      algns=0 : Choose the fastest algorithm
+%
+%      algns=0 : Always choose multi-win
+%
+%      algns=1 : Always choose shear
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR : Peter L. Soendergaard.
+
+M=size(coef,1);
+N=size(coef,2);
+W=size(coef,3);
+
+L=N*a;
+
+% FIXME : Calls non-comp function 
+if phasetype==1
+    coef=phaseunlock(coef,a,'lt',lt);
+end;
+
+if lt(2)==1
+    f = comp_isepdgt(coef,g,L,a,M); 
+
+    
+else
+    
+    if (algns==1) || (algns==0 && lt(2)<=2) 
+        
+        % ----- algorithm starts here, split into sub-lattices ---------------
+        
+        mwin=comp_nonsepwin2multi(g,a,M,lt,L);
+        
+        % phase factor correction (backwards), for more information see 
+        % analysis routine
+        
+        E = exp(2*pi*i*a*kron(0:N/lt(2)-1,ones(1,lt(2))).*...
+                rem(kron(ones(1,N/lt(2)), 0:lt(2)-1)*lt(1),lt(2))/M);
+
+        coef=bsxfun(@times,coef,E);
+        
+        % simple algorithm: split into sublattices and add the result from each
+        % sublattice.
+        f=zeros(L,W,assert_classname(coef,g));
+        for ii=0:lt(2)-1
+            % Extract sublattice
+            sub=coef(:,ii+1:lt(2):end,:);
+            f=f+comp_idgt(sub,mwin(:,ii+1),lt(2)*a,[0 1],0,0);  
+        end;
+
+    else
+
+        g=fir2long(g,L);
+      
+        [s0,s1,br] = shearfind(L,a,M,lt);
+        
+        f=comp_inonsepdgt_shear(coef,g,a,s0,s1,br);
+    end;
+
+end;    
diff --git a/inst/comp/comp_idgt_fac.m b/inst/comp/comp_idgt_fac.m
new file mode 100644
index 0000000..96ba2b4
--- /dev/null
+++ b/inst/comp/comp_idgt_fac.m
@@ -0,0 +1,168 @@
+function f=comp_idgt_fac(coef,gf,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgt_fac
+%@verbatim
+%COMP_IDGT_FAC  Full-window factorization of a Gabor matrix.
+%   Usage:  f=comp_idgt_fac(c,g,a,M)
+%
+%   Input parameters:
+%         c     : M x N array of coefficients.
+%         gf    : Factorization of window (from facgabm).
+%         a     : Length of time shift.
+%         M     : Number of frequency shifts.
+%   Output parameters:
+%         f     : Reconstructed signal.
+%
+%   Do not call this function directly, use IDGT.
+%   This function does not check input parameters!
+%
+%   If input is a matrix, the transformation is applied to
+%   each column.
+%
+%   This function does not handle multidimensional data, take care before
+%   you call it.
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgt_fac.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Calculate the parameters that was not specified.
+N=L/a;
+b=L/M;
+
+R=prod(size(gf))/L;
+
+W=prod(size(coef))/(M*N*R);
+
+N=L/a;
+b=L/M;
+
+[c,h_a,h_m]=gcd(a,M);
+h_a=-h_a;
+p=a/c;
+q=M/c;
+d=N/q;
+
+ff=zeros(p,q*W,c,d,assert_classname(coef,gf));
+C=zeros(q*R,q*W,c,d,assert_classname(coef,gf));
+f=zeros(L,W,assert_classname(coef,gf));
+
+% Apply ifft to the coefficients.
+%coef=ifft(reshape(coef,M,N*W))*sqrt(M);
+coef=ifft(coef)*sqrt(M);
+  
+% Set up the small matrices
+
+coef=reshape(coef,M,N,R,W);
+
+if p==1
+
+  for rw=0:R-1
+    for w=0:W-1
+      for s=0:d-1
+	for l=0:q-1
+	  for u=0:q-1
+	    C(u+1+rw*q,l+1+w*q,:,s+1)=coef((1:c)+l*c,mod(u+s*q+l,N)+1,rw+1,w+1);
+	  end;
+	end;
+      end;
+    end;
+  end;
+else
+  % Rational oversampling
+  for rw=0:R-1
+    for w=0:W-1
+      for s=0:d-1
+	for l=0:q-1
+	  for u=0:q-1
+	    C(u+1+rw*q,l+1+w*q,:,s+1)=coef((1:c)+l*c,mod(u+s*q-l*h_a,N)+1,rw+1,w+1);
+	  end;
+	end;
+      end;
+    end;
+  end;
+end;
+
+% FFT them
+if d>1
+  C=fft(C,[],4);
+end;
+
+% Multiply them
+for r=0:c-1    
+  for s=0:d-1
+    CM=reshape(C(:,:,r+1,s+1),q*R,q*W);
+    GM=reshape(gf(:,r+s*c+1),p,q*R);
+
+    ff(:,:,r+1,s+1)=GM*CM;
+  end;
+end;
+
+% Inverse FFT
+if d>1
+  ff=ifft(ff,[],4);
+end;
+
+% Place the result  
+if p==1
+
+  for s=0:d-1
+    for w=0:W-1
+      for l=0:q-1
+	f((1:c)+mod(s*M+l*a,L),w+1)=reshape(ff(1,l+1+w*q,:,s+1),c,1);
+      end;
+    end;
+  end;
+
+else
+  % Rational oversampling
+  for w=0:W-1
+    for s=0:d-1
+      for l=0:q-1
+	for k=0:p-1
+	  f((1:c)+mod(k*M+s*p*M-l*h_a*a,L),w+1)=reshape(ff(k+1,l+1+w*q,:,s+1),c,1);
+	end;
+      end;
+    end;
+  end;
+
+end;
+
+
+
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_idgt_fb.m b/inst/comp/comp_idgt_fb.m
new file mode 100644
index 0000000..de8d406
--- /dev/null
+++ b/inst/comp/comp_idgt_fb.m
@@ -0,0 +1,152 @@
+function [f]=comp_idgt_fb(coef,g,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgt_fb
+%@verbatim
+%COMP_IDGT_FB  Filter bank IDGT.
+%   Usage:  f=comp_idgt_fb(c,g,L,a,M);
+%       
+%   This is a computational routine. Do not call it directly.
+%
+%   Input must be in the M x N*W format, so the N and W dimension is
+%   combined.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgt_fb.php}
+%@seealso{idgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Calculate the parameters that was not specified.
+N=L/a;
+b=L/M;
+
+%W=prod(size(coef))/(M*N);
+W = size(coef,3);
+
+N=L/a;
+b=L/M;
+
+gl=length(g);
+glh=floor(gl/2);  % gl-half
+
+%if ndims(coef)>2
+%  error('Reshape to M x N*W');
+%end;
+
+% Apply ifft to the coefficients.
+coef=ifft(coef)*sqrt(M);
+
+%coef=reshape(coef,M,N,W);
+
+% The fftshift actually makes some things easier.
+g=fftshift(g);
+
+f=zeros(L,W,assert_classname(coef,g));
+
+ff=zeros(gl,1,assert_classname(coef,g));
+
+% Rotate the coefficients, duplicate them until they have same
+% length as g, and multiply by g.
+% FIXME Kill the loop over w by bsxfun
+for w=1:W
+  
+    
+  % ----- Handle the first boundary using periodic boundary conditions. ---
+  for n=0:ceil(glh/a)-1
+    delay=mod(-n*a+glh,M);
+    for ii=0:gl/M-1
+      for m=0:delay-1
+        ff(m+ii*M+1)=coef(M-delay+m+1,n+1,w)*g(m+ii*M+1);
+      end;
+      for m=0:M-delay-1
+        ff(m+ii*M+delay+1)=coef(m+1,n+1,w)*g(m+delay+ii*M+1);
+      end;
+    end;
+    
+    sp=mod(n*a-glh,L);
+    ep=mod(n*a-glh+gl-1,L);
+    
+    % Add the ff vector to f at position sp.
+    for ii=0:L-sp-1
+      f(sp+ii+1,w)=f(sp+ii+1,w)+ff(1+ii);
+    end;
+    for ii=0:ep
+      f(1+ii,w)=f(1+ii,w)+ff(L-sp+1+ii); 
+    end;
+  end;
+
+  % ----- Handle the middle case. ---------------------
+  for n=ceil(glh/a):floor((L-ceil(gl/2))/a)
+    delay=mod(-n*a+glh,M);    
+    for ii=0:gl/M-1
+      for m=0:delay-1
+        ff(m+ii*M+1)=coef(M-delay+m+1,n+1,w)*g(m+ii*M+1);
+      end;
+      for m=0:M-delay-1
+        ff(m+ii*M+delay+1)=coef(m+1,n+1,w)*g(m+delay+ii*M+1);
+      end;
+    end;
+
+    sp=mod(n*a-glh,L);
+    ep=mod(n*a-glh+gl-1,L);
+  
+    % Add the ff vector to f at position sp.
+    for ii=0:ep-sp
+      f(ii+sp+1,w)=f(ii+sp+1,w)+ff(ii+1);
+    end;
+  end;
+
+  % ----- Handle the last boundary using periodic boundary conditions. ---
+  % This n is one-indexed, to avoid to many +1
+  for n=floor((L-ceil(gl/2))/a)+1:N-1
+    delay=mod(-n*a+glh,M);
+    for ii=0:gl/M-1
+      for m=0:delay-1
+        ff(m+ii*M+1)=coef(M-delay+m+1,n+1,w)*g(m+ii*M+1);
+      end;
+      for m=0:M-delay-1
+        ff(m+ii*M+delay+1)=coef(m+1,n+1,w)*g(m+delay+ii*M+1);
+      end;
+    end;
+    
+    sp=mod(n*a-glh,L);
+    ep=mod(n*a-glh+gl-1,L);
+    
+    % Add the ff vector to f at position sp.
+    for ii=0:L-sp-1
+      f(sp+ii+1,w)=f(sp+ii+1,w)+ff(1+ii);
+    end;
+    for ii=0:ep
+      f(1+ii,w)=f(1+ii,w)+ff(L-sp+1+ii); 
+    end;
+  end;
+end;
+
+% Scale correctly.
+f=sqrt(M)*f;
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_idgt_long.m b/inst/comp/comp_idgt_long.m
new file mode 100644
index 0000000..baad397
--- /dev/null
+++ b/inst/comp/comp_idgt_long.m
@@ -0,0 +1,60 @@
+function f=comp_idgt_long(coef,g,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgt_long
+%@verbatim
+%COMP_IDGT_FAC  Full-window factorization of a Gabor matrix.
+%   Usage:  f=comp_idgt_long(c,g,L,a,M)
+%
+%   Input parameters:
+%         c     : M x N x W array of coefficients.
+%         g     : Window.
+%         a     : Length of time shift.
+%         M     : Number of frequency shifts.
+%   Output parameters:
+%         f     : Reconstructed signal.
+%
+%   Do not call this function directly, use IDGT.
+%   This function does not check input parameters!
+%
+%   If input is a matrix, the transformation is applied to
+%   each column.
+%
+%   This function does not handle multidimensional data, take care before
+%   you call it.
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgt_long.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+% Get the factorization of the window.
+gf = comp_wfac(g,a,M);      
+
+% Call the computational subroutine.
+f  = comp_idgt_fac(coef,gf,L,a,M);
diff --git a/inst/comp/comp_idgtreal.m b/inst/comp/comp_idgtreal.m
new file mode 100644
index 0000000..82291e7
--- /dev/null
+++ b/inst/comp/comp_idgtreal.m
@@ -0,0 +1,71 @@
+function f=comp_idgtreal(coef,g,a,M,lt,phasetype)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgtreal
+%@verbatim
+%COMP_IDGTREAL  Compute IDGTREAL
+%   Usage:  f=comp_idgtreal(c,g,a,M,lt,phasetype);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         lt    : lattice type
+%   Output parameters:
+%         f     : Signal.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgtreal.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: OK
+
+N=size(coef,2);
+L=N*a;
+b=L/M;
+
+
+
+M2=floor(M/2)+1;
+M2short=ceil(M/2);
+
+if lt(2)==1
+    if phasetype==1
+        TimeInd = (0:(N-1))/N;
+        FreqInd = (0:(M2-1))*b;
+        
+        phase = FreqInd'*TimeInd;
+        phase = exp(-2*i*pi*phase);
+        
+        % Handle multisignals
+        coef = bsxfun(@times,coef,phase);
+        
+    end;
+    
+    f = comp_isepdgtreal(coef,g,L,a,M);
+    
+else
+    % Quinqux lattice
+    f=comp_inonsepdgtreal_quinqux(coef,g,a,M);
+    
+end;
+
+
diff --git a/inst/comp/comp_idgtreal_fac.m b/inst/comp/comp_idgtreal_fac.m
new file mode 100644
index 0000000..fcecdaf
--- /dev/null
+++ b/inst/comp/comp_idgtreal_fac.m
@@ -0,0 +1,170 @@
+function f=comp_idgtreal_fac(coef,gf,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgtreal_fac
+%@verbatim
+%COMP_IDGTREAL_FAC  Full-window factorization of a Gabor matrix assuming.
+%   Usage:  f=comp_idgtreal_fac(c,gf,L,a,M)
+%
+%   Input parameters:
+%         c     : M x N array of coefficients.
+%         gf    : Factorization of window (from facgabm).
+%         a     : Length of time shift.
+%         M     : Number of frequency shifts.
+%   Output parameters:
+%         f     : Reconstructed signal.
+%
+%   Do not call this function directly, use IDGT.
+%   This function does not check input parameters!
+%
+%   If input is a matrix, the transformation is applied to
+%   each column.
+%
+%   This function does not handle multidimensional data, take care before
+%   you call it.
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgtreal_fac.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Calculate the parameters that was not specified.
+N=L/a;
+b=L/M;
+M2=floor(M/2)+1;
+
+R=prod(size(gf))/L;
+
+%W=size(coef,2)/(N*R);
+W = size(coef,3);
+
+N=L/a;
+b=L/M;
+
+[c,h_a,h_m]=gcd(a,M);
+h_a=-h_a;
+p=a/c;
+q=M/c;
+d=N/q;
+
+ff=zeros(p,q*W,c,d,assert_classname(coef,gf));
+C=zeros(q*R,q*W,c,d,assert_classname(coef,gf));
+f=zeros(L,W,assert_classname(coef,gf));
+
+% Apply ifft to the coefficients.
+coef=ifftreal(coef,M)*sqrt(M);
+  
+% Set up the small matrices
+
+coef=reshape(coef,M,N,R,W);
+
+if p==1
+
+  for rw=0:R-1
+    for w=0:W-1
+      for s=0:d-1
+	for l=0:q-1
+	  for u=0:q-1
+	    C(u+1+rw*q,l+1+w*q,:,s+1)=coef((1:c)+l*c,mod(u+s*q+l,N)+1,rw+1,w+1);
+	  end;
+	end;
+      end;
+    end;
+  end;
+else
+  % Rational oversampling
+  for rw=0:R-1
+    for w=0:W-1
+      for s=0:d-1
+	for l=0:q-1
+	  for u=0:q-1
+	    C(u+1+rw*q,l+1+w*q,:,s+1)=coef((1:c)+l*c,mod(u+s*q-l*h_a,N)+1,rw+1,w+1);
+	  end;
+	end;
+      end;
+    end;
+  end;
+end;
+
+% FFT them
+if d>1
+  C=fft(C,[],4);
+end;
+
+% Multiply them
+for r=0:c-1    
+  for s=0:d-1
+    CM=reshape(C(:,:,r+1,s+1),q*R,q*W);
+    GM=reshape(gf(:,r+s*c+1),p,q*R);
+
+    ff(:,:,r+1,s+1)=GM*CM;
+  end;
+end;
+
+% Inverse FFT
+if d>1
+  ff=ifft(ff,[],4);
+end;
+
+% Place the result  
+if p==1
+
+  for s=0:d-1
+    for w=0:W-1
+      for l=0:q-1
+	f((1:c)+mod(s*M+l*a,L),w+1)=reshape(ff(1,l+1+w*q,:,s+1),c,1);
+      end;
+    end;
+  end;
+
+else
+  % Rational oversampling
+  for s=0:d-1
+    for w=0:W-1
+      for l=0:q-1
+	for k=0:p-1
+	  f((1:c)+mod(k*M+s*p*M-l*h_a*a,L),w+1)=reshape(ff(k+1,l+1+w*q,:,s+1),c,1);
+	end;
+      end;
+    end;
+  end;
+
+end;
+
+f=real(f);
+
+
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_idgtreal_fb.m b/inst/comp/comp_idgtreal_fb.m
new file mode 100644
index 0000000..1c0a464
--- /dev/null
+++ b/inst/comp/comp_idgtreal_fb.m
@@ -0,0 +1,155 @@
+function [f]=comp_idgtreal_fb(coef,g,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgtreal_fb
+%@verbatim
+%COMP_IDGT_FB  Filter bank IDGT.
+%   Usage:  f=comp_idgt_fb(c,g,L,a,M);
+%       
+%   This is a computational routine. Do not call it directly.
+%
+%   Input must be in the M x N*W format, so the N and W dimension is
+%   combined.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgtreal_fb.php}
+%@seealso{idgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Calculate the parameters that was not specified.
+N=L/a;
+b=L/M;
+
+%W=size(coef,2)/N;
+W = size(coef,3);
+
+N=L/a;
+b=L/M;
+
+gl=length(g);
+glh=floor(gl/2);  % gl-half
+
+%if ndims(coef)>2
+%  error('Reshape to M2 x N*W');
+%end;
+
+% Apply ifft to the coefficients.
+coef=ifftreal(coef,M)*sqrt(M);
+
+%coef=reshape(coef,M,N,W);
+
+% The fftshift actually makes some things easier.
+g=fftshift(g);
+
+f=zeros(L,W,assert_classname(coef,g));
+
+% Make multicolumn g by replication.
+gw=repmat(g,1,W);
+
+ff=zeros(gl,1,assert_classname(coef,g));
+
+% Rotate the coefficients, duplicate them until they have same
+% length as g, and multiply by g.
+
+for w=1:W
+  
+    
+  % ----- Handle the first boundary using periodic boundary conditions. ---
+  for n=0:ceil(glh/a)-1
+    delay=mod(-n*a+glh,M);
+    for ii=0:gl/M-1
+      for m=0:delay-1
+        ff(m+ii*M+1)=coef(M-delay+m+1,n+1,w)*g(m+ii*M+1);
+      end;
+      for m=0:M-delay-1
+        ff(m+ii*M+delay+1)=coef(m+1,n+1,w)*g(m+delay+ii*M+1);
+      end;
+    end;
+    
+    sp=mod(n*a-glh,L);
+    ep=mod(n*a-glh+gl-1,L);
+    
+    % Add the ff vector to f at position sp.
+    for ii=0:L-sp-1
+      f(sp+ii+1,w)=f(sp+ii+1,w)+ff(1+ii);
+    end;
+    for ii=0:ep
+      f(1+ii,w)=f(1+ii,w)+ff(L-sp+1+ii); 
+    end;
+  end;
+
+  % ----- Handle the middle case. ---------------------
+  for n=ceil(glh/a):floor((L-ceil(gl/2))/a)
+    delay=mod(-n*a+glh,M);    
+    for ii=0:gl/M-1
+      for m=0:delay-1
+        ff(m+ii*M+1)=coef(M-delay+m+1,n+1,w)*g(m+ii*M+1);
+      end;
+      for m=0:M-delay-1
+        ff(m+ii*M+delay+1)=coef(m+1,n+1,w)*g(m+delay+ii*M+1);
+      end;
+    end;
+
+    sp=mod(n*a-glh,L);
+    ep=mod(n*a-glh+gl-1,L);
+  
+    % Add the ff vector to f at position sp.
+    for ii=0:ep-sp
+      f(ii+sp+1,w)=f(ii+sp+1,w)+ff(ii+1);
+    end;
+  end;
+
+  % ----- Handle the last boundary using periodic boundary conditions. ---
+  % This n is one-indexed, to avoid to many +1
+  for n=floor((L-ceil(gl/2))/a)+1:N-1
+    delay=mod(-n*a+glh,M);
+    for ii=0:gl/M-1
+      for m=0:delay-1
+        ff(m+ii*M+1)=coef(M-delay+m+1,n+1,w)*g(m+ii*M+1);
+      end;
+      for m=0:M-delay-1
+        ff(m+ii*M+delay+1)=coef(m+1,n+1,w)*g(m+delay+ii*M+1);
+      end;
+    end;
+    
+    sp=mod(n*a-glh,L);
+    ep=mod(n*a-glh+gl-1,L);
+    
+    % Add the ff vector to f at position sp.
+    for ii=0:L-sp-1
+      f(sp+ii+1,w)=f(sp+ii+1,w)+ff(1+ii);
+    end;
+    for ii=0:ep
+      f(1+ii,w)=f(1+ii,w)+ff(L-sp+1+ii); 
+    end;
+  end;
+end;
+
+% Scale correctly.
+f=sqrt(M)*f;
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_idgtreal_long.m b/inst/comp/comp_idgtreal_long.m
new file mode 100644
index 0000000..b8553d9
--- /dev/null
+++ b/inst/comp/comp_idgtreal_long.m
@@ -0,0 +1,66 @@
+function f=comp_idgtreal_long(coef,g,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idgtreal_long
+%@verbatim
+%COMP_IDGTREAL_FAC  Full-window factorization of a Gabor matrix assuming.
+%   Usage:  f=comp_idgtreal_long(c,g,L,a,M)
+%
+%   Input parameters:
+%         c     : M x N x W array of coefficients.
+%         g     : window (from facgabm).
+%         a     : Length of time shift.
+%         M     : Number of frequency shifts.
+%   Output parameters:
+%         f     : Reconstructed signal.
+%
+%   Do not call this function directly, use IDGT.
+%   This function does not check input parameters!
+%
+%   If input is a matrix, the transformation is applied to
+%   each column.
+%
+%   This function does not handle multidimensional data, take care before
+%   you call it.
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idgtreal_long.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Get the factorization of the window.
+gf = comp_wfac(g,a,M);      
+        
+% Call the computational subroutine.
+f = comp_idgtreal_fac(coef,gf,L,a,M);
+
+
+
+
diff --git a/inst/comp/comp_idwilt.m b/inst/comp/comp_idwilt.m
new file mode 100644
index 0000000..cb8892a
--- /dev/null
+++ b/inst/comp/comp_idwilt.m
@@ -0,0 +1,81 @@
+function [f]=comp_idwilt(coef,g)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idwilt
+%@verbatim
+%COMP_IDWILT  Compute Inverse discrete Wilson transform.
+% 
+%   This is a computational routine. Do not call it
+%   directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idwilt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+M=size(coef,1)/2;
+N=2*size(coef,2);
+W=size(coef,3);
+
+a=M;
+
+L=N*a;
+
+coef2=zeros(2*M,N,W,assert_classname(coef,g));
+
+% First and middle modulation are transferred unchanged.
+coef2(1,1:2:N,:) = coef(1,:,:);
+if mod(M,2)==0
+  coef2(M+1,1:2:N,:) = coef(M+1,:,:);
+else
+  coef2(M+1,2:2:N,:) = coef(M+1,:,:);
+end;
+
+if M>2
+  % cosine, first column.
+  coef2(3:2:M,1:2:N,:)        = 1/sqrt(2)*coef(3:2:M,:,:);
+  coef2(2*M-1:-2:M+2,1:2:N,:) = 1/sqrt(2)*coef(3:2:M,:,:);
+
+  % sine, second column
+  coef2(3:2:M,2:2:N,:)        = -1/sqrt(2)*i*coef(M+3:2:2*M,:,:);
+  coef2(2*M-1:-2:M+2,2:2:N,:) =  1/sqrt(2)*i*coef(M+3:2:2*M,:,:);
+end;
+
+
+% sine, first column.
+coef2(2:2:M,1:2:N,:)        = -1/sqrt(2)*i*coef(2:2:M,:,:);
+coef2(2*M:-2:M+2,1:2:N,:)   =  1/sqrt(2)*i*coef(2:2:M,:,:);
+
+% cosine, second column
+coef2(2:2:M,2:2:N,:)        = 1/sqrt(2)*coef(M+2:2:2*M,:,:);
+coef2(2*M:-2:M+2,2:2:N,:)   = 1/sqrt(2)*coef(M+2:2:2*M,:,:);
+
+f = comp_isepdgt(coef2,g,L,a,2*M);
+
+
+% Apply the final DGT
+%f=comp_idgt(coef2,g,a,[0 1],0,0);
+
+% Clean signal if it is known to be real
+if (isreal(coef) && isreal(g))
+  f=real(f);
+end;
+
+
diff --git a/inst/comp/comp_idwiltii.m b/inst/comp/comp_idwiltii.m
new file mode 100644
index 0000000..162dc88
--- /dev/null
+++ b/inst/comp/comp_idwiltii.m
@@ -0,0 +1,68 @@
+function [coef2]=comp_idwiltii(coef,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idwiltii
+%@verbatim
+%COMP_IDWILTII  Compute Inverse discrete Wilson transform type II
+% 
+%   This is a computational routine. Do not call it
+%   directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idwiltii.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+N=size(coef,1)/M;
+W=size(coef,2);
+L=N*a;
+
+coef=reshape(coef,M*2,N/2,W);
+
+coef2=zeros(2*M,N,W,assert_classname(coef));
+
+% First and middle modulation are transferred unchanged.
+coef2(1,1:2:N,:) = coef(1,:,:);
+
+coef2(2:2:M,1:2:N,:)        = -i/sqrt(2)*coef(2:2:M,:,:);
+coef2(2*M:-2:M+2,1:2:N,:)   = -i/sqrt(2)*coef(2:2:M,:,:);
+
+coef2(2:2:M,2:2:N,:)        =  1/sqrt(2)*coef(M+2:2:2*M,:,:);
+coef2(2*M:-2:M+2,2:2:N,:)   = -1/sqrt(2)*coef(M+2:2:2*M,:,:);
+
+if M>2
+  coef2(3:2:M,1:2:N,:)        = 1/sqrt(2)*coef(3:2:M,:,:);
+  coef2(2*M-1:-2:M+2,1:2:N,:) = -1/sqrt(2)*coef(3:2:M,:,:);
+  
+  coef2(3:2:M,2:2:N,:)        = -i/sqrt(2)*coef(M+3:2:2*M,:,:);
+  coef2(2*M-1:-2:M+2,2:2:N,:) = -i/sqrt(2)*coef(M+3:2:2*M,:,:);
+end;
+
+if mod(M,2)==0
+  coef2(M+1,2:2:N,:) = -i*coef(M+1,:,:);
+else
+  coef2(M+1,1:2:N,:) = -i*coef(M+1,:,:);
+end;
+
+
+
+
+
+
+
+
diff --git a/inst/comp/comp_idwiltiii.m b/inst/comp/comp_idwiltiii.m
new file mode 100644
index 0000000..34856ce
--- /dev/null
+++ b/inst/comp/comp_idwiltiii.m
@@ -0,0 +1,67 @@
+function [f]=comp_idwiltiii(coef,g)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idwiltiii
+%@verbatim
+%COMP_IDWILTIII  Compute Inverse discrete Wilson transform type III.
+% 
+%   This is a computational routine. Do not call it
+%   directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idwiltiii.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+M=size(coef,1);
+N=size(coef,2);
+W=size(coef,3);
+a=M;
+
+L=N*M;
+
+coef2=zeros(2*M,N,W,assert_classname(coef,g));
+
+coef2(1:2:M,1:2:N,:)        = exp( i*pi/4)*coef(1:2:M,1:2:N,:);
+coef2(2*M:-2:M+1,1:2:N,:)   = exp(-i*pi/4)*coef(1:2:M,1:2:N,:);
+
+coef2(1:2:M,2:2:N,:)        = exp(-i*pi/4)*coef(1:2:M,2:2:N,:);
+coef2(2*M:-2:M+1,2:2:N,:)   = exp( i*pi/4)*coef(1:2:M,2:2:N,:);
+
+coef2(2:2:M,1:2:N,:)        = exp(-i*pi/4)*coef(2:2:M,1:2:N,:);
+coef2(2*M-1:-2:M+1,1:2:N,:) = exp( i*pi/4)*coef(2:2:M,1:2:N,:);
+
+coef2(2:2:M,2:2:N,:)        = exp( i*pi/4)*coef(2:2:M,2:2:N,:);
+coef2(2*M-1:-2:M+1,2:2:N,:) = exp(-i*pi/4)*coef(2:2:M,2:2:N,:);
+
+% Apply the generalized DGT and scale.
+%f=comp_igdgt(coef2,g,a,2*M,L,0,.5,0,0)/sqrt(2);
+
+f = comp_isepdgt(coef2,g,L,a,2*M);
+
+halfmod=exp(pi*i*(0:L-1).'/(2*M))/sqrt(2);
+f=f.*repmat(halfmod,1,W);
+
+if isreal(coef) && isreal(g)
+  f=real(f);
+end;
+
+
+
diff --git a/inst/comp/comp_idwiltiv.m b/inst/comp/comp_idwiltiv.m
new file mode 100644
index 0000000..e34eee4
--- /dev/null
+++ b/inst/comp/comp_idwiltiv.m
@@ -0,0 +1,52 @@
+function [coef2]=comp_idwiltiv(coef,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_idwiltiv
+%@verbatim
+%COMP_IDWILTIV  Compute Inverse discrete Wilson transform type IV.
+% 
+%   This is a computational routine. Do not call it
+%   directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_idwiltiv.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+N=size(coef,1)/M;
+W=size(coef,2);
+L=N*a;
+
+coef=reshape(coef,M,N,W);
+
+coef2=zeros(2*M,N,W,assert_classname(coef));
+
+coef2(1:2:M,1:2:N,:)        = exp(i*pi/4)/sqrt(2)*coef(1:2:M,1:2:N,:);
+coef2(2*M:-2:M+1,1:2:N,:)   = exp(i*pi*3/4)/sqrt(2)*coef(1:2:M,1:2:N,:);
+
+coef2(1:2:M,2:2:N,:)        = exp(-i*pi/4)/sqrt(2)*coef(1:2:M,2:2:N,:);
+coef2(2*M:-2:M+1,2:2:N,:)   = exp(-i*pi*3/4)/sqrt(2)*coef(1:2:M,2:2:N,:);
+
+coef2(2:2:M,1:2:N,:)        = exp(-i*pi/4)/sqrt(2)*coef(2:2:M,1:2:N,:);
+coef2(2*M-1:-2:M+1,1:2:N,:) = exp(-i*pi*3/4)/sqrt(2)*coef(2:2:M,1:2:N,:);
+
+coef2(2:2:M,2:2:N,:)        = exp(i*pi/4)/sqrt(2)*coef(2:2:M,2:2:N,:);
+coef2(2*M-1:-2:M+1,2:2:N,:) = exp(i*pi*3/4)/sqrt(2)*coef(2:2:M,2:2:N,:);
+
+
+
diff --git a/inst/comp/comp_iedgt6.m b/inst/comp/comp_iedgt6.m
new file mode 100644
index 0000000..46c7ec7
--- /dev/null
+++ b/inst/comp/comp_iedgt6.m
@@ -0,0 +1,44 @@
+function [cout]=comp_iedgt6(cin,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iedgt6
+%@verbatim
+%COMP_IEDGT6   Compute inverse even DGT type 6
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iedgt6.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+N=size(cin,1)/M;
+W=size(cin,2);
+L=N*a;
+
+cin=reshape(cin,M,N,W);
+
+cout=zeros(M,2*N,W,assert_classname(cin));
+cout(:,1:N,:)=cin;
+
+% Copy the non modulated coefficients.
+cout(1,N+1:2*N,:)=cin(1,N:-1:1,:);
+
+% Copy the modulated coefficients.
+cout(2:M,N+1:2*N,:)=-cin(M:-1:2,N:-1:1,:);
+
+
+
+
diff --git a/inst/comp/comp_ifftreal.m b/inst/comp/comp_ifftreal.m
new file mode 100644
index 0000000..9553590
--- /dev/null
+++ b/inst/comp/comp_ifftreal.m
@@ -0,0 +1,41 @@
+function f=comp_ifftreal(c,N)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ifftreal
+%@verbatim
+%COMP_IFFTREAL  Compute an IFFTREAL
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ifftreal.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+N2=floor(N/2)+1;
+
+% Force IFFT along dimension 1, since we have permuted the dimensions
+% manually
+if rem(N,2)==0
+  f=[c;...
+     flipud(conj(c(2:end-1,:)))];
+else
+  f=[c;...
+     flipud(conj(c(2:end,:)))];
+end;
+
+f=real(ifft(f,N,1));
+
+
+
diff --git a/inst/comp/comp_ifilterbank.m b/inst/comp/comp_ifilterbank.m
new file mode 100644
index 0000000..d8bc6ea
--- /dev/null
+++ b/inst/comp/comp_ifilterbank.m
@@ -0,0 +1,138 @@
+function f = comp_ifilterbank(c,g,a,L)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ifilterbank
+%@verbatim
+%COMP_IFILTERBANK Compute inverse filterbank
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ifilterbank.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M = numel(g);
+classname = assert_classname(c{1});
+
+
+% Divide filters into time domain and frequency domain groups
+mFreq = 1:M;
+mTime = mFreq(cellfun(@(gEl) isfield(gEl,'h') ,g)>0); 
+mFreq(mTime) = [];
+
+f = [];
+
+if ~isempty(mTime)
+   % Pick imp. resp.
+   gtime = cellfun(@(gEl) gEl.h, g(mTime),'UniformOutput',0);
+
+   % Call the routine
+   gskip = cellfun(@(gEl) gEl.offset ,g(mTime));
+   f = comp_ifilterbank_td(c(mTime),gtime,a(mTime),L,gskip,'per');
+end
+
+if ~isempty(mFreq)
+   % Pick frequency domain filters
+   gfreq = g(mFreq);
+   % Divide filters into the full-length and band-limited groups
+   mFreqFullL = 1:numel(gfreq);
+   amFreqCell = mat2cell(a(mFreq,:).',size(a,2),ones(1,numel(mFreq)));
+   mFreqBL = mFreqFullL(cellfun(@(gEl,aEl) numel(gEl.H)~=L || (numel(aEl)>1 && aEl(2) ~=1), gfreq(:),amFreqCell(:))>0);
+   mFreqFullL(mFreqBL) = [];
+   
+   mFreqFullL = mFreq(mFreqFullL);
+   mFreqBL = mFreq(mFreqBL);
+   
+   F = [];
+   if ~isempty(mFreqBL)
+      conjG = cellfun(@(gEl) cast(gEl.H,classname), g(mFreqBL),'UniformOutput',0);
+      foff = cellfun(@(gEl) gEl.foff, g(mFreqBL));
+      % Cast from logical to double.
+      realonly = cellfun(@(gEl) cast(isfield(gEl,'realonly') && gEl.realonly,'double'), g(mFreqBL));
+      F = comp_ifilterbank_fftbl(c(mFreqBL),conjG,foff,a(mFreqBL,:),realonly);
+   end   
+   
+   if ~isempty(mFreqFullL)
+      conjG = cellfun(@(gEl) cast(gEl.H,classname), g(mFreqFullL),'UniformOutput',0);
+      
+      % In case some of the filters were BL
+      if isempty(F)
+         F = comp_ifilterbank_fft(c(mFreqFullL),conjG,a(mFreqFullL));
+      else
+         F = F + comp_ifilterbank_fft(c(mFreqFullL),conjG,a(mFreqFullL));
+      end
+   end
+   
+   % In case some of the filters were TD
+   if isempty(f)
+      f = ifft(F);
+   else
+      f = f + ifft(F);
+   end
+end
+
+
+
+
+% W = size(c{1},2);
+% M = numel(g);
+% classname = assert_classname(c{1});
+% 
+% f=zeros(L,W,classname);
+% 
+% % This routine must handle the following cases
+% %
+% %   * Time-side or frequency-side filters (test for  isfield(g,'H'))
+% %
+% %   * Cell array or matrix input (test for iscell(c))
+% %
+% %   * Regular or fractional subsampling (test for info.isfractional)
+% 
+% 
+% for m=1:M
+%     conjG=conj(comp_transferfunction(g{m},L));
+%         
+%     % For Octave 3.6 compatibility
+%     conjG=cast(conjG,classname);
+%     
+%     % Handle fractional subsampling (this implies frequency side filters)
+%     if isfield(g{m},'H') && numel(g{m}.H)~=L
+%         N=size(c{m},1);
+%         Llarge=ceil(L/N)*N;
+%         amod=Llarge/N;
+%         
+%         for w=1:W                        
+%             % This repmat cannot be replaced by bsxfun
+%             innerstuff=middlepad(circshift(repmat(fft(c{m}(:,w)),amod,1),-g{m}.foff),L);
+%             innerstuff(numel(g{m}.H)+1:end) = 0;
+%             f(:,w)=f(:,w)+(circshift(innerstuff.*circshift(conjG,-g{m}.foff),g{m}.foff));
+%         end;                
+%     else
+%         if iscell(c)
+%             for w=1:W
+%                 % This repmat cannot be replaced by bsxfun
+%                 f(:,w)=f(:,w)+(repmat(fft(c{m}(:,w)),a(m),1).*conjG);
+%             end;
+%         else
+%             for w=1:W
+%                 % This repmat cannot be replaced by bsxfun
+%                 f(:,w)=f(:,w)+(repmat(fft(c(:,m,w)),a(m),1).*conjG);
+%             end;            
+%         end;
+%     end;
+% end;
+% 
+% f = ifft(f);
+
diff --git a/inst/comp/comp_ifilterbank_fft.m b/inst/comp/comp_ifilterbank_fft.m
new file mode 100644
index 0000000..c8b8a7f
--- /dev/null
+++ b/inst/comp/comp_ifilterbank_fft.m
@@ -0,0 +1,38 @@
+function F = comp_ifilterbank_fft(c,G,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ifilterbank_fft
+%@verbatim
+%COMP_IFILTERBANK_FFT  Compute filtering in FD
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ifilterbank_fft.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+W = size(c{1},2);
+M = numel(G);
+L = numel(G{1});
+F = zeros(L,W);
+
+for m=1:M
+   for w=1:W
+      % This repmat cannot be replaced by bsxfun
+      F(:,w)=F(:,w)+repmat(fft(c{m}(:,w)),a(m),1).*conj(G{m});
+   end;
+end
diff --git a/inst/comp/comp_ifilterbank_fftbl.m b/inst/comp/comp_ifilterbank_fftbl.m
new file mode 100644
index 0000000..de6fce5
--- /dev/null
+++ b/inst/comp/comp_ifilterbank_fftbl.m
@@ -0,0 +1,75 @@
+function F = comp_ifilterbank_fftbl(c,G,foff,a,realonly)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ifilterbank_fftbl
+%@verbatim
+%COMP_IFILTERBANK_FFTBL  Compute filtering in FD
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ifilterbank_fftbl.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M = numel(c);
+W = size(c{1},2);
+
+if size(a,2)>1
+   afrac=a(:,1)./a(:,2);
+else
+   afrac = a(:,1);
+end
+
+if 0
+   N = cellfun(@(cEl) size(cEl,1),c);
+   L = N.*afrac;
+   assert(all(rem(L,1))<1e-6,'%s: Bad subband lengths. \n',upper(mfilename));
+   L = round(L);
+   assert(all(L==L(1)),'%s:Bad subband lengths. \n',upper(mfilename));
+   L = L(1);
+else
+   L = afrac(1).*size(c{1},1);
+end
+
+F = zeros(L,W,assert_classname(c{1}));
+
+fsuppRangeSmall = cellfun(@(fEl,GEl) mod([fEl:fEl+numel(GEl)-1].',L)+1 ,num2cell(foff),G,'UniformOutput',0);
+%
+for w=1:W 
+   for m=1:M
+     Ctmp = postpad(circshift(fft(c{m}(:,w)),-foff(m)),numel(G{m}));
+     %Ctmp = postpad(fft(c{m}(:,w)),numel(G{m}));
+     F(fsuppRangeSmall{m},w)=F(fsuppRangeSmall{m},w) + Ctmp.*conj(G{m});
+   end;
+end
+
+
+% Handle the real only as a separate filter using recursion
+realonlyRange = 1:M;
+realonlyRange = realonlyRange(realonly>0);
+
+if ~isempty(realonlyRange)
+   Gconj = cellfun(@(gEl) conj(gEl(end:-1:1)),G(realonlyRange),'UniformOutput',0);
+   LG = cellfun(@(gEl) numel(gEl),Gconj);
+   foffconj = mod(L-foff(realonlyRange)-LG,L)+1;
+   aconj = a(realonlyRange,:);
+
+   cconj = comp_ifilterbank_fftbl(F,Gconj,L,foffconj,aconj,0);
+   for ii=1:numel(cconj)
+      c{realonlyRange(ii)} = (c{realonlyRange(ii)} + cconj{ii})/2;
+   end
+end
diff --git a/inst/comp/comp_ifilterbank_td.m b/inst/comp/comp_ifilterbank_td.m
new file mode 100644
index 0000000..d9eb4ca
--- /dev/null
+++ b/inst/comp/comp_ifilterbank_td.m
@@ -0,0 +1,72 @@
+function f=comp_ifilterbank_td(c,g,a,Ls,offset,ext)  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ifilterbank_td
+%@verbatim
+%COMP_IFILTERBANK_TD   Synthesis filterbank by conv2
+%   Usage:  f=comp_ifilterbank_td(c,g,a,Ls,skip,ext);
+%
+%   Input parameters:
+%         c    : Cell array of length M, each element is N(m)*W matrix.
+%         g    : Filterbank filters - length M cell-array, each element is vector of length filtLen(m) 
+%         a    : Upsampling factors - array of length M.
+%         skip : Delay of the filters - scalar or array of length M.
+%         Ls   : Output length.
+%         ext  : Border exension technique.
+%
+%   Output parameters:
+%         f  : Output Ls*W array. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ifilterbank_td.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%input channel number
+W=size(c{1},2);
+%filter number
+M=numel(g);
+%length of filters
+filtLen = cellfun(@(x) numel(x),g(:));
+
+skip = -(1-filtLen-offset(:));
+% Allow filter delay only in the filter support range
+if(any(skip(:)>=filtLen) || any(skip)<0)
+  error('%s: The filter zero index position outside of the filter support.', upper(mfilename));  
+end
+
+if(numel(skip)==1)
+    skip = skip*ones(M,1);
+end
+
+
+% Output memory allocation
+f=zeros(Ls,W,assert_classname(c{1},g{1}));
+
+if(~strcmp(ext,'per'))
+    ext = 'zero';
+end
+
+skipOut = a(:).*(filtLen-1)+skip(:);
+
+% W channels are done simultaneously
+for m=1:M
+   cext = comp_extBoundary(c{m},filtLen(m)-1,ext,'dim',1); 
+   ftmp = conv2(conj(flipud(g{m}(:))),comp_ups(cext,a(m)));
+   f = f + ftmp(1+skipOut(m):Ls+skipOut(m),:); 
+end
+
diff --git a/inst/comp/comp_ifwt.m b/inst/comp/comp_ifwt.m
new file mode 100644
index 0000000..d6cef6c
--- /dev/null
+++ b/inst/comp/comp_ifwt.m
@@ -0,0 +1,98 @@
+function f = comp_ifwt(c,g,J,a,Ls,ext)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ifwt
+%@verbatim
+%COMP_IFWT Compute Inverse DWT
+%   Usage:  f = comp_ifwt(c,g,J,a,Ls,ext);
+%
+%   Input parameters:
+%         c     : Cell array of length M = J*(filtNo-1)+1. Each element is Lc(m)*W array
+%         g     : Synthesis wavelet filters - cell-array of length filtNo.
+%         J     : Number of filterbank iterations.
+%         a     : Upsampling factors - array of length filtNo.
+%         Ls    : Length of the reconstructed signal.
+%         ext   : 'per','zero','odd','even', Type of the forward transform boundary handling.
+%
+%   Output parameters:
+%         f     : Reconstructed data - Ls*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ifwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% see comp_fwt for explanantion
+assert(a(1)==a(2),'First two elements of a are not equal. Such wavelet filterbank is not suported.');
+
+
+% Impulse responses to a correct format.
+filtNo = numel(g);
+gCell = cellfun(@(gEl) conj(flipud(gEl.h(:))),g,'UniformOutput',0);
+
+if strcmp(ext,'per')
+   % Initial shift of the filter to compensate for it's delay.
+   % "Zero" delay reconstruction is produced.
+   % offset = cellfun(@(gEl) gEl.offset,g); 
+   offset = cellfun(@(gEl) 1-numel(gEl.h)-gEl.offset,g); 
+elseif strcmp(ext,'valid')
+   offset = -cellfun(@(gEl) numel(gEl.h)-1,g);
+else
+   % -1 + 1 = 0 is used for better readability and to be consistent
+   % with the shift in comp_fwt.
+   % Here we are cheating, because we are making the filters
+   % anti-causal to compensate for the delay introduced by causal
+   % analysis filters. 
+   % Instead, we could have used causal filters here and do the
+   % delay compensation at the end (cropping f).
+   % offset = -cellfun(@(gEl) numel(gEl),gCell) + (a -1) +1;
+   offset = -(a-1);
+end
+
+
+Lc = cellfun(@(cEl) size(cEl,1),c);
+Lc(end+1) = Ls;
+tempca = c(1);
+cRunPtr = 2;
+for jj=1:J
+   tempca=comp_ifilterbank_td([tempca;c(cRunPtr:cRunPtr+filtNo-2)],gCell,a,Lc(cRunPtr+filtNo-1),offset,ext); 
+   cRunPtr = cRunPtr + filtNo -1;
+end
+% Save reconstructed data.
+f = tempca;
+
+
+
+% for ch=1:chans
+%   tempca = c(LcStart(1):LcEnd(1),ch);
+%   LcRunPtr = filtNo+1;
+%   cRunPtr = 2;
+%   for jj=1:J
+%      tempca = comp_upconv({tempca}, Lc(LcRunPtr),{tmpg{1}},a(1),skip(1),ext,0);
+%      for ff=2:filtNo
+%         % tempca = tempca + comp_upconv({c{cRunPtr}(:,ch)}, Lc(LcRunPtr),{tmpg},a(ff),skip,doNoExt,0);
+%         tempca = tempca + comp_upconv({c(LcStart(cRunPtr):LcEnd(cRunPtr),ch)}, Lc(LcRunPtr),{tmpg{ff}},a(ff),skip(ff),ext,0);
+%         cRunPtr = cRunPtr + 1;
+%      end
+%      LcRunPtr = LcRunPtr + filtNo -1;
+%   end
+%   f(:,ch) = tempca;
+% end
+
+
+    
+    
diff --git a/inst/comp/comp_igdgt.m b/inst/comp/comp_igdgt.m
new file mode 100644
index 0000000..eab7e7b
--- /dev/null
+++ b/inst/comp/comp_igdgt.m
@@ -0,0 +1,75 @@
+function f=comp_igdgt(c,g,a,M,L,c_t,c_f,c_w,timeinv)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_igdgt
+%@verbatim
+%COMP_IGDGT  Compute IGDGT
+%   Usage:  f=comp_igdgt(c,g,a,M,L,c_t,c_f,c_w,timeinv);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         L     : length of transform.
+%         c_t     : Centering in time of modulation.
+%         c_f     : Centering in frequency of modulation.
+%         c_w     : Centering in time of window.
+%         timeinv : Should we compute a time invariant Gabor system.
+%
+%   Output parameters:
+%         f     : Signal.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_igdgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR : Peter L. Soendergaard.
+
+b=L/M;
+N=L/a;
+
+Lwindow=size(g,1);
+W=size(c,3);
+
+% Pre-process if c_t is different from 0.
+if (c_t~=0)
+  halfmod=repmat(exp(2*pi*i*c_t*((0:M-1)+c_f).'/M),1,N*W);
+
+  % The following is necessary because REPMAT does not work for
+  % 3D arrays.
+  halfmod=reshape(halfmod,M,N,W);
+    
+  c=c.*halfmod;
+end;
+
+% Eventual phaselocking
+if timeinv
+  c=phaseunlock(c,a);
+end;
+
+f=comp_idgt(c,g,a,[0 1],0,0);
+
+% Postprocess to handle c_f different from 0.
+if (c_f~=0)
+  halfmod=exp(2*pi*i*c_f*(0:L-1).'/M);
+  f=f.*repmat(halfmod,1,W);
+end;
+
+
+
diff --git a/inst/comp/comp_inonsepdgt.m b/inst/comp/comp_inonsepdgt.m
new file mode 100644
index 0000000..cdfc1b2
--- /dev/null
+++ b/inst/comp/comp_inonsepdgt.m
@@ -0,0 +1,138 @@
+function f=comp_inonsepdgt(coef,g,a,lt,do_timeinv,alg)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_inonsepdgt
+%@verbatim
+%COMP_INONSEPDGT  Compute Inverse discrete Gabor transform
+%   Usage:  f=inonsepdgt(c,g,a,lt);
+%           f=inonsepdgt(c,g,a,lt,Ls);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         lt    : Lattice type
+%         do_timeinv : Do a time invariant phase ?
+%         alg   : Choose algorithm
+%   Output parameters:
+%         f     : Signal.
+%
+%   inonsepdgt(c,g,a,lt) computes the Gabor expansion of the input
+%   coefficients c with respect to the window g, time shift a and
+%   lattice type lt. The number of channels is deduced from the size of
+%   the coefficients c.
+%
+%      alg=0 : Choose the fastest algorithm
+%
+%      alg=0 : Always choose multi-win
+%
+%      alg=1 : Always choose shear
+%
+%   This is a computational subroutine, do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_inonsepdgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Nicki Holighaus and Peter L. Soendergaard
+%   TESTING: TEST_NONSEPDGT
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+
+M=size(coef,1);
+N=size(coef,2);
+W=size(coef,3);
+L=N*a;
+
+if (alg==1) || (alg==0 && lt(2)<=2) 
+    
+    % ----- algorithm starts here, split into sub-lattices ---------------
+    
+    mwin=comp_nonsepwin2multi(g,a,M,lt,L);
+    
+    % phase factor correction (backwards), for more information see 
+    % analysis routine
+    
+    E = exp(2*pi*i*a*kron(0:N/lt(2)-1,ones(1,lt(2))).*...
+            rem(kron(ones(1,N/lt(2)), 0:lt(2)-1)*lt(1),lt(2))/M);
+
+    coef=bsxfun(@times,coef,E);
+    
+    % simple algorithm: split into sublattices and add the result from eacg
+    % sublattice.
+    f=zeros(L,W,assert_classname(coef,g));
+    for ii=0:lt(2)-1
+        % Extract sublattice
+        sub=coef(:,ii+1:lt(2):end);
+        f=f+comp_idgt(sub,mwin(:,ii+1),lt(2)*a,M,L,0);  
+    end;
+
+else
+
+    [s0,s1,br] = shearfind(L,a,M,lt);
+    
+    b=L/M;
+    ar = a*b/br;
+    Mr = L/br;
+    Nr = L/ar;
+    
+    ind = [ar 0; 0 br]*[kron((0:L/ar-1),ones(1,L/br));kron(ones(1,L/ar), ...
+                                                      (0:L/br-1))];
+    phs = reshape(mod((s1*(ind(1,:)-s0*ind(2,:)).^2+s0*ind(2,:).^2)*(L+1) ...
+                    -2*(s0 ~= 0)*ind(1,:).*ind(2,:),2*L),L/br,L/ar);    
+    phs = exp(-pi*1i*phs/L);
+
+    ind_final = [1 0;-s1 1]*[1 -s0;0 1]*ind;
+    ind_final = mod(ind_final,L);
+    
+    if s1 ~= 0
+        g = comp_pchirp(L,s1).*g;
+    end
+    
+    if s0 ~= 0
+        
+        c_rect = zeros(Nr,Mr,W,assert_classname(coef,g));
+        g = comp_pchirp(L,-s0).*fft(g);
+        for w=0:W-1
+            c_rect(ind(1,[1:Mr,end:-1:Mr+1])/ar+1+(ind(2,:)/br)*Nr+w*M*N) = ...
+                coef(floor(ind_final(2,:)/b)+1+(ind_final(1,:)/a)*M+w*M* ...
+                     N).*phs(ind(2,:)/br+1+(ind(1,:)/ar)*Mr);
+        end;
+        f = comp_idgt(c_rect,g,br,Nr,L,0);
+        f = ifft(bsxfun(@times,comp_pchirp(L,s0),f));   
+        
+    else
+        
+        c_rect = zeros(Mr,Nr,W,assert_classname(coef,g));
+        for w=0:W-1
+            c_rect(ind(2,:)/br+1+(ind(1,:)/ar)*Mr+w*M*N) = ... 
+                coef(floor(ind_final(2,:)/b)+1+(ind_final(1,:)/a)*M+w*M*N);       
+            c_rect(:,:,w+1) = phs.*c_rect(:,:,w+1);
+        end;
+        f = comp_idgt(c_rect,g,ar,Mr,L,0);
+        
+    end
+    
+    if s1 ~= 0
+        f = bsxfun(@times,comp_pchirp(L,-s1),f);
+    end        
+
+end;
+    
+
diff --git a/inst/comp/comp_inonsepdgt_shear.m b/inst/comp/comp_inonsepdgt_shear.m
new file mode 100644
index 0000000..bf37077
--- /dev/null
+++ b/inst/comp/comp_inonsepdgt_shear.m
@@ -0,0 +1,132 @@
+function f=comp_inonsepdgt_shear(coef,g,a,s0,s1,br)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_inonsepdgt_shear
+%@verbatim
+%COMP_INONSEPDGT_SHEAR  Compute IDGT
+%   Usage:  f=comp_inonsepdgt_shear(c,g,a,lt,phasetype);
+%
+%   Input parameters:
+%         c        : Array of coefficients.
+%         g        : Window function.
+%         a        : Length of time shift.
+%         s0,s1,br : shearfind parameters
+%   Output parameters:
+%         f     : Signal.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_inonsepdgt_shear.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M=size(coef,1);
+N=size(coef,2);
+W=size(coef,3);
+
+L=N*a;
+
+b=L/M;
+ar = a*b/br;
+Mr = L/br;
+Nr = L/ar;
+
+ind = [ar 0; 0 br]*[kron((0:L/ar-1),ones(1,L/br));kron(ones(1,L/ar), ...
+                                                  (0:L/br-1))];
+phs = reshape(mod((s1*(ind(1,:)-s0*ind(2,:)).^2+s0*ind(2,:).^2)*(L+1) ...
+                  -2*(s0 ~= 0)*ind(1,:).*ind(2,:),2*L),L/br,L/ar);    
+phs = exp(-pi*1i*phs/L);
+
+ind_final = [1 0;-s1 1]*[1 -s0;0 1]*ind;
+ind_final = mod(ind_final,L);
+
+if s1 ~= 0
+    g = comp_pchirp(L,s1).*g;
+end
+
+if s0 == 0
+
+    c_rect = zeros(Mr,Nr,W,assert_classname(coef,g));
+    if 0
+        
+        for w=0:W-1
+            c_rect(ind(2,:)/br+1+(ind(1,:)/ar)*Mr+w*M*N) = ... 
+                coef(floor(ind_final(2,:)/b)+1+(ind_final(1,:)/a)*M+w*M*N);       
+            c_rect(:,:,w+1) = phs.*c_rect(:,:,w+1);
+        end;
+        
+    else
+    
+        tmp1=mod(s1*a*(L+1),2*N);
+        
+        for k=0:Nr-1   
+            phsidx= mod(mod(tmp1*k,2*N)*k,2*N);
+            
+            for m=0:Mr-1
+                phs = exp(-pi*1i*phsidx/N);
+                
+                idx1 =       mod(    k        ,N);
+                idx2 = floor(mod(-s1*k*a+m*b,L)/b);
+                
+                for w=0:W-1    
+                     c_rect(m+1,k+1,w+1) = coef(idx2+1,idx1+1,w+1).*phs;
+                end;
+            end;
+        end;
+        
+    end;
+    
+    
+    f = comp_idgt(c_rect,g,ar,[0 1],0,0);
+        
+else
+
+    c_rect = zeros(Nr,Mr,W,assert_classname(coef,g));
+    p = comp_pchirp(L,-s0);
+
+    g = p.*fft(g);
+
+    twoN=2*N;
+    cc1=ar/a;
+    cc2=mod(-s0*br/a,twoN);
+    cc3=mod(a*s1*(L+1),twoN);
+    cc4=mod(cc2*br*(L+1),twoN);
+    cc5=mod(2*cc1*br,twoN);
+    cc6=mod((s0*s1+1)*br,L);
+    
+    for k=0:Nr-1   
+        for m=0:Mr-1
+            sq1=mod(k*cc1+cc2*m,twoN);
+            phsidx = mod(mod(cc3*sq1.^2,twoN)-mod(m*(cc4*m+k*cc5),twoN),twoN);            
+            phs = exp(-pi*1i*phsidx/N);
+            
+            idx1 =       mod(    k*cc1       +cc2*m,N);
+            idx2 = floor(mod(-s1*k*ar+(s0*s1+1)*m*br,L)/b);
+            
+            for w=0:W-1                    
+                c_rect(mod(-k,Nr)+1,m+1,w+1) = coef(idx2+1,idx1+1,w+1).*phs;
+            end;
+        end;
+    end;                    
+    
+    f = comp_idgt(c_rect,g,br,[0 1],0,0);
+    f = ifft(bsxfun(@times,comp_pchirp(L,s0),f));   
+    
+end
+
+if s1 ~= 0
+    f = bsxfun(@times,comp_pchirp(L,-s1),f);
+end            
+
diff --git a/inst/comp/comp_inonsepdgtreal_quinqux.m b/inst/comp/comp_inonsepdgtreal_quinqux.m
new file mode 100644
index 0000000..cbf892a
--- /dev/null
+++ b/inst/comp/comp_inonsepdgtreal_quinqux.m
@@ -0,0 +1,84 @@
+function f=comp_inonsepdgtreal_quinqux(coef,g,a,M,do_timeinv)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_inonsepdgtreal_quinqux
+%@verbatim
+%COMP_INONSEPDGTREAL_QUINQUX  Compute Inverse discrete Gabor transform
+%   Usage:  f=inonsepdgt(c,g,a,M);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of channels
+%         do_timeinv : Do a time invariant phase ?
+%   Output parameters:
+%         f     : Signal.
+%
+%
+%   This is a computational subroutine, do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_inonsepdgtreal_quinqux.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Nicki Holighaus and Peter L. Soendergaard
+%   TESTING: TEST_NONSEPDGT
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+
+M2=size(coef,1);
+N=size(coef,2);
+W=size(coef,3);
+L=N*a;
+
+coef2=zeros(M,N,W,assert_classname(coef,g));
+
+coef2(1:M2,:,:)=coef;
+if rem(M,2)==0
+    coef2(M2+1:M,1:2:N-1,:)=conj(coef(M2-1:-1:2,1:2:N-1,:));
+    coef2(M2:M,2:2:N  ,:)  =conj(coef(M2-1:-1:1,2:2:N,:));
+else
+    coef2(M2+1:M,1:2:N-1,:)=conj(coef(M2:-1:2,1:2:N-1,:));
+    coef2(M2+1:M,2:2:N  ,:)=conj(coef(M2-1:-1:1,2:2:N,:));
+end;
+
+coef=coef2;
+
+lt=[1 2];
+mwin=comp_nonsepwin2multi(g,a,M,lt,L);
+
+% phase factor correction (backwards), for more information see 
+% analysis routine
+
+E = exp(2*pi*i*a*kron(0:N/2-1,ones(1,2)).*...
+        rem(kron(ones(1,N/2), 0:2-1),2)/M);
+
+coef = bsxfun(@times,coef,E);
+
+% simple algorithm: split into sublattices and add the result from eacg
+% sublattice.
+f=zeros(L,W,assert_classname(coef,g));
+for ii=0:2-1
+    % Extract sublattice
+    sub=coef(:,ii+1:2:end,:);
+    f=f+comp_idgt(sub,mwin(:,ii+1),2*a,[0 1],0,0);  
+end;
+    
+
diff --git a/inst/comp/comp_irdgt.m b/inst/comp/comp_irdgt.m
new file mode 100644
index 0000000..5f16db2
--- /dev/null
+++ b/inst/comp/comp_irdgt.m
@@ -0,0 +1,52 @@
+function cout=comp_irdgt(cin,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_irdgt
+%@verbatim
+%COMP_IRDGT  Compute inverse real DGT.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_irdgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+N=size(cin,1)/M;
+W=size(cin,2);
+L=N*a;
+
+cin=reshape(cin,M,N,W);
+
+Mhalf=ceil(M/2);
+Mend=Mhalf*2-1;
+
+cout=zeros(M,N,W,assert_classname(cin));
+
+% Copy the first coefficient, it is real
+cout(1,:,:)=cin(1,:,:);
+
+cout(2:Mhalf,:,:)=(cin(2:2:Mend,:,:)- i*cin(3:2:Mend,:,:))/sqrt(2);
+cout(M-Mhalf+2:M,:,:)= (cin(Mend-1:-2:2,:,:)  +i*cin(Mend:-2:3,:,:))/sqrt(2);
+
+% If f has an even length, we must also copy the Nyquest-wave
+% (it is real)
+if mod(M,2)==0
+  cout(M/2+1,:,:)=cin(M,:,:);
+end;
+
+
+
+
+
diff --git a/inst/comp/comp_irdgtii.m b/inst/comp/comp_irdgtii.m
new file mode 100644
index 0000000..910b75b
--- /dev/null
+++ b/inst/comp/comp_irdgtii.m
@@ -0,0 +1,51 @@
+function [cout]=comp_irdgtii(cin,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_irdgtii
+%@verbatim
+%COMP_IRDGTII Compute inverse real DGT type II
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_irdgtii.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+M=size(cin,1);
+N=size(cin,2);
+W=size(cin,3);
+L=N*a;
+
+Mhalf=ceil(M/2);
+Mend=Mhalf*2-1;
+
+cout=zeros(M,N,W,assert_classname(cin));
+
+% Copy the first coefficient, it is real
+cout(1,:,:)=cin(1,:,:);
+
+cout(2:Mhalf,:,:)=(cin(2:2:Mend,:,:)- i*cin(3:2:Mend,:,:))/sqrt(2);
+cout(M-Mhalf+2:M,:,:)= -(cin(Mend-1:-2:2,:,:)  +i*cin(Mend:-2:3,:,:))/sqrt(2);
+
+% If f has an even length, we must also copy the Nyquest-wave
+% (it is imaginary)
+if mod(M,2)==0
+  cout(M/2+1,:,:)=-i*cin(M,:,:);
+end;
+
+
+
+
diff --git a/inst/comp/comp_irdgtiii.m b/inst/comp/comp_irdgtiii.m
new file mode 100644
index 0000000..345b657
--- /dev/null
+++ b/inst/comp/comp_irdgtiii.m
@@ -0,0 +1,54 @@
+function cout=comp_irdgtiii(cin,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_irdgtiii
+%@verbatim
+%COMP_IRDGTIII  Compute inverse real DGT type III.
+% 
+%   This is a computational routine. Do not call it
+%   directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_irdgtiii.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+N=size(cin,1)/M;
+W=size(cin,2);
+L=N*a;
+
+cin=reshape(cin,M,N,W);
+
+Mhalf=floor(M/2);
+
+cout=zeros(M,N,W,assert_classname(cin));
+
+for m=0:Mhalf-1
+  cout(m+1,:,:)=1/sqrt(2)*(cin(2*m+1,:,:)-i*cin(2*m+2,:,:));
+  cout(M-m,:,:)=1/sqrt(2)*(cin(2*m+1,:,:)+i*cin(2*m+2,:,:));
+end;
+
+if mod(M,2)==1
+  cout((M+1)/2,:,:)=cin(M,:,:);
+end;
+
+
+
+
+
+
diff --git a/inst/comp/comp_isepdgt.m b/inst/comp/comp_isepdgt.m
new file mode 100644
index 0000000..cb1557b
--- /dev/null
+++ b/inst/comp/comp_isepdgt.m
@@ -0,0 +1,54 @@
+function [f]=comp_isepdgt(coef,g,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_isepdgt
+%@verbatim
+%COMP_ISEPDGT  Separable IDGT.
+%   Usage:  f=comp_isepdgt(c,g,L,a,M);
+%       
+%   This is a computational routine. Do not call it directly.
+%
+%   Input must be in the M x N x W format.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_isepdgt.php}
+%@seealso{idgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+Lwindow=size(g,1);
+
+    if L==Lwindow
+        % Do full-window algorithm.
+        % coef=reshape(coef,M,prod(size(coef))/M);
+        
+        % Get the factorization of the window.
+        %gf = comp_wfac(g,a,M);      
+
+        % Call the computational subroutine.
+        f  = comp_idgt_long(coef,g,L,a,M);
+    else
+        %coef=reshape(coef,M,prod(size(coef))/M);
+        % Do filter bank algorithm.
+        % Call the computational subroutine.
+
+        f=comp_idgt_fb(coef,g,L,a,M);
+    end;
diff --git a/inst/comp/comp_isepdgtreal.m b/inst/comp/comp_isepdgtreal.m
new file mode 100644
index 0000000..6d10ab2
--- /dev/null
+++ b/inst/comp/comp_isepdgtreal.m
@@ -0,0 +1,54 @@
+function [f]=comp_isepdgtreal(coef,g,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_isepdgtreal
+%@verbatim
+%COMP_ISEPDGTREAL  Separable IDGT.
+%   Usage:  f=comp_isepdgtreal(c,g,L,a,M);
+%       
+%   This is a computational routine. Do not call it directly.
+%
+%   Input must be in the M x N x W format, so the N and W dimension is
+%   combined.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_isepdgtreal.php}
+%@seealso{idgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+Lwindow=size(g,1);
+
+
+    if L==Lwindow
+        % Do full-window algorithm.
+        
+        % Get the factorization of the window.
+        %gf = comp_wfac(g,a,M);      
+        
+        % Call the computational subroutine.
+        f = comp_idgtreal_long(coef,g,L,a,M);
+        
+    else
+        % Do filter bank algorithm.
+        % Call the computational subroutine.
+        f = comp_idgtreal_fb(coef,g,L,a,M);
+    end;
diff --git a/inst/comp/comp_iufilterbank_td.m b/inst/comp/comp_iufilterbank_td.m
new file mode 100644
index 0000000..f970d7c
--- /dev/null
+++ b/inst/comp/comp_iufilterbank_td.m
@@ -0,0 +1,74 @@
+function f=comp_iufilterbank_td(c,g,a,Ls,skip,ext)  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iufilterbank_td
+%@verbatim
+%COMP_IUFILTERBANK_TD   Synthesis Uniform filterbank by conv2
+%   Usage:  f=comp_iufilterbank_td(c,g,a,Ls,skip,ext);
+%
+%   Input parameters:
+%         c    : N*M*W array of coefficients.
+%         g    : Filterbank filters - filtLen*M array. 
+%         a    : Upsampling factor - scalar.
+%         Ls   : Output length.
+%         skip : Delay of the filters - scalar or array of length M.
+%         ext  : Border exension technique.
+%
+%   Output parameters:
+%         f  : Output Ls*W array. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iufilterbank_td.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%input channel number
+W=size(c,3);
+%filter number
+M=size(g,2);
+%length of filters
+filtLen = size(g,1);
+% Allow filter delay only in the filter support range
+if(all(skip>=filtLen) || all(skip<0))
+  error('%s: The filter zero index position outside of the filter support.', upper(mfilename));  
+end
+
+if(numel(skip)==1)
+    skip = skip*ones(M,1);
+end
+
+% Output memory allocation
+f=zeros(Ls,W,assert_classname(c,g));
+
+if(~strcmp(ext,'per'))
+    ext = 'zero';
+end
+
+
+skipOut = a*(filtLen-1)+skip;
+
+% W channels are done simultaneously
+for m=1:M
+   cext = comp_extBoundary(squeeze(c(:,m,:)),filtLen-1,ext,'dim',1); 
+   ftmp = conv2(g(:,m),comp_ups(cext,a));
+   f = f + ftmp(1+skipOut(m):Ls+skipOut(m),:); 
+end
+
+
+ 
+
+
diff --git a/inst/comp/comp_iufwt.m b/inst/comp/comp_iufwt.m
new file mode 100644
index 0000000..501987e
--- /dev/null
+++ b/inst/comp/comp_iufwt.m
@@ -0,0 +1,66 @@
+function f = comp_iufwt(c,g,J,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iufwt
+%@verbatim
+%COMP_IUFWT Compute Inverse Undecimated DWT
+%   Usage:  f = comp_iufwt(c,g,J,a);
+%
+%   Input parameters:
+%         c     : L*M*W array of coefficients, M=J*(filtNo-1)+1.
+%         g     : Synthesis wavelet filters-Cell-array of length filtNo.
+%         J     : Number of filterbank iterations.
+%         a     : Upsampling factors - array of length filtNo.
+%
+%   Output parameters:
+%         f     : Reconstructed data - L*W array.
+%
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iufwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% see comp_fwt for explanantion
+assert(a(1)==a(2),'First two elements of a are not equal. Such wavelet filterbank is not suported.');
+
+% For holding the impulse responses.
+filtNo = length(g);
+gOffset = cellfun(@(gEl) gEl.offset,g(:));
+%Change format to a matrix
+gMat = cell2mat(cellfun(@(gEl) gEl.h(:),g(:)','UniformOutput',0));
+%Scale all filters
+%gMat = bsxfun(@times,gMat,sqrt(1/(J+1)));
+gMat = bsxfun(@times,gMat,sqrt(1./(a(:)')));
+
+% Read top-level appr. coefficients.
+ca = squeeze(c(:,1,:));
+cRunPtr = 2;
+for jj=1:J
+   % Current iteration filter upsampling factor.
+   filtUps = a(1)^(J-jj); 
+   % Zero index position of the upsampled filetrs.
+   offset = filtUps.*gOffset ;%+ filtUps; 
+   % Run the filterbank
+   ca=comp_iatrousfilterbank_td([reshape(ca,size(ca,1),1,size(ca,2)),...
+                 c(:,cRunPtr:cRunPtr+filtNo-2,:)],gMat,filtUps,offset); 
+   % Bookkeeping
+   cRunPtr = cRunPtr + filtNo -1;
+end
+% Copy to the output.
+f = ca;
+    
diff --git a/inst/comp/comp_iuwfbt.m b/inst/comp/comp_iuwfbt.m
new file mode 100644
index 0000000..2c67597
--- /dev/null
+++ b/inst/comp/comp_iuwfbt.m
@@ -0,0 +1,82 @@
+function f=comp_iuwfbt(c,wtNodes,nodesUps,rangeLoc,rangeOut)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iuwfbt
+%@verbatim
+%COMP_IUWFBT Compute Inverse Undecimated Wavelet Filter-Bank Tree
+%   Usage:  f=comp_iuwfbt(c,wtNodes,nodesUps,rangeLoc,rangeOut)
+%
+%   Input parameters:
+%         c        : Coefficient array of dim. L*M*W.
+%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
+%                    BF order. Length nodeNo cell array of structures.
+%         nodesUps : Filters upsampling factor of each node. Array of
+%                    length nodeNo.
+%         rangeLoc : Idxs of each node inputs. Length nodeNo 
+%                    cell array of vectors.
+%         rangeOut : Input subband idxs of each node inputs.
+%
+%   Output parameters:
+%         f     : Reconstructed data L*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iuwfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+L = size(c,1);
+W = size(c,3);
+catmp = [];
+ca = [];
+% For each node in tree in the BF order...
+for jj=1:length(wtNodes)
+    % Node filters subs. factors
+    a = wtNodes{jj}.a;
+    % Node filters to a matrix
+    gMat = cell2mat(cellfun(@(gEl) gEl.h(:),wtNodes{jj}.g(:)','UniformOutput',0));
+    % Normalize each filter
+    gMat = bsxfun(@rdivide,gMat,sqrt(a(:)'));
+    % Node filters initial skips
+    gOffset = cellfun(@(gEl) gEl.offset,wtNodes{jj}.g);
+    
+    % Zero index position of the upsampled filters.
+    offset = nodesUps(jj).*(gOffset) ;%- nodesUps(jj);
+     
+    % Re-allocate catmp if the filtNo differs from the one used in previous
+    % iteration.
+    filtNo = size(gMat,2);
+    if(filtNo~=size(catmp,2))
+       catmp = zeros(L,filtNo,W);
+    end
+
+    % Read from input subbands
+    catmp(:,rangeLoc{jj},:) = c(:,rangeOut{jj},:);
+    diffRange = 1:filtNo;
+    diffRange(rangeLoc{jj}) = [];
+    % Read from intermediate outputs
+    if(~isempty(diffRange))
+       catmp(:,diffRange(end:-1:1),:) = ca(:,1:numel(diffRange),:);
+    end
+    
+    %Run filterbank
+    catmp = comp_iatrousfilterbank_td(catmp,gMat,nodesUps(jj),offset);
+    %Save intermediate output
+    ca = horzcat(ca(:,numel(diffRange)+1:end,:),reshape(catmp,size(catmp,1),1,size(catmp,2)));
+end
+f = catmp;
+
+
diff --git a/inst/comp/comp_iuwpfbt.m b/inst/comp/comp_iuwpfbt.m
new file mode 100644
index 0000000..fce8758
--- /dev/null
+++ b/inst/comp/comp_iuwpfbt.m
@@ -0,0 +1,66 @@
+function f=comp_iuwpfbt(c,wtNodes,nodesUps,pOutIdxs,chOutIdxs)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iuwpfbt
+%@verbatim
+%COMP_IUWPFBT Compute Inverse Undecimated Wavelet Packet Filter-Bank Tree
+%   Usage:  f=comp_iuwpfbt(c,wtNodes,nodesUps,pOutIdxs,chOutIdxs)
+%
+%   Input parameters:
+%         c          : Coefficients stored in L*M*W array.
+%         wtNodes    : Filterbank tree nodes (elementary filterbans) in
+%                      reverse BF order. Cell array of structures of length nodeNo.
+%         nodesUps   : Filters upsampling factor of each node. Array of
+%                      length nodeNo.
+%         pOutIdxs   : Idx of each node's parent. Array of length nodeNo.
+%         chOutIdxs  : Idxs of each node children. Cell array of vectors of
+%                      length nodeNo.
+%
+%   Output parameters:
+%         f     : Reconstructed data in L*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iuwpfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% For each node in tree in the BF order...
+ for jj=1:length(wtNodes)
+    % Node filters subs. factors
+    a = wtNodes{jj}.a;
+    % Node filters to a matrix
+    gMat = cell2mat(cellfun(@(gEl) gEl.h(:),wtNodes{jj}.g(:)','UniformOutput',0));
+    % Normalize each filter
+    gMat = bsxfun(@rdivide,gMat,sqrt(a(:)'));
+    % Node filters initial skips
+    gOffset = cellfun(@(gEl) gEl.offset,wtNodes{jj}.g);
+    
+    % Zero index position of the upsampled filters.
+    offset = nodesUps(jj).*(gOffset);% + nodesUps(jj);
+
+    % Run filterbank
+    ctmp = comp_iatrousfilterbank_td(c(:,chOutIdxs{jj},:),gMat,nodesUps(jj),offset);
+    
+    if(pOutIdxs(jj))
+       % Add to the existing subband
+       c(:,pOutIdxs(jj),:) = (1/sqrt(2))*(c(:,pOutIdxs(jj),:)+reshape(ctmp,size(ctmp,1),1,size(ctmp,2)));
+    else
+       % We are at the root.
+       f = ctmp;
+    end
+ end
+
diff --git a/inst/comp/comp_iwfac.m b/inst/comp/comp_iwfac.m
new file mode 100644
index 0000000..d7a6428
--- /dev/null
+++ b/inst/comp/comp_iwfac.m
@@ -0,0 +1,85 @@
+function [g]=comp_iwfac(gf,L,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iwfac
+%@verbatim
+%COMP_IWFAC  Compute inverse window factorization
+%   Usage: g=comp_iwfac(gf,a,M);
+%
+%   Input parameters:
+%         gf    : Factored Window
+%         a     : Length of time shift.
+%         M     : Number of frequency bands.
+%   Output parameters:
+%         g     : Window function.
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iwfac.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Calculate the parameters that was not specified
+R=prod(size(gf))/L;
+
+N=L/a;
+b=L/M;
+
+% The four factorization parameters.
+c=gcd(a,M);
+p=a/c;
+q=M/c;
+d=N/q;
+
+gf=reshape(gf,p,q*R,c,d);
+
+% Scale by the sqrt(M) comming from Walnuts representation
+gf=gf/sqrt(M);
+
+
+% fft them
+if d>1
+  gf=ifft(gf,[],4);
+end;
+
+g=zeros(L,R,assert_classname(gf));
+
+% Set up the small matrices
+for w=0:R-1
+  for s=0:d-1
+    for l=0:q-1
+      for k=0:p-1
+	g((1:c)+mod(k*M-l*a+s*p*M,L),w+1)=reshape(gf(k+1,l+1+q*w,:,s+1),c,1);
+      end;
+    end;
+  end;
+end;
+
+
+
diff --git a/inst/comp/comp_iwfbt.m b/inst/comp/comp_iwfbt.m
new file mode 100644
index 0000000..93a11b5
--- /dev/null
+++ b/inst/comp/comp_iwfbt.m
@@ -0,0 +1,75 @@
+function f=comp_iwfbt(c,wtNodes,outLens,rangeLoc,rangeOut,ext)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iwfbt
+%@verbatim
+%COMP_IWFBT Compute Inverse Wavelet Filter-Bank Tree
+%   Usage:  f=comp_iwfbt(c,wtNodes,outLens,rangeLoc,rangeOut,ext)
+%
+%   Input parameters:
+%         c        : Coefficients stored in the cell array.
+%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
+%                    reverse BF order. Length nodeNo cell array of structures.
+%         outLens  : Output lengths of each node. Length nodeNo array.
+%         rangeLoc : Idxs of each node inputs. Length nodeNo 
+%                    cell array of vectors.
+%         rangeOut : Input subband idxs of each node inputs.
+%         ext      : Type of the forward transform boundary handling.
+%
+%   Output parameters:
+%         f       : Reconstructed outLens(end)*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iwfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Do non-expansve transform if ext='per'
+doPer = strcmp(ext,'per');
+
+ca = {};
+ % Go over all nodes in breadth-first order
+for jj=1:length(wtNodes)
+    % Node filters to a cell array
+    gCell = cellfun(@(gEl) conj(flipud(gEl.h(:))),wtNodes{jj}.g(:),'UniformOutput',0);
+    % Node filters subs. factors
+    a = wtNodes{jj}.a;
+    % Node filters initial skips
+    if(doPer)
+       offset = cellfun(@(gEl) 1-numel(gEl.h)-gEl.offset,wtNodes{jj}.g(:));
+    else
+       offset = -(a-1);
+    end
+    filtNo = numel(gCell);
+    
+    % Prepare input cell-array
+    catmp = cell(filtNo,1);
+    % Read data from subbands
+    catmp(rangeLoc{jj}) = c(rangeOut{jj});
+    diffRange = 1:filtNo;
+    diffRange(rangeLoc{jj}) = [];
+    % Read data from intermediate outputs (filters are taken in reverse order)
+    catmp(diffRange(end:-1:1)) = ca(1:numel(diffRange));
+    
+    %Run filterbank
+    catmp = comp_ifilterbank_td(catmp,gCell,a,outLens(jj),offset,ext);
+    %Save intermediate output
+    ca = [ca(numel(diffRange)+1:end);catmp];
+end
+f = catmp;
+
+
diff --git a/inst/comp/comp_iwpfbt.m b/inst/comp/comp_iwpfbt.m
new file mode 100644
index 0000000..f4f0889
--- /dev/null
+++ b/inst/comp/comp_iwpfbt.m
@@ -0,0 +1,69 @@
+function f=comp_iwpfbt(c,wtNodes,pOutIdxs,chOutIdxs,Ls,ext,do_scale)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_iwpfbt
+%@verbatim
+%COMP_IWFBT Compute Inverse Wavelet Packet Filter-Bank Tree
+%   Usage:  f=comp_iwpfbt(c,wtNodes,pOutIdxs,chOutIdxs,Ls,ext)
+%
+%   Input parameters:
+%         c          : Coefficients stored in cell array.
+%         wtNodes    : Filterbank tree nodes (elementary filterbans) in
+%                      reverse BF order. Cell array of structures of length nodeNo.
+%         pOutIdxs   : Idx of each node's parent. Array of length nodeNo.
+%         chOutIdxs  : Idxs of each node children. Cell array of vectors of
+%                      length nodeNo.
+%         ext        : Type of the forward transform boundary handling.
+%
+%   Output parameters:
+%         f          : Reconstructed data in L*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_iwpfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Do non-expansve transform if ext=='per'
+doPer = strcmp(ext,'per');
+
+% For each node in tree in the BF order...
+ for jj=1:length(wtNodes)
+    % Node filters to a cell array
+    gCell = cellfun(@(gEl)conj(flipud(gEl.h(:))),wtNodes{jj}.g(:),'UniformOutput',0);
+    % Node filters subs. factors
+    a = wtNodes{jj}.a;
+    % Node filters initial skips
+    if(doPer)
+       offset = cellfun(@(gEl) 1-numel(gEl.h)-gEl.offset,wtNodes{jj}.g);
+    else
+       offset = -(a-1);
+    end
+    
+    if(pOutIdxs(jj))
+       % Run filterbank and add to the existing subband.
+       ctmp = comp_ifilterbank_td(c(chOutIdxs{jj}),gCell,a,size(c{pOutIdxs(jj)},1),offset,ext);
+       c{pOutIdxs(jj)} = c{pOutIdxs(jj)}+ctmp;
+       if do_scale
+           c{pOutIdxs(jj)} = (1/sqrt(2))*c{pOutIdxs(jj)};
+       end
+    else
+       % We are at the root.
+       f = comp_ifilterbank_td(c(chOutIdxs{jj}),gCell,a,Ls,offset,ext);
+    end
+ end
+     
+ 
diff --git a/inst/comp/comp_nonsepdgt_multi.m b/inst/comp/comp_nonsepdgt_multi.m
new file mode 100644
index 0000000..97caf24
--- /dev/null
+++ b/inst/comp/comp_nonsepdgt_multi.m
@@ -0,0 +1,60 @@
+function c=comp_nonsepdgt_multi(f,g,a,M,lt)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_nonsepdgt_multi
+%@verbatim
+%COMP_NONSEPDGT_MULTI  Compute Non-separable Discrete Gabor transform
+%   Usage:  c=comp_nonsepdgt_multi(f,g,a,M,lt);
+%
+%   This is a computational subroutine, do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_nonsepdgt_multi.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Nicki Holighaus and Peter L. Soendergaard
+%   TESTING: TEST_NONSEPDGT
+%   REFERENCE: REF_NONSEPDGT
+
+% Assert correct input.
+
+L=size(f,1);
+W=size(f,2);
+N=L/a;
+
+% ----- algorithm starts here, split into sub-lattices ---------------
+
+c=zeros(M,N,W,assert_classname(f,g));
+
+mwin=comp_nonsepwin2multi(g,a,M,lt,L);
+
+% simple algorithm: split into sublattices
+
+for ii=0:lt(2)-1
+    c(:,ii+1:lt(2):end,:)=comp_dgt(f,mwin(:,ii+1),lt(2)*a,M,[0 1],0,0,0);
+end;
+
+% Phase factor correction 
+E = zeros(1,N,assert_classname(f,g));
+for win=0:lt(2)-1
+    for n=0:N/lt(2)-1
+        E(win+n*lt(2)+1) = exp(-2*pi*i*a*n*rem(win*lt(1),lt(2))/M);
+    end;
+end;
+
+c=bsxfun(@times,c,E);
+
diff --git a/inst/comp/comp_nonsepdgt_shear.m b/inst/comp/comp_nonsepdgt_shear.m
new file mode 100644
index 0000000..9f248ca
--- /dev/null
+++ b/inst/comp/comp_nonsepdgt_shear.m
@@ -0,0 +1,154 @@
+function c=comp_nonsepdgt_shear(f,g,a,M,s0,s1,br);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_nonsepdgt_shear
+%@verbatim
+%COMP_NONSEPDGT_SHEAR  Compute Non-separable Discrete Gabor transform
+%   Usage:  c=nonsepdgt(f,g,a,M,lt);
+%
+%   This is a computational subroutine, do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_nonsepdgt_shear.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Nicki Holighaus and Peter L. Soendergaard
+%   TESTING: TEST_NONSEPDGT
+%   REFERENCE: REF_NONSEPDGT
+
+% Assert correct input.
+
+L=size(f,1);
+W=size(f,2);
+b=L/M;
+N=L/a;
+
+c=zeros(M,N,W,assert_classname(f,g));
+
+ar = a*b/br;
+Mr = L/br;
+Nr = L/ar;
+
+            
+if s1 ~= 0
+    p = comp_pchirp(L,s1);
+    g = p.*g;
+    f = bsxfun(@times,p,f);
+end
+
+if s0 == 0
+
+    c_rect = comp_dgt_long(f,g,a,M);
+    tmp1=mod(s1*a*(L+1),2*N);
+
+    for k=0:Nr-1   
+        phsidx= mod(mod(tmp1*k,2*N)*k,2*N);
+        phs = exp(pi*1i*phsidx/N);
+        idx2 = floor(mod(-s1*k*a+(0:Mr-1)*b,L)/b);
+            
+        c(idx2+1,k+1,:) = c_rect(:,k+1,:).*phs;
+    end;
+    
+else 
+    twoN=2*N;
+    cc1=ar/a;
+    cc2=mod(-s0*br/a,twoN);
+    cc3=mod(a*s1*(L+1),twoN);
+    cc4=mod(cc2*br*(L+1),twoN);
+    cc5=mod(2*cc1*br,twoN);
+    cc6=mod((s0*s1+1)*br,L);
+    
+    p = comp_pchirp(L,-s0);
+    g = p.*fft(g)/L;
+    f = bsxfun(@times,p,fft(f));
+    
+    c_rect = comp_dgt_long(f,g,br,Nr);
+    
+    for k=0:Nr-1   
+        for m=0:Mr-1
+            sq1=mod(k*cc1+cc2*m,twoN);
+            phsidx = mod(mod(cc3*sq1.^2,twoN)-mod(m*(cc4*m+k*cc5),twoN),twoN);            
+            phs = exp(pi*1i*phsidx/N);
+            
+            idx1 =       mod(   cc1*k+cc2*m,N);
+            idx2 = floor(mod(-s1*ar*k+cc6*m,L)/b);
+            
+            c(idx2+1,idx1+1,:) = c_rect(mod(-k,Nr)+1,m+1,:).*phs;
+        end;
+    end;                    
+end;
+
+
+% This is some old code just kept around for historical/documentational
+% purposes
+if 0
+
+    ind = [ar 0; 0 br]*[kron((0:L/ar-1),ones(1,L/br));kron(ones(1,L/ar), ...
+                                                  (0:L/br-1))];
+
+   
+    phs = reshape(mod((s1*(ind(1,:)-s0*ind(2,:)).^2+s0*ind(2,:).^2)*(L+1) ...
+                      -2*(s0 ~= 0)*ind(1,:).*ind(2,:),2*L),Mr,Nr);
+
+    ind_final = [1 0;-s1 1]*[1 -s0;0 1]*ind;
+
+    phs = exp(pi*1i*phs/L);
+
+    ind_final = mod(ind_final,L);
+    
+    if s1 ~= 0
+        g = comp_pchirp(L,s1).*g;
+        f = bsxfun(@times,comp_pchirp(L,s1),f);
+    end
+    
+    if s0 ~= 0
+        g = comp_pchirp(L,-s0).*fft(g)/L;
+        f = bsxfun(@times,comp_pchirp(L,-s0),fft(f));
+        
+        c_rect = comp_dgt_long(f,g,br,Nr);
+        
+        for w=0:W-1
+            
+            c(floor(ind_final(2,:)/b)+1+(ind_final(1,:)/a)*M+w*M*N) = ...
+                c_rect(ind(1,[1:Mr,end:-1:Mr+1])/ar+1+(ind(2,:)/br)*Nr+w*M*N).* ...
+                phs(ind(2,:)/br+1+(ind(1,:)/ar)*Mr);
+        end;
+    else 
+        
+        c_rect = comp_dgt_long(f,g,ar,Mr);
+        
+        for w=1:W
+            c_rect(:,:,w) = phs.*c_rect(:,:,w);
+        end;
+        
+        % The code line below this comment executes the commented for-loop
+        % using Fortran indexing.
+        %
+        % for jj = 1:size(ind,2)        
+        %     c(floor(ind_final(2,jj)/b)+1, ind_final(1,jj)/a+1) = ...
+        %         c_rect(ind(2,jj)/br+1, ind(1,jj)/ar+1);
+        % end
+        for w=0:W-1
+            c(floor(ind_final(2,:)/b)+1+(ind_final(1,:)/a)*M+w*M*N) = ... 
+                c_rect(ind(2,:)/br+1+(ind(1,:)/ar)*Mr+w*M*N);
+        end;
+    end;
+        
+end;
+
+
+
diff --git a/inst/comp/comp_nonsepdgtreal_quinqux.m b/inst/comp/comp_nonsepdgtreal_quinqux.m
new file mode 100644
index 0000000..ccbdc0d
--- /dev/null
+++ b/inst/comp/comp_nonsepdgtreal_quinqux.m
@@ -0,0 +1,61 @@
+function c=comp_nonsepdgtreal_quinqux(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_nonsepdgtreal_quinqux
+%@verbatim
+%COMP_NONSEPDGTREAL_QUINQUX  Compute Non-separable Discrete Gabor transform
+%   Usage:  c=comp_nonsepdgtreal_quinqux(f,g,a,M);
+%
+%   This is a computational subroutine, do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_nonsepdgtreal_quinqux.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Nicki Holighaus and Peter L. Soendergaard
+%   TESTING: TEST_NONSEPDGT
+%   REFERENCE: REF_NONSEPDGT
+
+lt=[1 2];
+
+L=size(f,1);
+W=size(f,2);
+N=L/a;
+M2=floor(M/2)+1;
+
+% ----- algorithm starts here, split into sub-lattices ---------------
+
+c=zeros(M,N,W,assert_classname(f,g));
+
+mwin=comp_nonsepwin2multi(g,a,M,[1 2],L);
+
+% simple algorithm: split into sublattices
+
+for ii=0:1
+    c(:,ii+1:2:end,:)=comp_dgt(f,mwin(:,ii+1),2*a,M,[0 1],0,0,0);
+end;
+
+% Phase factor correction 
+E = zeros(1,N,assert_classname(f,g));
+for win=0:1
+    for n=0:N/2-1
+        E(win+n*2+1) = exp(-2*pi*i*a*n*rem(win,2)/M);
+    end;
+end;
+
+c=bsxfun(@times,c(1:M2,:,:),E);
+
diff --git a/inst/comp/comp_nonsepwin2multi.m b/inst/comp/comp_nonsepwin2multi.m
new file mode 100644
index 0000000..3f0b790
--- /dev/null
+++ b/inst/comp/comp_nonsepwin2multi.m
@@ -0,0 +1,37 @@
+function mwin=comp_nonsepwin2multi(g,a,M,lt,L);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_nonsepwin2multi
+%@verbatim
+% Create multiwindow from non-sep win
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_nonsepwin2multi.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+g=fir2long(g,L);
+
+Lg=size(g,1);
+
+b=L/M;
+mwin=zeros(Lg,lt(2),assert_classname(g));
+l=long2fir((0:L-1).'/L,Lg);
+for ii=0:lt(2)-1
+  wavenum=mod(ii*lt(1),lt(2))*b/lt(2);
+  mwin(:,ii+1)=exp(2*pi*i*l*wavenum).*circshift(g,ii*a);
+end;
+
diff --git a/inst/comp/comp_pchirp.m b/inst/comp/comp_pchirp.m
new file mode 100644
index 0000000..ac787cb
--- /dev/null
+++ b/inst/comp/comp_pchirp.m
@@ -0,0 +1,41 @@
+function g=comp_pchirp(L,n)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_pchirp
+%@verbatim
+%COMP_PCHIRP  Compute periodic chirp
+%   Usage:  g=comp_pchirp(L,n);
+%
+%   pchirp(L,n) returns a periodic, discrete chirp of length L that
+%   revolves n times around the time-frequency plane in frequency. n must be
+%   an integer number.
+%
+%   This is a computational routine. Do not call it unless you have
+%   verified the input parameters.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_pchirp.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+l= (0:L-1).';
+X = mod(mod(mod(n*l,2*L).*l,2*L)*(L+1),2*L);
+g = exp(pi*1i*X/L);
+
diff --git a/inst/comp/comp_pgauss.m b/inst/comp/comp_pgauss.m
new file mode 100644
index 0000000..3f3291b
--- /dev/null
+++ b/inst/comp/comp_pgauss.m
@@ -0,0 +1,73 @@
+function [g]=comp_pgauss(L,w,c_t,c_f)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_pgauss
+%@verbatim
+%COMP_PGAUSS  Sampled, periodized Gaussian.
+%   
+%   Computational routine: See help on PGAUSS.
+%
+%   center=0  gives whole-point centered function.
+%   center=.5 gives half-point centered function.
+%
+%   Does not check input parameters, do not call this
+%   function directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_pgauss.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% c_t - time centering
+% c_f - frequency centering
+
+% Input data type cannot be determined
+g=zeros(L,1);
+
+if L==0
+  return;
+end;
+
+sqrtl=sqrt(L);
+safe=4;
+
+% Keep the delay in a sane interval
+c_t=rem(c_t,L);
+
+% Outside the interval [-safe,safe] then exp(-pi*x.^2) is numerically zero.
+nk=ceil(safe/sqrt(L/sqrt(w)));
+lr=(0:L-1).'+c_t;
+for k=-nk:nk  
+  g=g+exp(-pi*(lr/sqrtl-k*sqrtl).^2/w+2*pi*i*c_f*(lr/L-k));
+end;
+
+% Normalize it exactly.
+g=g/norm(g);
+
+% This normalization is only approximate, it works for the continous case
+% but not for the discrete
+%g=g*(w*L/2)^(-.25);
+
+
+
+
+
diff --git a/inst/comp/comp_sepdgt.m b/inst/comp/comp_sepdgt.m
new file mode 100644
index 0000000..6ab9fd0
--- /dev/null
+++ b/inst/comp/comp_sepdgt.m
@@ -0,0 +1,42 @@
+function [coef]=comp_sepdgt(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_sepdgt
+%@verbatim
+%COMP_SEPDGT  Separable DGT
+%   Usage:  c=comp_sepdgt(f,g,a,M);
+%  
+%   This is a computational routine. Do not call it directly.
+%
+%   See help on DGT.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_sepdgt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+L=size(f,1);
+Lwindow=size(g,1);
+
+if Lwindow<L
+   % Do the filter bank algorithm
+   coef=comp_dgt_fb(f,g,a,M);
+else
+   % Do the factorization algorithm
+   coef=comp_dgt_long(f,g,a,M);
+end;
diff --git a/inst/comp/comp_sepdgtreal.m b/inst/comp/comp_sepdgtreal.m
new file mode 100644
index 0000000..bea21ec
--- /dev/null
+++ b/inst/comp/comp_sepdgtreal.m
@@ -0,0 +1,47 @@
+function [coef]=comp_sepdgtreal(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_sepdgtreal
+%@verbatim
+%COMP_SEPDGTREAL  Filter bank DGT
+%   Usage:  c=comp_sepdgtreal(f,g,a,M);
+%  
+%   This is a computational routine. Do not call it directly.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_sepdgtreal.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   See help on DGT.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+L=size(f,1);
+Lwindow=size(g,1);
+
+    if Lwindow<L
+        % Do the filter bank algorithm
+        % Periodic boundary conditions
+        coef=comp_dgtreal_fb(f,g,a,M);
+        %c=reshape(c,M2,N,W);
+        
+    else
+        % Do the factorization algorithm 
+        coef=comp_dgtreal_long(f,g,a,M);
+        %c=reshape(c,M2,N,W);
+
+    end;
diff --git a/inst/comp/comp_sigreshape_post.m b/inst/comp/comp_sigreshape_post.m
new file mode 100644
index 0000000..c12460c
--- /dev/null
+++ b/inst/comp/comp_sigreshape_post.m
@@ -0,0 +1,43 @@
+function f=comp_sigreshape_post(f,fl,wasrow,remembershape)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_sigreshape_post
+%@verbatim
+%COMP_SIGRESHAPE_POST
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_sigreshape_post.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+% Get original dimensionality
+fd=length(remembershape);
+
+if fd>2
+  f=reshape(f,[fl,remembershape(2:fd)]);
+else
+  if wasrow
+    f=f.';
+  end;
+end;
+
+
+
diff --git a/inst/comp/comp_sigreshape_pre.m b/inst/comp/comp_sigreshape_pre.m
new file mode 100644
index 0000000..53118d5
--- /dev/null
+++ b/inst/comp/comp_sigreshape_pre.m
@@ -0,0 +1,68 @@
+function [f,fl,W,wasrow,remembershape]=comp_sigreshape_pre(f,callfun,do_ndim)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_sigreshape_pre
+%@verbatim
+%COMP_SIGRESHAPE_PRE
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_sigreshape_pre.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+    
+wasrow=0;
+
+% Rember the shape if f is multidimensional.
+remembershape=size(f);
+fd=length(remembershape);
+
+
+% Multi-dimensional mode, apply to first dimension.
+if fd>2
+	
+  if (do_ndim>0) && (fd>do_ndim)
+    error([callfun,': ','Cannot process multidimensional arrays.']);
+  end;
+  
+  fl=size(f,1);
+  W=prod(remembershape)/fl;
+
+  % Reshape to matrix if multidimensional.
+  f=reshape(f,fl,W);
+
+else
+
+  if size(f,1)==1
+    wasrow=1;
+    % Make f a column vector.
+    f=f(:);
+  end;
+  
+  fl=size(f,1);
+  W=size(f,2);
+  
+end;
+
+
+
+
+
+
diff --git a/inst/comp/comp_transferfunction.m b/inst/comp/comp_transferfunction.m
new file mode 100644
index 0000000..34760e7
--- /dev/null
+++ b/inst/comp/comp_transferfunction.m
@@ -0,0 +1,63 @@
+function H=comp_transferfunction(g,L)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_transferfunction
+%@verbatim
+%COMP_TRANSFERFUNCTION  Compute the transfer function
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_transferfunction.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+l=(0:L-1).'/L;
+if isfield(g,'h')
+    
+    % This is not safe when already having imp. resp. of length L
+    % with zero delay (periodically wrapped).
+ 
+    g_time=circshift(postpad(g.h,L),g.offset);
+
+    
+    if isfield(g,'fc')
+       g_time = g_time.*exp(2*pi*1i*round(g.fc*L/2)*l);
+    end
+        
+    if isfield(g,'realonly') && g.realonly
+        g_time=real(g_time);
+    end;
+        
+    H=fft(g_time);
+    
+elseif isfield(g,'H')
+    if ~isnumeric(g.H)
+        g.H=g.H(L);
+        g.foff=g.foff(L);
+    end;
+    
+    H=circshift(postpad(g.H(:),L),g.foff);
+    
+    if isfield(g,'delay')
+       H = H.*exp(-2*pi*1i*round(g.delay)*l);
+    end
+    
+    if isfield(g,'realonly') && g.realonly
+        H=(H+involute(H))/2;
+    end;
+else
+    error('%s: Unrecognized filter format. The struct should have either .h or .H field.',upper(mfilename));    
+end;
+
diff --git a/inst/comp/comp_ufilterbank_fft.m b/inst/comp/comp_ufilterbank_fft.m
new file mode 100644
index 0000000..aab9ce8
--- /dev/null
+++ b/inst/comp/comp_ufilterbank_fft.m
@@ -0,0 +1,52 @@
+function c=comp_ufilterbank_fft(f,g,a);  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ufilterbank_fft
+%@verbatim
+%COMP_UFILTERBANK_FFT   Classic filtering by FFT
+%   Usage:  c=comp_ufilterbank_fft(f,g,a);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ufilterbank_fft.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+L=size(f,1);
+W=size(f,2);
+M=size(g,2);
+
+N=L/a;
+
+c=zeros(N,M,W,assert_classname(f,g));
+
+% This routine does not yet use FFTREAL, because it must be able to
+% handle downsampling, which is much easier to express in the FFT case.
+G=fft(fir2long(g,L));
+
+for w=1:W
+  F=fft(f(:,w));
+  for m=1:M
+    c(:,m,w)=ifft(sum(reshape(F.*G(:,m),N,a),2))/a;
+  end;
+end;
+
+if isreal(f) && isreal(g)
+  c=real(c);
+end;
+  
+
+
diff --git a/inst/comp/comp_ufilterbank_td.m b/inst/comp/comp_ufilterbank_td.m
new file mode 100644
index 0000000..57cf3e2
--- /dev/null
+++ b/inst/comp/comp_ufilterbank_td.m
@@ -0,0 +1,84 @@
+function c=comp_ufilterbank_td(f,g,a,skip,ext)  
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ufilterbank_td
+%@verbatim
+%COMP_UFILTERBANK_TD   Uniform filterbank by conv2
+%   Usage:  c=comp_ufilterbank_td(f,g,a,skip,ext);
+%
+%   Input parameters:
+%         f   : Input data - L*W array.
+%         g   : Filterbank filters - filtLen*M array. 
+%         a   : Subsampling factor - scalar.
+%         skip: Delay of the filters - scalar or array of length M. 
+%         ext : Border exension technique.
+%
+%   Output parameters:
+%         c  : N*M*W array of coefficients
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ufilterbank_td.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%input data length
+L=size(f,1);
+%input channel number
+W=size(f,2);
+%filter number
+M=size(g,2);
+%length of filters
+filtLen = size(g,1);
+% Allow filter delay only in the filter support range
+if(all(skip>=filtLen) || all(skip<0))
+  error('%s: The filter zero index position outside of the filter support.', upper(mfilename));  
+end
+
+if(numel(skip)==1)
+    skip = skip*ones(M,1);
+end
+
+% Determine output length
+% Lext -- length of the signal after convolution before subsampling
+% N -- after subsampling
+if(strcmp(ext,'per'))
+   Lext = L;
+   N = ceil(Lext/a);
+else
+   Lext = (L+filtLen-1);
+   N = ceil((Lext-skip)/a); 
+end
+%The minimum input signal length which produces N output samples
+Lreq = a*(N-1) + 1;
+
+% Output memory allocation
+c=zeros(N,M,W,assert_classname(f,g));
+
+% Explicitly extend the input. length(fext) = length(f) + 2*(filtLen-1)
+fext = comp_extBoundary(f,filtLen-1,ext,'dim',1);
+% CONV2 does 2-D linear convolution. 'valid' option crops tails
+% length(fextconv2) = length(f) + (filtLen-1)
+% length(c(:,m,:)) = N
+% W channels done simultaneously by conv2
+for m=1:M
+  c(:,m,:) = comp_downs(conv2(fext,g(:,m),'valid'),a,skip(m),Lreq); 
+end;
+
+ 
+
+
diff --git a/inst/comp/comp_ufwt.m b/inst/comp/comp_ufwt.m
new file mode 100644
index 0000000..465c03b
--- /dev/null
+++ b/inst/comp/comp_ufwt.m
@@ -0,0 +1,71 @@
+function c = comp_ufwt(f,h,J,a)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ufwt
+%@verbatim
+%COMP_UFWT Compute Undecimated DWT
+%   Usage:  c=comp_ufwt(f,h,J,a);
+%
+%   Input parameters:
+%         f     : Input data - L*W array.
+%         h     : Analysis Wavelet filters - cell-array of length filtNo.
+%         J     : Number of filterbank iterations.
+%         a     : Subsampling factors - array of length filtNo.
+%
+%   Output parameters:
+%         c     : L*M*W array of coefficients, where M=J*(filtNo-1)+1.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ufwt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+% This could be removed with some effort. The question is, are there such
+% wavelet filters? If your filterbank has different subsampling factors after first two filters, please send a feature request.
+assert(a(1)==a(2),'First two elements of a are not equal. Such wavelet filterbank is not suported.');
+
+% For holding the time-reversed, complex conjugate impulse responses.
+filtNo = length(h);
+%Change format to a matrix
+hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),h(:)','UniformOutput',0));
+%Divide each column (filter) by a element of a
+hMat = bsxfun(@rdivide,hMat,sqrt(a(:)'));
+%Delays
+hOffset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,h(:));
+
+% Allocate output
+[L, W] = size(f);
+M = J*(filtNo-1)+1;
+c = zeros(L,M,W,assert_classname(f,hMat));
+
+ca = f;
+runPtr = size(c,2) - (filtNo-2);
+for jj=1:J
+    % Zero index position of the upsampled filters.
+    offset = a(1)^(jj-1).*(hOffset);
+    % Run filterbank.
+    ca=comp_atrousfilterbank_td(ca,hMat,a(1)^(jj-1),offset);
+    % Bookkeeping
+    c(:,runPtr:runPtr+filtNo-2,:)=ca(:,2:end,:);
+    ca = squeeze(ca(:,1,:));
+    runPtr = runPtr - (filtNo - 1);
+end
+% Saving final approximation coefficients.
+c(:,1,:) = ca;
+
+
diff --git a/inst/comp/comp_ups.m b/inst/comp/comp_ups.m
new file mode 100644
index 0000000..30bef8f
--- /dev/null
+++ b/inst/comp/comp_ups.m
@@ -0,0 +1,126 @@
+function fups = comp_ups(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_ups
+%@verbatim
+%COMP_UPS Upsampling
+%   Usage: fups = comp_ups(f,a) 
+%          fups = comp_ups(f,a,type,'dim',dim)
+%          fups = comp_ups(f,a,skip,L,'dim',dim) 
+%   
+%   Input parameters:
+%         f     : Input vector/matrix.
+%         a     : Upsampling factor.
+%         type  : Type of the upsampling/initial skip.
+%         L     : Required output length.
+%         dim   : Direction of upsampling.
+%   Output parameters:
+%         fups  : Upsampled vector/matrix.
+%
+%   Upsamples input f by a factor a (puts a-1 zeros between data elements)
+%   along dimension dim. If dim is not specified, first non-singleton
+%   dimension is used. Parameter type (integer from [0:3]) specifies whether the upsampling
+%   includes beginning/tailing zeros:
+%
+%   type=0 (default): Includes just tailing zeros.
+%   type=1: No beginning nor tailing zeros.
+%   type=2: Includes just begining zeros.
+%   type=3: Includes both. 
+%
+%   If non-empty parameter L is passed, it specifies the required output
+%   length and the type changes to skip which denotes how many zeros to
+%   add before the first sample.
+%
+%   Examples:
+%   ---------
+%
+%   The outcome of the default upsampling type is equal to the upsampling performed
+%   directly in the frequency domain using repmat:
+%
+%      f = 1:4;
+%      a = 3;
+%      fupsTD = comp_ups(f,a)
+%      fupsFD = real(ifft(repmat(fft(f),1,a)))
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_ups.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+definput.keyvals.dim = [];
+definput.keyvals.a = 2;
+definput.keyvals.type = 0;
+definput.keyvals.L = [];
+[flags,kv,a,type,L]=ltfatarghelper({'a','type','L'},definput,varargin);
+
+% a have to be positive integer
+if(a<1)
+    a = 1;
+end
+if(type<0)
+    type = 0;
+end
+
+if(a<0 || rem(a,1)~=0)
+    error('%s: Parameter *a* have to be a positive integer.',upper(mfilename));
+end
+% if L == [], supported types are 0-3
+if(isempty(L)&&(type<0||type>3))
+    error('%s: Unsupported upsampling type.',upper(mfilename));
+end
+
+if(~isempty(L)&&type>=L)
+    error('%s: Initial zeros count is bigger than the output length.',upper(mfilename));
+end
+
+if(ndims(f)>2)
+    error('%s: Multidimensional signals (d>2) are not supported.',upper(mfilename));
+end
+
+%% ----- step 1 : Verify f and determine its length -------
+[f,~,Ls,~,dim,~,order]=assert_sigreshape_pre(f,[],kv.dim,upper(mfilename));
+
+
+if(~isempty(L))
+    fups=zeros(L,size(f,2),assert_classname(f)); 
+    fbound = min(ceil((L-type)/a),Ls);
+    fups(1+type:a:fbound*a+type,:)=f(1:fbound); 
+else
+    if(type==0)
+      % Include just tailing zeros.
+      fups=zeros(a*Ls,size(f,2),assert_classname(f));    
+      fups(1:a:end,:)=f; 
+    elseif(type==1)
+      % Do not include beginning nor tailing zeros.
+      fups=zeros(a*Ls-(a-1),size(f,2),assert_classname(f));    
+      fups(1:a:end,:)=f;    
+    elseif(type==2)
+      % Include just beginning zeros.
+      fups=zeros(a*Ls,size(f,2),assert_classname(f));    
+      fups(a:a:end,:)=f;  
+    elseif(type==3)
+      % Include both beginning and tailing zeros.
+      fups=zeros(a*Ls+a-1,size(f,2),assert_classname(f));    
+      fups(a:a:end,:)=f;   
+    end
+end
+
+permutedSizeAlt = size(fups);
+fups=assert_sigreshape_post(fups,dim,permutedSizeAlt,order);
+
+
diff --git a/inst/comp/comp_uwfbt.m b/inst/comp/comp_uwfbt.m
new file mode 100644
index 0000000..4851296
--- /dev/null
+++ b/inst/comp/comp_uwfbt.m
@@ -0,0 +1,74 @@
+function c=comp_uwfbt(f,wtNodes,nodesUps,rangeLoc,rangeOut)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_uwfbt
+%@verbatim
+%COMP_UWFBT Compute Undecimated Wavelet Filterbank Tree
+%   Usage:  c=comp_uwfbt(f,wtNodes,nodesUps,rangeLoc,rangeOut);
+%
+%   Input parameters:
+%         f        : Input L*W array.
+%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
+%                    BF order. Length nodeNo cell array of structures.
+%         nodesUps : Filters upsampling factor of each node. Array of
+%                    length nodeNo.
+%         rangeLoc : Idxs of each node terminal outputs. Length nodeNo 
+%                    cell array of vectors.
+%         rangeOut : Output subband idxs of each node terminal outputs.
+%
+%   Output parameters:
+%         c     : Coefficient array of dim. L*M*W.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_uwfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+% Pre-allocated output
+[L, W] = size(f);
+M = sum(cellfun(@(rEl) numel(rEl),rangeOut));
+c = zeros(L,M,W,assert_classname(f,wtNodes{1}.h{1}.h));
+
+% Convenience input reshape
+ca = reshape(f,size(f,1),1,size(f,2));
+% For each node in tree in the BF order...
+for jj=1:numel(wtNodes)
+   % Node filters subs. factors
+   a = wtNodes{jj}.a;
+   % Node filters to a matrix
+   hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),wtNodes{jj}.h(:)','UniformOutput',0));
+   % Normalize each filter
+   hMat = bsxfun(@rdivide,hMat,sqrt(a(:)'));
+   % Node filters initial skips
+   hOffset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNodes{jj}.h);
+   % Zero index position of the upsampled filters.
+   offset = nodesUps(jj).*(hOffset);
+   
+   % Run filterbank.
+   catmp=comp_atrousfilterbank_td(squeeze(ca(:,1,:)),hMat,nodesUps(jj),offset);
+   % Bookkeeping
+   % Copy what goes directly to the output...
+   c(:,rangeOut{jj},:)=catmp(:,rangeLoc{jj},:);
+   % ...and save the rest.
+   diffRange = 1:size(hMat,2);
+   diffRange(rangeLoc{jj}) = [];
+   ca = [ca(:,2:end,:), catmp(:,diffRange,:)];
+end 
+
+
+
diff --git a/inst/comp/comp_uwpfbt.m b/inst/comp/comp_uwpfbt.m
new file mode 100644
index 0000000..f652ce9
--- /dev/null
+++ b/inst/comp/comp_uwpfbt.m
@@ -0,0 +1,81 @@
+function c=comp_uwpfbt(f,wtNodes,rangeLoc,nodesUps)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_uwpfbt
+%@verbatim
+%COMP_UWPFBT Compute Undecimated Wavelet Packet Filterbank Tree
+%   Usage:  c=comp_uwpfbt(f,wtNodes,nodesUps);
+%
+%   Input parameters:
+%         f        : Input data as L*W array.
+%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
+%                    BF order. Cell array of structures of length nodeNo.
+%         nodesUps : Filters upsampling factor of each node. Array of
+%                    length nodeNo. 
+%
+%   Output parameters:
+%         c        : Coefficients stored in L*M*W array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_uwpfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Pre-allocated output
+[L, W] = size(f);
+M = sum(cellfun(@(wtEl) numel(wtEl.h),wtNodes));
+c = zeros(L,M,W,assert_classname(f,wtNodes{1}.h{1}.h));
+
+% Convenience input reshape
+ca = reshape(f,size(f,1),1,size(f,2));
+cOutRunIdx = 1;
+cInRunIdxs = [1];
+% For each node in tree in the BF order...
+for jj=1:numel(wtNodes)
+   % Node filters subs. factors
+   a = wtNodes{jj}.a;
+   % Node filters to a matrix
+   hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),wtNodes{jj}.h(:)','UniformOutput',0));
+   % Normalize each each filter
+   hMat = bsxfun(@rdivide,hMat,sqrt(a(:)'));
+   % Node filters initial skips
+   hOffet = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNodes{jj}.h);
+   % Number of filters of the current node
+   filtNo = size(hMat,2);
+   % Zero index position of the upsampled filters.
+   offset = nodesUps(jj).*(hOffet);
+
+   % Run filterbank
+   c(:,cOutRunIdx:cOutRunIdx + filtNo-1,:)=...
+      comp_atrousfilterbank_td(squeeze(ca(:,1,:)),hMat,nodesUps(jj),offset);
+   
+   % Bookkeeping
+   outRange = cOutRunIdx:cOutRunIdx+filtNo-1;
+   outRange(rangeLoc{jj}) = [];
+   cInRunIdxs = [cInRunIdxs(2:end),outRange];
+   
+   cOutRunIdx = cOutRunIdx + filtNo;
+   
+   % Prepare input for the next iteration
+   if ~isempty(cInRunIdxs)
+      c(:,cInRunIdxs(1),:) = c(:,cInRunIdxs(1),:)/sqrt(2);
+      ca = c(:,cInRunIdxs(1),:);
+   end
+end   
+
+
+
diff --git a/inst/comp/comp_warpedfoff.m b/inst/comp/comp_warpedfoff.m
new file mode 100644
index 0000000..e02c057
--- /dev/null
+++ b/inst/comp/comp_warpedfoff.m
@@ -0,0 +1,27 @@
+function foff=comp_warpedfoff(fc,bw,fs,L,scaletofreq)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_warpedfoff
+%@verbatim
+%COMP_WARPEDFOFF  foff for warped filters
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_warpedfoff.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+foff=floor(scaletofreq(fc-.5*bw)/fs*L)+1;
+
diff --git a/inst/comp/comp_warpedfreqresponse.m b/inst/comp/comp_warpedfreqresponse.m
new file mode 100644
index 0000000..a47a91d
--- /dev/null
+++ b/inst/comp/comp_warpedfreqresponse.m
@@ -0,0 +1,90 @@
+function H=comp_warpedfreqresponse(wintype,fc,bw,fs,L,freqtoscale,scaletofreq,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_warpedfreqresponse
+%@verbatim
+%COMP_WARPEDFREQRESPONSE  Transfer function of warped filter
+%   Usage: H=comp_warpedfreqresponse(wintype,fc,bw,fs,L,freqtoscale);
+%          H=comp_warpedfreqresponse(wintype,fc,bw,fs,L,freqtoscale,normtype);
+%
+%   Input parameters:
+%      wintype     : Type of window (from firwin)
+%      fc          : Centre frequency, in scale units.
+%      bw          : Bandwith, in scale units.
+%      fs          : Sampling frequency in Hz.
+%      L           : Transform length (in samples).
+%      freqtoscale : Function to convert Hz into scale units.
+%      scaletofreq : Function to convert scale units into Hz.
+%      normtype    : Normalization flag to pass to NORMALIZE.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_warpedfreqresponse.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+definput.import={'normalize'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Compute the values in Aud of the channel frequencies of an FFT of
+% length L.
+bins_lo   = freqtoscale(modcent(fs*(0:L-1)/L,fs)).';
+
+% This one is necessary to represent the highest frequency filters, which
+% overlap into the negative frequencies.
+nyquest2  = 2*freqtoscale(fs/2);
+bins_hi   = nyquest2+bins_lo;
+
+% firwin makes a window of width 1 centered around 0 on the scale, so we rescale the
+% bins in order to pass the correct width to firwin and subtract fc
+bins_lo=(bins_lo-fc)/bw;
+bins_hi=(bins_hi-fc)/bw;
+
+pos_lo=comp_warpedfoff(fc,bw,fs,L,scaletofreq);
+% The "floor" below often cuts away a non-zero sample, but it makes
+% the support stay below the limit needed for the painless case. Same
+% deal 4 lines below.
+pos_hi=floor(scaletofreq(fc+.5*bw)/fs*L);
+
+if pos_hi>L/2
+    % Filter is high pass and spilling into the negative frequencies
+    pos_hi=floor(scaletofreq(fc+.5*bw-nyquest2)/fs*L);    
+end;
+
+win_lo=firwin(wintype,bins_lo);
+win_hi=firwin(wintype,bins_hi);
+
+H=win_lo+win_hi;
+   
+H=normalize(H,flags.norm);
+
+H=circshift(H,-pos_lo);
+upidx=modcent(pos_hi-pos_lo,L);
+
+% ------ Testing ---------------
+if 0
+    bb=circshift(bins_lo,-pos_lo);
+    if bb(1)<-0.5
+        % Adjust bin_lo
+        error('Could do better here.');
+    end;
+    if (bb(upidx+1)<0.5) && (bb(upidx+1)>0)
+        disp('Chopped non-zero sample.');
+        bb(upidx+1)
+    end;
+end;
+
+H=H(1:upidx);
+
diff --git a/inst/comp/comp_wfac.m b/inst/comp/comp_wfac.m
new file mode 100644
index 0000000..a777376
--- /dev/null
+++ b/inst/comp/comp_wfac.m
@@ -0,0 +1,102 @@
+function gf=comp_wfac(g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_wfac
+%@verbatim
+%COMP_WFAC  Compute window factorization
+%  Usage: gf=comp_wfac(g,a,M);
+%
+%   References:
+%     T. Strohmer. Numerical algorithms for discrete Gabor expansions. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 8, pages 267-294. Birkhauser, Boston, 1998.
+%     
+%     P. L. Soendergaard. An efficient algorithm for the discrete Gabor
+%     transform using full length windows. IEEE Signal Process. Letters,
+%     submitted for publication, 2007.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_wfac.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+  
+L=size(g,1);
+R=size(g,2);
+
+N=L/a;
+b=L/M;
+
+c=gcd(a,M);
+p=a/c;
+q=M/c;
+d=N/q;
+
+gf=zeros(p,q*R,c,d,assert_classname(g));
+
+% Set up the small matrices
+% The w loop is only used for multiwindows, which should be a rare occurence.
+% Therefore, we make it the outermost
+if p==1  
+  % Integer oversampling
+  if (c==1) && (d==1) && (R==1)
+    % --- Short time Fourier transform of single signal ---
+    % This is used for spectrograms of short signals.            
+    for l=0:q-1	  
+      gf(1,l+1,1,1)=g(mod(-l,L)+1);
+    end;
+
+  else
+
+    for w=0:R-1
+      for s=0:d-1
+	for l=0:q-1	  
+	  gf(1,l+1+q*w,:,s+1)=g((1:c)+mod(-l*a+s*p*M,L),w+1);
+	end;
+      end;
+    end;
+
+  end;
+else
+  % Rational oversampling
+
+  for w=0:R-1
+    for s=0:d-1
+      for l=0:q-1
+	for k=0:p-1	    
+	  gf(k+1,l+1+q*w,:,s+1)=g((1:c)+c*mod(k*q-l*p+s*p*q,d*p*q),w+1);
+	end;
+      end;
+    end;
+  end;
+
+end;
+
+% dft them
+if d>1
+  gf=fft(gf,[],4);
+end;
+
+% Scale by the sqrt(M) comming from Walnuts representation
+gf=gf*sqrt(M);
+
+gf=reshape(gf,p*q*R,c*d);
+
+
diff --git a/inst/comp/comp_wfbt.m b/inst/comp/comp_wfbt.m
new file mode 100644
index 0000000..4c474a2
--- /dev/null
+++ b/inst/comp/comp_wfbt.m
@@ -0,0 +1,76 @@
+function c=comp_wfbt(f,wtNodes,rangeLoc,rangeOut,ext)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_wfbt
+%@verbatim
+%COMP_WFBT Compute Wavelet Filterbank Tree
+%   Usage:  c=comp_wfbt(f,wtNodes,rangeLoc,rangeOut,ext);
+%
+%   Input parameters:
+%         f        : Input L*W array.
+%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
+%                    BF order. Length nodeNo cell array of structures.
+%         rangeLoc : Idxs of each node terminal outputs. Length nodeNo 
+%                    cell array of vectors.
+%         rangeOut : Output subband idxs of each node terminal outputs.
+%         ext      : Type of the forward transform boundary handling.
+%
+%   Output parameters:
+%         c        : Cell array of coefficients. Each element is one
+%                    subband (matrix with W columns).
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_wfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Do non-expansve transform if ext=='per'
+doPer = strcmp(ext,'per');
+% Pre-allocated output
+c = cell(sum(cellfun(@(rEl) numel(rEl),rangeOut)),1);
+
+ ca = {f};
+ % Go over all nodes in breadth-first order
+ for jj=1:numel(wtNodes)
+    % Load current filterbank
+    wtNode = wtNodes{jj}.h(:);
+    % Node filters to a cell array
+    hCell = cellfun(@(hEl) conj(flipud(hEl.h(:))),wtNode,'UniformOutput',0);
+    % Node filters subs. factors
+    a = wtNodes{jj}.a;
+    % Node filters initial skips
+    if(doPer)
+       offset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNode);
+    else
+       offset = -(a-1);
+    end
+
+    % Run filterbank
+    catmp=comp_filterbank_td(ca{1},hCell,a,offset,ext);
+    % Pick what goes directy to the output...
+    c(rangeOut{jj}) = catmp(rangeLoc{jj});
+    % and save the rest.
+    diffRange = 1:numel(hCell);
+    diffRange(rangeLoc{jj}) = [];
+    ca = [ca(2:end);catmp(diffRange)];
+ end        
+
+
+
+
+
+
diff --git a/inst/comp/comp_window.m b/inst/comp/comp_window.m
new file mode 100644
index 0000000..a3813c1
--- /dev/null
+++ b/inst/comp/comp_window.m
@@ -0,0 +1,190 @@
+function [g,info] = comp_window(g,a,M,L,lt,callfun);
+%-*- texinfo -*-
+%@deftypefn {Function} comp_window
+%@verbatim
+%COMP_WINDOW  Compute the window from numeric, text or cell array.
+%   Usage: [g,info] = comp_window(g,a,M,L,s,callfun);
+%
+%   [g,info]=COMP_WINDOW(g,a,M,L,lt,callfun) will compute the window
+%   from a text description or a cell array containing additional
+%   parameters.
+%
+%   This function is the driving routine behind GABWIN and WILWIN.
+%
+%   See the help on GABWIN and WILWIN for more information.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_window.php}
+%@seealso{gabwin, wilwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+% Basic discovery: Some windows depend on L, and some windows help define
+% L, so the calculation of L is window dependant.
+  
+% Default values.
+info.gauss=0;
+info.wasrow=0;
+info.isfir=0;
+info.istight=0;
+info.isdual=0;
+
+isrect=(lt(2)==1);
+
+% Manually get the list of window names
+definput=arg_firwin(struct);
+firwinnames =  definput.flags.wintype;
+
+% Create window if string was given as input.
+if ischar(g)
+  winname=lower(g);
+  switch(winname)
+   case {'pgauss','gauss'}
+    complain_L(L,callfun);
+    g=comp_pgauss(L,a*M/L,0,0);
+    info.gauss=1;
+    info.tfr=a*M/L;
+   case {'psech','sech'}
+    complain_L(L,callfun);
+    g=psech(L,a*M/L);
+    info.tfr=a*M/L;
+   case {'dualgauss','gaussdual'}
+    complain_L(L,callfun);
+    g=comp_pgauss(L,a*M/L,0,0);
+    if isrect
+      g=gabdual(g,a,M);
+    else
+      g=gabdual(g,a,M,'lt',lt);
+    end;
+    info.isdual=1;
+    info.tfr=a*M/L;
+   case {'tight'}
+    complain_L(L,callfun);
+    if isrect
+      g=gabtight(a,M,L);
+    else
+      g=gabtight(a,M,L,'lt',lt);
+    end;
+    info.tfr=a*M/L;
+    info.istight=1;
+   case firwinnames
+    [g,firinfo]=firwin(winname,M,'2');
+    info.isfir=1;
+    if firinfo.issqpu
+      info.istight=1;
+    end;
+   otherwise
+    error('%s: Unknown window type: %s',callfun,winname);
+  end;
+end;
+
+if iscell(g)
+  if isempty(g) || ~ischar(g{1})
+    error('First element of window cell array must be a character string.');
+  end;
+  
+  winname=lower(g{1});
+  
+  switch(winname)
+   case {'pgauss','gauss'}
+    complain_L(L,callfun);
+    [g,info.tfr]=pgauss(L,g{2:end});
+    info.gauss=1;
+   case {'psech','sech'}
+    complain_L(L,callfun);
+    [g,info.tfr]=psech(L,g{2:end});    
+   case {'dual'}
+    gorig = g{2};   
+    [g,info.auxinfo] = comp_window(gorig,a,M,L,lt,callfun);    
+    if isrect
+      g = gabdual(g,a,M,L);
+    else
+      g = gabdual(g,a,M,L,'lt',lt);
+    end;
+    % gorig can be string or cell array
+    if info.auxinfo.isfir && test_isfir(gorig,M) 
+       info.isfir = 1; 
+    end
+    info.isdual=1;
+   case {'tight'}
+    gorig = g{2};
+    [g,info.auxinfo] = comp_window(gorig,a,M,L,lt,callfun);    
+    if isrect
+      g = gabtight(g,a,M,L);
+    else
+      g = gabtight(g,a,M,L,'lt',lt);
+    end;
+    % The same as in dual?
+    if info.auxinfo.isfir && test_isfir(gorig,M) 
+       info.isfir = 1; 
+    end
+    info.istight=1;
+   case firwinnames
+    g=firwin(winname,g{2},'energy',g{3:end});
+    info.isfir=1;
+   otherwise
+    error('Unsupported window type.');
+  end;
+end;
+
+if isnumeric(g)
+  if size(g,2)>1
+    if size(g,1)==1
+      % g was a row vector.
+      g=g(:);
+      info.wasrow=1;
+    end;
+  end;
+end;
+
+if rem(length(g),M)~=0
+  % Zero-extend the window to a multiple of M
+  g=fir2long(g,ceil(length(g)/M)*M);
+end;
+
+% Information to be determined post creation.
+info.wasreal = isreal(g);
+info.gl      = length(g);
+
+if (~isempty(L) && (info.gl<L))
+  info.isfir=1;
+end;
+
+function complain_L(L,callfun)
+  
+  if isempty(L)
+    error(['%s: You must specify a length L if a window is represented as a ' ...
+           'text string or cell array.'],callfun);
+  end;
+  
+  
+function isfir=test_isfir(gorig,M)
+    % Original window is FIR, dual window is FIR if length of the original
+    % window is <= M. This is true if the length was not explicitly
+    % defined (gorig{2}).
+      if iscell(gorig) && numel(gorig)>1 && isnumeric(gorig{2}) && gorig{2}<=M...
+         || ischar(gorig)   
+        isfir = 1; 
+      else
+         isfir = 0;
+      end
+
+
+
+
diff --git a/inst/comp/comp_wpfbt.m b/inst/comp/comp_wpfbt.m
new file mode 100644
index 0000000..07519ac
--- /dev/null
+++ b/inst/comp/comp_wpfbt.m
@@ -0,0 +1,84 @@
+function c=comp_wpfbt(f,wtNodes,rangeLoc,ext,do_scale)
+%-*- texinfo -*-
+%@deftypefn {Function} comp_wpfbt
+%@verbatim
+%COMP_WPFBT Compute Wavelet Packet Filterbank Tree
+%   Usage:  c=comp_wpfbt(f,wtNodes,ext);
+%
+%   Input parameters:
+%         f        : Input L*W array.
+%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
+%                    BF order. Length nodeNo cell array of structures.
+%         ext      : Type of the forward transform boundary handling.
+%
+%   Output parameters:
+%         c        : Coefficients stored in cell-array. Each element is one
+%                    subband (matrix with W columns).
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/comp_wpfbt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Do non-expansve transform if ext=='per'
+doPer = strcmp(ext,'per');
+% Pre-allocated output
+c = cell(sum(cellfun(@(wtEl) numel(wtEl.h),wtNodes)),1);
+
+ca = f;
+cOutRunIdx = 1;
+cInRunIdxs = [1];
+% Go over all nodes in breadth-first order
+for jj=1:numel(wtNodes)
+   % Node filters to a cell array
+   hCell = cellfun(@(hEl) conj(flipud(hEl.h(:))),wtNodes{jj}.h(:),'UniformOutput',0);
+   % Node filters subs. factors
+   a = wtNodes{jj}.a;
+   % Node filters initial skips
+   if(doPer)
+      offset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNodes{jj}.h);
+   else
+      offset = -(a-1);
+   end
+   filtNo = numel(hCell);
+   
+   % Run filterbank
+   c(cOutRunIdx:cOutRunIdx + filtNo-1)=...
+                               comp_filterbank_td(ca,hCell,a,offset,ext);
+   
+   % Bookeeping. Store idxs of just computed outputs.
+   outRange = cOutRunIdx:cOutRunIdx+filtNo-1;
+   % Omit those, which are not decomposed further
+   outRange(rangeLoc{jj}) = [];
+   cInRunIdxs = [cInRunIdxs(2:end),outRange];
+   
+   cOutRunIdx = cOutRunIdx + filtNo;
+   
+   % Prepare input for the next iteration
+   % Scaling introduced in order to preserve energy 
+   % (parseval tight frame)
+   if ~isempty(cInRunIdxs)
+      if do_scale
+         c{cInRunIdxs(1)} = c{cInRunIdxs(1)}/sqrt(2);
+      end
+      ca = c{cInRunIdxs(1)};
+   end
+end   
+
+
+
diff --git a/inst/comp/compinit.m b/inst/comp/compinit.m
new file mode 100644
index 0000000..9ece0eb
--- /dev/null
+++ b/inst/comp/compinit.m
@@ -0,0 +1,26 @@
+status=2;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} compinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/compinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/complain_notposint.m b/inst/comp/complain_notposint.m
new file mode 100644
index 0000000..161673c
--- /dev/null
+++ b/inst/comp/complain_notposint.m
@@ -0,0 +1,29 @@
+function complain_notposint(var,varname)
+
+if ~isnumeric(var) || var<=0 || rem(var,1)~=0 
+   error('%s: %s should be a positive integer.',upper(mfilename),varname)
+end
+
+%-*- texinfo -*-
+%@deftypefn {Function} complain_notposint
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/complain_notposint.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/comp/demo_blockproc_header.m b/inst/comp/demo_blockproc_header.m
new file mode 100644
index 0000000..783b7ba
--- /dev/null
+++ b/inst/comp/demo_blockproc_header.m
@@ -0,0 +1,45 @@
+function failed=demo_blockproc_header(demo_name,demo_nargin)
+failed = 0;
+if demo_nargin<1
+   fprintf(['\n%s:\nTo run the demo, use one of the following:\n\n',...
+          '%s(''gspi.wav'') to play gspi.wav (any wav file will do).\n',...
+          '%s(''dialog'') to choose the wav file via file chooser dialog GUI.\n',...
+          '%s(f,''fs'',fs) to play from a column vector f using sampling frequency fs.\n',...
+          '%s(''playrec'') to record from a mic and play simultaneously.\n\n',...
+          'Avalable input and output devices can be listed by |blockdevices|.\n',...
+          'Particular device can be chosen by passing additional key-value pair ''devid'',devid.\n',...
+          'Output channels of the device cen be selected by additional key-value pair ''playch'',[ch1,ch2].\n',...
+          'Input channels of the device cen be selected by additional key-value pair ''recch'',[ch1].\n\n',...
+          ]...
+          ,upper(demo_name),demo_name,demo_name,demo_name,demo_name);
+    failed=1;
+end
+
+try
+   playrec('isInitialised');
+catch
+   error('%s: playrec or portaudio are not properly compiled. ',demo_name);
+end
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_header
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/demo_blockproc_header.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+end
diff --git a/inst/comp/gabpars_from_window.m b/inst/comp/gabpars_from_window.m
new file mode 100644
index 0000000..f69cf3f
--- /dev/null
+++ b/inst/comp/gabpars_from_window.m
@@ -0,0 +1,90 @@
+function [g,L,info] = gabpars_from_window(g,a,M,L,callfun)
+%-*- texinfo -*-
+%@deftypefn {Function} gabpars_from_window
+%@verbatim
+%GABPARS_FROM_WINDOW  Compute g and L from window
+%   Usage: [g,g.info,L] = gabpars_from_window(f,g,a,M);
+%
+%   Use this function if you know a window and a lattice
+%   for the DGT. The function will calculate a transform length L and
+%   evaluate the window g into numerical form.
+%
+%   If the transform length is unknown (as it usually is unless explicitly
+%   specified by the user), set L to be [] in the input to this function.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/gabpars_from_window.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<5
+  stacknames=dbstack;  
+  callfun=stacknames(2).name;
+end;
+
+assert_squarelat(a,M,1,callfun,0);
+
+if ~isempty(L)
+  if (prod(size(L))~=1 || ~isnumeric(L))
+    error('%s: L must be a scalar',callfun);
+  end;
+  
+  if rem(L,1)~=0
+    error('%s: L must be an integer',callfun);
+  end;
+end;
+
+if isnumeric(g)
+  Lwindow=length(g);
+else
+  Lwindow=0;
+end;
+
+
+if isempty(L)
+  % Smallest length transform.
+  Lsmallest=lcm(a,M);
+
+  % Choose a transform length larger than both the length of the
+  % signal and the window.
+  L=ceil(Lwindow/Lsmallest)*Lsmallest;
+else
+
+  if rem(L,M)~=0
+    error('%s: The length of the transform must be divisable by M = %i',...
+          callfun,M);
+  end;
+
+  if rem(L,a)~=0
+    error('%s: The length of the transform must be divisable by a = %i',...
+          callfun,a);
+  end;
+
+  if L<Lwindow
+    error('%s: Window is too long.',callfun);
+  end;
+
+end;
+
+b=L/M;
+N=L/a;
+
+[g,info]=gabwin(g,a,M,L,[0 1],'callfun',callfun);
+
+
+
+
diff --git a/inst/comp/gabpars_from_windowsignal.m b/inst/comp/gabpars_from_windowsignal.m
new file mode 100644
index 0000000..afd8d66
--- /dev/null
+++ b/inst/comp/gabpars_from_windowsignal.m
@@ -0,0 +1,82 @@
+function [f,g,L,Ls,W,info] = gabpars_from_windowsignal(f,g,a,M,L,lt,callfun)
+%-*- texinfo -*-
+%@deftypefn {Function} gabpars_from_windowsignal
+%@verbatim
+%GABPARS_FROM_WINDOWSIGNAL  Compute g and L from window and signal
+%   Usage: [g,g.info,L] = gabpars_from_windowsignal(f,g,a,M,L);
+%
+%   Use this function if you know an input signal, a window and a lattice
+%   for the DGT. The function will calculate a transform length L and
+%   evaluate the window g into numerical form. The signal will be padded and
+%   returned as a column vector.
+%
+%   If the transform length is unknown (as it usually is unless explicitly
+%   specified by the user), set L to be [] in the input to this function.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/gabpars_from_windowsignal.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<6
+  stacknames=dbstack;  
+  callfun=stacknames(2).name;
+end;
+
+% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,callfun,0);
+
+
+if isempty(L)
+
+    % ----- step 2b : Verify a, M and get L from the signal length f----------
+    L=dgtlength(Ls,a,M);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+    Luser=dgtlength(L,a,M);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i.'],callfun,L,Luser)
+    end;
+
+end;
+
+% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,'callfun',callfun);
+
+if L<info.gl
+  error('%s: Window is too long.',callfun);
+end;
+
+% ----- final cleanup ---------------
+
+f=postpad(f,L);
+
+% If the signal is single precision, make the window single precision as
+% well to avoid mismatches.
+if isa(f,'single')
+  g=single(g);
+end;
+
+
+
+
+
diff --git a/inst/comp/nonsepgabpars_from_window.m b/inst/comp/nonsepgabpars_from_window.m
new file mode 100644
index 0000000..8a31325
--- /dev/null
+++ b/inst/comp/nonsepgabpars_from_window.m
@@ -0,0 +1,59 @@
+function [g,L,info] = nonsepgabpars_from_window(g,a,M,lt,L,callfun)
+%-*- texinfo -*-
+%@deftypefn {Function} nonsepgabpars_from_window
+%@verbatim
+%NONSEPGABPARS_FROM_WINDOW  Compute g and L from window
+%   Usage: [g,g.info,L] = gabpars_from_window(f,g,a,M,lt,L);
+%
+%   Use this function if you know a window and a lattice
+%   for the NONSEPDGT. The function will calculate a transform length L and
+%   evaluate the window g into numerical form.
+%
+%   If the transform length is unknown (as it usually is unless explicitly
+%   specified by the user), set L to be [] in the input to this function.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/nonsepgabpars_from_window.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<6
+  stacknames=dbstack;  
+  callfun=stacknames(2).name;
+end;
+
+if isempty(L)
+  if isnumeric(g)
+    L=length(g);
+  else
+    L=dgtlength(1,a,M,lt);
+  end;
+else
+  Lcheck=dgtlength(L,a,M,lt);
+  if Lcheck~=L
+    error('%s: Invalid transform size L',upper(mfilename));
+  end;
+end;
+
+[g,info] = comp_window(g,a,M,L,lt,'NONSEPGABDUAL');
+
+if (info.isfir)  
+  if info.istight
+    g=g/sqrt(2);
+  end;  
+end;
+
diff --git a/inst/comp/vect2cell.m b/inst/comp/vect2cell.m
new file mode 100644
index 0000000..02f6336
--- /dev/null
+++ b/inst/comp/vect2cell.m
@@ -0,0 +1,30 @@
+function c = vect2cell(x,idx)
+
+idxEnd = cumsum(idx(:));
+idxStart = [1;1+idxEnd(1:end-1)];
+c = arrayfun(@(idS,idE) x(idS:idE,:),idxStart,idxEnd,'UniformOutput',0);
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} vect2cell
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/comp/vect2cell.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/demos/Contents.m b/inst/demos/Contents.m
new file mode 100644
index 0000000..fa50d5b
--- /dev/null
+++ b/inst/demos/Contents.m
@@ -0,0 +1,70 @@
+% LTFAT - Demos
+%
+%   Peter L. Soendergaard, 2007 - 2014.
+%
+%   This page documents the demos.
+%
+%   Basic demos
+%     DEMO_DGT              - DGT and comparison to SGRAM
+%     DEMO_GABFIR           - FIR windows in Gabor systems.
+%
+%   Compression
+%     DEMO_IMAGECOMPRESSION - Image compression using DWILT and FWT
+%     DEMO_AUDIOCOMPRESSION - Audio compression using a WMDCT.
+%
+%   Denoising 
+%     DEMO_AUDIODENOISE     - Audio denoising using a WMDCT.
+%
+%   Applications
+%     DEMO_OFDM             - Simple OFDM demo.
+%     DEMO_AUDIOSHRINK      - Lasso shrinkage of audio signal.
+%     DEMO_GABMULAPPR       - Approx. of time-varying system.
+%
+%   Aspects of particular functions
+%     DEMO_NSDGT            - Non-stationary Gabor systems
+%     DEMO_PGAUSS           - How to use PGAUSS.
+%     DEMO_PBSPLINE         - How to use PBSPLINE.
+%     DEMO_GABMIXDUAL       - How to use GABMIXDUAL.
+%     DEMO_FRAMEMUL         - Time-frequency localization by Gabor multiplier.
+%     DEMO_PHASEPLOT        - Phaseplots.
+%     DEMO_FRSYNABS         - Iterative spectrogram reconstruction.
+%     DEMO_NEXTFASTFFT      - Next fast FFT size.
+%
+%  Auditory scales and filters
+%     DEMO_AUDSCALES        - Different auditory scales.
+%     DEMO_AUDITORYFILTERBANK - Erb-spaced auditory filterbank.
+%
+%  Block-processing demos
+%     DEMO_BLOCKPROC_BASICLOOP        - Simple audio playback loop.
+%     DEMO_BLOCKPROC_PARAMEQUALIZER   - Parametric equalizer.
+%     DEMO_BLOCKPROC_DENOISING        - Variable noise-reduction.
+%     DEMO_BLOCKPROC_SLIDINGSGRAM     - Sliding spectrogram plot.
+%     DEMO_BLOCKPROC_SLIDINGCQT       - Sliding CQT plot.
+%     DEMO_BLOCKPROC_SLIDINGERBLETS   - Sliding Erblets plot.
+%     DEMO_BLOCKPROC_PITCHSHIFT       - Simple pich shifting.
+%     DEMO_BLOCKPROC_DGTEQUALIZER     - Variable Gabor Multiplier as equalizer.
+%     
+%
+%   For help, bug reports, suggestions etc. send email to 
+%   ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/demos/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
diff --git a/inst/demos/demo_audiocompression.m b/inst/demos/demo_audiocompression.m
new file mode 100644
index 0000000..2cdd2eb
--- /dev/null
+++ b/inst/demos/demo_audiocompression.m
@@ -0,0 +1,96 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_audiocompression
+%@verbatim
+%DEMO_AUDIOCOMPRESSION  Audio compression using N-term approx
+%
+%   This demos shows how to do audio compression using best N-term
+%   approximation of an WMDCT transform.
+%
+%   The signal is transformed using an orthonormal WMDCT transform.
+%   Then approximations with a fixed number N of coefficients are obtained
+%   by:
+%
+%      Linear approximation: The N coefficients with lowest frequency
+%       index are kept.
+%
+%      Non-linear approximation: The N largest coefficients (in
+%       magnitude) are kept.
+%
+%   The corresponding approximated signal can be computed using IWMDCT.
+%
+%   Figure 1: Rate-distorition plot
+%
+%      The figure shows the output Signal to Noise Ratio (SNR) as a function
+%      of the number of retained coefficients.
+%
+%   Note: The inverse WMDCT is not needed for computing computing
+%   SNRs. Instead Parseval theorem states that the norm of a signal equals
+%   the norm of the sequence of its WMDCT coefficients.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_audiocompression.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Load audio signal
+% Use the 'glockenspiel' signal.
+sig=gspi;
+
+% Shorten signal
+L = 2^16;
+sig = sig(1:L);
+
+% Number of frequency channels
+M = 1024;
+
+% Number of time steps
+N = L/M;
+
+% Generate window
+gamma = wilorth(M,L);
+
+% Compute wmdct coefficients
+c = wmdct(sig,gamma,M);
+
+
+% L2 norm of signal
+InputL2Norm = norm(c,'fro');
+
+% Approximate, and compute SNR values
+kmax = M;
+kmin = kmax/32;             % 32 is an arbitrary choice
+krange = kmin:32:(kmax-1);  % same remark
+
+for k = krange,
+    ResL2Norm_NL = norm(c-largestn(c,k*N),'fro');
+    SNR_NL(k) = 20*log10(InputL2Norm/ResL2Norm_NL);
+    ResL2Norm_L = norm(c(k:kmax,:),'fro');
+    SNR_L(k) = 20*log10(InputL2Norm/ResL2Norm_L);
+end
+
+
+% Plot
+figure(1);
+
+set(gca,'fontsize',14);
+plot(krange*N,SNR_NL(krange),'x-b',...
+     krange*N,SNR_L(krange),'o-r');
+axis tight; grid;
+legend('Best N-term','Linear');
+xlabel('Number of Samples', 'fontsize',14);
+ylabel('SNR (dB)','fontsize',14);
+
diff --git a/inst/demos/demo_audiodenoise.m b/inst/demos/demo_audiodenoise.m
new file mode 100644
index 0000000..a163171
--- /dev/null
+++ b/inst/demos/demo_audiodenoise.m
@@ -0,0 +1,91 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_audiodenoise
+%@verbatim
+%DEMO_AUDIODENOISE  Audio denoising using thresholding
+%
+%   This demos shows how to do audio denoising using thresholding
+%   of WMDCT transform.
+%
+%   The signal is transformed using an orthonormal WMDCT transform
+%   followed by a thresholding. Then the signal is reconstructed
+%   and compared with the original.
+%
+%   Figure 1: Denoising
+%
+%      The figure shows the original signal, the noisy signal and denoised
+%      signals using hard and soft threshholding applied to the WMDCT of the
+%      noise signal.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_audiodenoise.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Load audio signal
+% Use the 'glockenspiel' signal.
+sig=gspi;
+
+SigLength = 2^16;
+sig = sig(1:SigLength);
+
+% Initializations
+NbFreqBands = 1024;
+sigma = 0.5;
+Relative_Threshold = 0.1;
+tau = Relative_Threshold*sigma;
+
+% Generate window
+gamma = wilorth(NbFreqBands,SigLength);
+
+% add noise to the signal
+sigma = sigma * std(sig);
+nsig = sig + sigma * randn(size(sig));
+
+% Compute wmdct coefficients
+c = wmdct(nsig,gamma,NbFreqBands);
+
+% Hard Thresholding
+chard=thresh(c,tau);
+
+% Reconstruct
+hrec = real(iwmdct(chard,gamma));
+
+% Soft thresholding
+csoft=thresh(c,tau,'soft');
+
+% Reconstruct
+srec = real(iwmdct(csoft,gamma));
+
+% Plot
+figure(1);
+subplot(4,1,1); plot(sig); legend('Original');
+subplot(4,1,2); plot(nsig); legend('Noisy');
+subplot(4,1,3); plot(hrec); legend('Hard threshold');
+subplot(4,1,4); plot(srec); legend('Soft threshold');
+
+% Results
+InputSNR = 20 *log10(std(sig)/std(nsig-sig));
+OutputSNR_h = 20 *log10(std(sig)/std(hrec-sig));
+OutputSNR_s = 20 *log10(std(sig)/std(srec-sig));
+
+fprintf(' RESULTS:\n');
+fprintf('      Input SNR: %f dB.\n',InputSNR);
+fprintf('      Output SNR (hard): %f dB.\n',OutputSNR_h);
+fprintf('      Output SNR (soft): %f dB.\n',OutputSNR_s);
+fprintf(' Signals are stored in variables sig, nsig, hrec, srec\n');
+
diff --git a/inst/demos/demo_audioshrink.m b/inst/demos/demo_audioshrink.m
new file mode 100644
index 0000000..4bed4fe
--- /dev/null
+++ b/inst/demos/demo_audioshrink.m
@@ -0,0 +1,123 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_audioshrink
+%@verbatim
+%DEMO_AUDIOSHRINK  Decomposition into tonal and transient parts
+%
+%   This demos shows how to do audio coding and "tonal + transient"
+%   decomposition using group lasso shrinkage of two WMDCT transforms
+%   with different time-frequency resolutions.
+%
+%   The signal is transformed using two orthonormal WMDCT bases.
+%   Then group lasso shrinkage is applied to the two transforms
+%   in order to:
+%
+%      select fixed frequency lines of large WMDCT coefficients on the
+%       wide window WMDCT transform
+%
+%      select fixed time lines of large WMDCT coefficients on the
+%       narrow window WMDCT transform
+% 
+%   The corresponding approximated signals are computed with the
+%   corresponding inverse, IWMDCT.
+%
+%   Figure 1: Plots and time-frequency images
+%
+%      The upper plots in the figure show the tonal parts of the signal, the
+%      lower plots show the transients. The TF-plots on the left are the
+%      corresponding wmdct coefficients found by appropriate group lasso
+%      shrinkage
+%
+%   Corresponding reconstructed tonal and transient sounds may be
+%   listened from arrays rec1 and rec2 (sampling rate: 44.1 kHz)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_audioshrink.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+% Load audio signal and add noise
+% -------------------------------
+% Use the 'glockenspiel' signal.
+sig=gspi;
+fs=44100;
+
+% Shorten signal
+siglen = 2^16;
+sig = sig(1:siglen);
+
+% Add Gaussian white noise
+nsig = sig + 0.01*randn(size(sig));
+
+% Tonal layer
+% -----------
+
+% Create a WMDCT basis with 256 channels
+F1=frametight(frame('wmdct','gauss',256));
+
+% Group lasso and invert
+c1 = franagrouplasso(F1,nsig,0.8,'soft','freq');
+rec1 = frsyn(F1,c1);
+
+% Transient layer
+% ---------------
+
+% Create a WMDCT basis with 32 channels
+F2=frametight(frame('wmdct','gauss',32));
+
+c2 = franagrouplasso(F2,nsig,0.5,'soft','time');
+rec2 = frsyn(F2,c2);
+
+% Plots
+% -----
+
+% Dynamic range for plotting
+dr=50;
+xplot=(0:siglen-1)/fs;
+
+figure(1);
+subplot(2,2,1);
+plot(xplot,rec1);
+xlabel('Time (s)');
+axis tight;
+
+subplot(2,2,2);
+plotframe(F1,c1,fs,dr);
+
+subplot(2,2,3);
+plot(xplot,rec2);
+xlabel('Time (s)');
+axis tight;
+
+subplot(2,2,4);
+plotframe(F2,c2,fs,dr);
+
+% Count the number of non-zero coefficients
+N1=sum(abs(c1)>0);
+N2=sum(abs(c2)>0);
+
+p1 = 100*N1/siglen;
+p2 = 100*N2/siglen;
+p=p1+p2;
+
+fprintf('Percentage of retained coefficients: %f + %f = %f\n',p1,p2,p);
+
+disp('To play the original, type "soundsc(sig,fs)"');
+disp('To play the tonal part, type "soundsc(rec1,fs)"');
+disp('To play the transient part, type "soundsc(rec2,fs)"');
+
diff --git a/inst/demos/demo_auditoryfilterbank.m b/inst/demos/demo_auditoryfilterbank.m
new file mode 100644
index 0000000..f21e44e
--- /dev/null
+++ b/inst/demos/demo_auditoryfilterbank.m
@@ -0,0 +1,115 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_auditoryfilterbank
+%@verbatim
+%DEMO_AUDITORYFILTERBANK  Construct an auditory filterbank
+%
+%   In this file we construct a uniform filterbank using a the impulse
+%   response of a 4th order gammatone for each channel. The center frequencies
+%   are equidistantly spaced on an ERB-scale, and the width of the filter are
+%   choosen to match the auditory filter bandwidth as determined by Moore.
+%
+%   Each channel is subsampled by a factor of 8 (a=8), and to generate a
+%   nice plot, 4 channels per Erb has been used.
+%
+%   The filterbank covers only the positive frequencies, so we must use
+%   FILTERBANKREALDUAL and FILTERBANKREALBOUNDS.
+%
+%   Figure 1: Classic spectrogram
+%
+%      A classic spectrogram of the spoken sentense. The dynamic range has
+%      been set to 50 dB, to highlight the most important features.
+%
+%   Figure 2: Auditory filterbank representation
+%
+%      Auditory filterbank representation of the spoken sentense using
+%      gammatone filters on an Erb scale.  The dynamic range has been set to
+%      50 dB, to highlight the most important features.
+%
+%
+%   References:
+%     B. R. Glasberg and B. Moore. Derivation of auditory filter shapes from
+%     notched-noise data. Hearing Research, 47(1-2):103, 1990.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_auditoryfilterbank.php}
+%@seealso{freqtoaud, audfiltbw, gammatonefir, ufilterbank, filterbankrealdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+% Use part of the 'cocktailparty' spoken sentense.
+f=cocktailparty;
+f=f(20001:80000,:);
+fs=44100;
+a=8;
+channels_per_erb=2;
+filterlength=5000;
+dynrange_for_plotting=50;
+
+% Determine minimal transform length
+Ls=length(f);
+L=ceil(filterlength/a)*a;
+
+% Number of channels, slightly less than 1 ERB(Cambridge) per channel.
+M=ceil(freqtoerb(fs/2)*channels_per_erb);
+
+% Compute center frequencies.
+fc=erbspace(0,fs/2,M);
+
+%% --------------- display classic spectrogram -------------------
+figure(1);
+sgram(f,fs,dynrange_for_plotting);
+
+
+%% ---------------  Gammatone filters ----------------------------
+
+if 1
+
+g_gam=gammatonefir(fc,fs,filterlength,'peakphase');
+
+% In production code, it is not necessary to call 'filterbankrealbounds',
+% this is just for veryfying the setup.
+disp('Frame bound ratio for gammatone filterbank, should be close to 1 if the filters are choosen correctly.');
+filterbankrealbounds(g_gam,a,L)
+
+% Create reconstruction filters
+gd_gam=filterbankrealdual(g_gam,a,L);
+
+% Analysis transform
+coef_gam=ufilterbank(f,g_gam,a);
+
+% Synthesis transform
+r_gam=2*real(ifilterbank(coef_gam,gd_gam,a,Ls));
+
+disp('Relative error in reconstruction, should be close to zero.');
+norm(f-r_gam)/norm(f)
+
+figure(2);
+plotfilterbank(coef_gam,a,fc,fs,dynrange_for_plotting,'audtick');
+
+F  = frame('ufilterbankreal',g_gam,a,M);
+c2 = frana(F,f); 
+Ls=length(f);
+
+[r_iter,relres,iter] = frsyniter(F,c2,Ls);
+disp('Relative error in interative reconstruction, should be close to zero.');
+norm(f-r_iter)/norm(f)
+
+end;
+
diff --git a/inst/demos/demo_audscales.m b/inst/demos/demo_audscales.m
new file mode 100644
index 0000000..9e5b622
--- /dev/null
+++ b/inst/demos/demo_audscales.m
@@ -0,0 +1,62 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_audscales
+%@verbatim
+%DEMO_AUDSCALES  Plot of the different auditory scales
+%
+%   This demos generates a simple figure that shows the behaviour of
+%   the different audiory scales in the frequency range from 0 to 8000 Hz.
+%
+%   Figure 1: Auditory scales
+%
+%      The figure shows the behaviour of the audiory scales on a normalized
+%      frequency plot.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_audscales.php}
+%@seealso{freqtoaud, audtofreq, audspace, audspacebw}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp(['Type "help demo_audscales" to see a description of how this ', ...
+      'demo works.']);
+
+% Set the limits
+flow=0;
+fhigh=8000;
+plotpoints=50;
+
+xrange=linspace(flow,fhigh,plotpoints);
+
+
+figure(1);
+
+types   = {'erb','bark','mel','erb83','mel1000'};
+symbols = {'k-' ,'ro'  ,'gx' ,'b+'   ,'y*'};
+
+hold on;
+for ii=1:numel(types)
+  curve = freqtoaud(xrange,types{ii});
+  % Normalize the frequency to a maximum of 1.
+  curve=curve/curve(end);
+  plot(xrange,curve,symbols{ii});
+end;
+hold off;
+legend(types{:},'Location','SouthEast');
+xlabel('Frequency (Hz)');
+ylabel('Auditory unit (normalized)');
+
diff --git a/inst/demos/demo_blockproc_basicloop.m b/inst/demos/demo_blockproc_basicloop.m
new file mode 100644
index 0000000..ef42dea
--- /dev/null
+++ b/inst/demos/demo_blockproc_basicloop.m
@@ -0,0 +1,54 @@
+function demo_blockproc_basicloop(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_basicloop
+%@verbatim
+%DEMO_BLOCKPROC_BASICLOOP Basic real-time audio manipulation
+%   Usage: demo_blockproc_basicloop('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_BASICLOOP without arguments.
+%
+%   The demo runs simple playback loop allowing to set gain in dB.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_basicloop.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+% Basic Control pannel (Java object)
+p = blockpanel({
+               {'GdB','Gain',-20,20,0,21},...
+               });
+
+% Setup blocktream
+block(source,varargin{:},'loadind',p);
+
+flag = 1;
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+   gain = blockpanelget(p,'GdB');
+   gain = 10^(gain/20);
+   
+   [f,flag] = blockread();
+   blockplay(f*gain);
+end
+blockdone(p);
+
diff --git a/inst/demos/demo_blockproc_denoising.m b/inst/demos/demo_blockproc_denoising.m
new file mode 100644
index 0000000..5e65e95
--- /dev/null
+++ b/inst/demos/demo_blockproc_denoising.m
@@ -0,0 +1,84 @@
+function demo_blockproc_denoising(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_denoising
+%@verbatim
+%DEMO_BLOCKPROC_DENOISING Variable coefficients thresholding
+%   Usage: demo_blockproc_denoising('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_DENOISING without arguments.
+%
+%   The present demo allows you to set the coefficient threshold during the
+%   playback using the control panel.
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_denoising.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+% Control pannel (Java object)
+% Each entry determines one parameter to be changed during the main loop
+% execution.
+p = blockpanel({
+               {'GdB','Gain',-20,20,0,21},...
+               {'Thr','Treshold',0,0.1,0,1000}
+               });
+    
+% Buffer length
+bufLen = 1024;
+% Number of frequency channels
+M = 1000;
+
+% Setup blocktream
+fs=block(source,varargin{:},'loadind',p,'L',bufLen);
+
+% Window length in ms
+winLenms = 20; %floor(fs*winLenms/1e3)
+[F,Fdual] = framepair('dgtreal',{'hann',floor(fs*winLenms/1e3)},'dual',40,M);
+[Fa,Fs] = blockframepairaccel(F,Fdual, bufLen,'segola');
+
+
+flag = 1;
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+   
+  % Obtain parameters from the control panel
+  gain = 10^(p.getParam('GdB')/20); % dB -> val
+  thres = p.getParam('Thr');
+  %bufLen = floor(p.getParam('bufLen'));
+
+  % Read block of length bufLen
+  [f,flag] = blockread();
+  % Apply analysis frame
+  c = blockana(Fa, f*gain); 
+  % Plot
+  % blockplot(fobj,F,c);
+  % Apply thresholding
+  c = thresh(c,thres,'soft');
+  % Apply synthesis frame
+  fhat = real(blocksyn(Fs, c, size(f,1)));
+  % Play the block
+  %fhat = f;
+  blockplay(fhat);
+end
+blockdone(p);
+
+
diff --git a/inst/demos/demo_blockproc_dgtequalizer.m b/inst/demos/demo_blockproc_dgtequalizer.m
new file mode 100644
index 0000000..f1065be
--- /dev/null
+++ b/inst/demos/demo_blockproc_dgtequalizer.m
@@ -0,0 +1,101 @@
+function demo_blockproc_dgtequalizer(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_dgtequalizer
+%@verbatim
+%DEMO_BLOCKPROC_DGTEQUALIZER Real-time audio manipulation in the transform domain
+%   Usage: demo_blockproc_dgtequalizer('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_DGTEQUALIZER without arguments.
+%
+%   This script demonstrates a real-time Gabor coefficient manipulation.
+%   Frequency bands of Gabor coefficients are multiplied (weighted) by
+%   values taken from sliders having a similar effect as a octave equalizer.
+%   The shown spectrogram is a result of a re-analysis of the synthetized 
+%   block to show a frequency content of what is actually played. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_dgtequalizer.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+M = 1000;
+
+fobj = blockfigure();
+            
+octaves = 6;
+voices = 1;
+eqbands = (octaves)*voices;
+
+d = floor((floor(M/2)+1)*2.^(-(0:eqbands-1)./(voices)));
+d = fliplr([d,0]); 
+
+% Basic Control pannel (Java object)
+parg = {{'GdB','Gain',-20,20,0,21}};
+for ii=1:eqbands
+   parg{end+1} = {sprintf('G%idB',ii),sprintf('band%i',ii),-20,20,0,21};
+end
+
+p = blockpanel(parg);
+    
+
+bufLen = 1024;
+% Setup blocktream
+fs=block(source,varargin{:},'loadind',p,'L',bufLen);
+
+% Window length in ms
+winLenms = 20; %floor(fs*winLenms/1e3)
+[F,Fdual] = framepair('dgtreal',{'hann',floor(fs*winLenms/1e3)},'dual',40,M);
+[Fa,Fs] = blockframepairaccel(F,Fdual, bufLen,'segola');
+
+flag = 1;
+ola = [];
+ola2 = [];
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+   gain = blockpanelget(p);
+   gain = 10.^(gain/20);
+
+   [f,flag] = blockread();
+   f=f*gain(1);
+   gain = gain(2:end);
+   
+   [c, ola] = blockana(Fa, f, ola);
+   
+   cc = framecoef2tf(Fa,c);
+   % Do the weighting
+   for ii=1:eqbands
+      cc(d(ii)+1:d(ii+1),:,:) = gain(ii)*cc(d(ii)+1:d(ii+1),:,:);
+   end
+   c = frametf2coef(Fa,cc);
+   
+   fhat = blocksyn(Fs, c, size(f,1));
+   
+   
+   blockplay(fhat);
+   
+   % Do re-analysis of the modified
+   [c2, ola2] = blockana(Fa, fhat, ola2);
+   blockplot(fobj,Fa,c2(:,1));
+end
+blockdone(p,fobj);
+
+
diff --git a/inst/demos/demo_blockproc_paramequalizer.m b/inst/demos/demo_blockproc_paramequalizer.m
new file mode 100644
index 0000000..70485e3
--- /dev/null
+++ b/inst/demos/demo_blockproc_paramequalizer.m
@@ -0,0 +1,264 @@
+function demo_blockproc_paramequalizer(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_paramequalizer
+%@verbatim
+%DEMO_BLOCKPROC_PARAMEQUALIZER Real-time equalizer demonstration
+%   Usage: demo_blockproc_paramequalizer('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_PARAMEQUALIZER without arguments.
+%
+%   This demonstration shows an example of a octave parametric
+%   equalizer. See chapter 5.2 in the book by Zolzer.
+% 
+%   References:
+%     U. Zolzer. Digital Audio Signal Processing. John Wiley & Sons Ltd, 2
+%     edition, 2008.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_paramequalizer.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+% Buffer length
+% Larger the number the higher the processing delay. 1024 with fs=44100Hz
+% makes ~23ms.
+% The value can be any positive integer.
+% Note that the processing itself can introduce additional delay.
+bufLen = 1024;
+
+% Quality parameter of the peaking filters
+Q = sqrt(2);
+
+% Filters 
+filts = [
+         struct('Hb',[1;0],'Ha',[1;0],'G',0,'Z',[0;0],'type','lsf'),...
+         struct('Hb',[1;0;0],'Ha',[1;0;0],'G',0,'Z',[0;0],'type','peak'),...
+         struct('Hb',[1;0;0],'Ha',[1;0;0],'G',0,'Z',[0;0],'type','peak'),...
+         struct('Hb',[1;0;0],'Ha',[1;0;0],'G',0,'Z',[0;0],'type','peak'),...
+         struct('Hb',[1;0;0],'Ha',[1;0;0],'G',0,'Z',[0;0],'type','peak'),...
+         struct('Hb',[1;0;0],'Ha',[1;0;0],'G',0,'Z',[0;0],'type','hsf')...
+        ];
+     
+     
+% Control pannel (Java object)
+% Each entry determines one parameter to be changed during the main loop
+% execution.
+
+pcell = cell(1,numel(filts));
+for ii=1:numel(filts)
+   pcell{ii} =  {sprintf('band%i',ii),'Gain',-10,10,filts(ii).G,41};
+end
+p = blockpanel(pcell); 
+
+% Setup blocktream
+fs = block(source,varargin{:},'loadind',p);
+
+% Cutoff/center frequency
+feq = [0.0060, 0.0156, 0.0313, 0.0625, 0.1250, 0.2600]*fs;
+
+% Build the filters
+[filts(1).Ha, filts(1).Hb] = parlsf(feq(1),blockpanelget(p,'band1'),fs);
+[filts(2).Ha, filts(2).Hb] = parpeak(feq(2),Q,blockpanelget(p,'band2'),fs);
+[filts(3).Ha, filts(3).Hb] = parpeak(feq(3),Q,blockpanelget(p,'band3'),fs);
+[filts(4).Ha, filts(4).Hb] = parpeak(feq(4),Q,blockpanelget(p,'band4'),fs);
+[filts(5).Ha, filts(5).Hb] = parpeak(feq(5),Q,blockpanelget(p,'band5'),fs);
+[filts(6).Ha, filts(6).Hb] = parhsf(feq(6),blockpanelget(p,'band6'),fs);
+
+flag = 1;
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+   
+  % Obtain gains of the respective filters
+  G = blockpanelget(p,'band1','band2','band3','band4','band5','band6');
+  
+  % Check if any of the user-defined gains is different from the actual ones
+  % and do recomputation.
+   for ii=1:numel(filts)
+     if G(ii)~=filts(ii).G
+        filts(ii).G = G(ii);
+        if strcmpi('lsf',filts(ii).type)
+           [filts(ii).Ha, filts(ii).Hb] = parlsf(feq(ii),filts(ii).G,fs);
+        elseif strcmpi('hsf',filts(ii).type)
+           [filts(ii).Ha, filts(ii).Hb] = parhsf(feq(ii),filts(ii).G,fs);
+        elseif strcmpi('peak',filts(ii).type)
+           [filts(ii).Ha, filts(ii).Hb] = parpeak(feq(ii),Q,filts(ii).G,fs);   
+        else
+           error('Uknown filter type.');
+        end
+     end
+  end
+       
+  % Read block of length bufLen
+  [f,flag] = blockread(bufLen);
+ 
+  % Do the filtering. Output of one filter is passed to the input of the
+  % following filter. Internal conditions are used and stored. 
+  for ii=1:numel(filts)
+    [f,filts(ii).Z] = filter(filts(ii).Ha,filts(ii).Hb,f,filts(ii).Z);
+  end
+
+  % Play the block
+  blockplay(f);
+end
+blockdone(p);
+
+function [Ha,Hb]=parlsf(fc,G,Fs)
+% PARLSF Parametric Low-Shelwing filter
+%   Input parameters:
+%         fm    : Cut-off frequency
+%         G     : Gain in dB
+%         Fs    : Sampling frequency
+%   Output parameters:
+%         Ha    : Transfer function numerator coefficients.
+%         Hb    : Transfer function denominator coefficients.
+%
+%  For details see Table 5.4 in the reference.
+Ha = zeros(3,1);
+Hb = zeros(3,1);
+%b0
+Hb(1) = 1;
+Ha(1) = 1;
+K = tan(pi*fc/Fs);
+if G>0
+   V0=10^(G/20);
+   den = 1 + sqrt(2)*K + K*K;
+   % a0
+   Ha(1) = (1+sqrt(2*V0)*K+V0*K*K)/den;
+   % a1
+   Ha(2) = 2*(V0*K*K-1)/den;
+   % a2
+   Ha(3) = (1-sqrt(2*V0)*K+V0*K*K)/den;
+   % b1
+   Hb(2) = 2*(K*K-1)/den;
+   % b2
+   Hb(3) = (1-sqrt(2)*K+K*K)/den;
+elseif G<0
+   V0=10^(-G/20);
+   den = 1 + sqrt(2*V0)*K + V0*K*K;
+   % a0
+   Ha(1) = (1+sqrt(2)*K+K*K)/den;
+   % a1
+   Ha(2) = 2*(K*K-1)/den;
+   % a2
+   Ha(3) = (1-sqrt(2)*K+K*K)/den;
+   % b1
+   Hb(2) = 2*(V0*K*K-1)/den;
+   % b2
+   Hb(3) = (1-sqrt(2*V0)*K+V0*K*K)/den;
+end
+
+function [Ha,Hb]=parpeak(fc,Q,G,Fs)
+% PARLSF Parametric Peaking filter
+%   Input parameters:
+%         fm    : Cut-off frequency
+%         Q     : Filter quality. Q=fc/B, where B is filter bandwidth.
+%         G     : Gain in dB
+%         Fs    : Sampling frequency
+%   Output parameters:
+%         Ha    : Transfer function numerator coefficients.
+%         Hb    : Transfer function denominator coefficients.
+%
+%  For details see Table 5.3 in the reference.
+Ha = zeros(3,1);
+Hb = zeros(3,1);
+%b0
+Hb(1) = 1;
+Ha(1) = 1;
+K = tan(pi*fc/Fs);
+if G>0
+   V0=10^(G/20);
+   den = 1 + K/Q + K*K;
+   % a0
+   Ha(1) = (1+V0*K/Q+K*K)/den;
+   % a1
+   Ha(2) = 2*(K*K-1)/den;
+   % a2
+   Ha(3) = (1-V0*K/Q+K*K)/den;
+   % b1
+   Hb(2) = 2*(K*K-1)/den;
+   % b2
+   Hb(3) = (1-K/Q+K*K)/den;
+elseif G<0
+   V0=10^(-G/20);
+   den = 1 + V0*K/Q + V0*K*K;
+   % a0
+   Ha(1) = (1+K/Q+K*K)/den;
+   % a1
+   Ha(2) = 2*(K*K-1)/den;
+   % a2
+   Ha(3) = (1-K/Q+K*K)/den;
+   % b1
+   Hb(2) = 2*(K*K-1)/den;
+   % b2
+   Hb(3) = (1-V0*K/Q+K*K)/den;
+end
+
+function [Ha,Hb]=parhsf(fm,G,Fs)
+% PARLSF Parametric High-shelving filter
+%   Input parameters:
+%         fm    : Cut-off frequency
+%         G     : Gain in dB
+%         Fs    : Sampling frequency
+%   Output parameters:
+%         Ha    : Transfer function numerator coefficients.
+%         Hb    : Transfer function denominator coefficients.
+%
+%  For details see Table 5.3 in the reference.
+Ha = zeros(3,1);
+Hb = zeros(3,1);
+%b0
+Hb(1) = 1;
+Ha(1) = 1;
+K = tan(pi*fm/Fs);
+if G>0
+   V0=10^(G/20);
+   den = 1 + sqrt(2)*K + K*K;
+   % a0
+   Ha(1) = (V0+sqrt(2*V0)*K+K*K)/den;
+   % a1
+   Ha(2) = 2*(K*K-V0)/den;
+   % a2
+   Ha(3) = (V0-sqrt(2*V0)*K+K*K)/den;
+   % b1
+   Hb(2) = 2*(K*K-1)/den;
+   % b2
+   Hb(3) = (1-sqrt(2)*K+K*K)/den;
+elseif G<0
+   V0=10^(-G/20);
+   den = V0 + sqrt(2*V0)*K + K*K;
+   % a0
+   Ha(1) = (1+sqrt(2)*K+K*K)/den;
+   % a1
+   Ha(2) = 2*(K*K-1)/den;
+   % a2
+   Ha(3) = (1-sqrt(2)*K+K*K)/den;
+   % b1
+   Hb(2) = 2*(K*K/V0-1)/den;
+   % b2
+   Hb(3) = (1-sqrt(2/V0)*K+K*K/V0)/den;
+end
+
+
+
+
+
diff --git a/inst/demos/demo_blockproc_pitchshift.m b/inst/demos/demo_blockproc_pitchshift.m
new file mode 100644
index 0000000..a1d5cfd
--- /dev/null
+++ b/inst/demos/demo_blockproc_pitchshift.m
@@ -0,0 +1,101 @@
+function demo_blockproc_pitchshift(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_pitchshift
+%@verbatim
+%DEMO_BLOCKPROC_PITCHSHIFT Pitch shift by Gabor coefficient bands shift
+%   Usage: demo_blockproc_pitchshift('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_PITCHSHIFT without arguments.
+%
+%   This script demonstrates a real-time Gabor coefficient manipulation.
+%   Frequency bands are shifted up or down according to the slider
+%   position.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_pitchshift.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+M = 1000;
+
+fobj = blockfigure();
+
+% Basic Control pannel (Java object)
+parg = {
+        {'GdB','Gain',-20,20,0,21},...
+        {'Shi','Shift',-200,200,0,401}
+       };
+
+p = blockpanel(parg);
+
+bufLen = 1024;
+% Setup blocktream
+fs=block(source,varargin{:},'loadind',p,'L',bufLen);
+
+% Window length in ms
+winLenms = 20; 
+[F,Fdual] = framepair('dgtreal',{'hann',floor(fs*winLenms/1e3)},'dual',128,M);
+[Fa,Fs] = blockframepairaccel(F,Fdual, bufLen,'segola');
+
+flag = 1;
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+   gain = blockpanelget(p,'GdB');
+   gain = 10.^(gain/20);
+   shift = fix(blockpanelget(p,'Shi'));
+
+   % Read block of data
+   [f,flag] = blockread();
+
+   % Apply gain
+   f=f*gain;
+   
+   % Obtain DGT coefficients
+   c = blockana(Fa, f);
+   
+   % Do the actual coefficient shift
+   cc = Fa.coef2native(c,size(c));
+   
+   if(strcmpi(source,'playrec'))
+      % Hum removal (aka low-pass filter)
+      cc(1:2,:,:) = 0;
+   end
+   
+   if shift<0
+      cc = [cc(-shift+1:end,:,:); zeros(-shift,size(cc,2),size(cc,3))];
+   else
+      cc = [zeros(shift,size(cc,2),size(cc,3)); cc(1:end-shift,:,:)];
+   end
+   c = Fa.native2coef(cc);
+   
+   % Plot the transposed coefficients
+   blockplot(fobj,Fa,c(:,1));
+   
+   % Reconstruct from the modified coefficients
+   fhat = blocksyn(Fs, c, size(f,1));
+
+   % Enqueue to be played
+   blockplay(fhat);
+end
+% Clear and close all
+blockdone(p,fobj);
+
diff --git a/inst/demos/demo_blockproc_slidingcqt.m b/inst/demos/demo_blockproc_slidingcqt.m
new file mode 100644
index 0000000..d366d58
--- /dev/null
+++ b/inst/demos/demo_blockproc_slidingcqt.m
@@ -0,0 +1,98 @@
+function demo_blockproc_slidingcqt(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_slidingcqt
+%@verbatim
+%DEMO_BLOCKPROC_SLIDINGCQT Basic real-time rolling CQT-spectrogram visualization
+%   Usage: demo_blockproc_slidingcqt('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_SLIDINGCQT without arguments.
+%
+%   This demo shows a simple rolling CQT-spectrogram of whatever is specified in
+%   source. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_slidingcqt.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+% Control pannel (Java object)
+% Each entry determines one parameter to be changed during the main loop
+% execution.
+p = blockpanel({
+               {'GdB','Gain',-20,20,0,21},...
+               {'cMult','C mult',-40,40,10,41}
+               });
+           
+fobj = blockfigure();
+    
+% Buffer length
+% Larger the number the higher the processing delay. 1024 with fs=44100Hz
+% makes ~23ms.
+% Note that the processing itself can introduce additional delay.
+bufLen = 1024;
+zpad = bufLen/2;
+
+% Setup blocktream
+fs=block(source,varargin{:},'loadind',p,'L',bufLen);
+
+% Prepare CQT filters in range 200Hz--20kHz, 48 bins per octave
+% 320 + 2 filters in total.
+[g,a]=cqtfilters(fs,200,20000,48,2*bufLen+2*zpad,'fractionaluniform');
+
+% Prepare a frame object representing the filterbank
+F = frame('filterbankreal',g,a,numel(a));
+% Accelerate the frame object to be used with the "sliced" block processing
+% handling.
+Fa = blockframeaccel(F,bufLen,'sliced','zpad',zpad);
+
+% This variable holds overlaps in coefficients needed in the sliced block
+% handling between consecutive loop iterations.
+cola = [];
+flag = 1;
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+  % Get parameters 
+  [gain, mult] = blockpanelget(p,'GdB','cMult');
+  % Overal gain of the input
+  gain = 10^(gain/20);
+  % Coefficient magnitude mult. factor
+  % Introduced to make coefficients to tune
+  % the coefficients to fit into dB range used by
+  % blockplot.
+  mult = 10^(mult/20);
+
+  % Read block of length bufLen
+  [f,flag] = blockread();
+  f = f*gain;
+  % Apply analysis frame
+  c = blockana(Fa, f); 
+  % Append coefficients to plot  
+  cola = blockplot(fobj,Fa,mult*c(:,1),cola);
+  % Play the samples
+  blockplay(f);
+end
+
+% Close the stream, destroy the objects
+blockdone(p,Fa,fobj);
+
+
+
+
diff --git a/inst/demos/demo_blockproc_slidingerblets.m b/inst/demos/demo_blockproc_slidingerblets.m
new file mode 100644
index 0000000..287ba59
--- /dev/null
+++ b/inst/demos/demo_blockproc_slidingerblets.m
@@ -0,0 +1,85 @@
+function demo_blockproc_slidingerblets(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_slidingerblets
+%@verbatim
+%DEMO_BLOCKPROC_SLIDINGERBLETS Basic real-time rolling erblet-spectrogram visualization
+%   Usage: demo_blockproc_slidingerblets('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_SLIDINGERBLETS without arguments.
+%
+%   This demo shows a simple rolling erblet-spectrogram of whatever is specified in
+%   source. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_slidingerblets.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+% Control pannel (Java object)
+% Each entry determines one parameter to be changed during the main loop
+% execution.
+p = blockpanel({
+               {'GdB','Gain',-20,20,0,21},...
+               {'cMult','C mult',0,80,20,81}
+               });
+            
+fobj = blockfigure();
+    
+% Buffer length
+% Larger the number the higher the processing delay. 1024 with fs=44100Hz
+% makes ~23ms.
+% The value can be any positive integer.
+% Note that the processing itself can introduce additional delay.
+bufLen = 1024;
+
+% Setup blocktream
+fs=block(source,varargin{:},'loadind',p,'L',bufLen);
+
+% Number of filters
+M = 200;
+[g,a]=erbfilters(fs,2*bufLen,'fractionaluniform','M',M);
+F = frame('filterbankreal',g,a,size(a,1));
+Fa = blockframeaccel(F,bufLen,'sliced');
+
+flag = 1;
+cola = [];
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+  % Get parameters 
+  [gain,mult] = blockpanelget(p,'GdB','cMult');
+  gain = 10^(gain/20);
+  mult = 10^(mult/20);
+
+  % Read block of length bufLen
+  [f,flag] = blockread();
+  f = f*gain;
+  % Apply analysis frame
+  c = blockana(Fa, f); 
+  % Plot
+  cola = blockplot(fobj,Fa,mult*c(:,1),cola);
+  
+  blockplay(f);
+end
+blockdone(p,fobj,Fa);
+
+
+
+
diff --git a/inst/demos/demo_blockproc_slidingsgram.m b/inst/demos/demo_blockproc_slidingsgram.m
new file mode 100644
index 0000000..25c6d6c
--- /dev/null
+++ b/inst/demos/demo_blockproc_slidingsgram.m
@@ -0,0 +1,82 @@
+function demo_blockproc_slidingsgram(source,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} demo_blockproc_slidingsgram
+%@verbatim
+%DEMO_BLOCKPROC_SLIDINGSGRAM Basic real-time rolling spectrogram visualization
+%   Usage: demo_blockproc_slidingsgram('gspi.wav')
+%
+%   For additional help call DEMO_BLOCKPROC_SLIDINGSGRAM without arguments.
+%
+%   This demo shows a simple rolling spectrogram of whatever is specified in
+%   source. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_blockproc_slidingsgram.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if demo_blockproc_header(mfilename,nargin)
+   return;
+end
+
+% Basic Control pannel (Java object)
+p = blockpanel({
+               {'GdB','Gain',-20,20,0,21},...
+               });
+
+% Basic sepctrogram figure (Java object)
+fobj = blockfigure();
+
+%
+bufLen = 1024;
+% Setup blocktream
+fs=block(source,varargin{:},'loadind',p,'L',bufLen);
+
+
+% Using dgtreal with 20ms hann window, hop factor 80, 1000 channels.
+% Redundancy factor 12.5
+winLenms = 20;
+a = 100;
+M = 3000;
+
+F = frame('dgtreal',{'hann',floor(fs*winLenms/1e3)},a,M);
+F = blockframeaccel(F, bufLen,'segola');
+
+
+flag = 1;
+%Loop until end of the stream (flag) and until panel is opened
+while flag && p.flag
+   % Obtain the global gain value
+   gain = blockpanelget(p,'GdB');
+   gain = 10^(gain/20);
+
+   % Read the next block of samples
+   [f,flag] = blockread();
+   f=f*gain;
+   
+   % Do analysis using the specified frame. 
+   c = blockana(F, f); 
+   
+   % Draw the first channel coefficients
+   blockplot(fobj,F,c(:,1));
+   
+   % Enqueue to play
+   blockplay(f);
+end
+blockdone(p,fobj);
+
diff --git a/inst/demos/demo_dgt.m b/inst/demos/demo_dgt.m
new file mode 100644
index 0000000..b0496f8
--- /dev/null
+++ b/inst/demos/demo_dgt.m
@@ -0,0 +1,165 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_dgt
+%@verbatim
+%DEMO_DGT  Basic introduction to DGT analysis/synthesis
+%
+%   This demo shows how to compute Gabor coefficients of a signal.
+%
+%   Figure 1: Spectrogram of the 'bat' signal.
+%
+%      The figure shows a spectrogram of the 'bat' signal. The
+%      coefficients are shown on a linear scale.
+%
+%   Figure 2: Gabor coefficients of the 'bat' signal.
+%
+%      The figure show a set of Gabor coefficients for the 'bat' signal,
+%      computed using a DGT with a Gaussian window. The coefficients
+%      contains all the information to reconstruct the signal, even though
+%      there a far fewer coefficients than the spectrogram contains.
+%
+%   Figure 3: Real-valued Gabor analysis
+%
+%      This figure shows only the coefficients for the positive
+%      frequencies. As the signal is real-value, these coefficients
+%      contain all the necessary information. Compare to the shape of the
+%      spectrogram shown on Figure 1.
+%
+%   Figure 4: DGT coefficients on a spectrogram
+%
+%      This figure shows how the coefficients from DGTREAL can be picked
+%      from the coefficients computed by a full Short-time Fourier
+%      transform, as visualized by a spectrogram.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_dgt.php}
+%@seealso{sgram, dgt, dgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_dgt" to see a description of how this demo works.');
+
+% Load a test signal
+f=bat;
+
+% sampling rate of the test signal, only important for plotting
+fs=143000;
+
+% Length of signal
+Ls=length(f);
+
+disp(' ');
+disp('------ Spectrogram analysis -----------------------------------');
+
+figure(1);
+c_sgram=sgram(f,fs,'lin');
+title('Spectrogram of the bat test signal.');
+
+
+% Number of coefficients in the Spectrogram
+no_sgram=numel(c_sgram);
+
+disp(' ');
+disp('The spectrogram is highly redundant.');
+fprintf('No. of coefficients in the signal:       %i\n',Ls);
+fprintf('No. of coefficients in the spectrogram:  %i\n',no_sgram);
+fprintf('Redundacy of the spectrogram:            %f\n',no_sgram/Ls);
+
+% WARNING: In the above code, the spectrogram routine SGRAM returns the
+% coefficients use to plot the image. These coefficients are ONLY
+% intended to be used by post-processing image tools, and in this
+% example, the are only used to illustrate the redundancy of the
+% spectogram. Numerical Gabor signal analysis and synthesis should ALWAYS
+% be done using the DGT, IDGT, DGTREAL and IDGTREAL functions, see the
+% following sections of this example.
+
+disp(' ');
+disp('---- Simple Gabor analysis using a standard Gaussian window. ----');
+
+disp('Setup parameters for a Discrete Gabor Transform.')
+disp('Time shift:')
+a=20
+
+disp('Number of frequency channels.');
+M=40
+
+disp(' ');
+disp('Note that it must hold that L = M*b = N*a for some integers b, N and L,');
+disp('and that a<M. L is the transform length, and the DGT will choose the');
+disp('smallest possible value of L that is larger or equal to the length of the');
+disp('signal. Choosing a<M makes the transform redundant, otherwise the');
+disp('transform will be lossy, and reconstruction will not be possible.');
+
+% Simple DGT using a standard Gaussian window.
+c=dgt(f,'gauss',a,M);
+
+disp('Number of time shifts in transform:')
+N = size(c,2);
+
+disp('Length of transform:')
+L = N*a
+
+
+figure(2);
+plotdgt(c,a,'linsq');
+title('Gabor coefficients.');
+
+disp(' ');
+disp(['The redundancy of the Gabor transform can be reduced without loosing ' ...
+      'information.']);
+fprintf('No. of coefficients in the signal:       %i\n',Ls);
+fprintf('No. of output coefficients from the DGT: %i\n',numel(c));
+fprintf('Redundacy of the DGT (in this case)      %f\n',numel(c)/Ls);
+
+disp(' ');
+disp('---- Real valued Gabor analysis. ----');
+
+% Figure 1 and Figure 2 looks quite different, because Figure 2 also
+% displays the coefficients for the n
+
+% Simple real valued DGT using a standard Gaussian window.
+c_real=dgtreal(f,'gauss',a,M);
+
+figure(3);
+plotdgtreal(c_real,a,M,'linsq');
+title('Positive-frequency DGT coefficients (DGTREAL).');
+
+figure(4);
+b=L/M;
+[X,Y]=meshgrid(1:a:L+a,1:b:L/2+b);
+
+hold on;
+imagesc(c_sgram);
+plot([X(:),X(:)]',[Y(:),Y(:)]','wo','Linewidth',1);
+axis('xy','image');
+hold off;
+title('Placement of the DGTREAL coefficients on the spectrogram.');
+
+disp(' ');
+disp('---- Perfect reconstruction. ----');
+
+% Reconstruction from the full DGT coefficients
+r      = idgt(c,'gaussdual',a);
+
+% Reconstruction from the DGTREAL coefficients
+% The parameter M cannot be deduced from the size of the coefficient
+% array c_real, so it is an explicit input parameter.
+r_real = idgtreal(c_real,'gaussdual',a,M);
+
+fprintf('Reconstruction error using IDGT:      %e\n',norm(f-r));
+fprintf('Reconstruction error using IDGTREAL:  %e\n',norm(f-r_real));
+
diff --git a/inst/demos/demo_firwin.m b/inst/demos/demo_firwin.m
new file mode 100644
index 0000000..8fceeed
--- /dev/null
+++ b/inst/demos/demo_firwin.m
@@ -0,0 +1,37 @@
+clf;
+hold all;
+
+L=30;
+dr=110;
+magresp(firwin('hanning',L,'1'),'fir','dynrange',dr);
+magresp(firwin('hamming',L,'1'),'fir','dynrange',dr);
+magresp(firwin('blackman',L,'1'),'fir','dynrange',dr);
+magresp(firwin('nuttall',L,'1'),'fir','dynrange',dr);
+magresp(firwin('itersine',L,'1'),'fir','dynrange',dr);
+
+legend('Hann','Hamming','Blackman','Nuttall','Itersine');
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} demo_firwin
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_firwin.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/demos/demo_framemul.m b/inst/demos/demo_framemul.m
new file mode 100644
index 0000000..b412650
--- /dev/null
+++ b/inst/demos/demo_framemul.m
@@ -0,0 +1,174 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_framemul
+%@verbatim
+%DEMO_FRAMEMUL  Time-frequency localization by a Gabor multiplier
+%
+%   This script creates several different time-frequency symbols
+%   and demonstrate their effect on a random, real input signal.
+%
+%   Figure 1: Cut a circle in the TF-plane
+%
+%      This figure shows the symbol (top plot, only the positive frequencies are displayed),
+%      the input random signal (bottom) and the output signal (middle).
+%
+%   Figure 2: Keep low frequencies (low-pass)
+%
+%      This figure shows the symbol (top plot, only the positive frequencies are displayed),
+%      the input random signal (bottom) and the output signal (middle).
+%
+%   Figure 3: Keep middle frequencies (band-pass)
+%
+%      This figure shows the symbol (top plot, only the positive frequencies are displayed),
+%      the input random signal (bottom) and the output signal (middle).
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_framemul.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_framemul" to see a description of how this demo works.');
+
+% Setup some suitable parameters for the Gabor system
+L=480;
+a=20;
+M=24;
+
+b=L/M;
+N=L/a;
+
+% Plotting initializations
+t_axis = (0:(M-1))*a;
+f_max = floor(N/2)-1;
+f_range = 1:(f_max+1);
+f_axis = f_range*b;
+
+xlabel_angle = 7;
+ylabel_angle = -11;
+
+% Create a tight window, so it can be used for both analysis and
+% synthesis.
+
+% Frames framework equivalent g=gabtight(a,M,L);
+F = frametight(frame('dgt','gauss',a,M));
+
+
+% Create the random signal.
+f=randn(L,1);
+
+% ------- sharp cutoff operator ---------
+% This cuts out a circle in the TF-plane. 
+symbol1=zeros(M,N);
+
+for m=0:M-1
+  for n=0:N-1
+    if (m-M/2)^2+(n-N/2)^2 <(M/4)^2
+      symbol1(m+1,n+1)=1;
+    end;
+  end;
+end;
+
+% The symbol as defined by the above loops is centered such
+% that it keeps the high frequencys. To obtain the low ones, we
+% move the symbol along the first dimension:
+symbol1=fftshift(symbol1,1);
+
+
+% Do the actual filtering
+% Frames framework equivalent to ff1=gabmul(f,symbol1,g,a);
+ff1 = framemul(f,F,F,framenative2coef(F,symbol1));
+
+
+% plotting
+figure(1);
+
+subplot(3,1,1);
+mesh(t_axis,f_axis,symbol1(f_range,:));
+
+if isoctave
+  xlabel('Time');
+  ylabel('Frequency');
+else
+  xlabel('Time','rotation',xlabel_angle);
+  ylabel('Frequency','rotation',ylabel_angle);
+end;
+
+subplot(3,1,2);
+plot(real(ff1));
+
+subplot(3,1,3);
+plot(f);
+
+
+% ---- Tensor product symbol, keep low frequencies.
+t1=pgauss(M);
+t2=pgauss(N);
+
+symbol2=fftshift(t1*t2',2);
+
+% Do the actual filtering
+% Frames framework equivalent to ff2=gabmul(f,symbol2,g,a);
+ff2 = framemul(f,F,F,framenative2coef(F,symbol2));
+
+figure(2);
+
+subplot(3,1,1);
+mesh(t_axis,f_axis,symbol2(f_range,:));
+
+if isoctave
+  xlabel('Time');
+  ylabel('Frequency');
+else
+  xlabel('Time','rotation',xlabel_angle);
+  ylabel('Frequency','rotation',ylabel_angle);
+end;
+
+subplot(3,1,2);
+plot(real(ff2));
+
+subplot(3,1,3);
+plot(f);
+
+% ----- Tensor product symbol, keeps middle frequencies.
+t1=circshift(pgauss(M,.5),round(M/4))+circshift(pgauss(M,.5),round(3*M/4));
+t2=pgauss(N);
+
+symbol3=fftshift(t1*t2',2);
+
+% Do the actual filtering
+% Frames framework equivalent to ff3=gabmul(f,symbol3,g,a);
+ff3 = framemul(f,F,F,framenative2coef(F,symbol3));
+
+figure(3);
+
+subplot(3,1,1);
+mesh(t_axis,f_axis,symbol3(f_range,:));
+
+if isoctave
+  xlabel('Time');
+  ylabel('Frequency');    
+else    
+  xlabel('Time','rotation',xlabel_angle);
+  ylabel('Frequency','rotation',ylabel_angle);
+end;
+
+subplot(3,1,2);
+plot(real(ff3));
+
+subplot(3,1,3);
+plot(f);
+
diff --git a/inst/demos/demo_frsynabs.m b/inst/demos/demo_frsynabs.m
new file mode 100644
index 0000000..5d572c6
--- /dev/null
+++ b/inst/demos/demo_frsynabs.m
@@ -0,0 +1,68 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_frsynabs
+%@verbatim
+%DEMO_FRSYNABS  Contruction of a signal with a given spectrogram
+%
+%   This demo demonstrates iterative reconstruction of a spectrogram.
+%
+%   Figure 1: Original spectrogram
+%
+%      This figure shows the target spectrogram
+%
+%   Figure 2: Linear reconstruction
+%
+%      This figure shows a spectrogram of a linear reconstruction of the
+%      target spectrogram.
+%
+%   Figure 3: Iterative reconstruction using the Griffin-Lim method.
+%
+%      This figure shows a spectrogram of an iterative reconstruction of the
+%      target spectrogram using the Griffin-Lim projection method.
+%
+%   Figure 4: Iterative reconstruction using the BFGS method
+%
+%      This figure shows a spectrogram of an iterative reconstruction of the
+%      target spectrogram using the BFGS method.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_frsynabs.php}
+%@seealso{isgramreal, isgram}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+s=ltfattext;
+
+figure(1);
+imagesc(s);
+colormap(gray);
+axis('xy');
+
+figure(2);
+F = frame('dgtreal','gauss',8,800); 
+scoef = framenative2coef(F,s);
+sig_lin = frsyn(F,sqrt(scoef));
+sgram(sig_lin,'dynrange',100);
+
+figure(3);
+sig_griflim = frsynabs(F,scoef);
+sgram(sig_griflim,'dynrange',100);
+
+figure(4);
+sig_bfgs = frsynabs(F,scoef,'bfgs');
+sgram(sig_bfgs,'dynrange',100);
+
diff --git a/inst/demos/demo_gabfir.m b/inst/demos/demo_gabfir.m
new file mode 100644
index 0000000..0f5e517
--- /dev/null
+++ b/inst/demos/demo_gabfir.m
@@ -0,0 +1,237 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_gabfir
+%@verbatim
+%DEMO_GABFIR  Working with FIR windows
+%
+%   This demo demonstrates how to work with FIR windows in Gabor systems.
+%
+%   FIR windows are the windows traditionally used in signal processing.
+%   They are short, much shorter than the signal, and this is used to make
+%   effecient algorithms. They are also the only choice for applications
+%   involving streaming data.
+%
+%   It is very easy to compute a spectrogram or Gabor coefficients using a
+%   FIR window. The hard part is reconstruction, because both the window and
+%   the dual window used for reconstruction must be FIR, and this is hard
+%   to obtain, if the window is longer than the number of channels.
+%
+%   This demo demonstrates two methods:
+%
+%     1) Using a Gabor frame with a simple structure, for which dual/tight
+%        FIR windows are easy to construct. This is a very common
+%        technique in traditional signal processing, but it limits the
+%        choice of windows and lattice parameters.
+%
+%     2) Cutting a canonical dual/tight window. We compute the canonical
+%        dual window of the analysis window, and cut away the parts that
+%        are close to zero. This will work for any analysis window and
+%        any lattice constant, but the reconstruction obtained is not
+%        perfect.
+%
+%   Figure 1: Hanning FIR window
+%
+%      This figure shows the a Hanning window in the time domain and its
+%      magnitude response.
+%
+%   Figure 2: Kaiser-Bessel FIR window
+%
+%      This figure shows a Kaiser Bessel window and its magnitude response,
+%      and the same two plots for the canonical dual of the window.
+%
+%   Figure 3: Gaussian FIR window for low redundancy
+%
+%      This figure shows a truncated Gaussian window and its magnitude
+%      response. The same two plots are show for the truncated canonical
+%      dual window.
+%
+%   Figure 4: Almost tight Gaussian FIR window
+%
+%      This figure shows a tight Gaussian window that has been truncated
+%      and its magnitude response.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_gabfir.php}
+%@seealso{firwin, firkaiser, gabdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% -------- first part: Analytically known FIR window ----------------- 
+
+% The lattice constants to use.
+a=16;
+M=2*a;
+
+% When working with FIR windows, some routines (gabdualnorm, magresp)
+% require a transform length. Strictly speaking, this should be infinity,
+% but this is not possible in the current implementation. Choosing an
+% LLong that is some high multiple of M provides a very good approximation
+% of the correct result.
+LLong=M*16;
+
+% Compute the iterated sine window. This window is a tight window when used
+% with a Gabor system where the number of channels is larger than or
+% equal to the length of the window.
+g=gabwin('itersine',a,M);
+
+disp('');
+disp('Reconstruction error using itersine window, should be close to zero:');
+gabdualnorm(g,g,a,M,LLong)
+
+figure(1);
+
+% Plot the window in the time-domain.
+subplot(2,1,1);
+plot(fftshift(g));
+title('itersine FIR window.');
+
+% Plot the magnitude response of the window (the frequency representation of
+% the window on a dB scale).
+subplot(2,1,2);
+magresp(g,'fir','dynrange',100);
+title('Magnitude response of itersine window.');
+
+% -------- second part: True, short FIR window -------------------------
+
+% If the length of the window is less than or equal to the number of
+% channels M, then the canonical dual and tight windows will have the
+% same support. This case is explicitly supported by gabdual
+
+% Set up a nice Kaiser-Bessel window.
+g=firkaiser(M,3.2,'energy');
+
+% Compute the canonical dual window
+gd=gabdual(g,a,M);
+
+disp('');
+disp('Reconstruction error canonical dual of Kaiser window, should be close to zero:');
+gabdualnorm(g,gd,a,M)
+
+figure(2);
+
+% Plot the window in the time-domain.
+subplot(2,2,1);
+plot(fftshift(g));
+title('Kaiser window.');
+
+% Plot the magnitude response of the window (the frequency representation of
+% the window on a dB scale).
+subplot(2,2,2);
+magresp(g,'fir','dynrange',100);
+title('Magnitude response of Kaiser window.');
+
+% Plot the window in the time-domain.
+subplot(2,2,3);
+plot(fftshift(gd));
+title('Dual of Kaiser window.');
+
+% Plot the magnitude response of the window (the frequency representation of
+% the window on a dB scale).
+subplot(2,2,4);
+magresp(gd,'fir','dynrange',100);
+title('Magnitude response of dual Kaiser window.');
+
+
+% -------- Third part, cutting a LONG window --------------
+
+% We can now work with any lattice constants and lower redundancies.
+a=12;
+M=18;
+
+% LLong plays the same role as in the first part. It must be a multiple of
+% both 'a' and M.
+LLong=M*a*16;
+
+% Construct an LONG Gaussian window with optimal time/frequency resolution.
+glong=pgauss(LLong,a*M/LLong);
+
+% Cut it to a FIR window, preserving the WPE symmetry.
+% The length must be a multiple of M.
+gfir=long2fir(glong,2*M,'wp');
+
+% Extend the cutted window, and compute the dual window of this.
+gfirextend=fir2long(gfir,LLong);
+gd_long=gabdual(gfirextend,a,M);
+
+% Cut it, preserving the WPE symmetry
+gd_fir=long2fir(gd_long,6*M,'wp');
+
+% Compute the reconstruction error
+disp('');
+disp('Reconstruction error using cutted dual window.');
+recerr = gabdualnorm(gfir,gd_fir,a,M,LLong)
+
+disp('');
+disp('or expressed in dB:');
+10*log10(recerr)
+
+figure(3);
+
+% Plot the window in the time-domain.
+subplot(2,2,1);
+plot(fftshift(gfir));
+title('Gaussian FIR window.');
+
+% Plot the magnitude response of the window (the frequency representation of
+% the window on a dB scale).
+subplot(2,2,2);
+magresp(gfir,'fir','dynrange',100);
+title('Magnitude response of FIR Gaussian.')
+
+% Plot the window in the time-domain.
+subplot(2,2,3);
+plot(fftshift(gd_fir));
+title('Dual of Gaussian FIR window.');
+
+% Plot the magnitude response of the window (the frequency representation of
+% the window on a dB scale).
+subplot(2,2,4);
+magresp(gd_fir,'fir','dynrange',100);
+title('Magnitude response.');
+
+% ----- Fourth part, cutting a tight LONG window --------------
+
+% We reuse all the parameters of the previous demo.
+
+% Get a tight window.
+gt_long = gabtight(a,M,LLong);
+
+% Cut it
+gt_fir = long2fir(gt_long,6*M);
+
+% Compute the reconstruction error
+disp('');
+disp('Reconstruction error using cutted tight window.');
+recerr = gabdualnorm(gt_fir,gt_fir,a,M,LLong)
+
+disp('');
+disp('or expressed in dB:');
+10*log10(recerr)
+
+figure(4);
+
+% Plot the window in the time-domain.
+subplot(2,1,1);
+plot(fftshift(gt_fir));
+title('Almost tight FIR window.');
+
+% Plot the magnitude response of the window (the frequency representation of
+% the window on a dB scale).
+subplot(2,1,2);
+magresp(gt_fir,'fir','dynrange',100);
+title('Magnitude response.');
+
diff --git a/inst/demos/demo_gablasso.m b/inst/demos/demo_gablasso.m
new file mode 100644
index 0000000..776637f
--- /dev/null
+++ b/inst/demos/demo_gablasso.m
@@ -0,0 +1,92 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_gablasso
+%@verbatim
+%DEMO_GABLASSO  Sparse regression by Lasso method
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_gablasso.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Signals
+siglen=512;
+t=((0:siglen-1)/siglen).';
+x0 = sin(2*pi*64*t);
+x=x0+randn(size(x0))/2;
+
+% DCGT parameters
+a=2;
+M=128;
+
+% Regression parameters
+lambda = 0.08;
+maxit=500;
+tol=1e-1;
+
+F=frametight(frame('dgtreal','gauss',a,M));
+
+% LASSO
+[tcl,relres,iter,xrecl] = franalasso(F,x,lambda,'maxit',maxit,'tol',tol);
+
+% GLASSO
+[tcgl,relres,iter,xrecgl] = franagrouplasso(F,x,lambda,'maxit',maxit,'tol',tol);
+
+% Displays
+figure(1);
+subplot(2,2,1);
+plot(x0); 
+axis tight; 
+grid; 
+title('Original')
+
+subplot(2,2,2);
+plot(x);
+axis tight; 
+grid; 
+title('Noisy')
+
+subplot(2,2,3);
+plot(real(xrecl)); 
+axis tight; 
+grid; 
+title('LASSO')
+
+subplot(2,2,4);
+plot(real(xrecgl)); 
+axis tight; 
+grid; 
+title('GLASSO')
+
+dr=80;
+
+figure(2);
+subplot(2,2,1);
+framegram(F,x0,'dynrange',dr);
+title('Original')
+
+subplot(2,2,2); 
+framegram(F,x,'dynrange',dr);
+title('Noisy')
+
+subplot(2,2,3);
+framegram(F,xrecl,'dynrange',dr);
+title('LASSO')
+
+subplot(2,2,4); 
+framegram(F,xrecgl,'dynrange',dr);
+title('Group LASSO')
+
diff --git a/inst/demos/demo_gabmixdual.m b/inst/demos/demo_gabmixdual.m
new file mode 100644
index 0000000..765c726
--- /dev/null
+++ b/inst/demos/demo_gabmixdual.m
@@ -0,0 +1,124 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_gabmixdual
+%@verbatim
+%DEMO_GABMIXDUAL  How to use GABMIXDUAL
+%
+%   This script illustrates how one can produce dual windows
+%   using GABMIXDUAL
+%
+%   The demo constructs a dual window that is more concentrated in
+%   the time domain by mixing the original Gabor window by one that is
+%   extremely well concentrated. The result is somewhat in the middle
+%   of these two.
+% 
+%   The lower framebound of the mixing Gabor system is horrible,
+%   but this does not carry over to the gabmixdual.
+%
+%   Figure 1: Gabmixdual of two Gaussians.
+%
+%      The first row of the figure shows the canonical dual window
+%      of the input window, which is a Gaussian function perfectly
+%      localized in the time and frequency domains.
+%
+%      The second row shows the canonical dual window of the window we
+%      will be mixing with: This is a Gaussian that is 10 times more
+%      concentrated in the time domain than in the frequency domain.
+%      The resulting canonical dual window has rapid decay in the time domain.
+%
+%      The last row shows the gabmixdual of these two. This is a non-canonical
+%      dual window of the first Gaussian, with decay resembling that of the
+%      second.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_gabmixdual.php}
+%@seealso{gabmixdual, gabdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_gabmixdual" to see a description of how this demo works.');
+
+L=120;
+a=10;
+M=12;
+
+% Compute frequency shift.
+b=L/M;
+
+% Optimally centered Gaussian
+g1=pgauss(L);
+
+% Compute and print framebounds.
+[A1,B1]=gabframebounds(g1,a,M);
+disp('');
+disp('Framebounds of initial Gabor system:');
+A1, B1
+
+% Narrow Gaussian
+g2=pgauss(L,.1);
+
+% Compute and print framebounds.
+[A2,B2]=gabframebounds(g2,a,M);
+disp('');
+disp('Framebounds of mixing Gabor system:');
+A2, B2
+
+% Create a gabmixdual. The window gd is a dual window to g1
+gd=gabmixdual(g1,g2,a,M);
+
+% Compute and print framebounds.
+[Am,Bm]=gabframebounds(gd,a,M);
+disp('');
+disp('Framebounds of gabmixdual Gabor system:');
+Am, Bm
+
+% Create canonical duals, for plotting.
+gc1=gabdual(g1,a,M);
+gc2=gabdual(g2,a,M);
+
+% Standard note on plotting:
+%
+% - The windows are all centered around zero, but this
+%   is not visually pleasing, so the window must be
+%   shifted to the middle by an FFTSHIFT
+
+figure(1);
+
+subplot(3,2,1);
+plot(fftshift(gc1));
+title('Canonical dual window.');  
+
+subplot(3,2,2);
+plot(20*log10(abs(fftshift(gc1))));
+title('Decay of canonical dual window.');  
+
+subplot(3,2,3);
+plot(fftshift(gc2));
+title('Can. dual of mix. window.');
+
+subplot(3,2,4);
+plot(20*log10(abs(fftshift(gc2))));
+title('Decay of can.dual of mix. window.')
+
+subplot(3,2,5);
+plot(fftshift(gd));
+title('Gabmixdual');
+
+subplot(3,2,6);
+plot(20*log10(abs(fftshift(gd))));
+title('Decay of gabmixdual');
+
diff --git a/inst/demos/demo_gabmulappr.m b/inst/demos/demo_gabmulappr.m
new file mode 100644
index 0000000..b303d53
--- /dev/null
+++ b/inst/demos/demo_gabmulappr.m
@@ -0,0 +1,115 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_gabmulappr
+%@verbatim
+%DEMO_GABMULAPPR Approximate a slowly time variant system by a Gabor multiplier
+%   
+%   This script construct a slowly time variant system and performs the 
+%   best approximation by a Gabor multiplier with specified parameters
+%   (a and L see below). Then it shows the action of the slowly time 
+%   variant system (A) as well as of the best approximation of (A) by a 
+%   Gabor multiplier (B) on a sinusoids and an exponential sweep.
+%
+%   Figure 1: Spectrogram of signals
+%
+%      The figure shows the spectogram of the output of the two systems applied on a 
+%      sinusoid (left) and an exponential sweep.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_gabmulappr.php}
+%@seealso{gabmulappr}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter Balazs.
+%   based on demo_gabmulappr.m 
+
+disp('Type "help demo_gabmulappr" to see a description of how this demo works.');
+
+% Setup parameters for the Gabor system and length of the signal
+L=576; % Length of the signal
+a=32;   % Time shift 
+M=72;  % Number of modulations
+fs=44100; % assumed sampling rate
+SNRtv=63; % signal to noise ratio of change rate of time-variant system
+
+% construction of slowly time variant system
+% take an initial vector and multiply by random vector close to one
+A = [];
+c1=(1:L/2); c2=(L/2:-1:1); c=[c1 c2].^(-1); % weight of decay x^(-1)
+A(1,:)=(rand(1,L)-0.5).*c;  % convolution kernel
+Nlvl = exp(-SNRtv/10);
+Slvl = 1-Nlvl;
+for ii=2:L;
+     A(ii,:)=(Slvl*circshift(A(ii-1,:),[0 1]))+(Nlvl*(rand(1,L)-0.5)); 
+end;
+A = A/norm(A)*0.99; % normalize matrix
+
+% perform best approximation by gabor multiplier
+sym=gabmulappr(A,a,M);
+
+% creation of 3 different input signals (sinusoids)
+x=2*pi*(0:L-1)/L.';
+f1 = 1000; % frequency in Hz
+s1=0.99*sin((fs/f1).*x);
+% Ramp the signal to avoid distortions at the end, ramp are 5% of total
+% length of the signal.
+s1=rampsignal(s1,round(L*.05));
+
+L1=ceil(L*0.9);
+e1=0.99*expchirp(L1,500,fs/2*0.9,'fs',fs);
+% Ramp signal as before.
+e1=rampsignal(e1,round(L1*.05));
+e1=[e1;zeros(L-L1,1)];
+
+% application of the slowly time variant system
+As1=A*s1';  
+Ae1=A*e1;
+
+% application of the Gabor multiplier
+Gs1=gabmul(s1,sym,a); 
+Ge1=gabmul(e1,sym,a);
+
+% Plotting the results
+%% ------------- figure 1 ------------------------------------------
+
+clim=[-40,13];
+figure(1);
+subplot(2,2,1);
+sgram(real(As1),'tfr',10,'clim',clim,'nocolorbar'); 
+title (sprintf('Spectogram of output signal: \n Time-variant system applied on sinusoid'),'Fontsize',14);
+set(get(gca,'XLabel'),'Fontsize',14);
+set(get(gca,'YLabel'),'Fontsize',14);
+
+subplot(2,2,2);
+sgram(real(Ae1),'tfr',10,'clim',clim,'nocolorbar'); 
+title (sprintf('Spectogram of output signal: \n Time-variant system applied on exponential sweep'),'Fontsize',14);
+set(get(gca,'XLabel'),'Fontsize',14);
+set(get(gca,'YLabel'),'Fontsize',14);
+
+subplot(2,2,3);
+sgram(real(Gs1),'tfr',10,'clim',clim,'nocolorbar');
+title (sprintf('Spectogram of output signal: \n Best approximation by Gabor multipliers applied on sinusoid'),'Fontsize',14);
+set(get(gca,'XLabel'),'Fontsize',14);
+set(get(gca,'YLabel'),'Fontsize',14);
+
+subplot(2,2,4);
+sgram(real(Ge1),'tfr',10,'clim',clim,'nocolorbar');
+title (sprintf('Spectogram of output signal: \n Best approximation by Gabor multipliers applied on exponential sweep'),'Fontsize',14);
+set(get(gca,'XLabel'),'Fontsize',14);
+set(get(gca,'YLabel'),'Fontsize',14);
+
diff --git a/inst/demos/demo_imagecompression.m b/inst/demos/demo_imagecompression.m
new file mode 100644
index 0000000..a56801d
--- /dev/null
+++ b/inst/demos/demo_imagecompression.m
@@ -0,0 +1,108 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_imagecompression
+%@verbatim
+%DEMO_IMAGECOMPRESSION  Image compression using N-term approximation
+%
+%   This demo shows how to perform a simple imagecompression using either
+%   a Wilson basis or a Wavelet. The compression step is done by
+%   retaining only 5% of the coefficients. 
+%
+%   Figure 1: Wilson and WMDCT basis
+%
+%      This right figure shows the image compressed using a DWILT basis with
+%      8 channels. This corresponds quite closely to JPEG compression,
+%      except that the borders between neigbouring blocs are smoother,
+%      since the DWILT uses a windowing function.
+%
+%      The left figure shows the same, now
+%      using a MDCT basis. The MDCT produces more visible artifacts, as the
+%      slowest changing frequency in each block has a half-wave
+%      modulation. This is visible on otherwise smooth backgrounds.
+%
+%   Figure 2: Wavelet
+%
+%      The Wavelet used is the DB2 with J=8 levels. On the right figure
+%      the standard layout has been used, on the left the tensor layout
+%      was used.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_imagecompression.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%% Parameters for the problem formulation
+
+% Use the cameraman image
+f=cameraman;
+
+% Ratio to keep
+r=0.05;
+
+%% Parameters for the Wilson systems
+% Analysis window
+ga='itersine';
+
+% synthesis window
+gs='itersine';
+
+% No. of channels
+M=8;
+
+%% Parameters for the Wavelet system
+% Analysis filters
+wa={'ana','db',6};
+
+% Synthesis filters
+ws={'syn','db',6};
+
+% No. of levels 
+J=5;
+
+%% Compute the Wilson figures
+figure(1);
+
+subplot(1,2,1);
+c_dwilt =dwilt2(f,ga,M);
+cc_dwilt=largestr(c_dwilt,r);
+r_dwilt =idwilt2(cc_dwilt,gs);
+imagesc(r_dwilt);
+colormap(gray), axis('image');
+
+subplot(1,2,2);
+c_wmdct =wmdct2(f,ga,M);
+cc_wmdct=largestr(c_wmdct,r);
+r_wmdct =iwmdct2(cc_wmdct,gs);
+imagesc(r_wmdct);
+colormap(gray), axis('image');
+
+%% Compute the Wavelet figures
+
+figure(2);
+
+subplot(1,2,1);
+c_fwt =fwt2(f,wa,J);
+[cc_fwt,n]=largestr(c_fwt,r);
+r_fwt =ifwt2(cc_fwt,ws,J);
+imagesc(r_fwt);
+colormap(gray), axis('image');
+
+subplot(1,2,2);
+c_fwt =fwt2(f,wa,J,'tensor');
+cc_fwt=largestr(c_fwt,r);
+r_fwt =ifwt2(cc_fwt,ws,J,'tensor');
+imagesc(r_fwt);
+colormap(gray), axis('image');
diff --git a/inst/demos/demo_nextfastfft.m b/inst/demos/demo_nextfastfft.m
new file mode 100644
index 0000000..5c6abae
--- /dev/null
+++ b/inst/demos/demo_nextfastfft.m
@@ -0,0 +1,71 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_nextfastfft
+%@verbatim
+%DEMO_NEXTFASTFFT  Next fast FFT number
+%
+%   This demo shows the behaviour of the NEXTFASTFFT function.
+%
+%   Figure 1: Benchmark of the FFT routine
+%
+%      The figure shows the sizes returned by the NEXTFASTFFT function
+%      compared to using nextpow2. As can be seen, the NEXTFASTFFT
+%      approach gives FFT sizes that are much closer to the input size.
+%
+%   Figure 2: Efficiency of the table
+%
+%      The figure show the highest output/input ratio for varying input
+%      sizes. As can be seen, the efficiency is better for larger input
+%      values, where the output size is at most a few percent larger than
+%      the input size.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_nextfastfft.php}
+%@seealso{nextfastfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Range to use for testing.
+% It is important for this script that
+% range_max = 2^nextpow2(range_max) = nextfastfft(range_max), so it must
+% be a power of 2.
+range_min=100;
+range_max=1024;
+r=range_min:range_max;
+
+% r2 contains the next higher sizes using nextpow2
+r2=2.^nextpow2(r);
+
+% r3 contains the next higher sizes using nextfastfft
+r3=nextfastfft(r);
+
+figure(1);
+plot(r,r,r,r2,r,r3);
+xlabel('Input size.');
+ylabel('FFT size.');
+legend('Same size','nextpow2','nextfastfft','Location','SouthEast');
+
+%% Efficiency analysis of the table
+[dummy,table]=nextfastfft(1);
+
+eff=table(2:end)./(table(1:end-1)+1);
+
+figure(2);
+semilogx(table(2:end),eff);
+xlabel('Input size.');
+ylabel('Output/input ratio.');
+mean(eff)
diff --git a/inst/demos/demo_nsdgt.m b/inst/demos/demo_nsdgt.m
new file mode 100644
index 0000000..9ffd0f1
--- /dev/null
+++ b/inst/demos/demo_nsdgt.m
@@ -0,0 +1,108 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_nsdgt
+%@verbatim
+%DEMO_NSDGT  Nonsationary Gabor transform demo
+%
+%   This script sets up a nonstationary Gabor frame with the specified
+%   parameters, computes windows and corresponding canonical dual windows
+%   and a test signal, and plots the windows and the energy of the 
+%   coefficients.
+%
+%   Figure 1: Windows + dual windows
+% 
+%      This figure shows the window functions used and the corresponding
+%      canonical dual windows. 
+%
+%   Figure 2: Spectrogram (absolute value of coefficients in dB)
+%
+%      This figure shows a (color coded) image of the nsdgt coefficient
+%      modulus. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_nsdgt.php}
+%@seealso{nsdgt, insdgt, nsgabdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp(['Type "help demo_nsdgt" to see a description of how this example',...
+  ' works.']);
+
+% Setup parameters and length of signal.
+
+Ls=965; % Length of signal.
+
+N=16; % Number of time positions
+
+% Define a set of windows with length growing linearly. The step beetween
+% to consecutive windows also grows linearly.
+
+M=round(linspace(40,200,N)');
+a=cumsum(round(M/2));
+a=a-a(1);
+
+a_new=round(M/2);
+
+g={};
+for ii=1:length(M)
+    g{ii}=firwin('hann',M(ii));
+end
+
+% Compute corresponding dual windows
+gd=nsgabdual(g,a_new,Ls);
+
+% Plot them
+figure(1);
+color = ['b', 'r'];
+for ii = 1:length(a)
+    subplot(2,1,1);
+    hold on;
+    plot(a(ii)-1-floor(M(ii)/2)+(1:M(ii)), fftshift(g{ii}),...
+      color(rem(ii,2)+1));
+    subplot(2,1,2);
+    hold on;
+    plot(a(ii)-1-floor(M(ii)/2)+(1:M(ii)), fftshift(gd{ii}),...
+      color(rem(ii,2)+1));
+end
+
+subplot(2,1,1);
+title('Analysis windows');
+xlabel('Time index');
+subplot(2,1,2);
+title('Dual synthesis windows');
+xlabel('Time index');
+
+% Define a sinus test signal.
+f=sin(2*pi*0.3*(0:Ls-1)');
+
+% Calculate coefficients.
+c=nsdgt(f,g,a_new,M);
+
+% Plot corresponding spectrogram
+figure(2);
+plotnsdgt(c,a,'dynrange',100);
+title('Spectrogram of test signal')
+
+% Test reconstruction
+f_r=insdgt(c,gd,a_new,Ls);
+
+% Print relative error of reconstruction.
+rec_err = norm(f-f_r)/norm(f);
+
+fprintf(['Relative error of reconstruction (should be close to zero.):'...
+    '   %e \n'],rec_err);
+
diff --git a/inst/demos/demo_ofdm.m b/inst/demos/demo_ofdm.m
new file mode 100644
index 0000000..534800d
--- /dev/null
+++ b/inst/demos/demo_ofdm.m
@@ -0,0 +1,156 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_ofdm
+%@verbatim
+%DEMO_OFDM  Demo of Gabor systems used for OFDM
+%
+%   This demo shows how to use a Gabor Riesz basis for OFDM.
+%
+%   We want to transmit a signal consisting of 0's and 1's through a
+%   noisy communication channel. This is accomplished in the following
+%   steps in the demo:
+%
+%     1) Convert this digital signal into complex valued coefficients by
+%        QAM modulation.
+%
+%     2) Construct the signal to be transmitted by an inverse Gabor
+%        transform of the complex coefficients
+%
+%     3) "Transmit" the signal by applying a spreading operator to the
+%        signal and adding white noise
+%
+%     4) Convert the received signal into noisy coefficients by a Gabor
+%        transform
+%
+%     5) Convert the noisy coefficients into bits by inverse QAM.
+%
+%   Some simplifications used to make this demo simple:
+%
+%      We assume that the whole spectrum is available for transmission.
+%
+%      The window and its dual have full length support. This is not
+%       practical, because all data would have to be processed at once.
+%       Instead, an FIR should be used, with both the window and its dual
+%       having a short length.
+%
+%      The window is periodic. The data at the very end interferes with
+%       the data at the very beginning. A simple way to solve this is to
+%       transmit zeros at the beginning and at the end, to flush the system
+%       properly.
+%
+%   Figure 1: Received coefficients.
+%
+%      This figure shows the distribution in the complex plane of the 
+%      received coefficients. If the channel was perfect, all the points
+%      should appear at the complex roots of unity (1,i,-1 and -i). This
+%      demo is random, so everytime it is run it produces a new plot, and
+%      the error rate may vary.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_ofdm.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_ofdm" to see a description of how this demo works.');
+%% ----------- setup of signal and transmission system --------------------
+
+% Number of channels to use
+M=20;
+
+% Time-distance between succesive transmission. This must be
+% larger than M, otherwise the symbols will interfere.
+a=24;
+
+% Number of bits to transmit, must be divisable by 2*M
+nbits=16000;
+
+% Length (in samples) of transmitted signal.
+L=nbits/(2*M)*a;
+
+% We choose an orthonormal window.
+g=gabtight(a,M,L);
+
+%% ----------- Setup of communication channel ---------------------------
+
+% Larger means more random
+howrandom=.3;  
+
+% Rate of decay away from (1,1). Larger means smaller spread (faster decay).
+spreaddecay=1.2; 
+
+% Noiselevel for the channel.
+noiselevel=0.05;
+
+% Define the symbol of the spreading operator
+symbol=sparse(L,L);
+for ii=1:3
+  for jj=1:3
+    symbol(ii,jj)=(1-abs(randn(1)*howrandom))*exp(-(ii+jj-1)*spreaddecay);
+  end;
+end;
+
+% Make the symbol conserve real signals.
+symbol=(symbol+involute(symbol))/2;
+
+% Make sure that energy is conserved
+symbol=symbol/sum(abs(symbol(:)));
+
+%% ------------ Convert input data into analog signal -------------------
+
+% Create a random stream of bits.
+inputdata=round(rand(nbits,1));
+
+% QAM modulate it
+transmitdata=qam4(inputdata);
+
+% Create the signal to be tranmitted
+f=idgt(reshape(transmitdata,M,[]),g,a);
+
+% --- transmission of signal - influence of the channel ----------
+
+% Apply the underspread operator.
+f=spreadop(f,symbol);
+
+% add white noise.
+noise = ((randn(size(f))-.5)+i*(randn(size(f))-.5));
+f=f+noise*noiselevel/norm(noise)*norm(f);
+
+% --- reconstruction of received signal ------------------------
+
+% Obtain the noisy coefficients from the transmitted signal
+receivedcoefficients = dgt(f,g,a,M);
+
+% Convert the analog signal to the digital coefficients by inverse QAM
+receivedbits=iqam4(receivedcoefficients(:));
+
+%% --- visualization and print output -------------------------
+
+% Plot the coefficients in the complex plane.
+figure(1);
+plot(receivedcoefficients(:),'.');
+axis([-1 1 -1 1]);
+
+% Test for errors.
+
+disp(' ');
+disp('Number of faulty bits:');
+faulty=sum(abs(receivedbits-inputdata))
+
+disp(' ');
+disp('Error rate:');
+faulty/nbits
+
diff --git a/inst/demos/demo_pbspline.m b/inst/demos/demo_pbspline.m
new file mode 100644
index 0000000..c2cb1da
--- /dev/null
+++ b/inst/demos/demo_pbspline.m
@@ -0,0 +1,145 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_pbspline
+%@verbatim
+%DEMO_PBSPLINE  How to use PBSPLINE
+%
+%   This script illustrates various properties of the
+%   PBSPLINE function.
+%
+%   Figure 1: Three first splines
+%
+%      This figure shows the three first splines (order 0,1 and 2)
+%      and their dual windows.
+%
+%      Note that they are calculated for an even number of the parameter a,
+%      meaning that they are not exactly splines, but a slightly smoother
+%      construction, that still form a partition of unity.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_pbspline.php}
+%@seealso{pbspline, middlepad}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_pbspline" to see a description of how this demo works.');
+
+% Setup parameters and length of signal.
+% Note that it must hold that L=M*b=N*a for some integers
+% b and N, and that a <= M
+
+L=72;  % Length of signal.
+a=6;   % Time shift.
+M=9;   % Number of modulations.
+
+% Calculate the frequency shift.
+b=L/M;
+
+% The following call creates a B-spline of order 2.
+% The translates of a multiple of 'a' of this function
+% creates a partition of unity.
+% 'ntaps' contains the number of non-zero elements of g
+[g,ntaps]=pbspline(L,2,a);
+
+disp('');
+disp('Length of the generated window:');
+ntaps
+
+% This DFT of g is real and whole point even
+disp('');
+disp('Norm of imaginary part. Should be close to zero.');
+norm(imag(dft(g)))
+
+disp('');
+disp('Window is whole point even. Should be 1.');
+isevenfunction(g)
+
+% We can cut g to length ntap without loosing any information:
+% Cut g
+gcut=middlepad(g,ntaps);
+
+disp('');
+disp('Length of g after cutting.');
+length(gcut)
+
+% extend gcut again
+gextend=middlepad(gcut,L);
+
+% gextend is identical to g
+disp('');
+disp('difference between original g, and gextend.');
+disp('Should be close to zero.');
+norm(g-gextend)
+
+
+% Plot the three first splines and their canonical dual windows:
+
+% Calculate the splines.
+g1=pbspline(L,0,a);
+g2=pbspline(L,1,a);
+g3=pbspline(L,2,a);
+
+% Calculate their dual windows.
+g1d=gabdual(g1,a,M);
+g2d=gabdual(g2,a,M);
+g3d=gabdual(g3,a,M);
+
+% Standard note on plotting:
+%
+% - All windows have real DFTs, but Matlab does not
+%   always recoqnize this, so we have to filter away
+%   the small imaginary part by calling REAL(...)
+%
+% - The windows are all centered around zero, but this
+%   is not visually pleasing, so the window must be
+%   shifted to the middle by an FFTSHIFT
+%
+
+figure(1);
+
+xplot=(0:L-1).';
+
+subplot(3,2,1);
+plot(xplot,fftshift(g1),...
+     xplot,circshift(fftshift(g1),a),...
+     xplot,circshift(fftshift(g1),-a));
+title('Zero order spline.');
+
+subplot(3,2,2);
+plot(xplot,fftshift(g1d));
+title('Dual window.');
+
+subplot(3,2,3);
+plot(xplot,fftshift(g2),...
+     xplot,circshift(fftshift(g2),a),...
+     xplot,circshift(fftshift(g2),-a));
+title('First order spline.');
+
+subplot(3,2,4);
+plot(xplot,fftshift(g2d));
+title('Dual window.');
+
+subplot(3,2,5);
+plot(xplot,fftshift(g3),...
+     xplot,circshift(fftshift(g3),a),...
+     xplot,circshift(fftshift(g3),-a));
+title('Second order spline.');
+
+subplot(3,2,6);
+plot(xplot,fftshift(g3d));
+title('Dual window.');
+
diff --git a/inst/demos/demo_pgauss.m b/inst/demos/demo_pgauss.m
new file mode 100644
index 0000000..3b0c8df
--- /dev/null
+++ b/inst/demos/demo_pgauss.m
@@ -0,0 +1,125 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_pgauss
+%@verbatim
+%DEMO_PGAUSS  How to use PGAUSS
+%
+%   This script illustrates various properties of the Gaussian function.
+%
+%   Figure 1: Window+Dual+Tight
+%
+%      This figure shows an optimally centered Gaussian for a 
+%      given Gabor system, its canonical dual and tight windows
+%      and the DFTs of these windows.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_pgauss.php}
+%@seealso{pgauss}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_pgauss" to see a description of how this demo works.');
+
+% A quick test: If the second input parameter to
+% pgauss is not specified, the output will be
+% invariant under an unitary DFT. Matlabs FFT is does not
+% preserve the norm, so it must be scaled a bit.
+
+L=128;
+g=pgauss(L);
+
+disp('');
+disp('Test of DFT invariance: Should be close to zero.');
+norm(g-dft(g))
+
+% Setup parameters and length of signal.
+% Note that it must hold that L=M*b=N*a for some integers
+% b and N, and that a <= M
+L=72;  % Length of signal.
+a=6;   % Time shift.
+M=9;   % Number of modulations.
+
+% Calculate the frequency shift.
+b=L/M;
+
+% For this Gabor system, the optimally concentrated Gaussian
+% is given by
+g=pgauss(L,a/b);
+
+% This is not invarient with respect to a DFT, but it is still
+% real and whole point even
+disp('');
+disp('The function is WP even. The following should be 1.');
+isevenfunction(g)
+
+disp('Therefore, its DFT is real.');
+disp('The norm of the imaginary part should be close to zero.');
+norm(imag(dft(g)))
+
+% Calculate the canonical dual.
+gdual=gabdual(g,a,M);
+
+% Calculate the canonical tight window.
+gtight=gabtight(g,a,M);
+
+% Plot them:
+
+% Standard note on plotting:
+%
+% - All windows have real DFTs, but Matlab does not
+%   always recoqnize this, so we have to filter away
+%   the small imaginary part by calling REAL(...)
+%
+% - The windows are all centered around zero, but this
+%   is not visually pleasing, so the window must be
+%   shifted to the middle by an FFTSHIFT
+%
+
+gf_plot      = fftshift(real(dft(g)));
+gdual_plot   = fftshift(gdual);
+gdualf_plot  = fftshift(real(dft(gdual)));
+gtight_plot  = fftshift(gtight);
+gtightf_plot = fftshift(real(dft(gtight)));
+figure(1);
+
+subplot(3,2,1);
+x=(1:L).';
+plot(x,fftshift(g),'-',...
+     x,circshift(fftshift(g),a),'-',...
+     x,circshift(fftshift(g),-a),'-');
+title('g=pgauss(72,6/8)');
+
+subplot(3,2,2);
+plot(gf_plot);
+title('g, frequency domain');
+
+subplot(3,2,3);
+plot(gdual_plot);
+title('Dual window of g');
+
+subplot(3,2,4);
+plot(gdualf_plot);
+title('dual window, frequency domain');
+
+subplot(3,2,5);
+plot(gtight_plot);
+title('Tight window generated from g');
+
+subplot(3,2,6);
+plot(gtightf_plot);
+title('tight window, frequency domain');
+
diff --git a/inst/demos/demo_phaseplot.m b/inst/demos/demo_phaseplot.m
new file mode 100644
index 0000000..1f08180
--- /dev/null
+++ b/inst/demos/demo_phaseplot.m
@@ -0,0 +1,134 @@
+%-*- texinfo -*-
+%@deftypefn {Function} demo_phaseplot
+%@verbatim
+%DEMO_PHASEPLOT  Give demos of nice phaseplots
+%
+%   This script creates a synthetic signal and then uses PHASEPLOT on it,
+%   using several of the possible options.
+% 
+%   For real-life signal only small parts should be analyzed. In the chosen
+%   demo the fundamental frequency of the speaker can be nicely seen.
+%
+%   Figure 1: Synthetic signal
+%
+%      Compare this to the pictures in reference 2 and 3. In 
+%      the first two figures a synthetic signal is analyzed. It consists of a 
+%      sinusoid, a small Delta peak, a periodic triangular function and a 
+%      Gaussian. In the time-invariant version in the first part the periodicity 
+%      of the sinusoid can be nicely seen also in the phase coefficients. Also
+%      the points of discontinuities can be seen as asymptotic lines approached
+%      by parabolic shapes. In the third part both properties, periodicity and 
+%      discontinuities can be nicely seen. A comparison to the spectogram shows 
+%      that the rectangular part in the middle of the signal can be seen by the
+%      phase plot, but not by the spectogram.
+% 
+%      In the frequency-invariant version, the fundamental frequency of the
+%      sinusoid can still be guessed as the position of an horizontal
+%      asymptotic line.
+%
+%   Figure 2: Synthetic signal, thresholded.
+%
+%      This figure shows the same as Figure 1, except that values with low
+%      magnitude has been removed.
+%
+%   Figure 3: Speech signal.
+%
+%      The figure shows a part of the 'linus' signal. The fundamental
+%      frequency of the speaker can be nicely seen.
+%
+%   References:
+%     R. Carmona, W. Hwang, and B. Torresani. Multiridge detection and
+%     time-frequency reconstruction. IEEE Trans. Signal Process., 47:480-492,
+%     1999.
+%     
+%     R. Carmona, W. Hwang, and B. Torresani. Practical Time-Frequency
+%     Analysis: continuous wavelet and Gabor transforms, with an
+%     implementation in S, volume 9 of Wavelet Analysis and its Applications.
+%     Academic Press, San Diego, 1998.
+%     
+%     A. Grossmann, M. Holschneider, R. Kronland-Martinet, and J. Morlet.
+%     Detection of abrupt changes in sound signals with the help of wavelet
+%     transforms. Inverse Problem, pages 281-306, 1987.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demo_phaseplot.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+disp('Type "help demo_phaseplot" to see a description of how this demo works.');
+
+tt=0:98;
+f1=sin(2*pi*tt/33); % sinusoid
+
+f2=zeros(1,100);
+f2(50)=1; % delta-like
+
+f3=fftshift(firwin('tria',32)).';
+
+f4 = fftshift(pgauss(100)).';
+f4 = f4/max(f4);
+
+sig = 0.9*[f1 0 f2 f3 -f3 f3 f4 0 0 0 0];
+
+figure(1);
+sgram(sig,'lin','nf');
+
+figure(2);
+subplot(3,1,1);
+plot(sig);
+title('Synthetic signal');
+
+subplot(3,1,2);
+phaseplot(sig,'freqinv'); 
+title('Phaseplot of synthetic signal - frequency-invariant phase');
+
+subplot(3,1,3);
+phaseplot(sig,'timeinv')
+title('Phaseplot of synthetic signal - time-invariant phase');
+
+figure(3);
+subplot(3,1,1);
+plot(sig);
+title('Synthetic signal');
+
+subplot(3,1,2);
+phaseplot(sig,'freqinv','thr',0.001)
+title('Phaseplot of synthetic signal - thresholded version, freq. inv. phase');
+
+subplot(3,1,3);
+phaseplot(sig,'thr',0.001)
+title('Phaseplot of synthetic signal - thresholded version, time inv. phase');
+
+figure(4);
+f=linus;
+f = f(4500:8000);
+
+subplot(3,1,1);
+plot(f);
+axis tight;
+title('Speech signal: linus');
+
+subplot(3,1,2);
+phaseplot(f)
+title('Phaseplot of linus');
+
+subplot(3,1,3);
+phaseplot(f,'thr',.001)
+title('Phaseplot of linus - thresholded version');
+
+
diff --git a/inst/demos/demosinit.m b/inst/demos/demosinit.m
new file mode 100644
index 0000000..b4e655d
--- /dev/null
+++ b/inst/demos/demosinit.m
@@ -0,0 +1,27 @@
+status=1;
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} demosinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/demos/demosinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/deprecated/Contents.m b/inst/deprecated/Contents.m
new file mode 100644
index 0000000..f1859f2
--- /dev/null
+++ b/inst/deprecated/Contents.m
@@ -0,0 +1,41 @@
+% LTFAT - Deprecated functions
+%
+%  Peter L. Soendergaard, 2012 - 2014.
+%
+%  The functions in the directory has been deprecated, and their use is
+%  no longer recommended. The help of each function provides a
+%  description on how to replace the function.
+%  
+%  Deprecated functions
+%    GABELITISTLASSO   - Use FRANAGROUPLASSO  
+%    GABGROUPLASSO     - Use FRANAGROUPLASSO
+%    GABLASSO          - Use FRANALASSO
+%    GABMULEIGS        - Use FRAMEMULEIGS
+%    GABMUL            - Use FRAMEMUL
+%    FRAMEMATRIX       - Use FRSYNMATRIX
+%    IUFILTERBANK      - Use IFILTERBANK
+%    IUNSDGT           - Use INSDGT
+%    IUNSDGTREAL       - Use INSDGTREAL
+%    TFMAT             - Use FRSYNMATRIX or OPERATORMATRIX
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/deprecated/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/deprecated/deprecatedinit.m b/inst/deprecated/deprecatedinit.m
new file mode 100644
index 0000000..2f0d332
--- /dev/null
+++ b/inst/deprecated/deprecatedinit.m
@@ -0,0 +1,26 @@
+status=1;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} deprecatedinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/deprecatedinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/deprecated/framematrix.m b/inst/deprecated/framematrix.m
new file mode 100644
index 0000000..0d5d909
--- /dev/null
+++ b/inst/deprecated/framematrix.m
@@ -0,0 +1,96 @@
+function G=framematrix(F,L);
+%-*- texinfo -*-
+%@deftypefn {Function} framematrix
+%@verbatim
+%FRAMEMATRIX  Frame synthesis operator matrix
+%   Usage: G=framematrix(F,L);
+%
+%   G=frsynmatrix(F,L) returns the matrix representation G of the frame
+%   synthesis operator for a frame F of length L. The frame object F*
+%   must have been created using FRAME.
+%
+%   The frame synthesis operator matrix contains all the frame atoms as
+%   column vectors. It has dimensions L xNcoef, where Ncoef is the
+%   number of coefficients. The number of coefficients can be found as
+%   Ncoef=framered(F)*L. This means that the frame matrix is usually
+%   *very* large, and this routine should only be used for small values of
+%   L.
+%
+%   The action of the frame analysis operator FRANA is equal to
+%   multiplication with the Hermitean transpose of the frame
+%   matrix. Consider the following simple example:
+%
+%     L=200;
+%     F=frame('dgt','gauss',10,20);
+%     G=frsynmatrix(F,L);
+%     testsig = randn(L,1);
+%     res = frana(F,testsig)-G'*testsig;
+%     norm(res)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/framematrix.php}
+%@seealso{frame, frana, frsyn}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+warning(['LTFAT: FRAMEMATRIX has been deprecated and will be removed',...
+         ' in the future releases, please use FRSYNMATRIX instead.']);   
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+Lcheck=framelength(F,L);
+if Lcheck~=L
+    error('%s: Incompatible frame length.',upper(mfilename));
+end;
+
+if F.realinput
+    
+    %switch(F.type)
+    %  case 'dgtreal'
+        
+    %  This code correctly reproduces the matrix represenation of the
+    %  analysis operator, but not of the synthesis.
+    %
+    %    F2=frame('dgt',F.g,F.a,F.M);
+    %    G2=frsynmatrix(F2,L);
+    %    M2=floor(F.M/2)+1;
+    %    N=L/F.a;
+    %    G=zeros(L,M2*N);
+    %    for n=0:N-1
+    %        G(:,1+n*M2:(n+1)*M2)=G2(:,1+n*F.M:M2+n*F.M);
+    %    end;
+        
+    %  otherwise
+        error(['%s: The synthesis operator of real-valued-input frames does is ' ...
+               'non-linear and does not have a matrix represenation.']);
+        %end;
+else
+    
+  % Generic code handles all frames where there are no extra coefficients
+  % in the representation
+  Ncoef = framered(F)*L;
+  % sprintf for Octave compatibility
+  assert(abs(Ncoef-round(Ncoef))<1e-3,sprintf('%s: There is a bug. Ncoef=%d should be an integer.',upper(mfilename),Ncoef));
+  Ncoef=round(Ncoef);
+  coef=eye(Ncoef);
+  G = frsyn(F,coef);  
+end;
+
+
diff --git a/inst/deprecated/gabelitistlasso.m b/inst/deprecated/gabelitistlasso.m
new file mode 100644
index 0000000..26883a1
--- /dev/null
+++ b/inst/deprecated/gabelitistlasso.m
@@ -0,0 +1,168 @@
+function [tc,relres,iter,xrec] = gabelitistlasso(x,g,a,M,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabelitistlasso
+%@verbatim
+%GABELITISTLASSO  Elitist LASSO regression in Gabor domain
+%   Usage: [tc,xrec] = gabelitistlasso(x,g,a,M,lambda,C,tol,maxit)
+%   Input parameters:
+%       x        : Input signal
+%       g        : Synthesis window function
+%       a        : Length of time shift
+%       M        : Number of channels
+%       lambda   : Regularization parameter, controls sparsity of the
+%                  solution
+%   Output parameters:
+%      tc        : Thresholded coefficients
+%      relres    : Vector of residuals.
+%      iter      : Number of iterations done.
+%      xrec      : Reconstructed signal
+%
+%   GABELITISTLASSO(x,g,a,M,lambda) solves the elitist LASSO regression
+%   problem in the Gabor domain: minimize a functional of the synthesis
+%   coefficients defined as the sum of half the l^2 norm of the
+%   approximation error and the mixed l^2 / l^1 norm of the coefficient
+%   sequence, with a penalization coefficient lambda.
+%  
+%   The matrix of Gabor coefficients is labelled in terms of groups and
+%   members.  The obtained expansion is sparse in terms of groups, no
+%   sparsity being imposed to the members of a given group. This is achieved
+%   by a regularization term composed of l^2 norm within a group, and l^1 norm
+%   with respect to groups.
+%
+%   [tc,relres,iter] = GABELITISTLASSO(...) returns the residuals relres*
+%   in a vector and the number of iteration steps done, maxit.
+%
+%   [tc,relres,iter,xrec] = GABELITISTLASSO(...) returns the reconstructed
+%   signal from the coefficients, xrec. Note that this requires additional
+%   computations.
+%
+%   The function takes the following optional parameters at the end of
+%   the line of input arguments:
+%
+%     'freq'     Group in frequency (search for tonal components). This is the
+%                default.
+%
+%     'time'     Group in time (search for transient components). 
+%
+%     'C',cval   Landweber iteration parameter: must be larger than
+%                square of upper frame bound. Default value is the upper
+%                frame bound.
+%
+%     'tol',tol  Stopping criterion: minimum relative difference between
+%                norms in two consecutive iterations. Default value is
+%                1e-2.
+%
+%     'maxit',maxit
+%                Stopping criterion: maximal number of iterations to do. Default value is 100.
+%
+%     'print'    Display the progress.
+%
+%     'quiet'    Don't print anything, this is the default.
+%
+%     'printstep',p
+%                If 'print' is specified, then print every p'th
+%                iteration. Default value is 10;
+%
+%   The parameters C, itermax and tol may also be specified on the
+%   command line in that order: gabgrouplasso(x,g,a,M,lambda,C,tol,maxit).
+%
+%   The solution is obtained via an iterative procedure, called Landweber
+%   iteration, involving iterative group thresholdings.
+%
+%   The relationship between the output coefficients is given by :
+%
+%     xrec = idgt(tc,g,a);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/gabelitistlasso.php}
+%@seealso{gablasso, gabframebounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<5
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isvector(x)
+    error('Input signal must be a vector.');
+end
+
+% Define initial value for flags and key/value pairs.
+definput.flags.group={'freq','time'};
+
+definput.keyvals.C=[];
+definput.keyvals.itermax=100;
+definput.keyvals.tol=1e-2;
+definput.keyvals.printstep=10;
+definput.flags.print={'print','quiet'};
+
+[flags,kv]=ltfatarghelper({'C','tol','maxit'},definput,varargin);
+
+% Determine transform length, and calculate the window.
+[x,g,L] = gabpars_from_windowsignal(x,g,a,M,[],'GABELITISTLASSO');
+
+if isempty(kv.C)
+  [A_dummy,kv.C] = gabframebounds(g,a,M,L);
+end;
+
+
+tchoice = flags.do_time;
+N = floor(length(x)/a);
+
+% Normalization to turn lambda to a value comparable to lasso
+if tchoice
+    lambda = lambda * sqrt(N);
+else
+    lambda = lambda * sqrt(M);
+end
+
+% Various parameter initializations
+threshold = lambda/kv.C;
+
+% Initialization of thresholded coefficients
+c0 = dgt(x,g,a,M);
+tc0 = c0;
+relres = 1e16;
+iter = 0;
+
+% Main loop
+while ((iter < kv.itermax)&&(relres >= kv.tol))
+    tc = c0 - dgt(idgt(tc0,g,a),g,a,M);
+    tc = tc0 + tc/kv.C;
+    if tchoice
+        tc = tc';
+    end;
+    tc = elitistthresh(tc,threshold,'soft');
+    if tchoice
+        tc = tc';
+    end;
+    relres = norm(tc(:)-tc0(:))/norm(tc0(:));
+    tc0 = tc;
+    iter = iter + 1;
+    if flags.do_print
+      if mod(iter,kv.printstep)==0
+        fprintf('Iteration %d: relative error = %f\n',iter,relres);
+      end;
+    end;
+end
+
+% Reconstruction
+if nargout>3
+  xrec = idgt(tc,g,a);
+end;
+
diff --git a/inst/deprecated/gabgrouplasso.m b/inst/deprecated/gabgrouplasso.m
new file mode 100644
index 0000000..a80ce9e
--- /dev/null
+++ b/inst/deprecated/gabgrouplasso.m
@@ -0,0 +1,44 @@
+function [tc,relres,iter,xrec] = gabgrouplasso(x,g,a,M,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabgrouplasso
+%@verbatim
+%GABGROUPLASSO  Group LASSO regression in Gabor domain
+%   Usage: [tc,xrec] = gabgrouplasso(x,g,a,M,group,lambda,C,maxit,tol)
+%
+%   GABGROUPLASSO has been deprecated. Please use FRANAGROUPLASSO instead.
+%
+%   A call to GABGROUPLASSO(x,g,a,M,lambda) can be replaced by :
+%
+%     F=frame('dgt',g,a,M);
+%     tc=franagrouplasso(F,lambda);
+%
+%   Any additional parameters passed to GABGROUPLASSO can be passed to
+%   FRANAGROUPLASSO in the same manner.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/gabgrouplasso.php}
+%@seealso{frame, franagrouplasso}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+warning(['LTFAT: GABGROUPLASSO has been deprecated, please use FRAMEGROUPLASSO ' ...
+         'instead. See the help on GABGROUPLASSO for more details.']);   
+
+F=newframe('dgt',[],g,a,M);
+[tc,relres,iter,xrec] = framegrouplasso(F,lambda,varargin{:});
+
diff --git a/inst/deprecated/gablasso.m b/inst/deprecated/gablasso.m
new file mode 100644
index 0000000..4419ac9
--- /dev/null
+++ b/inst/deprecated/gablasso.m
@@ -0,0 +1,44 @@
+function [tc,relres,iter,xrec] = gablasso(x,g,a,M,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gablasso
+%@verbatim
+%GABLASSO  LASSO regression in Gabor domain
+%   Usage: [tc,xrec] = gablasso(x,a,M,lambda,C,tol,maxit)
+%
+%   GABLASSO has been deprecated. Please use FRANALASSO instead.
+%
+%   A call to GABLASSO(x,g,a,M,lambda) can be replaced by :
+%
+%     F=frame('dgt',[],g,a,M);
+%     tc=franalasso(F,lambda);
+%
+%   Any additional parameters passed to GABLASSO can be passed to
+%   FRANALASSO in the same manner.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/gablasso.php}
+%@seealso{frame, franalasso}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+warning(['LTFAT: GABLASSO has been deprecated, please use FRANALASSO ' ...
+         'instead. See the help on GABLASSO for more details.']);   
+
+F=newframe('dgt',[],g,a,M);
+[tc,relres,iter,xrec] = franalasso(F,lambda,varargin{:});
+
diff --git a/inst/deprecated/gabmul.m b/inst/deprecated/gabmul.m
new file mode 100644
index 0000000..db1d753
--- /dev/null
+++ b/inst/deprecated/gabmul.m
@@ -0,0 +1,120 @@
+function h=gabmul(f,c,p3,p4,p5)
+%-*- texinfo -*-
+%@deftypefn {Function} gabmul
+%@verbatim
+%GABMUL  Apply Gabor multiplier
+%   Usage:  h=gabmul(f,c,a);
+%           h=gabmul(f,c,g,a);
+%           h=gabmul(f,c,ga,gs,a);
+%
+%   Input parameters:
+%         f     : Input signal
+%         c     : symbol of Gabor multiplier
+%         g     : analysis/synthesis window
+%         ga    : analysis window
+%         gs    : synthesis window
+%         a     : Length of time shift.
+%   Output parameters:
+%         h     : Output signal
+%
+%   GABMUL has been deprecated. Please use construct a frame multiplier
+%   and use FRAMEMUL instead.
+%
+%   A call to GABMUL(f,c,ga,gs,a) can be replaced by :
+%
+%     [Fa,Fs]=framepair('dgt',ga,gs,a,M);
+%     fout=framemul(f,Fa,Fs,s);
+%
+%   Original help:
+%   --------------
+%
+%   GABMUL(f,c,g,a) filters f by a Gabor multiplier determined by
+%   the symbol c over the rectangular time-frequency lattice determined by
+%   a and M, where M is deduced from the size of c. The rows of c*
+%   correspond to frequency, the columns to temporal sampling points.  The
+%   window g will be used for both analysis and synthesis.
+%
+%   GABMUL(f,c,a) does the same using an optimally concentrated, tight
+%   Gaussian as window function.
+%
+%   GABMUL(f,c,ga,gs,a) does the same using the window ga for analysis
+%   and gs for synthesis.
+%
+%   The adjoint operator of GABMUL(f,c,ga,gs,a) is given by
+%   GABMUL(f,conj(c),gs,ga,a).
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/gabmul.php}
+%@seealso{dgt, idgt, gabdual, gabtight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+warning(['LTFAT: GABMUL has been deprecated, please use FRAMEMUL ' ...
+         'instead. See the help on GABMUL for more details.']);   
+
+error(nargchk(3,5,nargin));
+
+M=size(c,1);
+N=size(c,2);
+
+if nargin==3
+  a=p3;
+  L=a*N;
+  ga=gabtight(a,M,L);
+  gs=ga;
+end;
+
+if nargin==4;
+  ga=p3;
+  gs=p3;
+  a=p4;
+ end;
+
+if nargin==5;  
+  ga=p3;
+  gs=p4;
+  a=p5;
+end;
+
+if numel(c)==1
+  error('Size of symbol is too small. You probably forgot to supply it.');
+end;
+
+
+assert_squarelat(a,M,'GABMUL',0);
+
+% Change f to correct shape.
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,'DGT',0);
+
+[coef,Ls]=dgt(f,ga,a,M);
+
+if(~strcmp(class(c),'double'))
+   coef = cast(coef,class(c));
+end
+
+for ii=1:W
+  coef(:,:,ii)=coef(:,:,ii).*c;
+end;
+
+
+h=idgt(coef,gs,a,Ls);
+
+% Change h to have same shape as f originally had.
+h=comp_sigreshape_post(h,Ls,wasrow,remembershape);
+
+
diff --git a/inst/deprecated/gabmuleigs.m b/inst/deprecated/gabmuleigs.m
new file mode 100644
index 0000000..fe135b6
--- /dev/null
+++ b/inst/deprecated/gabmuleigs.m
@@ -0,0 +1,219 @@
+function [V,D]=gabmuleigs(K,c,p3,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabmuleigs
+%@verbatim
+%GABMULEIGS  Eigenpairs of Gabor multiplier
+%   Usage:  h=gabmuleigs(K,c,g,a);
+%           h=gabmuleigs(K,c,a);
+%           h=gabmuleigs(K,c,ga,gs,a);
+%
+%   Input parameters:
+%         K     : Number of eigenvectors to compute.
+%         c     : symbol of Gabor multiplier
+%         g     : analysis/synthesis window
+%         ga    : analysis window
+%         gs    : synthesis window
+%         a     : Length of time shift.
+%   Output parameters:
+%         V     : Matrix containing eigenvectors.
+%         D     : Eigenvalues.
+%
+%   GABMULEIGS has been deprecated. Please use construct a frame multiplier
+%   and use FRAMEMULEIGS instead.
+%
+%   A call to GABMULEIGS(K,c,ga,gs,a) can be replaced by :
+%
+%     [Fa,Fs]=framepair('dgt',ga,gs,a,M);
+%     [V,D]=framemuleigs(Fa,Fs,s,K);
+%
+%   Original help:
+%   --------------
+%
+%   GABMULEIGS(K,c,g,a) computes the K largest eigenvalues and eigen-
+%   vectors of the Gabor multiplier with symbol c and time shift a.  The
+%   number of channels is deduced from the size of the symbol c.  The
+%   window g will be used for both analysis and synthesis.
+%
+%   GABMULEIGS(K,c,ga,gs,a) does the same using the window the window ga*
+%   for analysis and gs for synthesis.
+%
+%   GABMULEIGS(K,c,a) does the same using the a tight Gaussian window of
+%   for analysis and synthesis.
+%
+%   If K is empty, then all eigenvalues/pairs will be returned.
+%
+%   GABMULEIGS takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'iter'       Call eigs to use an iterative algorithm.
+%
+%     'full'       Call eig to sole the full problem.
+%
+%     'auto'       Use the full method for small problems and the
+%                  iterative method for larger problems. This is the
+%                  default. 
+%
+%     'crossover',c
+%                  Set the problem size for which the 'auto' method
+%                  switches. Default is 200.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/gabmuleigs.php}
+%@seealso{gabmul, dgt, idgt, gabdual, gabtight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Change this to 1 or 2 to see the iterative method in action.
+printopts=0;
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if nargout==2
+  doV=1;
+else
+  doV=0;
+end;
+
+M=size(c,1);
+N=size(c,2);
+
+istight=1;
+if numel(p3)==1
+  % Usage: h=gabmuleigs(c,K,a);  
+  a=p3;
+  L=N*a;
+  ga=gabtight(a,M,L);
+  gs=ga;
+  arglist=varargin;
+else 
+  if numel(varargin{1})==1
+    % Usage: h=gabmuleigs(c,K,g,a);  
+    ga=p3;
+    gs=p3;
+    a=varargin{1};
+    L=N*a;
+    arglist=varargin(2:end);
+  else 
+    if numel(varargin{2})==1
+      % Usage: h=gabmuleigs(c,K,ga,gs,a);  
+      ga=p3;
+      gs=varargin{1};
+      a =varargin{2};
+      L=N*a;
+      istight=0;
+      arglist=varargin(3:end);
+    end;    
+  end;
+end;
+
+definput.keyvals.maxit=100;
+definput.keyvals.tol=1e-9;
+definput.keyvals.crossover=200;
+definput.flags.print={'quiet','print'};
+definput.flags.method={'auto','iter','full'};
+
+
+[flags,kv]=ltfatarghelper({},definput,arglist);
+
+
+% Do the computation. For small problems a direct calculation is just as
+% fast.
+
+if (flags.do_iter) || (flags.do_auto && L>kv.crossover)
+  
+  if flags.do_print
+    opts.disp=1;
+  else
+    opts.disp=0;
+  end;
+  opts.isreal = false;
+  opts.maxit  = kv.maxit;
+  opts.tol    = kv.tol;
+  
+  % Setup afun
+  afun(1,c,ga,gs,a,M,L);
+  
+  if doV
+    [V,D] = eigs(@afun,L,K,'LM',opts);
+  else
+    D     = eigs(@afun,L,K,'LM',opts);
+  end;
+
+else
+  % Compute the transform matrix.
+  bigM=tfmat('gabmul',c,ga,gs,a);
+
+  if doV
+    [V,D]=eig(bigM);
+  else
+    D=eig(bigM);
+  end;
+
+
+end;
+
+% The output from eig and eigs is a diagonal matrix, so we must extract the
+% diagonal.
+D=diag(D);
+
+% Sort them in descending order
+[~,idx]=sort(abs(D),1,'descend');
+D=D(idx(1:K));
+
+if doV
+  V=V(:,idx(1:K));
+end;
+
+% Clean the eigenvalues, if we know that they are real-valued
+%if isreal(ga) && isreal(gs) && isreal(c)
+%  D=real(D);
+%end;
+
+% The function has been written in this way, because Octave (at the time
+% of writing) does not accept additional parameters at the end of the
+% line of input arguments for eigs
+function y=afun(x,c_in,ga_in,gs_in,a_in,M_in,L_in)
+  persistent c;
+  persistent ga;
+  persistent gs;
+  persistent a;
+  persistent M;
+  persistent L; 
+  
+  if nargin>1
+    c  = c_in; 
+    ga = ga_in;
+    gs = gs_in;
+    a  = a_in; 
+    M  = M_in; 
+    L  = L_in;
+  else
+    y=comp_idgt(c.*comp_dgt(x,ga,a,M,[0 1],0,0,0),gs,a,[0 1],0,0);
+  end;
+
diff --git a/inst/deprecated/iufilterbank.m b/inst/deprecated/iufilterbank.m
new file mode 100644
index 0000000..94020a3
--- /dev/null
+++ b/inst/deprecated/iufilterbank.m
@@ -0,0 +1,38 @@
+function f=iufilterbank(varargin);  
+%-*- texinfo -*-
+%@deftypefn {Function} iufilterbank
+%@verbatim
+%IUFILTERBANK  Filter bank inversion, DEPRECATED
+%   Usage:  f=iufilterbank(c,g,a);
+%
+%   IUFILTERBANK has been deprecated by IFILTERBANK. Call IFILTERBANK
+%   with the exact same parameters as the old call to IUFILTERBANK.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/iufilterbank.php}
+%@seealso{ifilterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+warning(['LTFAT: IUFILTERBANK has been deprecated, used IFILTERBANK ' ...
+         'instead.']);
+  
+
+f=ifilterbank(varargin{:});
+
+
diff --git a/inst/deprecated/iunsdgt.m b/inst/deprecated/iunsdgt.m
new file mode 100644
index 0000000..81941e4
--- /dev/null
+++ b/inst/deprecated/iunsdgt.m
@@ -0,0 +1,64 @@
+function f=iunsdgt(c,g,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iunsdgt
+%@verbatim
+%IUNSDGT  Inverse uniform nonstationary discrete Gabor transform
+%   Usage:  f=iunsdgt(c,g,a,Ls);
+%
+%   Input parameters:
+%         c     : Cell array of coefficients.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         Ls    : Length of input signal.
+%   Output parameters:
+%         f     : Signal.
+%
+%   IUNSDGT(c,g,a,Ls) computes the nonstationary Gabor expansion of the 
+%   input coefficients c.
+%
+%   IUNSDGT is used to invert the function NSDGT. Read the help of NSDGT
+%   for details of variables format and usage.
+%
+%   For perfect reconstruction, the windows used must be dual windows of 
+%   the ones used to generate the coefficients. The windows can be
+%   generated unsing NSGABDUAL.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/iunsdgt.php}
+%@seealso{unsdgt, nsgabdual, nsgabtight, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGT
+%   REFERENCE: 
+%   Last changed 2009-05
+
+warning(['LTFAT: IUNSDGT has been deprecated, use INSDGT instead.']);  
+
+f=insdgt(varargin{:});
+
+  
+
diff --git a/inst/deprecated/iunsdgtreal.m b/inst/deprecated/iunsdgtreal.m
new file mode 100644
index 0000000..a4f2067
--- /dev/null
+++ b/inst/deprecated/iunsdgtreal.m
@@ -0,0 +1,63 @@
+function f=iunsdgtreal(c,g,a,M,Ls)
+%-*- texinfo -*-
+%@deftypefn {Function} iunsdgtreal
+%@verbatim
+%IUNSDGTREAL  Inverse uniform nonstationary discrete Gabor transform
+%   Usage:  f=iunsdgtreal(c,g,a,M,Ls);
+%
+%   Input parameters:
+%         c     : Cell array of coefficients.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         M     : Numbers of frequency channels.
+%         Ls    : Length of input signal.
+%   Output parameters:
+%         f     : Signal.
+%
+%   IUNSDGTREAL(c,g,a,M,Ls) computes the inverse uniform nonstationary Gabor
+%   expansion of the input coefficients c.
+%
+%   IUNSDGTREAL is used to invert the function UNSDGTREAL. Read the help of
+%   UNSDGTREAL for details of variables format and usage.
+%
+%   For perfect reconstruction, the windows used must be dual windows of 
+%   the ones used to generate the coefficients. The windows can be
+%   generated unsing NSGABDUAL.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/iunsdgtreal.php}
+%@seealso{unsdgt, nsgabdual, nsgabtight, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet and Peter L. Soendergaard
+%   TESTING: TEST_NSDGT
+%   REFERENCE: OK
+
+
+warning(['LTFAT: IUNSDGTREAL has been deprecated, use INSDGTREAL instead.']);
+  
+f=insdgtreal(varargin{:});
+
diff --git a/inst/deprecated/tfmat.m b/inst/deprecated/tfmat.m
new file mode 100644
index 0000000..214147b
--- /dev/null
+++ b/inst/deprecated/tfmat.m
@@ -0,0 +1,235 @@
+function F=tfmat(ttype,p2,p3,p4,p5)
+%-*- texinfo -*-
+%@deftypefn {Function} tfmat
+%@verbatim
+%TFMAT Matrix of transform / operator
+%   Usage:  F=tfmat('fourier',L);
+%           F=tfmat('dcti',L);
+%           F=tfmat('dgt',g,a,M);
+%           F=tfmat('dwilt',g,M);
+%           F=tfmat('wmdct',g,M);
+%           F=tfmat('zak',L,a);
+%           F=tfmat('gabmul',sym,a);
+%           F=tfmat('spread',c);
+%
+%   TFMAT has been deprecated. Please construct a frame (using FRAME)
+%   and use FRSYNMATRIX, or construct an operator (using OPERATORNEW)
+%   and use OPERATORMATRIX instead.
+%
+%   Original help
+%   -------------
+%
+%   TFMAT returns a matrix F containing the basis functions / atoms of
+%   one of the transforms in the toolbox. The atoms are placed as column
+%   vectors in the matrix. A forward transform (analysis) can be done by:
+%
+%     c=F'*f;
+%
+%   and a backwards or adjoint transform (synthesis) can be done by:
+%
+%     r=F*c;
+%
+%   The possibilities are:
+%
+%   TFMAT('fourier',L) returns the matrix of the unitary Fourier
+%   transform of length L. See DFT.
+%
+%   TFMAT('dcti',L) returns the matrix of the DCTI transform of length
+%   L. Similarly for 'dctii', 'dctiii', 'dctiv', 'dsti', 'dstii',
+%   'dstiii' or 'dstiv'.
+%
+%   TFMAT('dgt',g,a,M) returns a matrix containing all the atoms of the
+%   Gabor frame with window g and lattice constants a and M. 
+%   TFMAT('dgt',g,a,M,L) will do the same for a FIR window g.
+%
+%   TFMAT('dwilt',g,M) returns a matrix containing all the atoms of the
+%   Wilson  basis with window g and M channels. TFMAT(g,M,L) will do the
+%   same for a FIR window g.
+%
+%   TFMAT('wmdct',g,M) and TFMAT('wmdct',g,M,L) does the same for an WMDCT
+%   with M channels.
+%
+%   TFMAT('gabmul',sym,a) return the matrix of the Gabor multiplier with
+%   symbol sym and time shift a. TFMAT('gabmul',c,g,a) does the same
+%   using the window g for both analysis and synthesis.
+%   TFMAT('gabmul',sym,ga,gs,a) does the same using ga as analysis window
+%   and gs as synthesis window.
+%
+%   TFMAT('spread',c) returns the matrix of the spreading operator with
+%   symbol c.
+%
+%   TFMAT('zak',L,a) returns the transform matrix for a Zak transform of
+%   length L and parameter a.
+% 
+%   This function should mainly be used for educational purposes or for 
+%   experimenting with systems, as the generated matrix can
+%   become very large.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/deprecated/tfmat.php}
+%@seealso{frsynmatrix, operatormatrix}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+warning(['LTFAT: TFMAT has been deprecated, please use FRSYNMATRIX ' ...
+         'or OPERATORMATRIX instead.']);   
+
+if (nargin<1) || ~ischar(ttype)
+  error('You must specify the transform type')
+end;
+
+switch(lower(ttype))
+  case {'fourier','dft'}
+    error(nargchk(2,2,nargin));
+    F=idft(eye(p2));
+
+  case {'dcti'}
+    error(nargchk(2,2,nargin));
+    F=dcti(eye(p2))';
+
+  case {'dctii'}
+    error(nargchk(2,2,nargin));
+    F=dctii(eye(p2))';
+
+  case {'dctiii'}
+    error(nargchk(2,2,nargin));
+    F=dctiii(eye(p2))';
+
+  case {'dctiv'}
+    error(nargchk(2,2,nargin));
+    F=dctiv(eye(p2))';
+
+  case {'dsti'}
+    error(nargchk(2,2,nargin));
+    F=dsti(eye(p2))';
+
+  case {'dstii'}
+    error(nargchk(2,2,nargin));
+    F=dstii(eye(p2))';
+
+  case {'dstiii'}
+    error(nargchk(2,2,nargin));
+    F=dstiii(eye(p2))';
+
+  case {'dstiv'}
+    error(nargchk(2,2,nargin));
+    F=dstiv(eye(p2))';
+
+  case {'gabor','dgt'}
+    error(nargchk(4,5,nargin));
+    g=p2;    
+    if nargin==4
+      L=length(g);
+    else
+      L=p5;
+    end;
+    a=p3;
+    M=p4;
+    N=L/a;
+    c=reshape(eye(M*N),M,N,M*N);
+    F=idgt(c,g,a);
+
+  case {'wilson','dwilt'}
+    error(nargchk(3,4,nargin));
+    g=p2;    
+    if nargin==3
+      L=length(g);
+    else
+      L=p4;
+    end;
+    M=p3;
+    N=L/M;
+    c=reshape(eye(M*N),2*M,N/2,M*N);
+    F=idwilt(c,g);
+
+  case {'wmdct'}
+    error(nargchk(3,4,nargin));
+    g=p2;    
+    if nargin==3
+      L=length(g);
+    else
+      L=p4;
+    end;
+    M=p3;
+    N=L/M;
+    c=reshape(eye(M*N),M,N,M*N);
+    F=iwmdct(c,g);
+
+  case {'spread','spreadop'}
+    error(nargchk(2,2,nargin));
+    c=p2;
+    L=size(c,2);
+    F=spreadop(eye(L),c);
+
+  case {'gabmul'}
+    error(nargchk(3,5,nargin)); 
+    sym=p2;
+    M=size(sym,1);
+    N=size(sym,2);
+    switch(nargin)
+      case 3
+       a=p3;
+       L=a*N;
+       F=gabmul(eye(L),sym,a);
+     case 4
+       g=p3;
+       a=p4;       
+       L=a*N;
+       F=gabmul(eye(L),sym,g,a);
+     case 5
+       ga=p3;
+       gs=p4;
+       a=p5;       
+       L=a*N;
+       F=gabmul(eye(L),sym,ga,gs,a);
+    end;
+
+  case {'ndgt'}
+    error(nargchk(5,5,nargin));
+    g=p2;
+    a=p3;
+    M=p4;
+    L=p5;
+        
+    %!!! the computation using eye matrix doesn't work if M>sigLen
+    
+    N=length(a); % number of time positions
+    MN=sum(M); % total number of frame elements
+    
+    F=zeros(L,MN);
+    jj=0;
+    for ii=1:N
+      c={eye(M(ii))};
+      F(:,jj+(1:M(ii)))=indgt(c,g(ii),a(ii),L);
+      jj=jj+M(ii);
+    end
+    
+
+  case {'zak'}
+    error(nargchk(3,5,nargin))
+    L=p2;
+    a=p3;
+    N=L/a;
+    c=reshape(eye(L),a,N,L);
+    F=izak(c);
+
+  otherwise
+    error('Unknown transform.');
+end;
+
+
diff --git a/inst/filterbank/Contents.m b/inst/filterbank/Contents.m
new file mode 100644
index 0000000..3d2288d
--- /dev/null
+++ b/inst/filterbank/Contents.m
@@ -0,0 +1,57 @@
+% LTFAT - Filterbanks
+%
+%  Peter L. Soendergaard, 2011 - 2014
+%
+%  Transforms and basic routines
+%    FILTERBANK             - Filter bank
+%    UFILTERBANK            - Uniform Filter bank
+%    IFILTERBANK            - Inverse normal/uniform filter bank
+%    FILTERBANKWIN          - Evaluate filterbank window
+%    FILTERBANKLENGTH       - Length of filterbank to expand signal
+%    FILTERBANKLENGTHCOEF   - Length of filterbank to expand coefficients
+%
+%  Auditory inspired filterbanks
+%    CQT                    - Constant Q transform
+%    ICQT                   - Inverse constant Q transform
+%    ERBLETT                - Erb-let transform
+%    IERBLETT               - Inverse Erb-let transform
+%    INSDGFB                - Say what?
+%
+%  Filter generators
+%    CQTFILTERS             - Logaritmically spaced filters
+%    ERBFILTERS             - ERB-spaced filters
+%  
+%  Window construction and bounds
+%    FILTERBANKDUAL         - Canonical dual filters
+%    FILTERBANKTIGHT        - Canonical tight filters
+%    FILTERBANKREALDUAL     - Canonical dual filters for real signals
+%    FILTERBANKREALTIGHT    - Canonical tight filters for real signals
+%    FILTERBANKBOUNDS       - Frame bounds of filter bank
+%    FILTERBANKREALBOUNDS   - Frame bounds of filter bank for real signals
+%    FILTERBANKRESPONSE     - Total frequency response
+%
+%  Plots
+%    PLOTFILTERBANK         - Plot normal/uniform filter bank coefficients
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/filterbank/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
diff --git a/inst/filterbank/cqt.m b/inst/filterbank/cqt.m
new file mode 100644
index 0000000..0e15395
--- /dev/null
+++ b/inst/filterbank/cqt.m
@@ -0,0 +1,327 @@
+function [c,Ls,g,shift,M] = cqt(f,fmin,fmax,bins,fs,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} cqt
+%@verbatim
+%CQT  Constant-Q nonstationary Gabor filterbank
+%   Usage: [c,Ls,g,shift,M] = cqt(f,fmin,fmax,bins,fs,M)
+%          [c,Ls,g,shift,M] = cqt(f,fmin,fmax,bins,fs)
+%          [c,Ls,g,shift] = cqt(...)
+%          [c,Ls] = cqt(...)
+%          c = cqt(...)
+%
+%   Input parameters: 
+%         f         : The signal to be analyzed (For multichannel
+%                     signals, input should be a matrix which each
+%                     column storing a channel of the signal).
+%         fmin      : Minimum frequency (in Hz)
+%         fmax      : Maximum frequency (in Hz)
+%         bins      : Vector consisting of the number of bins per octave
+%         fs        : Sampling rate (in Hz)
+%         M         : Number of time channels (optional)
+%                     If M is constant, the output is converted to a
+%                     matrix
+%   Output parameters:
+%         c         : Transform coefficients (matrix or cell array)
+%         Ls        : Original signal length (in samples)
+%         g         : Cell array of Fourier transforms of the analysis 
+%                     windows
+%         shift     : Vector of frequency shifts
+%         M         : Number of time channels
+%
+%   This function computes a constant-Q transform via nonstationary Gabor
+%   filterbanks. Given the signal f, the constant-Q parameters fmin,
+%   fmax and bins, as well as the sampling rate fs of f, the
+%   corresponding constant-Q coefficients c are given as output. For
+%   reconstruction, the length of f and the filterbank parameters can
+%   be returned also.
+% 
+%   The transform produces phase-locked coefficients in the
+%   sense that each filter is considered to be centered at
+%   0 and the signal itself is modulated accordingly.
+%
+%   Optional input arguments arguments can be supplied like this:
+%       
+%       cqt(f,fmin,fmax,bins,fs,'min_win',min_win)
+%
+%   The arguments must be character strings followed by an
+%   argument:
+%
+%     'min_win',min_win        Minimum admissible window length 
+%                              (in samples) 
+%
+%     'Qvar',Qvar              Bandwidth variation factor
+%
+%     'M_fac',M_fac            Number of time channels are rounded to 
+%                              multiples of this
+%
+%     'winfun',winfun          Filter prototype (see FIRWIN for available 
+%                              filters)
+%     'fractional'             Allow fractional shifts and bandwidths
+%
+%
+%   Example:
+%   --------
+%
+%   The following example shows analysis and synthesis with CQT and ICQT:
+%
+%     [f,fs] = gspi;
+%     fmin = 200;
+%     fmax = fs/2;
+%     [c,Ls,g,shift,M] = cqt(f,fmin,fmax,48,fs);
+%     fr = icqt(c,g,shift,Ls);
+%     rel_err = norm(f-fr)/norm(f);
+%     plotfilterbank(c,Ls./M,[],fs,'dynrange',60);
+%
+% 
+%   References:
+%     N. Holighaus, M. Doerfler, G. A. Velasco, and T. Grill. A framework for
+%     invertible, real-time constant-Q transforms. IEEE Transactions on
+%     Audio, Speech and Language Processing, 21(4):775 -785, 2013.
+%     
+%     G. A. Velasco, N. Holighaus, M. Doerfler, and T. Grill. Constructing an
+%     invertible constant-Q transform with non-stationary Gabor frames.
+%     Proceedings of DAFX11, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/cqt.php}
+%@seealso{icqt, firwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Authors: Nicki Holighaus, Gino Velasco
+% Date: 10.04.13
+
+%% Check input arguments
+if nargin < 5
+    error('Not enough input arguments');
+end
+
+[f,Ls,W]=comp_sigreshape_pre(f,upper(mfilename),0);
+
+% Set defaults
+
+definput.keyvals.usrM = [];
+definput.keyvals.Qvar = 1;
+definput.keyvals.M_fac = 1;
+definput.keyvals.min_win = 4;
+definput.keyvals.winfun = 'hann';
+definput.flags.fractype = {'nofractional','fractional'};
+
+% Check input arguments
+
+[flags,keyvals,usrM]=ltfatarghelper({'usrM'},definput,varargin);
+
+%% Create the CQ-NSGT dictionary
+
+% Nyquist frequency
+nf = fs/2;
+
+% Limit fmax
+if fmax > nf
+    fmax = nf;
+end
+
+% Number of octaves
+b = ceil(log2(fmax/fmin))+1;
+
+if length(bins) == 1;
+    % Constant number of bins in each octave
+    bins = bins*ones(b,1);
+elseif length(bins) < b
+    % Pick bins for octaves for which it was not specified.
+    bins = bins(:);
+    bins( bins<=0 ) = 1;
+    bins = [bins ; bins(end)*ones(b-length(bins),1)];
+end
+
+% Prepare frequency centers in Hz
+fbas = zeros(sum(bins),1);
+
+ll = 0;
+for kk = 1:length(bins);
+    fbas(ll+(1:bins(kk))) = ...
+        fmin*2.^(((kk-1)*bins(kk):(kk*bins(kk)-1)).'/bins(kk));
+    ll = ll+bins(kk);
+end
+
+% Get rid of filters with frequency centers >=fmax and nf
+temp = find(fbas>=fmax,1);
+if fbas(temp) >= nf
+    fbas = fbas(1:temp-1);
+else
+    fbas = fbas(1:temp);
+end
+
+Lfbas = length(fbas);
+
+% Add filter at zero and nf frequencies
+fbas = [0;fbas;nf];
+
+% Mirror other filters
+% Length of fbas is now 2*(Lfbas+1)
+fbas(Lfbas+3:2*(Lfbas+1)) = fs-fbas(Lfbas+1:-1:2);
+
+% Convert frequency to samples
+fbas = fbas*(Ls/fs);
+
+% Set bandwidths
+bw = zeros(2*Lfbas+2,1);
+
+% Bandwidth of the low-pass filter around 0
+bw(1) = 2*fmin*(Ls/fs);
+bw(2) = (fbas(2))*(2^(1/bins(1))-2^(-1/bins(1)));
+
+for k = [3:Lfbas , Lfbas+2]
+    bw(k) = (fbas(k+1)-fbas(k-1));
+end
+
+% Bandwidth of last filter before the one at the nf
+bw(Lfbas+1) = (fbas(Lfbas+1))*(2^(1/bins(end))-2^(-1/bins(end)));
+
+% Mirror bandwidths
+bw(Lfbas+3:2*Lfbas+2) = bw(Lfbas+1:-1:2);
+
+% Make frequency centers integers
+posit = zeros(size(fbas));
+posit(1:Lfbas+2) = floor(fbas(1:Lfbas+2));
+posit(Lfbas+3:end) = ceil(fbas(Lfbas+3:end));
+
+% Keeping center frequency and changing bandwidth => Q=fbas/bw
+bw = keyvals.Qvar*bw;
+
+% M - number of coefficients in output bands (number of time channels).
+if flags.do_fractional
+    % Be pedantic about center frequencies by
+    % sub-sample precision positioning of the frequency window.
+    warning(['Fractional sampling might lead to a warning when ', ...
+        'computing the dual system']);
+    fprintf('');
+    corr_shift = fbas-posit;
+    M = ceil(bw+1);
+else
+    % Using the integer frequency window position.
+    bw = round(bw);
+    M = bw;
+end
+
+% Do not allow lower bandwidth than keyvals.min_win
+for ii = 1:numel(bw)
+    if bw(ii) < keyvals.min_win;
+        bw(ii) = keyvals.min_win;
+        M(ii) = bw(ii);
+    end
+end
+
+if flags.do_fractional
+    % Generate windows, while providing the x values.
+    % x - shift correction
+    % y - window length
+    % z - 'safe' window length
+    g = arrayfun(@(x,y,z) ...
+        firwin(keyvals.winfun,([0:ceil(z/2),-floor(z/2):-1]'-x)/y)/sqrt(y),corr_shift,...
+        bw,M,'UniformOutput',0);
+else
+    % Generate window, normalize to
+    g = arrayfun(@(x) firwin(keyvals.winfun,x)/sqrt(x),...
+        bw,'UniformOutput',0);
+end
+
+% keyvals.M_fac is granularity of output bands lengths
+% Round M to next integer multiple of keyvals.M_fac
+M = keyvals.M_fac*ceil(M/keyvals.M_fac);
+
+% Middle-pad windows at 0 and Nyquist frequencies
+% with constant region (tapering window) if the bandwidth is larger than
+% of the next in line window.
+for kk = [1,Lfbas+2]
+    if M(kk) > M(kk+1);
+        g{kk} = ones(M(kk),1);
+        g{kk}((floor(M(kk)/2)-floor(M(kk+1)/2)+1):(floor(M(kk)/2)+...
+            ceil(M(kk+1)/2))) = firwin('hann',M(kk+1));
+        g{kk} = g{kk}/sqrt(M(kk));
+    end
+end
+
+% The number of frequency channels
+N = length(posit);  
+
+% Handle the user defined output bands lengths.
+if ~isempty(usrM)
+    if numel(usrM) == 1
+        M = usrM*ones(N,1);
+    elseif numel(usrM)==N
+        M = usrM;
+    else
+        error(['%s: Number of enties of parameter M does not comply ',...
+               'with the number of frequency channels.'],upper(mfilename));
+    end    
+end
+
+%% The CQ-NSG transform
+
+% some preparation
+f = fft(f);
+
+c=cell(N,1); % Initialisation of the result
+
+% Obtain input type
+ftype = assert_classname(f);
+% The actual transform
+
+for ii = 1:N
+    Lg = length(g{ii});
+    
+    idx = [ceil(Lg/2)+1:Lg,1:ceil(Lg/2)];
+    win_range = mod(posit(ii)+(-floor(Lg/2):ceil(Lg/2)-1),Ls)+1;
+    
+    if M(ii) < Lg % if the number of frequency channels is too small,
+        % aliasing is introduced
+        col = ceil(Lg/M(ii));
+        temp = zeros(col*M(ii),W,ftype);
+        
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = ...
+            bsxfun(@times,f(win_range,:),g{ii}(idx));
+        temp = reshape(temp,M(ii),col,W);
+        
+        c{ii} = squeeze(ifft(sum(temp,2)));
+        
+        % Using c = cellfun(@(x) squeeze(ifft(x)),c,'UniformOutput',0);
+        % outside the loop instead does not provide speedup; instead it is
+        % slower in most cases.
+    else
+        temp = zeros(M(ii),W,ftype);
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = ...
+            bsxfun(@times,f(win_range,:),g{ii}(idx));
+        
+        c{ii} = ifft(temp);
+    end
+end
+
+% Reshape to a matrix if coefficient bands have uniform lengths.
+% This is maybe too confuzing.
+if max(M) == min(M)
+    c = cell2mat(c);
+    c = reshape(c,M(1),N,W);
+end
+
+% Return relative shifts between filters in frequency in samples
+% This does not correctly handle the fractional frequency positioning.
+if nargout > 3
+    shift = [mod(-posit(end),Ls); diff(posit)];
+end
+
diff --git a/inst/filterbank/cqtfilters.m b/inst/filterbank/cqtfilters.m
new file mode 100644
index 0000000..bcd0428
--- /dev/null
+++ b/inst/filterbank/cqtfilters.m
@@ -0,0 +1,333 @@
+function [g,a,fc,L]=cqtfilters(fs,fmin,fmax,bins,Ls,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} cqtfilters
+%@verbatim
+%CQTFILTERS   CQT-spaced filters
+%   Usage:  [g,a,fc]=cqtfilters(fs);
+%           [g,a,fc]=cqtfilters(fs,...);
+%
+%   Input parameters:
+%      fs    : Sampling rate (in Hz).
+%      fmin  : Minimum frequency (in Hz)
+%      fmax  : Maximum frequency (in Hz)
+%      bins  : Vector consisting of the number of bins per octave.
+%      Ls    : Signal length.
+%   Output parameters:
+%      g     : Cell array of filters.
+%      a     : Downsampling rate for each channel.
+%      fc    : Center frequency of each channel.
+%      L     : Next admissible length suitable for the generated filters.
+%
+%   [g,a,fc]=CQTFILTERS(fs,fmin,fmax,bins,Ls) constructs a set of 
+%   band-limited filters g which cover the required frequency range 
+%   fmin-fmax with bins filters per octave starting at fmin. All
+%   filters have (approximately) equal Q=f_c/f_b, hence constant-Q. The
+%   remainding frequency intervals not covered by these filters are captured
+%   by two additional filters (low-pass, high-pass). The signal length Ls*
+%   is mandatory, since we need to avoid too narrow frequency windows.
+%
+%   By default, a Hann window on the frequency side is choosen, but the
+%   window can be changed by passing any of the window types from
+%   FIRWIN as an optional parameter.
+%
+%   Because the downsampling rates of the channels must all divide the
+%   signal length, FILTERBANK will only work for multiples of the
+%   least common multiple of the downsampling rates. See the help of
+%   FILTERBANKLENGTH.
+%
+%   [g,a]=CQTFILTERS(...,'regsampling') constructs a non-uniform
+%   filterbank. The downsampling rates are constant in the octaves but
+%   can differ among octaves. This approach was chosen in order to minimize 
+%   the least common multiple of a, which determines a granularity of
+%   admissible input signal lengths.
+%
+%   [g,a]=CQTFILTERS(...,'uniform') constructs a uniform filterbank
+%   where the downsampling rate is the same for all the channels. This 
+%   results in most redundant representation, which produces nice plots.
+%
+%   [g,a]=CQTFILTERS(...,'fractional') constructs a filterbank with
+%   fractional downsampling rates a. The rates are constructed such
+%   that the filterbank can handle signal lengths that are multiples of
+%   L, so the benefit of the fractional downsampling is that you get to
+%   choose the value returned by FILTERBANKLENGTH. This results in the
+%   least redundant system.
+%
+%   [g,a]=CQTFILTERS(...,'fractionaluniform') constructs a filterbank with
+%   fractional downsampling rates a, which are uniform for all filters 
+%   except the "filling" low-pass and high-pass filters can have different
+%   fractional downsampling rates. This is usefull when uniform subsampling
+%   and low redundancy at the same time are desirable.
+%
+%   The filters are intended to work with signals with a sampling rate of
+%   fs.  
+%
+%   CQTFILTERS accepts the following optional parameters:
+%
+%     'winfun',winfun       Filter prototype (see FIRWIN for available 
+%                           filters). Default is 'hann'.
+%
+%     'Qvar',Qvar           Bandwidth variation factor. Multiplies the
+%                           calculated bandwidth. Default value is 1. 
+%                           If the value is less than one, the
+%                           system may no longer be painless.
+%
+%     'subprec'             Allow subsample window positions and
+%                           bandwidths to better approximate the constant-Q
+%                           property.
+%
+%     'complex'             Construct a filterbank that covers the entire
+%                           frequency range. When missing, only positive
+%                           frequencies are covered.
+%
+%     'min_win',min_win     Minimum admissible window length (in samples).
+%                           Default is 4. This restrict the windows not 
+%                           to become too narrow when L is low. This
+%                           however brakes the constant-Q property for such
+%                           windows and creates rippling in the overall
+%                           frequency response.     
+%
+%     'redmul',redmul       Redundancy multiplier. Increasing the value of 
+%                           this will make the system more redundant by 
+%                           lowering the channel downsampling rates. Default
+%                           value is 1. If the value is less than one, 
+%                           the system may no longer be painless.
+%
+%
+%   References:
+%     N. Holighaus, M. Doerfler, G. A. Velasco, and T. Grill. A framework for
+%     invertible, real-time constant-Q transforms. IEEE Transactions on
+%     Audio, Speech and Language Processing, 21(4):775 -785, 2013.
+%     
+%     G. A. Velasco, N. Holighaus, M. Doerfler, and T. Grill. Constructing an
+%     invertible constant-Q transform with non-stationary Gabor frames.
+%     Proceedings of DAFX11, 2011.
+%     
+%     C. Schoerkhuber, A. Klapuri, N. Holighaus, and M. Doerfler. A Matlab
+%     Toolbox for Efficient Perfect Reconstruction Time-Frequency Transforms
+%     with Log-Frequency Resolution. In Audio Engineering Society Conference:
+%     53rd International Conference: Semantic Audio. Audio Engineering
+%     Society, 2014.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/cqtfilters.php}
+%@seealso{erbfilters, cqt, firwin, filterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Authors: Nicki Holighaus, Gino Velasco
+% Date: 10.04.13
+% Modified by: Zdenek Prusa
+% Date: 10.02.14
+
+%% Check input arguments
+if nargin < 5
+    error('%s: Not enough input arguments.',upper(mfilename));
+end
+
+complain_notposint(fs,'fs');
+complain_notposint(fmin,'fmin');
+complain_notposint(fmax,'fmax');
+complain_notposint(bins,'bins');
+complain_notposint(Ls,'Ls');
+
+if fmin>=fmax
+    error('%s: fmin has to be less than fmax.',upper(mfilename));
+end
+
+
+definput.import = {'firwin'};
+definput.keyvals.L=[];
+definput.keyvals.Qvar = 1;
+definput.keyvals.redmul=1;
+definput.keyvals.min_win = 4;
+definput.flags.real     = {'real','complex'};
+definput.flags.subprec  = {'nosubprec','subprec'};
+definput.flags.sampling = {'regsampling','uniform',...
+                           'fractional','fractionaluniform'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_subprec
+    error('%s: TO DO: Subsample window positioning is not implemented yet.',...
+          upper(mfilename));
+end
+% Nyquist frequency
+nf = fs/2;
+
+% Limit fmax
+if fmax > nf
+    fmax = nf;
+end
+
+% Number of octaves
+b = ceil(log2(fmax/fmin))+1;
+
+if length(bins) == 1;
+    % Constant number of bins in each octave
+    bins = bins*ones(b,1);
+elseif length(bins) < b
+    % Pick bins for octaves for which it was not specified.
+    bins = bins(:);
+    bins( bins<=0 ) = 1;
+    bins = [bins ; bins(end)*ones(b-length(bins),1)];
+end
+
+% Prepare frequency centers in Hz
+fc = zeros(sum(bins),1);
+
+ll = 0;
+for kk = 1:length(bins);
+    fc(ll+(1:bins(kk))) = ...
+        fmin*2.^(((kk-1)*bins(kk):(kk*bins(kk)-1)).'/bins(kk));
+    ll = ll+bins(kk);
+end
+
+% Get rid of filters with frequency centers >=fmax and nf
+temp = find(fc>=fmax,1);
+if fc(temp) >= nf
+    fc = fc(1:temp-1);
+else
+    fc = fc(1:temp);
+end
+
+M = length(fc);
+
+% Add filter at zero and nf frequencies
+fc = [0;fc;nf];
+M2 = M + 2;
+
+% Set bandwidths
+fsupp = zeros(M2,1);
+
+% Bandwidth of the low-pass filter around 0
+fsupp(1) = 2*fmin;
+fsupp(2) = (fc(2))*(2^(1/bins(1))-2^(-1/bins(1)));
+
+for k = [3:M , M+1]
+    fsupp(k) = (fc(k+1)-fc(k-1));
+end
+
+fsupp(M+1) = (fc(M+1))*(2^(1/bins(end))-2^(-1/bins(end)));
+fsupp(M+2) = 2*(nf-fc(end-1));
+
+% Keeping center frequency and changing bandwidth => Q=fbas/bw
+fsupp = kv.Qvar*fsupp;
+
+% Do not allow lower bandwidth than keyvals.min_win
+fsuppmin = kv.min_win/Ls*fs;
+for ii = 1:numel(fsupp)
+    if fsupp(ii) < fsuppmin;
+        fsupp(ii) = fsuppmin;
+    end
+end
+
+% Find suitable channel subsampling rates
+aprecise=fs./fsupp/kv.redmul; 
+aprecise=aprecise(:);
+if any(aprecise<1)
+    error('%s: The maximum redundancy mult. for this setting is %5.2f',...
+         upper(mfilename), min(fs./fsupp));
+end
+
+%% Compute the downsampling rate
+if flags.do_regsampling
+        % Find minimum a in each octave and floor23 it.
+        s = M-cumsum(bins);
+        bins=bins(1:find(s<=0,1));
+        bins(end) = bins(end)-(sum(bins)-M);
+        aocts = mat2cell(aprecise(2:end-1),bins); 
+        aocts{1} = [aprecise(1);aocts{1}];
+        aocts{end} = [aocts{end};aprecise(end)];
+        a=cellfun(@(aEl) floor23(min(aEl)),aocts);
+  
+        % Determine the minimal transform length lcm(a)
+        L = filterbanklength(Ls,a);
+        
+        % Heuristic trying to reduce lcm(a)
+        while L>2*Ls && ~(all(a)==a(1))
+            maxa = max(a);
+            a(a==maxa) = 0;
+            a(a==0) = max(a);
+            L = filterbanklength(Ls,a);
+        end
+        
+        % Deal the integer subsampling factors
+        a = cell2mat(cellfun(@(aoEl,aEl) ones(numel(aoEl),1)*aEl,...
+            aocts,mat2cell(a,ones(numel(a),1)),'UniformOutput',0));
+
+elseif flags.do_fractional
+        L = Ls;
+        N=ceil(Ls./aprecise);
+        a=[repmat(Ls,M2,1),N];  
+elseif flags.do_fractionaluniform
+    L = Ls;
+    aprecise(2:end-1) = min(aprecise(2:end-1));
+    N=ceil(Ls./aprecise);
+    a=[repmat(Ls,M2,1),N]; 
+elseif flags.do_uniform
+    a=floor(min(aprecise));  
+    L=filterbanklength(Ls,a);
+    a = repmat(a,M2,1);
+end;
+
+
+% Get an expanded "a"
+afull=comp_filterbank_a(a,M2,struct());
+
+%% Compute the scaling of the filters
+% Individual filter peaks are made square root of the subsampling factor
+scal=sqrt(afull(:,1)./afull(:,2));
+
+if flags.do_real
+    % Scale the first and last channels
+    scal(1)=scal(1)/sqrt(2);
+    scal(M2)=scal(M2)/sqrt(2);
+else
+    % Replicate the centre frequencies and sampling rates, except the first and
+    % last
+    if ~flags.do_uniform
+        a=[a;flipud(a(2:M2-1,:))];
+    end;
+    scal=[scal;flipud(scal(2:M2-1))];
+    fc  =[fc; -flipud(fc(2:M2-1))];
+    fsupp=[fsupp;flipud(fsupp(2:M2-1))];
+end;
+
+% This is actually much faster than the vectorized call. 
+g = cell(1,M2);
+for m=1:M2
+  g{m} = blfilter(flags.wintype,fsupp(m),fc(m),'fs',fs,'scal',scal(m),'inf');
+end
+
+
+% Middle-pad windows at 0 and Nyquist frequencies
+% with constant region (tapering window) if the bandwidth is larger than
+% of the next in line window.
+kkpairs = [1,2;M2,M2-1];
+for idx = 1:size(kkpairs,1)
+    Mk = fsupp(kkpairs(idx,1));
+    Mknext = fsupp(kkpairs(idx,2));
+    if Mk > Mknext
+         g{kkpairs(idx,1)} = blfilter({'hann','taper',Mknext/Mk},...
+                             Mk,fc(kkpairs(idx)),'fs',fs,'scal',...
+                             scal(kkpairs(idx)),'inf');
+    end
+end
+
+
+
diff --git a/inst/filterbank/erbfilters.m b/inst/filterbank/erbfilters.m
new file mode 100644
index 0000000..83bc64f
--- /dev/null
+++ b/inst/filterbank/erbfilters.m
@@ -0,0 +1,291 @@
+function [g,a,fc,L]=erbfilters(fs,Ls,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} erbfilters
+%@verbatim
+%ERBFILTERS   ERB-spaced filters
+%   Usage:  [g,a,fc]=erbfilters(fs,Ls);
+%           [g,a,fc]=erbfilters(fs,Ls,...);
+%
+%   Input parameters:
+%      fs    : Sampling rate (in Hz).
+%      Ls    : Signal length.
+%   Output parameters:
+%      g     : Cell array of filters.
+%      a     : Downsampling rate for each channel.
+%      fc    : Center frequency of each channel.
+%      L     : Next admissible length suitable for the generated filters.
+% 
+%   [g,a,fc]=ERBFILTERS(fs,Ls) constructs a set of filters g that are
+%   equidistantly spaced on the ERB-scale (see FREQTOERB) with bandwidths
+%   that are proportional to the width of the auditory filters
+%   AUDFILTBW. The filters are intended to work with signals with a
+%   sampling rate of fs. The signal length Ls is mandatory, since we 
+%   need to avoid too narrow frequency windows.
+%
+%   By default, a Hann window on the frequency side is choosen, but the
+%   window can be changed by passing any of the window types from
+%   FIRWIN as an optional parameter.
+%
+%   Because the downsampling rates of the channels must all divide the
+%   signal length, FILTERBANK will only work for multiples of the
+%   least common multiple of the downsampling rates. See the help of
+%   FILTERBANKLENGTH.
+%
+%   [g,a,fc]=ERBFILTERS(fs,L,'fractional') constructs a filterbank with
+%   fractional downsampling rates a. The rates are constructed such
+%   that the filterbank can handle signal length that are multiples of
+%   L, so the benefit of the fractional downsampling is that you get to
+%   choose the value returned by FILTERBANKLENGTH.
+%
+%   [g,a,fc]=ERBFILTERS(fs,'uniform') constructs a uniform filterbank
+%   where the downsampling rate is the same for all channels.
+%
+%   ERBFILTERS accepts the following optional parameters:
+%
+%     'spacing',b     Specify the spacing in ERBS between the
+%                     filters. Default value is b=1.
+%
+%     'M',M           Specify the number of filters, M. If this
+%                     parameter is specified, it overwrites the
+%                     'spacing' parameter.
+%
+%     'redmul',redmul  Redundancy multiplier. Increasing the value of this
+%                      will make the system more redundant by lowering the
+%                      channel downsampling rates. It is only used if the
+%                      filterbank is a non-uniform filterbank. Default
+%                      value is 1. If the value is less than one, the
+%                      system may no longer be painless.
+%
+%     'symmetric'     Create filters that are symmetric around their centre
+%                     frequency. This is the default.
+%
+%     'warped'        Create asymmetric filters that are symmetric on the
+%                     Erb-scale.
+%
+%     'complex'       Construct a filterbank that covers the entire
+%                     frequency range.
+%
+%     'regsampling'   Choose the downsampling rates to be products of 2
+%                     and 3 (see FLOOR23 and CEIL23). This is the
+%                     default.
+%
+%     'fractional'    Use fractional downsampling. If this flag is
+%                     specified, you must also specify the 'L' parameter.
+%
+%     'bwmul',bwmul   Bandwidth of the filters relative to the bandwidth
+%                     returned by AUDFILTBW. Default is bwmul=1.
+%
+%     'min_win',min_win     Minimum admissible window length (in samples).
+%                           Default is 4. This restrict the windows not 
+%                           to become too narrow when L is low. 
+%
+%   Examples:
+%   ---------
+%
+%   In the first example, we construct a highly redudant uniform
+%   filterbank and visualize the result:
+%
+%     [f,fs]=greasy;  % Get the test signal
+%     [g,a,fc]=erbfilters(fs,length(f),'uniform','M',100);
+%     c=filterbank(f,g,a);
+%     plotfilterbank(c,a,fc,fs,90,'audtick');
+%
+%   In the second example, we construct a non-uniform filterbank with
+%   fractional sampling that works for this particular signal length, and
+%   test the reconstruction. The plot displays the response of the
+%   filterbank to verify that the filters are well-behaved both on a
+%   normal and an ERB-scale:
+%
+%     [f,fs]=greasy;  % Get the test signal
+%     L=length(f);
+%     [g,a,fc]=erbfilters(fs,L,'fractional');
+%     c=filterbank(f,{'realdual',g},a);
+%     r=2*real(ifilterbank(c,g,a));
+%     norm(f-r)
+%
+%     % Plot the response
+%     subplot(2,1,1);     
+%     R=filterbankresponse(g,a,L,fs,'real','plot');
+%
+%     subplot(2,1,2);
+%     semiaudplot(linspace(0,fs/2,L/2+1),R(1:L/2+1));
+%     ylabel('Magnitude');
+%
+%
+%   References:
+%     T. Necciari, P. Balazs, N. Holighaus, and P. L. Soendergaard. The ERBlet
+%     transform: An auditory-based time-frequency representation with perfect
+%     reconstruction. In Proceedings of the 38th International Conference on
+%     Acoustics, Speech, and Signal Processing (ICASSP 2013), pages 498-502,
+%     Vancouver, Canada, May 2013. IEEE.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/erbfilters.php}
+%@seealso{filterbank, ufilterbank, ifilterbank, ceil23}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Authors: Peter L. Soendergaard
+
+if nargin<2
+    error('%s: Not enough input argumets.',upper(mfilename))
+end
+
+complain_notposint(fs,'fs');
+complain_notposint(Ls,'Ls');
+
+definput.import = {'firwin'};
+definput.keyvals.M=[];
+definput.keyvals.bwmul=1;
+definput.keyvals.redmul=1;
+definput.keyvals.min_win = 4;
+definput.keyvals.spacing=1;
+definput.flags.warp     = {'symmetric','warped'};
+definput.flags.real     = {'real','complex'};
+definput.flags.sampling = {'regsampling','uniform','fractional',...
+                           'fractionaluniform'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Get the bandwidth of the choosen window by doing a probe
+winbw=norm(firwin(flags.wintype,1000)).^2/1000;
+
+% Construct the Erb filterbank
+
+
+if flags.do_real
+    if isempty(kv.M)
+        M2=ceil(freqtoerb(fs/2)/kv.spacing)+1;
+        M=M2;
+    else
+        M=kv.M;
+        M2=M;
+    end;
+else
+    if isempty(kv.M)
+        M2=ceil(freqtoerb(fs/2)/kv.spacing)+1;
+        M=2*(M2-1);
+    else
+        M=kv.M;
+        if rem(M,2)>0
+            error(['%s: M must be even for full frequency range ' ...
+                   'filterbanks.',upper(mfilename)]);
+        end;
+        M2=M/2+1;
+    end;
+    
+end;
+
+fc=erbspace(0,fs/2,M2).';
+
+    
+%% Compute the frequency support
+if flags.do_symmetric
+    % fsupp is measured in Hz
+    fsupp=round(audfiltbw(fc)/winbw*kv.bwmul);
+else
+    % fsupp_erb is measured in Erbs
+    % The scaling is incorrect, it does not account for the warping
+    fsupp_erb=1/winbw*kv.bwmul;
+    
+    % Convert fsupp into the correct widths in Hz, necessary to compute
+    % "a" in the next if-statement
+    fsupp=erbtofreq(freqtoerb(fc)+fsupp_erb/2)-erbtofreq(freqtoerb(fc)-fsupp_erb/2);
+    
+end;
+
+% Do not allow lower bandwidth than keyvals.min_win
+fsuppmin = kv.min_win/Ls*fs;
+for ii = 1:numel(fsupp)
+    if fsupp(ii) < fsuppmin;
+        fsupp(ii) = fsuppmin;
+    end
+end
+
+% Find suitable channel subsampling rates
+aprecise=fs./fsupp/kv.redmul; 
+aprecise=aprecise(:);
+
+%% Compute the downsampling rate
+if flags.do_regsampling
+    % Shrink "a" to the next composite number       
+    a=floor23(aprecise); 
+        
+    % Determine the minimal transform length
+    L=filterbanklength(Ls,a);
+    
+    % Heuristic trying to reduce lcm(a)
+    while L>2*Ls && ~(all(a)==a(1))
+        maxa = max(a);
+        a(a==maxa) = 0;
+        a(a==0) = max(a);
+        L = filterbanklength(Ls,a);
+    end
+    
+elseif flags.do_fractional
+    L = Ls;
+    N=ceil(Ls./aprecise);
+    a=[repmat(Ls,M2,1),N];                
+elseif flags.do_fractionaluniform
+    L = Ls;
+    N=ceil(Ls./min(aprecise));
+    a= repmat([Ls,N],M2,1); 
+elseif flags.do_uniform
+    a=floor(min(aprecise));  
+    L=filterbanklength(Ls,a);
+    a = repmat(a,M2,1);
+end;
+
+% Get an expanded "a"
+afull=comp_filterbank_a(a,M2,struct());
+
+%% Compute the scaling of the filters
+scal=sqrt(afull(:,1)./afull(:,2));
+
+%% Construct the real or complex filterbank
+
+if flags.do_real
+    % Scale the first and last channels
+    scal(1)=scal(1)/sqrt(2);
+    scal(M2)=scal(M2)/sqrt(2);
+else
+    % Replicate the centre frequencies and sampling rates, except the first and
+    % last
+    if ~flags.do_uniform
+        a=[a;flipud(a(2:M2-1,:))];
+    end;
+    scal=[scal;flipud(scal(2:M2-1))];
+    fc  =[fc; -flipud(fc(2:M2-1))];
+    if flags.do_symmetric
+        fsupp=[fsupp;flipud(fsupp(2:M2-1))];
+    end;
+    
+end;
+
+
+%% Compute the filters
+if flags.do_symmetric
+    g=blfilter(flags.wintype,fsupp,fc,'fs',fs,'scal',scal,'inf','min_win',4);    
+else
+    g=warpedblfilter(flags.wintype,fsupp_erb,fc,fs, at freqtoerb, at erbtofreq, ...
+                     'scal',scal,'inf'); 
+end;
+
+end
+
+
diff --git a/inst/filterbank/erblett.m b/inst/filterbank/erblett.m
new file mode 100644
index 0000000..9f10627
--- /dev/null
+++ b/inst/filterbank/erblett.m
@@ -0,0 +1,211 @@
+function [c,Ls,g,shift,M] = erblett(f,bins,fs,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} erblett
+%@verbatim
+%ERBLETT  ERBlet nonstationary Gabor filterbank
+%   Usage: [c,Ls,g,shift,M] = erblett(f,bins,fs,varargin)
+%          [c,Ls,g,shift] = erblett(...)
+%          [c,Ls] = erblett(...)
+%          c = erblett(...)
+%
+%   Input parameters: 
+%         f         : The signal to be analyzed (For multichannel
+%                     signals, input should be a matrix which each
+%                     column storing a channel of the signal)
+%         bins      : Desired bins per ERB
+%         fs        : Sampling rate of f (in Hz)
+%         varargin  : Optional input pairs (see table below)
+%   Output parameters:
+%         c         : Transform coefficients (matrix or cell array)
+%         Ls        : Original signal length (in samples)
+%         g         : Cell array of Fourier transforms of the analysis 
+%                     windows
+%         shift     : Vector of frequency shifts
+%         M         : Number of time channels
+%
+%   This function computes an ERBlet constant-Q transform via nonstationary 
+%   Gabor filterbanks. Given the signal f, the ERBlet parameter bins, 
+%   as well as the sampling rate fs of f, the corresponding ERBlet
+%   coefficients c are given as output. For reconstruction, the length of
+%   f and the filterbank parameters can be returned also.
+% 
+%   The transform produces phase-locked coefficients in the
+%   sense that each filter is considered to be centered at
+%   0 and the signal itself is modulated accordingly.
+%
+%   Optional input arguments arguments can be supplied like this:
+%
+%       erblett(f,bins,fs,'Qvar',Qvar)
+%
+%   The arguments must be character strings followed by an
+%   argument:
+%
+%     'Qvar',Qvar              Bandwidth variation factor
+%
+%     'M_fac',M_fac            Number of time channels are rounded to 
+%                              multiples of this
+%
+%     'winfun',winfun          Filter prototype (see FIRWIN for available 
+%                              filters)
+%
+%   Examples:
+%   ---------
+%
+%   The following example shows analysis and synthesis with ERBLETT and
+%   IERBLETT:
+%
+%       [f,fs] = gspi;
+%       binsPerERB = 4;
+%       [c,Ls,g,shift,M] = erblett(f,binsPerERB,fs);
+%       fr = ierblett(c,g,shift,Ls);
+%       rel_err = norm(f-fr)/norm(f)
+%       plotfilterbank(c,Ls./M,[],fs,'dynrange',60);
+%
+% 
+%   References:
+%     T. Necciari, P. Balazs, N. Holighaus, and P. L. Soendergaard. The ERBlet
+%     transform: An auditory-based time-frequency representation with perfect
+%     reconstruction. In Proceedings of the 38th International Conference on
+%     Acoustics, Speech, and Signal Processing (ICASSP 2013), pages 498-502,
+%     Vancouver, Canada, May 2013. IEEE.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/erblett.php}
+%@seealso{ierblett, firwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Authors: Thibaud Necciari, Nicki Holighaus
+% Date: 10.04.13
+
+%% Check input arguments
+if nargin < 3
+    error('Not enough input arguments');
+end
+
+[f,Ls,W]=comp_sigreshape_pre(f,upper(mfilename),0);
+
+% Set defaults
+
+definput.keyvals.usrM = [];
+definput.keyvals.Qvar = 1;
+definput.keyvals.M_fac = 1;
+definput.keyvals.winfun = 'nuttall';
+
+% Check input arguments
+
+[flags,keyvals,usrM]=ltfatarghelper({'usrM'},definput,varargin);
+
+%% Create the ERBlet dictionary
+
+df = fs/Ls; % frequency resolution in the FFT
+
+fmin = 0;
+fmax = fs/2;
+
+% Convert fmin and fmax into ERB
+erblims = freqtoerb([fmin,fmax]);
+
+% Determine number of freq. channels
+Nf = bins*ceil(erblims(2)-erblims(1));
+
+% Determine center frequencies
+fc = erbspace(fmin,fmax,Nf)';
+
+% Concatenate "virtual" frequency positions of negative-frequency windows
+fc = [fc ; flipud(fc(1:end-1))];
+
+gamma = audfiltbw(fc); % ERB scale
+
+% Convert center frequencies in Hz into samples
+
+posit = round(fc/df);% Positions of center frequencies in samples
+posit(Nf+1:end) = Ls-posit(Nf+1:end);% Extension to negative freq.
+
+% Compute desired essential (Gaussian) support for each filter
+Lwin = 4*round(gamma/df);
+
+% Nuttall windows are slightly broader than Gaussians, this is offset by 
+% the factor 1.1
+
+M = round(keyvals.Qvar*Lwin/1.1);
+
+% Compute cell array of analysis filters
+g = arrayfun(@(x) firwin(keyvals.winfun,x)/sqrt(x),M,'UniformOutput',0);
+
+g{1}=1/sqrt(2)*g{1};
+g{end}=1/sqrt(2)*g{end};
+
+M = keyvals.M_fac*ceil(M/keyvals.M_fac);
+N = length(posit);  % The number of frequency channels
+
+if ~isempty(usrM)
+    if numel(usrM) == 1
+        M = usrM*ones(N,1);
+    else
+        M = usrM;
+    end    
+end
+
+%% The ERBlet transform
+
+% some preparation
+
+f = fft(f);
+
+c=cell(N,1); % Initialisation of the result
+
+% The actual transform
+
+for ii = 1:N
+    Lg = length(g{ii});
+    
+    idx = [ceil(Lg/2)+1:Lg,1:ceil(Lg/2)];
+    win_range = mod(posit(ii)+(-floor(Lg/2):ceil(Lg/2)-1),Ls)+1;
+    
+    if M(ii) < Lg % if the number of frequency channels is too small,
+        % aliasing is introduced
+        col = ceil(Lg/M(ii));
+        temp = zeros(col*M(ii),W,assert_classname(f));
+        
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = ...
+            bsxfun(@times,f(win_range,:),g{ii}(idx));
+        temp = reshape(temp,M(ii),col,W);
+        
+        c{ii} = squeeze(ifft(sum(temp,2)));
+        
+        % Using c = cellfun(@(x) squeeze(ifft(x)),c,'UniformOutput',0);
+        % outside the loop instead does not provide speedup; instead it is
+        % slower in most cases.
+    else
+        temp = zeros(M(ii),W,assert_classname(f));
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = ...
+            bsxfun(@times,f(win_range,:),g{ii}(idx));
+        
+        c{ii} = ifft(temp);
+    end
+end
+
+if max(M) == min(M)
+    c = cell2mat(c);
+    c = reshape(c,M(1),N,W);
+end
+
+if nargout > 3
+    shift = [Ls-posit(end); diff(posit)];% Frequency hop sizes in samples
+end
diff --git a/inst/filterbank/filterbank.m b/inst/filterbank/filterbank.m
new file mode 100644
index 0000000..3feee37
--- /dev/null
+++ b/inst/filterbank/filterbank.m
@@ -0,0 +1,97 @@
+function c=filterbank(f,g,a,varargin);  
+%-*- texinfo -*-
+%@deftypefn {Function} filterbank
+%@verbatim
+%FILTERBANK   Apply filterbank
+%   Usage:  c=filterbank(f,g,a);
+%
+%   FILTERBANK(f,g,a) applies the filters given in g to the signal
+%   f. Each subband will be subsampled by a factor of a (the
+%   hop-size). In contrast to UFILTERBANK, a can be a vector so the
+%   hop-size can be channel-dependant. If f is a matrix, the
+%   transformation is applied to each column.
+%
+%   The filters g must be a cell-array, where each entry in the cell
+%   array corresponds to an FIR filter.
+%
+%   The output coefficients are stored a cell array. More precisely, the
+%   n'th cell of c, c{m}, is a 2D matrix of size M(n) xW and
+%   containing the output from the m'th channel subsampled at a rate of
+%   a(m).  c{m}(n,l) is thus the value of the coefficient for time index
+%   n, frequency index m and signal channel l.
+%
+%   The coefficients c computed from the signal f and the filterbank
+%   with windows g_m are defined by
+%
+%                 L-1
+%      c_m(n+1) = sum f(l+1) * g_m (a(m)n-l+1)
+%                 l=0
+%
+%   where an-l is computed modulo L.
+%
+%
+%   References:
+%     H. Boelcskei, F. Hlawatsch, and H. G. Feichtinger. Frame-theoretic
+%     analysis of oversampled filter banks. Signal Processing, IEEE
+%     Transactions on, 46(12):3256-3268, 2002.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbank.php}
+%@seealso{ufilterbank, ifilterbank, pfilt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'pfilt'};
+definput.keyvals.L=[];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,'FILTERBANK',0);
+
+mustbeuniform=0;
+  
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(callfun));
+end;
+  
+if isempty(L)
+  L=filterbanklength(Ls,a);
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+
+ if size(a,1)>1 
+   if  size(a,1)~=info.M
+     error(['%s: The number of entries in "a" must match the number of ' ...
+            'filters.'],upper(callfun));
+   end;
+ else
+   info.a=a*ones(info.M,1);
+ end;
+
+f=postpad(f,L);
+
+g = comp_filterbank_pre(g,info.a,L,kv.crossover);
+
+c=comp_filterbank(f,g,info.a);
+
+
+
diff --git a/inst/filterbank/filterbankbounds.m b/inst/filterbank/filterbankbounds.m
new file mode 100644
index 0000000..b546a2f
--- /dev/null
+++ b/inst/filterbank/filterbankbounds.m
@@ -0,0 +1,111 @@
+function [AF,BF]=filterbankbounds(g,a,L);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankbounds
+%@verbatim
+%FILTERBANKBOUNDS  Frame bounds of filter bank
+%   Usage: fcond=filterbankbounds(g,a);
+%          [A,B]=filterbankbounds(g,a);
+%
+%   FILTERBANKBOUNDS(g,a,L) calculates the ratio B/A of the frame bounds
+%   of the filterbank specified by g and a for a system of length
+%   L. The ratio is a measure of the stability of the system.
+%
+%   [A,B]=FILTERBANKBOUNDS(g,a,L) returns the lower and upper frame bounds
+%   explicitly.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankbounds.php}
+%@seealso{filterbank, filterbankdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if L~=filterbanklength(L,a)
+    error(['%s: Specified length L is incompatible with the length of ' ...
+           'the time shifts.'],upper(mfilename));
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+AF=Inf;
+BF=0;
+
+if info.isuniform
+  % Uniform filterbank, use polyphase representation
+  a=a(1);  
+
+  N=L/a;
+
+  % G1 is done this way just so that we can determine the data type.
+  G1=comp_transferfunction(g{1},L);
+  thisclass=assert_classname(G1);
+  G=zeros(L,M,thisclass);
+  G(:,1)=G1;
+  for ii=2:M
+    G(:,ii)=comp_transferfunction(g{ii},L);
+  end;
+  
+  H=zeros(a,M,thisclass);
+    
+  for w=0:N-1
+    idx = mod(w-(0:a-1)*N,L)+1;
+    H = G(idx,:);
+    
+    % A 'real' is needed here, because the matrices are known to be
+    % Hermitian, but sometimes Matlab/Octave does not recognize this.
+    work=real(eig(H*H'));
+    AF=min(AF,min(work));
+    BF=max(BF,max(work));
+    
+  end;
+  
+  AF=AF/a;
+  BF=BF/a;
+
+else
+
+    if info.ispainless
+        % Compute the diagonal of the frame operator.
+        f=comp_filterbankresponse(g,info.a,L,0);
+        
+        AF=min(f);
+        BF=max(f);
+    else
+        error(['%s: There is no fast method to find the frame bounds of ' ...
+               'this filterbank as it is neither uniform nor painless. ' ...
+               'Please see FRAMEBOUNDS for an iterative method that can ' ...
+               'solve the problem.'],upper(mfilename));                
+
+    end;    
+end;
+  
+if nargout<2
+    % Avoid the potential warning about division by zero.
+    if AF==0
+    AF=Inf;
+  else
+    AF=BF/AF;
+  end;
+end;
+
+
+
diff --git a/inst/filterbank/filterbankdual.m b/inst/filterbank/filterbankdual.m
new file mode 100644
index 0000000..cfff7e7
--- /dev/null
+++ b/inst/filterbank/filterbankdual.m
@@ -0,0 +1,134 @@
+function gdout=filterbankdual(g,a,L,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankdual
+%@verbatim
+%FILTERBANKDUAL  Dual filters
+%   Usage:  gd=filterbankdual(g,a);
+%           gd=filterbankdual(g,a,L);
+%
+%   FILTERBANKDUAL(g,a) computes the canonical dual filters of g for a
+%   channel subsampling rate of a (hop-size).
+%
+%   The input and output format of the filters g are described in the
+%   help of FILTERBANK.
+%
+%   FILTERBANKDUAL(g,a,L) computes canonical dual filters for a system
+%   of length L. If L is not specified, the shortest possible
+%   transform length is choosen.
+%
+%   To actually invert the output of a filterbank, use the dual filters
+%   together with the IFILTERBANK function.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankdual.php}
+%@seealso{filterbank, ufilterbank, ifilterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+if (~isempty(L)) && (L~=filterbanklength(L,a))
+    error(['%s: Specified length L is incompatible with the length of ' ...
+           'the time shifts.'],upper(mfilename));
+end;
+
+
+% Prioritize painless over uniform algorithm
+if info.isuniform && info.ispainless
+    info.isuniform = 0;
+end
+
+if info.isuniform
+    
+  % Uniform filterbank, use polyphase representation
+  if isempty(L)
+      error('%s: You need to specify L.',upper(mfilename));
+  end;
+
+  a=a(1);
+  
+  % G1 is done this way just so that we can determine the data type.
+  G1=comp_transferfunction(g{1},L);
+  thisclass=assert_classname(G1);
+  G=zeros(L,M,thisclass);
+  G(:,1)=G1;
+  for ii=2:M
+    G(:,ii)=comp_transferfunction(g{ii},L);
+  end;
+  
+  N=L/a;
+  
+  gd=zeros(N,M,thisclass);
+  
+  for w=0:N-1
+    idx = mod(w-(0:a-1)*N,L)+1;
+    H = G(idx,:);
+    
+    H=pinv(H)';
+    
+    gd(idx,:)=H;
+  end;
+  
+  gd=ifft(gd)*a;
+  
+  if isreal(g)
+    gd=real(gd);
+  end;
+  
+  gdout=cell(1,M);
+  for m=1:M
+    gdout{m}=struct('h',cast(gd(:,m),thisclass),'offset',0);
+  end;
+  
+else
+
+    if info.ispainless
+                
+        if isempty(L)
+            error('%s: You need to specify L.',upper(mfilename));
+        end;
+
+        F=comp_filterbankresponse(g,info.a,L,0);
+        
+        gdout=cell(1,M);
+        for m=1:M
+            thisgd=struct();
+            H=circshift(comp_transferfunction(g{m},L)./F,-g{m}.foff);
+            thisgd.H=H(1:numel(g{m}.H));
+            thisgd.foff=g{m}.foff;
+            thisgd.realonly=0;
+            thisgd.delay=0;
+            
+            gdout{m}=thisgd;
+        end;
+        
+    else
+        error(['%s: The canonical dual frame of this system is not a ' ...
+               'filterbank. You must call an iterative ' ...
+               'method to perform the desired inverstion. Please see ' ...
+               'FRANAITER or FRSYNITER.'],upper(mfilename));        
+
+    end;
+    
+end;
+
diff --git a/inst/filterbank/filterbankinit.m b/inst/filterbank/filterbankinit.m
new file mode 100644
index 0000000..8e81610
--- /dev/null
+++ b/inst/filterbank/filterbankinit.m
@@ -0,0 +1,26 @@
+status=1;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/filterbank/filterbanklength.m b/inst/filterbank/filterbanklength.m
new file mode 100644
index 0000000..18ab278
--- /dev/null
+++ b/inst/filterbank/filterbanklength.m
@@ -0,0 +1,64 @@
+function L=filterbanklength(Ls,a);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbanklength
+%@verbatim
+%FILTERBANKLENGTH  Filterbank length from signal
+%   Usage: L=filterbanklength(Ls,a);
+%
+%   FILTERBANKLENGTH(Ls,a) returns the length of a filterbank with
+%   time shifts a, such that it is long enough to expand a signal of
+%   length Ls.
+%
+%   If the filterbank length is longer than the signal length, the signal
+%   will be zero-padded by FILTERBANK or UFILTERBANK.
+%
+%   If instead a set of coefficients are given, call FILTERBANKLENGTHCOEF.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbanklength.php}
+%@seealso{filterbank, filterbanklengthcoef}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if ~isnumeric(Ls)
+  error('%s: Ls must be numeric.',upper(mfilename));
+end;
+
+if ~isscalar(Ls)
+  error('%s: Ls must a scalar.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+%if ~isvector(a)
+%    
+%end;
+
+if any(a<=0)
+      error('%s: "a" must consists of positive numbers only.',upper(mfilename));
+end;
+
+lcm_a=a(1);
+for m=2:size(a,1)
+  lcm_a=lcm(lcm_a,a(m,1));
+end;
+
+L=ceil(Ls/lcm_a)*lcm_a;
+
diff --git a/inst/filterbank/filterbanklengthcoef.m b/inst/filterbank/filterbanklengthcoef.m
new file mode 100644
index 0000000..f0aa853
--- /dev/null
+++ b/inst/filterbank/filterbanklengthcoef.m
@@ -0,0 +1,65 @@
+function L=filterbanklengthcoef(coef,a);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbanklengthcoef
+%@verbatim
+%FILTERBANKLENGTHCOEF  Filterbank length from coefficients
+%   Usage: L=filterbanklengthcoef(coef,a);
+%
+%   FILTERBANKLENGTHCOEF(coef,a) returns the length of a filterbank with
+%   time-shifts a, such that the filterbank is long enough to expand the
+%   coefficients coef.
+%
+%   If instead a signal is given, call FILTERBANKLENGTH.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbanklengthcoef.php}
+%@seealso{filterbank, filterbanklength}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if iscell(coef)
+  Mcoef=numel(coef);
+  cl=cellfun(@(x) size(x,1),coef);
+else
+  Mcoef=size(coef,2);
+  cl=ones(1,Mcoef)*size(coef,1);    
+end;
+
+cl=cl(:);
+
+% Make 'a' have the length of '
+if isvector(a)
+    a=bsxfun(@times,a,ones(numel(cl),1));
+    a=a(:);
+
+    L=a.*cl;
+else
+    L=a(:,1).*cl./a(:,2);
+end;
+
+
+if var(L)>0
+  error(['%s: Invalid set of coefficients. The product of the no. of ' ...
+         'coefficients and the channel time shift must be the same for ' ...
+         'all channels.'],upper(mfilename));
+end;
+
+L=L(1);
+
+
+
diff --git a/inst/filterbank/filterbankrealbounds.m b/inst/filterbank/filterbankrealbounds.m
new file mode 100644
index 0000000..eab4d45
--- /dev/null
+++ b/inst/filterbank/filterbankrealbounds.m
@@ -0,0 +1,115 @@
+function [AF,BF]=filterbankrealbounds(g,a,L);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankrealbounds
+%@verbatim
+%FILTERBANKREALBOUNDS  Frame bounds of filter bank for real signals only
+%   Usage: fcond=filterbankrealbounds(g,a);
+%          [A,B]=filterbankrealbounds(g,a);
+%
+%   FILTERBANKREALBOUNDS(g,a,L) calculates the ratio B/A of the frame
+%   bounds of the filterbank specified by g and a for a system of length
+%   L. The ratio is a measure of the stability of the system.  Use this
+%   function on the common construction where the filters in g only covers
+%   the positive frequencies.
+%
+%   [A,B]=FILTERBANKREALBOUNDS(g,a) returns the lower and upper frame
+%   bounds explicitly.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankrealbounds.php}
+%@seealso{filterbank, filterbankdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if L~=filterbanklength(L,a)
+    error(['%s: Specified length L is incompatible with the length of ' ...
+           'the time shifts.'],upper(mfilename));
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+AF=Inf;
+BF=0;
+  
+if info.isuniform
+  % Uniform filterbank, use polyphase representation
+  a=a(1);
+  
+  N=L/a;
+
+  % G1 is done this way just so that we can determine the data type.
+  G1=comp_transferfunction(g{1},L);
+  thisclass=assert_classname(G1);
+  G=zeros(L,M,thisclass);
+  G(:,1)=G1;
+  for ii=2:M
+    G(:,ii)=comp_transferfunction(g{ii},L);
+  end;
+  
+  Ha=zeros(a,M,thisclass);
+  Hb=zeros(a,M,thisclass);
+  
+  for w=0:N-1
+    idx_a = mod(w-(0:a-1)*N,L)+1;
+    idx_b = mod((0:a-1)*N-w,L)+1;
+    Ha = G(idx_a,:);
+    Hb = conj(G(idx_b,:));
+    
+    % A 'real' is needed here, because the matrices are known to be
+    % Hermitian, but sometimes Matlab/Octave does not recognize this.  
+    work=real(eig(real(Ha*Ha'+Hb*Hb')));
+    
+    AF=min(AF,min(work));
+    BF=max(BF,max(work));
+    
+  end;
+  
+  AF=AF/a;
+  BF=BF/a;
+  
+else
+    if info.ispainless
+        % Compute the diagonal of the frame operator.
+        f=comp_filterbankresponse(g,info.a,L,1);
+        
+        AF=min(f);
+        BF=max(f);
+    else
+        error(['%s: There is no fast method to find the frame bounds of ' ...
+               'this filterbank as it is neither uniform nor painless. ' ...
+               'Please see FRAMEBOUNDS for an iterative method that can ' ...
+               'solve the problem.'],upper(mfilename));                        
+    end;        
+end;
+
+if nargout<2
+  % Avoid the potential warning about division by zero.
+  if AF==0
+    AF=Inf;
+  else
+    AF=BF/AF;
+  end;
+end;
+  
+
+
diff --git a/inst/filterbank/filterbankrealdual.m b/inst/filterbank/filterbankrealdual.m
new file mode 100644
index 0000000..69626a9
--- /dev/null
+++ b/inst/filterbank/filterbankrealdual.m
@@ -0,0 +1,134 @@
+function gdout=filterbankrealdual(g,a,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankrealdual
+%@verbatim
+%FILTERBANKREALDUAL  Dual filters of filterbank for real signals only 
+%   Usage:  gd=filterbankdual(g,a);
+%
+%   filterabankdual(g,a) computes the canonical dual filters of g for a
+%   channel subsampling rate of a (hop-size). The dual filters work only
+%   for real-valued signals. Use this function on the common construction
+%   where the filters in g only covers the positive frequencies.
+%
+%   The format of the filters g are described in the
+%   help of FILTERBANK.
+%
+%   To actually invert the output of a filterbank, use the dual filters
+%   together with 2*real(ifilterbank(...)).
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankrealdual.php}
+%@seealso{filterbank, ufilterbank, ifilterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+if (~isempty(L)) && (L~=filterbanklength(L,a))
+        error(['%s: Specified length L is incompatible with the length of ' ...
+               'the time shifts.'],upper(mfilename));
+end;
+
+% Prioritize painless over uniform algorithm
+if info.isuniform && info.ispainless
+    info.isuniform = 0;
+end
+
+if info.isuniform
+        
+  % Uniform filterbank, use polyphase representation
+  if isempty(L)
+      error('%s: You need to specify L.',upper(mfilename));
+  end;
+  a=a(1);
+
+  % G1 is done this way just so that we can determine the data type.
+  G1=comp_transferfunction(g{1},L);
+  thisclass=assert_classname(G1);
+  G=zeros(L,M,thisclass);
+  G(:,1)=G1;
+  for ii=2:M
+    G(:,ii)=comp_transferfunction(g{ii},L);
+  end;
+  
+  N=L/a;
+  
+  % This is the original code
+  %for k=0:a-1
+  %  Ha(k+1,:) =      G(mod(w-k*N,L)+1,:);
+  %  Hb(k+1,:) = conj(G(mod(k*N-w,L)+1,:));
+  %end;
+  
+  gd=zeros(N,M,thisclass);
+  
+  for w=0:N-1
+    idx_a = mod(w-(0:a-1)*N,L)+1;
+    idx_b = mod((0:a-1)*N-w,L)+1;
+    Ha = G(idx_a,:);
+    Hb = conj(G(idx_b,:));
+    
+    Ha=(Ha*Ha'+Hb*Hb')\Ha;
+    
+    gd(idx_a,:)=Ha;
+  end;
+  
+  gd=ifft(gd)*a;
+  
+  if isreal(g)
+    gd=real(gd);
+  end;
+  
+  gdout=cell(1,M);
+  for m=1:M
+    gdout{m}=struct('h',cast(gd(:,m),thisclass),'offset',0);
+  end;
+  
+else
+
+    if info.ispainless
+        F=comp_filterbankresponse(g,info.a,L,1);
+        
+        gdout=cell(1,M);
+        for m=1:M
+            gl=numel(g{m}.H);
+            thisgd=struct();
+            H=circshift(comp_transferfunction(g{m},L)./F,-g{m}.foff);
+            thisgd.H=H(1:gl);
+            thisgd.foff=g{m}.foff;
+            thisgd.realonly=0;
+            thisgd.delay=0;
+            
+            gdout{m}=thisgd;
+        end;
+    else
+        error(['%s: The canonical dual frame of this system is not a ' ...
+               'filterbank. You must call an iterative ' ...
+               'method to perform the desired inverstion. Please see ' ...
+               'FRANAITER or FRSYNITER.'],upper(mfilename));                
+        
+    end;  
+end;
+
diff --git a/inst/filterbank/filterbankrealtight.m b/inst/filterbank/filterbankrealtight.m
new file mode 100644
index 0000000..09ddd9f
--- /dev/null
+++ b/inst/filterbank/filterbankrealtight.m
@@ -0,0 +1,132 @@
+function gtout=filterbankrealtight(g,a,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankrealtight
+%@verbatim
+%FILTERBANKREALTIGHT  Tight filters of filterbank for real signals only 
+%   Usage:  gd=filterbankrealtight(g,a);
+%
+%   filterabanktight(g,a) computes the canonical tight filters of g for a
+%   channel subsampling rate of a (hop-size). The tight filters work only
+%   for real-valued signals. Use this function on the common construction
+%   where the filters in g only covers the positive frequencies.
+%
+%   The format of the filters g are described in the
+%   help of FILTERBANK.
+%
+%   To actually invert the output of a filterbank, use the tight filters
+%   together with the ifilterbank function as in
+%   2*real(ifilterbank(...)).
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankrealtight.php}
+%@seealso{filterbank, ufilterbank, ifilterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+if (~isempty(L)) && (L~=filterbanklength(L,a))
+    error(['%s: Specified length L is incompatible with the length of ' ...
+           'the time shifts.'],upper(mfilename));
+end;
+
+% Prioritize painless over uniform algorithm
+if info.isuniform && info.ispainless
+    info.isuniform = 0;
+end
+
+if info.isuniform
+  % Uniform filterbank, use polyphase representation
+  if isempty(L)
+      error('%s: You need to specify L.',upper(mfilename));
+  end;
+
+  a=a(1);
+  
+  % G1 is done this way just so that we can determine the data type.
+  G1=comp_transferfunction(g{1},L);
+  thisclass=assert_classname(G1);
+  G=zeros(L,M,thisclass);
+  G(:,1)=G1;
+  for ii=2:M
+    G(:,ii)=comp_transferfunction(g{ii},L);
+  end;
+  
+  N=L/a;
+
+  gt=zeros(N,M,thisclass);
+  
+  for w=0:N-1
+    idx_a = mod(w-(0:a-1)*N,L)+1;
+    idx_b = mod((0:a-1)*N-w,L)+1;
+    Ha = G(idx_a,:);
+    Hb = conj(G(idx_b,:));
+    
+    Ha=sqrtm(Ha*Ha'+Hb*Hb')\Ha;
+    
+    gt(idx_a,:)=Ha;
+  end;
+  
+  gt=ifft(gt)*sqrt(a);
+  
+  if isreal(g)
+    gt=real(gt);
+  end;
+  
+  gtout=cell(1,M);
+  for m=1:M
+    gtout{m}=cast(gt(:,m),thisclass);
+  end;
+  
+else
+        
+    if info.ispainless
+                
+        Fsqrt=sqrt(comp_filterbankresponse(g,info.a,L,1));
+        
+        gtout=cell(1,M);
+        for m=1:M
+            gl=numel(g{m}.H);
+            thisgt=struct();
+            H=circshift(comp_transferfunction(g{m},L)./Fsqrt,-g{m}.foff);
+            thisgt.H=H(1:gl);
+            thisgt.foff=g{m}.foff;
+            thisgt.realonly=0;
+            thisgt.delay=0;
+            
+            gtout{m}=thisgt;
+        end;
+        
+    else
+        error(['%s: The canonical dual frame of this system is not a ' ...
+               'filterbank. You must call an iterative ' ...
+               'method to perform the desired inverstion. Please see ' ...
+               'FRANAITER or FRSYNITER.'],upper(mfilename));        
+
+    end;
+  
+end;
+
diff --git a/inst/filterbank/filterbankresponse.m b/inst/filterbank/filterbankresponse.m
new file mode 100644
index 0000000..8486f6a
--- /dev/null
+++ b/inst/filterbank/filterbankresponse.m
@@ -0,0 +1,86 @@
+function gf=filterbankresponse(g,a,L,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankresponse
+%@verbatim
+%FILTERBANKRESPONSE  Response of filterbank as function of frequency
+%   Usage:  gf=filterbankresponse(g,a,L);
+%      
+%   FILTERBANKRESPONSE(g,a,L) computes the total response in frequency of
+%   a filterbank specified by g and a for a signal length of
+%   L. This corresponds to summing up all channels. The output is a
+%   usefull tool to investigate the behaviour of the windows, as peaks
+%   indicate that a frequency is overrepresented in the filterbank, while
+%   a dip indicates that it is not well represented.
+%
+%   In mathematical terms, this function computes the diagonal of the
+%   Fourier transform of the frame operator when the filterbank is painless.
+%
+%   FILTERBANKRESPONSE(g,a,L,'real') does the same for a filterbank
+%   intended for positive-only filterbank.
+%
+%   FILTERBANKRESPONSE(g,a,L,fs) specifies the sampling rate fs. This
+%   is only used for plotting purposes.
+%
+%   FILTERBANKRESPONSE takes the following optional parameters:
+%
+%      'fs',fs    Sampling rate, used only for plotting.
+%
+%      'complex'  Assume that the filters cover the entire frequency
+%                 range. This is the default.
+%
+%      'real'     Assume that the filters only cover the positive
+%                 frequencies (and is intended to work with real-valued
+%                 signals only).
+%
+%      'noplot'   Don't plot the response, just return it.
+%
+%      'plot'     Plot the response using PLOTFFTREAL.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankresponse.php}
+%@seealso{filterbank, filterbankbounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+definput.flags.ctype={'complex','real'};
+definput.flags.plottype={'noplot','plot'};
+definput.flags.type={'total','individual'};
+definput.keyvals.fs=[];
+[flags,kv,fs]=ltfatarghelper({'fs'},definput,varargin);
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+gf = zeros(L,M);
+
+for m=1:M
+    gf(:,m) = comp_filterbankresponse(g(m),info.a(m),L,flags.do_real);
+end
+
+if flags.do_total
+    gf = sum(gf,2);
+end
+
+if flags.do_plot
+    if flags.do_real
+        plotfftreal(gf(1:floor(L/2)+1),fs,'lin');
+    else
+        plotfft(gf,fs,'lin');
+    end;
+end;
+
diff --git a/inst/filterbank/filterbanktight.m b/inst/filterbank/filterbanktight.m
new file mode 100644
index 0000000..2bf5652
--- /dev/null
+++ b/inst/filterbank/filterbanktight.m
@@ -0,0 +1,127 @@
+function gtout=filterbanktight(g,a,L);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbanktight
+%@verbatim
+%FILTERBANKTIGHT  Tight filters
+%   Usage:  gt=filterbanktight(g,a);
+%
+%   filterabanktight(g,a) computes the canonical tight filters of g for a
+%   channel subsampling rate of a (hop-size).
+%
+%   The input and output format of the filters g are described in the
+%   help of FILTERBANK.
+%
+%   filterabanktight(g,a,L) computes canonical tight filters for a system
+%   of length L. If L is not specified, the shortest possible transform
+%   length is choosen.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbanktight.php}
+%@seealso{filterbank, filterbankdual, ufilterbank, ifilterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+if (~isempty(L)) && (L~=filterbanklength(L,a))
+    error(['%s: Specified length L is incompatible with the length of ' ...
+           'the time shifts.'],upper(mfilename));
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+
+% Prioritize painless over uniform algorithm
+if info.isuniform && info.ispainless
+    info.isuniform = 0;
+end
+
+if info.isuniform
+  % Uniform filterbank, use polyphase representation
+  if isempty(L)
+      error('%s: You need to specify L.',upper(mfilename));
+  end;
+
+  a=a(1);
+
+  % G1 is done this way just so that we can determine the data type.
+  G1=comp_transferfunction(g{1},L);
+  thisclass=assert_classname(G1);
+  G=zeros(L,M,thisclass);
+  G(:,1)=G1;
+  for ii=2:M
+    G(:,ii)=comp_transferfunction(g{ii},L);
+  end;
+  
+  N=L/a;
+  
+  H=zeros(a,M,thisclass);
+  gt=zeros(N,M,thisclass);
+  
+  for w=0:N-1
+    idx = mod(w-(0:a-1)*N,L)+1;
+    H = G(idx,:);
+    
+    [U,S,V]=svd(H,'econ');
+    H=U*V';  
+    
+    gt(idx,:)=H;
+  end;
+  
+  gt=ifft(gt)*sqrt(a);  
+
+  if isreal(g)
+    gt=real(gt);
+  end;
+  
+  gtout=cell(1,M);
+  for m=1:M
+    gtout{m}=cast(gt(:,m),thisclass);
+  end;
+  
+else
+    
+    if info.ispainless
+        Fsqrt=sqrt(comp_filterbankresponse(g,info.a,L,0));
+        
+        gtout=cell(1,M);
+        for m=1:M
+            thisgt=struct();
+            H=circshift(comp_transferfunction(g{m},L)./Fsqrt,-g{m}.foff);
+            thisgt.H=H(1:numel(g{m}.H));
+            thisgt.foff=g{m}.foff;
+            thisgt.realonly=0;
+            thisgt.delay=0;
+            
+            gtout{m}=thisgt;
+        end;
+        
+    else
+        error(['%s: The canonical dual frame of this system is not a ' ...
+               'filterbank. You must call an iterative ' ...
+               'method to perform the desired inverstion. Please see ' ...
+               'FRANAITER or FRSYNITER.'],upper(mfilename));                
+    end;
+  
+end;
+
diff --git a/inst/filterbank/filterbankwin.m b/inst/filterbank/filterbankwin.m
new file mode 100644
index 0000000..37704b6
--- /dev/null
+++ b/inst/filterbank/filterbankwin.m
@@ -0,0 +1,190 @@
+function [g,info] = filterbankwin(g,a,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} filterbankwin
+%@verbatim
+%FILTERBANKWIN  Compute set of filter bank windows from text or cell array
+%   Usage: [g,info] = filterbankwin(g,a,L);
+%
+%   [g,info]=FILTERBANKWIN(g,a,L) computes a window that fits well with
+%   time shift a and transform length L. The window itself is as a cell
+%   array containing additional parameters.
+%
+%   The window can be specified directly as a cell array of vectors of
+%   numerical values. In this case, FILTERBANKWIN only checks assumptions
+%   about transform sizes etc.
+%
+%   [g,info]=FILTERBANKWIN(g,a) does the same, but the windows must be FIR
+%   windows, as the transform length is unspecified.
+%
+%   FILTERBANKWIN(...,'normal') computes a window for regular
+%   filterbanks, while FILTERBANKWIN(...,'real') does the same for the
+%   positive-frequency only filterbanks.
+%
+%   The window can also be specified as cell array. The possibilities are:
+%
+%     {'dual',...}
+%         Canonical dual window of whatever follows. See the examples below.
+%
+%     {'realdual',...}
+%         Canonical dual window for a positive-frequency filterbank
+%         of whatever follows. See the examples below.
+%
+%     {'tight',...}
+%         Canonical tight window of whatever follows. See the examples below.
+%
+%     {'realtight',...} 
+%         Canonical tight window for a real-valued for a positive
+%         frequency filterbank of whatever follows.
+%
+%   The structure info provides some information about the computed
+%   window:
+%
+%     info.M
+%        Number of windows (equal to the number of channels)
+%
+%     info.longestfilter
+%        Length of the longest filter
+%
+%     info.gauss
+%        True if the windows are Gaussian.
+%
+%     info.tfr
+%        Time/frequency support ratios of the window. Set whenever it makes sense.
+%
+%     info.isfir
+%        Input is an FIR window
+%
+%     info.isdual
+%        Output is the dual window of the auxiliary window.
+%
+%     info.istight
+%        Output is known to be a tight window.
+%
+%     info.auxinfo
+%        Info about auxiliary window.
+%   
+%     info.gl
+%        Length of windows.
+%
+%     info.isfac
+%        True if the frame generated by the window has a fast factorization.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/filterbankwin.php}
+%@seealso{filterbank, filterbankdual, filterbankrealdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% TO DO: Why is there a realtype flag?
+% Assert correct input.
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~iscell(g)
+  error('%s: Window g must be a cell array.',upper(mfilename));
+end;
+
+if isempty(g)
+  error('%s: Window g must not be empty.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.flags.realtype={'normal','real'};
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+if ischar(g{1})
+    winname=lower(g{1});
+    switch(winname)
+      case {'dual'}
+        [g,info.auxinfo] = filterbankwin(g{2},a,L);
+        g = filterbankdual(g,a,L);
+        info.isdual=1;
+        
+      case {'realdual'}
+        [g,info.auxinfo] = filterbankwin(g{2},a,L);
+        g = filterbankrealdual(g,a,L);
+        info.isdual=1;
+        
+      case {'tight'}
+        [g,info.auxinfo] = filterbankwin(g{2},a,L);    
+        g = filterbanktight(g,a,L);
+        info.istight=1;
+        
+      case {'realtight'}
+        [g,info.auxinfo] = filterbankwin(g{2},a,L);    
+        g = filterbankrealtight(g,a,L);        
+        info.istight=1;
+        
+      otherwise
+        error('%s: Unsupported window type %s.',winname,upper(mfilename));
+    end;
+end;
+
+info.M=numel(g);
+info.gl=zeros(info.M,1);
+info.offset=zeros(info.M,1);
+info.ispainless=1;
+info.isfractional=0;
+info.isuniform=0;
+info.isfir=1;
+
+[asan,info]=comp_filterbank_a(a,info.M,info);
+    
+for m=1:info.M
+    [g{m},info_win] = comp_fourierwindow(g{m},L,upper(mfilename));    
+    
+    if isfield(g{m},'H') 
+        if ~isnumeric(g{m}.H)
+            g{m}.H=g{m}.H(L);
+            g{m}.foff=g{m}.foff(L);
+        end;
+        % Check the painless condition
+        if numel(g{m}.H) > L/asan(m,1)*asan(m,2);
+           info.ispainless=0; 
+        end
+    else
+        info.ispainless=0;
+        info.gl(m)=numel(g{m}.h);
+        info.offset(m)=g{m}.offset;
+    end;
+    
+    % info.isfir==1 only if all filters are FIR
+    if isfield(info_win,'isfir')
+       if ~info_win.isfir && info.isfir
+          info.isfir = 0;
+       end
+    end
+end;
+
+info.isfac=info.isuniform || info.ispainless;
+
+
+if info.isfractional && info.isuniform
+    error('%s: The uniform algorithms cannot handle fractional downsampling.', ...
+          upper(mfilename));
+end;
+
+if info.isfir
+   info.longestfilter=max(info.gl);
+
+   if L<info.longestfilter
+     error('%s: One of the windows is longer than the transform length= %i.',upper(mfilename),info.longestfilter);
+   end;
+end
+
diff --git a/inst/filterbank/icqt.m b/inst/filterbank/icqt.m
new file mode 100644
index 0000000..9811fe9
--- /dev/null
+++ b/inst/filterbank/icqt.m
@@ -0,0 +1,70 @@
+function fr = icqt(c,g,shift,Ls,dual)
+%-*- texinfo -*-
+%@deftypefn {Function} icqt
+%@verbatim
+%ICQT  Constant-Q nonstationary Gabor synthesis
+%   Usage: fr = icqt(c,g,shift,Ls,dual)
+%          fr = icqt(c,g,shift,Ls)
+%          fr = icqt(c,g,shift)
+%
+%   Input parameters: 
+%         c         : Transform coefficients (matrix or cell array)
+%         g         : Cell array of Fourier transforms of the analysis 
+%                     windows
+%         shift     : Vector of frequency shifts
+%         Ls        : Original signal length (in samples)
+%         dual      : Synthesize with the dual frame
+%   Output parameters:
+%         fr        : Synthesized signal (Channels are stored in the 
+%                     columns)
+%
+%   Given the cell array c of non-stationary Gabor coefficients, and a 
+%   set of filters g and frequency shifts shift this function computes 
+%   the corresponding constant-Q synthesis.
+%
+%   If dual is set to 1 (default), an attempt is made to compute the 
+%   canonical dual frame for the system given by g, shift and the size 
+%   of the vectors in c. This provides perfect reconstruction in the 
+%   painless case, see the references for more information.
+% 
+%   This is just a dummy routine calling INSDGFB.
+%
+% 
+%   References:
+%     N. Holighaus, M. Doerfler, G. A. Velasco, and T. Grill. A framework for
+%     invertible, real-time constant-Q transforms. IEEE Transactions on
+%     Audio, Speech and Language Processing, 21(4):775 -785, 2013.
+%     
+%     G. A. Velasco, N. Holighaus, M. Doerfler, and T. Grill. Constructing an
+%     invertible constant-Q transform with non-stationary Gabor frames.
+%     Proceedings of DAFX11, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/icqt.php}
+%@seealso{cqt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Author: Nicki Holighaus
+% Date: 10.04.13
+
+if ~exist('dual','var')
+    dual = 1;
+end
+
+fr = insdgfb(c,g,shift,Ls,dual);
diff --git a/inst/filterbank/ierblett.m b/inst/filterbank/ierblett.m
new file mode 100644
index 0000000..875e2f3
--- /dev/null
+++ b/inst/filterbank/ierblett.m
@@ -0,0 +1,67 @@
+function fr = ierblett(c,g,shift,Ls,dual)
+%-*- texinfo -*-
+%@deftypefn {Function} ierblett
+%@verbatim
+%IERBLETT  ERBlet nonstationary Gabor synthesis
+%   Usage: fr = ierblett(c,g,shift,Ls,dual)
+%          fr = ierblett(c,g,shift,Ls)
+%          fr = ierblett(c,g,shift)
+%
+%   Input parameters: 
+%         c         : Transform coefficients (matrix or cell array)
+%         g         : Cell array of Fourier transforms of the analysis 
+%                     windows
+%         shift     : Vector of frequency shifts
+%         Ls        : Original signal length (in samples)
+%         dual      : Synthesize with the dual frame
+%   Output parameters:
+%         fr        : Synthesized signal (Channels are stored in the 
+%                     columns)
+%   Given the cell array c of non-stationary Gabor coefficients, and a 
+%   set of filters g and frequency shifts shift this function computes 
+%   the corresponding ERBlet synthesis.
+%
+%   If dual is set to 1 (default), an attempt is made to compute the 
+%   canonical dual frame for the system given by g, shift and the size 
+%   of the vectors in c. This provides perfect reconstruction in the 
+%   painless case, see the references for more information.
+%
+%   This is just a dummy routine calling INSDGFB.
+% 
+% 
+%   References:
+%     T. Necciari, P. Balazs, N. Holighaus, and P. L. Soendergaard. The ERBlet
+%     transform: An auditory-based time-frequency representation with perfect
+%     reconstruction. In Proceedings of the 38th International Conference on
+%     Acoustics, Speech, and Signal Processing (ICASSP 2013), pages 498-502,
+%     Vancouver, Canada, May 2013. IEEE.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/ierblett.php}
+%@seealso{erblett}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Author: Nicki Holighaus
+% Date: 10.04.13
+
+if ~exist('dual','var')
+    dual = 1;
+end
+
+fr = insdgfb(c,g,shift,Ls,dual);
diff --git a/inst/filterbank/ifilterbank.m b/inst/filterbank/ifilterbank.m
new file mode 100644
index 0000000..436e8e3
--- /dev/null
+++ b/inst/filterbank/ifilterbank.m
@@ -0,0 +1,100 @@
+function [f,Ls]=ifilterbank(c,g,a,varargin);  
+%-*- texinfo -*-
+%@deftypefn {Function} ifilterbank
+%@verbatim
+%IFILTERBANK  Filter bank inversion
+%   Usage:  f=ifilterbank(c,g,a);
+%
+%   IFILTERBANK(c,g,a) synthesizes a signal f from the coefficients c*
+%   using the filters stored in g for a channel subsampling rate of a (the
+%   hop-size). The coefficients has to be in the format returned by
+%   either FILTERBANK or UFILTERBANK.
+%
+%   The filter format for g is the same as for FILTERBANK.
+%
+%   If perfect reconstruction is desired, the filters must be the duals
+%   of the filters used to generate the coefficients. See the help on
+%   FILTERBANKDUAL.
+%
+%
+%   References:
+%     H. Boelcskei, F. Hlawatsch, and H. G. Feichtinger. Frame-theoretic
+%     analysis of oversampled filter banks. Signal Processing, IEEE
+%     Transactions on, 46(12):3256-3268, 2002.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/ifilterbank.php}
+%@seealso{filterbank, ufilterbank, filterbankdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'pfilt'};
+definput.keyvals.Ls=[];
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+L=filterbanklengthcoef(c,a);
+
+
+if iscell(c)
+  M=numel(c);
+else
+  M=size(c,2);
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+a = info.a;
+
+if info.M~=M
+  error(['%s: Number of filters must be equal to the number of channels ' ...
+            'of coefficients.'],upper(callfun));
+end
+
+ if size(a,1)>1 
+   if  size(a,1)~=M
+     error(['%s: The number of entries in "a" must match the number of ' ...
+            'filters.'],upper(callfun));
+   end;
+ else
+   a=a*ones(M,1);
+ end;
+
+g = comp_filterbank_pre(g,info.a,L,kv.crossover);
+
+% Handle ufilterbank output format here
+if isnumeric(c)
+   ctmp = c;
+   c = cell(M,1);
+   for m=1:M    
+      c{m}=squeeze(ctmp(:,m,:));
+   end;
+end
+
+
+f = comp_ifilterbank(c,g,a,L);
+  
+% Cut or extend f to the correct length, if desired.
+if ~isempty(Ls)
+  f=postpad(f,Ls);
+else
+  Ls=L;
+end;
+
diff --git a/inst/filterbank/insdgfb.m b/inst/filterbank/insdgfb.m
new file mode 100644
index 0000000..8087068
--- /dev/null
+++ b/inst/filterbank/insdgfb.m
@@ -0,0 +1,117 @@
+function fr = insdgfb(c,g,shift,Ls,dual)
+%-*- texinfo -*-
+%@deftypefn {Function} insdgfb
+%@verbatim
+%INSDGFB  Nonstationary Gabor filterbank synthesis
+%   Usage: fr = insdgfb(c,g,shift,Ls,dual)
+%          fr = insdgfb(c,g,shift,Ls)
+%          fr = insdgfb(c,g,shift)
+%
+%   Input parameters: 
+%         c         : Transform coefficients (matrix or cell array)
+%         g         : Cell array of Fourier transforms of the analysis 
+%                     windows
+%         shift     : Vector of frequency shifts
+%         Ls        : Original signal length (in samples)
+%         dual      : Synthesize with the dual frame
+%   Output parameters:
+%         fr        : Synthesized signal (Channels are stored in the 
+%                     columns)
+%
+%   Given the cell array c of non-stationary Gabor coefficients, and a 
+%   set of filters g and frequency shifts shift this function computes 
+%   the corresponding nonstationary Gabor filterbank synthesis.
+%
+%   If dual is set to 1 (default), an attempt is made to compute the 
+%   canonical dual frame for the system given by g, shift and the size 
+%   of the vectors in c. This provides perfect reconstruction in the 
+%   painless case, see the references for more information.
+% 
+% 
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%     N. Holighaus, M. Doerfler, G. A. Velasco, and T. Grill. A framework for
+%     invertible, real-time constant-Q transforms. IEEE Transactions on
+%     Audio, Speech and Language Processing, 21(4):775 -785, 2013.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/insdgfb.php}
+%@seealso{cqt, icqt, erblett, ierblett}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Author: Nicki Holighaus
+% Date: 10.04.13
+
+%% Check input arguments
+if nargin < 5
+    dual = 1;
+    if nargin < 3
+        error('Not enough input arguments');
+    end
+end
+
+if iscell(c) == 0 % If matrix format coefficients were used, convert to
+    % cell
+    [M,N,CH] = size(c);
+    c = reshape(c,N*M,CH);
+    c = mat2cell(c,M*ones(N,1),CH);
+else
+    N = length(c);
+    CH = size(c{1},2);
+    M = cellfun(@(x) size(x,1),c);
+end
+
+timepos = cumsum(shift);        % Calculate positions from shift vector
+NN = timepos(end);              % Reconstruction length before truncation
+timepos = timepos-shift(1);     % Adjust positions
+
+fr = zeros(NN,CH,assert_classname(c{1},g{1})); % Initialize output
+
+if nargin < 4
+    Ls = NN; % If original signal length is not given do not truncate
+end
+
+if dual == 1 % Attempt to compute canonical dual frame
+    g = nsgabdual(g,shift,M,Ls);
+end
+
+%% The overlap-add procedure including multiplication with the synthesis
+% windows
+
+if numel(M) == 1
+    M = M*ones(N,1);
+end
+
+for ii = 1:N
+    Lg = length(g{ii});
+    
+    win_range = mod(timepos(ii)+(-floor(Lg/2):ceil(Lg/2)-1),NN)+1;
+    
+    temp = fft(c{ii})*M(ii);
+    temp = temp(mod([end-floor(Lg/2)+1:end,1:ceil(Lg/2)]-1,M(ii))+1,:);
+    
+    fr(win_range,:) = fr(win_range,:) + ...
+        bsxfun(@times,temp,g{ii}([Lg-floor(Lg/2)+1:Lg,1:ceil(Lg/2)]));
+end
+
+fr = ifft(fr);
+fr = fr(1:Ls,:); % Truncate the signal to original length (if given)
diff --git a/inst/filterbank/nonu2ufilterbank.m b/inst/filterbank/nonu2ufilterbank.m
new file mode 100644
index 0000000..ffbed79
--- /dev/null
+++ b/inst/filterbank/nonu2ufilterbank.m
@@ -0,0 +1,94 @@
+function [gu,au,info]=nonu2ufilterbank(g,a)
+%-*- texinfo -*-
+%@deftypefn {Function} nonu2ufilterbank
+%@verbatim
+%NONU2UFILTERBANK   Non-uniform to Uniform filterbank transform
+%   Usage:  [gu,au]=nonu2ufilterbank(g,a)
+%
+%   [gu,au]=NONU2UFILTERBANK(g,a) calculates uniform filterbank gu, 
+%   au=lcm(a) which is identical to the (possibly non-uniform) filterbank
+%   g,*a in terms of the equal output coefficients. Each filter g{k} 
+%   is replaced by p=au/a(k) delayed versions of itself
+%   z^{-ma(k)}G_k(z) for m=0,...,p-1.
+%
+%   This allows using the factorisation algorithm when determining
+%   filterbank frame bounds in FILTERBANKBOUNDS and
+%   FILTERBANKREALBOUNDS and in the computation of the dual filterbank 
+%   in FILTERBANKDUAL and FILTERBAKREALDUAL which do not work 
+%   with non-uniform filterbanks.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/nonu2ufilterbank.php}
+%@seealso{ufilterbank, filterbank, filterbankbounds, filterbankdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   References: TBD
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~iscell(g) || ...
+   ~all(cellfun(@(gEl) isstruct(gEl) && (isfield(gEl,'h')||isfield(gEl,'H')),g))
+  error('%s: a must be a cell array of structs containing filter definition.',upper(mfilename));
+end;
+
+a = comp_filterbank_a(a,numel(g));
+
+if size(a,2)==2 && ~all(a(:,2)==1) && rem(a(:,1),1)~=0
+   error('%s: Filterbanks with fractional subsampling are not supported.',upper(mfilename)); 
+end
+
+au=filterbanklength(1,a);
+
+pk = au./a(:,1);
+
+gu=cell(sum(pk),1);
+
+auIdx = 1;
+for m=1:numel(g)
+   for ii=0:pk(m)-1
+      gu{auIdx} = g{m};
+      if(isfield(gu{auIdx},'H'))
+         if(~isfield(gu{auIdx},'delay'))
+            gu{auIdx}.delay = 0;
+         end
+         gu{auIdx}.delay = gu{auIdx}.delay-a(m)*ii;
+      end
+      
+      if(isfield(gu{auIdx},'h'))
+         if(~isfield(gu{auIdx},'offset'))
+            gu{auIdx}.offset = 0;
+         end
+         gu{auIdx}.offset = gu{auIdx}.offset-a(m)*ii;
+      end
+      auIdx = auIdx+1;
+   end
+end
+
+if nargout>2
+   % Array of lengths of identical filterbanks of each channel
+   info.p = pk;
+end
+
diff --git a/inst/filterbank/plotfilterbank.m b/inst/filterbank/plotfilterbank.m
new file mode 100644
index 0000000..bf99271
--- /dev/null
+++ b/inst/filterbank/plotfilterbank.m
@@ -0,0 +1,252 @@
+function coef = plotfilterbank(coef,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotfilterbank
+%@verbatim
+%PLOTFILTERBANK Plot filterbank and ufilterbank coefficients
+%   Usage:  plotfilterbank(coef,a);
+%           plotfilterbank(coef,a,fc);
+%           plotfilterbank(coef,a,fc,fs);
+%           plotfilterbank(coef,a,fc,fs,dynrange);
+%
+%   PLOTFILTERBANK(coef,a) plots filterbank coefficients coef obtained from
+%   either the FILTERBANK or UFILTERBANK functions. The coefficients must
+%   have been produced with a time-shift of a. For more details on the
+%   format of the variables coef and a, see the help of the FILTERBANK
+%   or UFILTERBANK functions.
+%
+%   PLOTFILTERBANK(coef,a,fc) makes it possible to specify the center
+%   frequency for each channel in the vector fc.
+%
+%   PLOTFILTERBANK(coef,a,fc,fs) does the same assuming a sampling rate of
+%   fs Hz of the original signal.
+%
+%   PLOTFILTERBANK(coef,a,fc,fs,dynrange) makes it possible to specify
+%   the dynamic range of the coefficients.
+%
+%   C=PLOTFILTERBANK(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar
+%   functions will create the plot. This is usefull for custom
+%   post-processing of the image data.
+%
+%   PLOTFILTERBANK supports all the optional parameters of TFPLOT. Please
+%   see the help of TFPLOT for an exhaustive list.
+%
+%   In addition to the flags and key/values in TFPLOT, PLOTFILTERBANK
+%   supports the following optional arguments:
+%
+%     'fc',fc       Centre frequencies of the channels. fc must be a vector with
+%                   the length equal to the number of channels. The
+%                   default value of [] means to plot the channel
+%                   no. instead of its frequency.
+%
+%     'ntickpos',n  Number of tick positions along the y-axis. The
+%                   position of the ticks are determined automatically.
+%                   Default value is 10.
+%
+%     'tick',t      Array of tick positions on the y-axis. Use this
+%                   option to specify the tick position manually.
+%
+%     'audtick'     Use ticks suitable for visualizing an auditory
+%                   filterbank. Same as 'tick',[0,100,250,500,1000,...].
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/plotfilterbank.php}
+%@seealso{filterbank, ufilterbank, tfplot, sgram}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'plotfilterbank','tfplot','ltfattranslate'};
+
+definput.keyvals.xres=800;
+
+[flags,kv]=ltfatarghelper({'fc','fs','dynrange'},definput,varargin);
+
+if iscell(coef)
+  M=numel(coef);
+  a = comp_filterbank_a(a,M);
+  
+  if all(rem(a(:,1),1)==0) && any(a(:,2)~=1)
+    % Well behaved fractional case   
+    % a(:,1) = L
+    % a(:,2) = cellfun(@(cEl) size(cEl,1),c);
+    L = a(1);
+  else
+    % Non-fractional case and non-integer hop factors
+    L=a(1)*size(coef{1},1);
+    % Sanity check
+    assert(rem(L,1)<1e-3,sprintf('%s: Invalid hop size.',upper(mfilename)));
+  end
+  
+
+  N=kv.xres;
+  coef2=zeros(M,N);
+  
+  for ii=1:M
+    row=coef{ii};
+    if numel(row)==1
+       coef2(ii,:) = row;
+       continue;
+    end
+    coef2(ii,:)=interp1(linspace(0,1,numel(row)),row,...
+                       linspace(0,1,N),'nearest');
+  end;
+  coef=coef2;
+  delta_t=L/N;
+else
+  a=a(1);
+  Nc=size(coef,1);
+  N=kv.xres;
+  M=size(coef,2);
+  coef=interp1(linspace(0,1,Nc),coef,...
+       linspace(0,1,N),'nearest');
+  coef=coef.';  
+  delta_t=a*Nc/N;
+end;
+
+% Freq. pos is just number of the channel.
+yr=1:M;
+
+if size(coef,3)>1
+  error('Input is multidimensional.');
+end;
+
+% Apply transformation to coefficients.
+if flags.do_db
+  coef=20*log10(abs(coef)+realmin);
+end;
+
+if flags.do_dbsq
+  coef=10*log10(abs(coef)+realmin);
+end;
+
+if flags.do_linsq
+  coef=abs(coef).^2;
+end;
+
+if flags.do_linabs
+  coef=abs(coef);
+end;
+
+if flags.do_lin
+  if ~isreal(coef)
+    error(['Complex valued input cannot be plotted using the "lin" flag.',...
+           'Please use the "linsq" or "linabs" flag.']);
+  end;
+end;
+
+% 'dynrange' parameter is handled by converting it into clim
+% clim overrides dynrange, so do nothing if clim is already specified
+if  ~isempty(kv.dynrange) && isempty(kv.clim)
+  maxclim=max(coef(:));
+  kv.clim=[maxclim-kv.dynrange,maxclim];
+end;
+
+% Handle clim by thresholding and cutting
+if ~isempty(kv.clim)
+  coef(coef<kv.clim(1))=kv.clim(1);
+  coef(coef>kv.clim(2))=kv.clim(2);
+end;
+
+if flags.do_tc
+  xr=(-floor(N/2):floor((N-1)/2))*a;
+else
+  xr=(0:N-1)*delta_t;
+end;
+
+if ~isempty(kv.fs)
+  xr=xr/kv.fs;
+end;
+
+switch(flags.plottype)
+  case 'image'
+    % Call imagesc explicitly with clim. This is necessary for the
+    % situations where the data (is by itself limited (from above or
+    % below) to within the specified range. Setting clim explicitly
+    % avoids the colormap moves in the top or bottom.
+    if isempty(kv.clim)
+      imagesc(xr,yr,coef);
+    else
+      imagesc(xr,yr,coef,kv.clim);
+    end;   
+  case 'contour'
+    contour(xr,yr,coef);
+  case 'surf'
+    surf(xr,yr,coef,'EdgeColor','none');
+  case 'pcolor'
+    pcolor(xr,yr,coef);
+end;
+
+if flags.do_colorbar
+  colorbar;
+end;
+
+axis('xy');
+if ~isempty(kv.fs)
+  xlabel(sprintf('%s (s)',kv.time),'fontsize',kv.fontsize);
+else
+  xlabel(sprintf('%s (%s)',kv.time,kv.samples),'fontsize',kv.fontsize);
+end;
+
+if isempty(kv.fc)
+  ylabel('Channel No.','fontsize',kv.fontsize);
+else
+  
+  if isempty(kv.tick)
+    tickpos=linspace(1,M,kv.ntickpos);
+    tick=spline(1:M,kv.fc,tickpos);
+    
+    set(gca,'YTick',tickpos);
+    set(gca,'YTickLabel',num2str(tick(:),3));
+
+  else
+    nlarge=1000;
+    tick=kv.tick;
+        
+    % Create a crude inverse mapping to determine the positions of the
+    % ticks. Include half a channel in each direction, because it is
+    % possible to display a tick mark all the way to the edge of the
+    % plot.
+    manyticks=spline(1:M,kv.fc,linspace(0.5,M+0.5,nlarge));
+    
+    % Keep only ticks <= than highest frequency+.5*bandwidth
+    tick=tick(tick<=manyticks(end));
+    
+    % Keep only ticks >= lowest frequency-.5*bandwidth
+    tick=tick(tick>=manyticks(1));    
+    
+    nticks=length(tick);
+    tickpos=zeros(nticks,1);
+    for ii=1:nticks
+      jj=find(manyticks>=tick(ii));
+      tickpos(ii)=jj(1)/nlarge*M;
+    end;
+
+    set(gca,'YTick',tickpos);
+    set(gca,'YTickLabel',num2str(tick(:)));
+
+  end;
+  
+  ylabel(sprintf('%s (Hz)',kv.frequency),'fontsize',kv.fontsize);
+  
+end;
+
+
diff --git a/inst/filterbank/ufilterbank.m b/inst/filterbank/ufilterbank.m
new file mode 100644
index 0000000..5d5d31c
--- /dev/null
+++ b/inst/filterbank/ufilterbank.m
@@ -0,0 +1,87 @@
+function c=ufilterbank(f,g,a,varargin);  
+%-*- texinfo -*-
+%@deftypefn {Function} ufilterbank
+%@verbatim
+%UFILTERBANK   Apply Uniform filterbank
+%   Usage:  c=ufilterbank(f,g,a);
+%
+%   UFILTERBANK(f,g,a) applies the filter given in g to the signal
+%   f. Each subband will be subsampled by a factor of a (the
+%   hop-size). If f is a matrix, the transformation is applied to each
+%   column.
+%
+%   The filters g must be a cell-array, where each entry in the cell
+%   array corresponds to an FIR filter.
+%
+%   If f is a single vector, then the output will be a matrix, where each
+%   column in f is filtered by the corresponding filter in g. If f is
+%   a matrix, the output will be 3-dimensional, and the third dimension will
+%   correspond to the columns of the input signal.
+%
+%   The coefficients c computed from the signal f and the filterbank
+%   with windows g_m are defined by
+%
+%                   L-1
+%      c(n+1,m+1) = sum f(l+1) * g_m (an-l+1)
+%                   l=0
+%
+%
+%
+%   References:
+%     H. Boelcskei, F. Hlawatsch, and H. G. Feichtinger. Frame-theoretic
+%     analysis of oversampled filter banks. Signal Processing, IEEE
+%     Transactions on, 46(12):3256-3268, 2002.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/filterbank/ufilterbank.php}
+%@seealso{ifilterbank, filterbankdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'pfilt'};
+definput.keyvals.L=[];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,'UFILTERBANK',0);
+
+a=a(1);
+
+if isempty(L)
+  L=filterbanklength(Ls,a);
+end;
+
+[g,info]=filterbankwin(g,a,L,'normal');
+M=info.M;
+N=L/a;
+
+f=postpad(f,L);
+
+c=zeros(N,M,W,assert_classname(f));
+g = comp_filterbank_pre(g,info.a,L,kv.crossover);
+
+ctmp=comp_filterbank(f,g,info.a);
+
+
+for m=1:M    
+    c(:,m,:)=ctmp{m};
+end;
+
diff --git a/inst/fourier/Contents.m b/inst/fourier/Contents.m
new file mode 100644
index 0000000..408f82a
--- /dev/null
+++ b/inst/fourier/Contents.m
@@ -0,0 +1,101 @@
+% LTFAT - Basic Fourier and DCT analysis.
+%
+%  Peter L. Soendergaard, 2008 - 2014.
+%
+%  Support routines
+%    FFTINDEX       -  Index of positive and negative frequencies.
+%    MODCENT        -  Centered modulo operation.
+%    FLOOR23        -  Previous number with only 2,3 factors
+%    FLOOR235       -  Previous number with only 2,3,5 factors
+%    CEIL23         -  Next number with only 2,3 factors
+%    CEIL235        -  Next number with only 2,3,5 factors
+%    NEXTFASTFFT    -  Next efficient FFT size (2,3,5,7).
+%  
+%  Basic Fourier analysis
+%    DFT            -  Unitary discrete Fourier transform.
+%    IDFT           -  Inverse of DFT.
+%    FFTREAL        -  FFT for real valued signals.
+%    IFFTREAL       -  Inverse of FFTREAL.
+%    GGA            -  Generalized Goertzel Algorithm.
+%    CHIRPZT        -  Chirped Z-transform.
+%    PLOTFFT        -  Plot FFT coefficients.
+%    PLOTFFTREAL    -  Plot FFTREAL coefficients.
+%
+%  Simple operations on periodic functions
+%    INVOLUTE       -  Involution.
+%    PEVEN          -  Even part of periodic function.
+%    PODD           -  Odd part of periodic function.
+%    PCONV          -  Periodic convolution.
+%    CONVOLVE       -  Fast, non-periodic convolution.
+%    PXCORR         -  Periodic cross correlation.
+%    ISEVENFUNCTION -  Test if function is even.
+%    MIDDLEPAD      -  Cut or extend even function.
+%
+%  Functions
+%    EXPWAVE        -  Complex exponential wave.
+%    PCHIRP         -  Periodic chirp.
+%    SHAH           -  Shah distribution.
+%    PHEAVISIDE     -  Periodic Heaviside function.
+%    PRECT          -  Periodic rectangle function.
+%    PSINC          -  Periodic sinc function.
+%
+%  Window functions
+%    PGAUSS         -  Periodic Gaussian.
+%    PSECH          -  Periodic SECH.
+%    PBSPLINE       -  Periodic B-splines.
+%    FIRWIN         -  FIR windows (Hanning,Hamming,Blackman,...).
+%    FIRKAISER      -  FIR Kaiser-Bessel window.
+%    FIR2LONG       -  Extend FIR window to LONG window.
+%    LONG2FIR       -  Cut LONG window to FIR window.
+%
+%  Filtering
+%    FIRFILTER      -  Construct an FIR filter.
+%    BLFILTER       -  Construct a band-limited filter.
+%    WARPEDBLFILTER -  Warped, band-limited filter.
+%    PFILT          -  Apply filter with periodic boundary conditions.
+%    MAGRESP        -  Magnitude response plot.
+%    TRANSFERFUNCTION - Computer the transfer function of a filter.
+%
+%  Hermite functions and fractional Fourier transforms
+%    PHERM          -  Periodic Hermite functions.
+%    HERMBASIS      -  Orthonormal basis of Hermite functions.    
+%    DFRACFT        -  Discrete Fractional Fourier transform
+%    FFRACFT        -  Fast Fractional Fourier transform
+%
+%  Approximation of continuous functions
+%    FFTRESAMPLE    -  Fourier interpolation.
+%    DCTRESAMPLE    -  Cosine interpolation.
+%    PDERIV         -  Derivative of periodic function.
+%
+%  Cosine and Sine transforms.
+%    DCTI           -  Discrete cosine transform type I
+%    DCTII          -  Discrete cosine transform type II
+%    DCTIII         -  Discrete cosine transform type III
+%    DCTIV          -  Discrete cosine transform type IV
+%    DSTI           -  Discrete sine transform type I
+%    DSTII          -  Discrete sine transform type II
+%    DSTIII         -  Discrete sine transform type III
+%    DSTIV          -  Discrete sine transform type IV
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/fourier/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
diff --git a/inst/fourier/blfilter.m b/inst/fourier/blfilter.m
new file mode 100644
index 0000000..109ecbf
--- /dev/null
+++ b/inst/fourier/blfilter.m
@@ -0,0 +1,185 @@
+function gout=blfilter(winname,fsupp,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} blfilter
+%@verbatim
+%BLFILTER  Construct a band-limited filter
+%   Usage:  g=blfilter(winname,fsupp,fc);
+%           g=blfilter(winname,fsupp,fc,...);
+%
+%   Input parameters:
+%      winname  : Name of prototype
+%      fsupp    : Support length of the prototype
+%
+%   BLFILTER(winname,fsupp) constructs a band-limited filter. The parameter
+%   winname specifies the shape of the frequency response. The name must be
+%   one of the shapes accepted by FIRWIN. The support of the frequency
+%   response measured in normalized frequencies is specified by fsupp.
+%
+%   BLFILTER(winname,fsupp,fc) constructs a filter with a centre
+%   frequency of fc measured in normalized frequencies.
+%
+%   If one of the inputs is a vector, the output will be a cell array
+%   with one entry in the cell array for each element in the vector. If
+%   more input are vectors, they must have the same size and shape and the
+%   the filters will be generated by stepping through the vectors. This
+%   is a quick way to create filters for FILTERBANK and UFILTERBANK.
+%
+%   BLFILTER accepts the following optional parameters:
+%
+%     'fs',fs     If the sampling frequency fs is specified then the support
+%                 fsupp and the centre frequency fc is specified in Hz.
+%
+%     'complex'   Make the filter complex valued if the centre frequency
+%                 is non-zero.necessary. This is the default.
+%
+%     'real'      Make the filter real-valued if the centre frequency
+%                 is non-zero.
+%
+%     'delay',d   Set the delay of the filter. Default value is zero.
+%
+%     'scal',s    Scale the filter by the constant s. This can be
+%                 useful to equalize channels in a filterbank.
+%
+%     'pedantic'  Force window frequency offset (g.foff) to a subsample 
+%                 precision by a subsample shift of the firwin output.
+%                 
+%
+%   It is possible to normalize the transfer function of the filter by
+%   passing any of the flags from the NORMALIZE function. The default
+%   normalization is 'energy'.
+%
+%   The filter can be used in the PFILT routine to filter a signal, or
+%   in can be placed in a cell-array for use with FILTERBANK or
+%   UFILTERBANK.
+%
+%   Output format:
+%   --------------
+%
+%   The output g from BLFILTER is a structure. This type of structure can
+%   be used to describe any bandlimited filter defined in terms of its
+%   transfer function. The structure contains the following fields:
+%
+%     g.H     This is an anonymous function taking the transform length L as
+%             input and producing the bandlimited transfer function in the
+%             form of a vector.
+%
+%     g.foff  This is an anonymous function taking the transform length L as
+%             input and procing the frequency offset of H as an integer. The
+%             offset is the value of the lowest frequency of H measured in
+%             frequency samples. foff is used to position the bandlimited
+%             tranfer function stored in H correctly when multiplying in the
+%             frequency domain.
+%
+%     g.delay  This is the desired delay of the filter measured in samples.
+%
+%     g.realonly
+%             This is an integer with value 1 if the filter defined a
+%             real-valued filter. In this case, the bandlimited transfer
+%             function H will be mirrored from the positive frequencies to
+%             the negative frequencies. If the filter is a natural lowpass
+%             filter correctly centered around 0, realonly does not need
+%             to be 1.
+%
+%     g.fs    The intended sampling frequency. This is an optional parameter
+%             that is *only* used for plotting and visualization.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/blfilter.php}
+%@seealso{firfilter, firwin, pfilt, filterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Define initial value for flags and key/value pairs.
+definput.import={'normalize'};
+definput.importdefaults={'energy'};
+definput.keyvals.delay=0;
+definput.keyvals.fc=0;
+definput.keyvals.fs=[];
+definput.keyvals.scal=1;
+definput.keyvals.min_win=1;
+definput.flags.pedantic = {'nopedantic','pedantic'};
+definput.flags.real={'complex','real'};
+
+[flags,kv]=ltfatarghelper({'fc'},definput,varargin);
+
+if flags.do_pedantic
+    error('%s: TO DO: Pedantic option not implemented yet.',...
+          upper(mfilename));
+end
+
+[fsupp,kv.fc,kv.delay,kv.scal]=scalardistribute(fsupp,kv.fc,kv.delay,kv.scal);
+
+if ~isempty(kv.fs)
+    fsupp=fsupp/kv.fs*2;
+    kv.fc=kv.fc/kv.fs*2;
+else
+   %If fs is not specified, allow fsupp to be in range 0-2
+   assert(all(fsupp>0) && all(fsupp<=2),'%s: Filter support should be in range ]0-2].',upper(mfilename));
+end;
+
+% Sanitize
+kv.fc=modcent(kv.fc,2);
+
+Nfilt=numel(fsupp);
+gout=cell(1,Nfilt);
+
+if ischar(winname)
+    wn = {winname};
+elseif iscell(winname)
+    wn = winname;
+else
+    error('%s: Incorrect format of winname.',upper(mfilename));
+end
+
+
+for ii=1:Nfilt
+    g=struct();
+    
+
+    
+    if flags.do_1 || flags.do_area 
+        g.H=@(L)    fftshift(firwin(wn{1},max([kv.min_win,...
+                                    round(L/2*fsupp(ii))]),wn{2:end},...
+                                    flags.norm))*kv.scal(ii)*L;        
+    end;
+    
+    if  flags.do_2 || flags.do_energy
+        g.H=@(L)    fftshift(firwin(wn{1},max([kv.min_win,...
+                                    round(L/2*fsupp(ii))]),wn{2:end},...
+                                    flags.norm))*kv.scal(ii)*sqrt(L);                
+    end;
+        
+    if flags.do_inf || flags.do_peak
+        g.H=@(L)    fftshift(firwin(wn{1},max([kv.min_win,...
+                                    round(L/2*fsupp(ii))]),wn{2:end},...
+                                    flags.norm))*kv.scal(ii);        
+        
+    end;
+        
+    g.foff=@(L) floor(L/2*kv.fc(ii))-floor(max([kv.min_win,round(L/2*fsupp(ii))])/2);
+    g.realonly=flags.do_real;
+    g.delay=kv.delay(ii);
+    g.fs=kv.fs;
+    gout{ii}=g;
+end;
+
+if Nfilt==1
+    gout=g;
+end;
+
+
diff --git a/inst/fourier/ceil23.m b/inst/fourier/ceil23.m
new file mode 100644
index 0000000..0f8469f
--- /dev/null
+++ b/inst/fourier/ceil23.m
@@ -0,0 +1,109 @@
+function [nfft,tableout]=ceil23(n)
+%-*- texinfo -*-
+%@deftypefn {Function} ceil23
+%@verbatim
+%CEIL23  Next number with only 2,3 factors
+%   Usage: nceil=ceil23(n);
+%
+%   CEIL23(n) returns the next number greater than or equal to n,
+%   which can be written as a product of powers of 2 and 3.
+%
+%   The algorithm will look up the best size in a table, which is computed
+%   the first time the function is run. If the input size is larger than the
+%   largest value in the table, the input size will be reduced by factors of
+%   2, until it is in range.
+%
+%   [nceil,table]=CEIL23(n) additionally returns the table used for lookup.
+%
+%   Examples:
+%   ---------
+%
+%   Return the first number larger or equal to 19 that can be written
+%   solely as products of powers of 2 and 3*:
+% 
+%     ceil23(19)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/ceil23.php}
+%@seealso{floor23, ceil235, nextfastfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+  
+  
+persistent table;
+  
+maxval=2^20;
+
+if isempty(table)
+    % Compute the table for the first time, it is empty.
+    l2=log(2);
+    l3=log(3);
+    l5=log(5);
+    lmaxval=log(maxval);
+    table=zeros(143,1);
+    ii=1;
+    prod2=1;
+    for i2=0:floor(lmaxval/l2)
+        prod3=prod2;
+        for i3=0:floor((lmaxval-i2*l2)/l3)               
+            table(ii)=prod3; 
+            prod3=prod3*3;
+            ii=ii+1;
+        end;
+        prod2=prod2*2;            
+    end;
+    table=sort(table);
+end;
+
+% Copy input to output. This allows us to efficiently work in-place.
+nfft=n;
+
+% Handle input of any shape by Fortran indexing.
+for ii=1:numel(n)
+  n2reduce=0;
+  
+  if n(ii)>maxval
+    % Reduce by factors of 2 to get below maxval
+    n2reduce=ceil(log2(nfft(ii)/maxval));
+    nfft(ii)=nfft(ii)/2^n2reduce;
+  end;
+  
+  % Use a simple bisection method to find the answer in the table.
+  from=1;
+  to=numel(table);
+  while from<=to
+    mid = round((from + to)/2);    
+    diff = table(mid)-nfft(ii);
+    if diff<0
+      from=mid+1;
+    else
+      to=mid-1;                       
+    end
+  end
+  nfft(ii)=table(from);
+  
+  % Add back the missing factors of 2 (if any)
+  nfft(ii)=nfft(ii)*2^n2reduce;
+  
+end;
+
+tableout=table;
+
+
diff --git a/inst/fourier/ceil235.m b/inst/fourier/ceil235.m
new file mode 100644
index 0000000..561e661
--- /dev/null
+++ b/inst/fourier/ceil235.m
@@ -0,0 +1,112 @@
+function [nfft,tableout]=ceil235(n)
+%-*- texinfo -*-
+%@deftypefn {Function} ceil235
+%@verbatim
+%CEIL235  Next number with only 2,3 and 5 factors
+%   Usage: nceil=ceil235(n);
+%
+%   CEIL235(n)  returns the next number greater than or equal to n,
+%   which can be written as a product of powers of 2, 3 and 5.
+%
+%   The algorithm will look up the best size in a table, which is computed
+%   the first time the function is run. If the input size is larger than the
+%   largest value in the table, the input size will be reduced by factors of
+%   2, until it is in range.
+%
+%   [nceil,table]=CEIL235(n) additionally returns the table used for lookup.
+%
+%   Examples:
+%   ---------
+%
+%   Return the first number larger or equal to 19 that can be written
+%   solely as products of powers of 2, 3 and 5*:
+% 
+%     ceil235(19)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/ceil235.php}
+%@seealso{floor235, ceil23, nextfastfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+    
+persistent table;
+  
+maxval=2^20;
+
+if isempty(table)
+    % Compute the table for the first time, it is empty.
+    l2=log(2);
+    l3=log(3);
+    l5=log(5);
+    lmaxval=log(maxval);
+    table=zeros(511,1);
+    ii=1;
+    prod2=1;
+    for i2=0:floor(lmaxval/l2)
+        prod3=prod2;
+        for i3=0:floor((lmaxval-i2*l2)/l3)               
+            prod5=prod3;
+            for i5=0:floor((lmaxval-i2*l2-i3*l3)/l5)
+                table(ii)=prod5; 
+                prod5=prod5*5;
+                ii=ii+1;
+            end;
+            prod3=prod3*3;
+        end;
+        prod2=prod2*2;            
+    end;
+    table=sort(table);
+end;
+
+% Copy input to output. This allows us to efficiently work in-place.
+nfft=n;
+
+% Handle input of any shape by Fortran indexing.
+for ii=1:numel(n)
+  n2reduce=0;
+  
+  if n(ii)>maxval
+    % Reduce by factors of 2 to get below maxval
+    n2reduce=ceil(log2(nfft(ii)/maxval));
+    nfft(ii)=nfft(ii)/2^n2reduce;
+  end;
+  
+  % Use a simple bisection method to find the answer in the table.
+  from=1;
+  to=numel(table);
+  while from<=to
+    mid = round((from + to)/2);    
+    diff = table(mid)-nfft(ii);
+    if diff<0
+      from=mid+1;
+    else
+      to=mid-1;                       
+    end
+  end
+  nfft(ii)=table(from);
+  
+  % Add back the missing factors of 2 (if any)
+  nfft(ii)=nfft(ii)*2^n2reduce;
+  
+end;
+
+tableout=table;
+
+
diff --git a/inst/fourier/chirpzt.m b/inst/fourier/chirpzt.m
new file mode 100644
index 0000000..3e1fb7d
--- /dev/null
+++ b/inst/fourier/chirpzt.m
@@ -0,0 +1,164 @@
+function c = chirpzt(f,K,fdiff,foff,fs,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} chirpzt
+%@verbatim
+%CHIRPZT Chirped Z-transform
+%   Usage:  c = chirpzt(f,K,fdiff)
+%           c = chirpzt(f,K,fdiff,foff)
+%           c = chirpzt(f,K,fdiff,foff,fs)
+%
+%   Input parameters:
+%         f      : Input data.
+%         K      : Number of values.
+%         fdiff  : Frequency increment.
+%         foff   : Starting frequency. 
+%         fs     : Sampling frequency. 
+%
+%   Output parameters:
+%         c      : Coefficient vector.
+%
+%   c = CHIRPZT(f,K,fdiff,foff) computes K samples of the discrete-time 
+%   fourier transform DTFT c of f at values c(k+1)=F(2pi(f_{off}+kf_{diff}))
+%   for k=0,dots,K-1 where F=DTFT(f). Values foff and fdiff should
+%   be in range of 0-1. If foff is ommited or empty, it is considered to
+%   be 0. If fdiff is ommited or empty, K equidistant values 
+%   c(k+1)=F(2pi k/K) are computed. If even K is ommited or empty, 
+%   input length is used instead resulting in the same values as fft does.
+%
+%   c = CHIRPZT(f,K,fdiff,foff,fs) computes coefficients using frequency 
+%   values relative to fs c(k+1)=F(2pi(f_{off}+kf_{diff})/fs) for k=0,dots,K-1.
+%
+%   The input f is processed along the first non-singleton dimension or
+%   along dimension dim if specified.
+%
+%   Examples:
+%   ---------
+%   
+%   Calculating DTFT samples of interest (aka zoom FFT):
+% 
+%     % Generate input signal
+%     fs = 8000;
+%     L = 2^10;
+%     k = (0:L-1).';
+%     f1 = 400;
+%     f2 = 825;
+%     f = 5*sin(2*pi*k*f1/fs + pi/4) + 2*sin(2*pi*k*f2/fs - pi/3);
+%
+%     % This is equal to fft(f)
+%     ck = chirpzt(f,L);
+%
+%     %chirpzt to FFT error:
+%     norm(ck-fft(f))
+%
+%     % Frequency "resolution" in Hz
+%     fdiff = 0.4;
+%     % Frequency offset in Hz
+%     foff = 803.9;
+%     % Number of frequency values
+%     K = 125;
+%     % DTFT samples. The frequency range of interest is 803.9-853.5 Hz
+%     ckchzt = chirpzt(f,K,fdiff,foff,fs);
+%
+%     % Plot modulus of coefficients
+%     figure(1);
+%     fax=foff+fdiff.*(0:K-1);
+%     hold on;
+%     stem(k/L*fs,abs(ck),'k');
+%     stem(fax,abs(ckchzt),'r:');
+%     set(gca,'XLim',[foff,foff+K*fdiff]);
+%     set(gca,'YLim',[0 1065]);
+%     xlabel('f[Hz]');
+%     ylabel('|ck|');
+%
+%     % Plot phase of coefficients
+%     figure(2);
+%     hold on;
+%     stem(k/L*fs,angle(ck),'k');
+%     stem(fax,angle(ckchzt),'r:');
+%     set(gca,'XLim',[foff,foff+K*fdiff]);
+%     set(gca,'YLim',[-pi pi]);
+%     xlabel('f[Hz]');
+%     ylabel('angle(ck)');
+%
+%
+%   References:
+%     L. Rabiner, R. Schafer, and C. Rader. The chirp Z-transform algorithm.
+%     Audio and Electroacoustics, IEEE Transactions on, 17(2):86-92, 1969.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/chirpzt.php}
+%@seealso{gga}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%% Check the input arguments
+if nargin < 1
+    error('%s: Not enough input arguments.',upper(mfilename))
+end
+
+if isempty(f)
+    error('%s: X must be a nonempty vector or a matrix.',upper(mfilename))
+end
+
+if nargin<6
+  dim=[];  
+end;
+
+[f,~,Ls,~,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,'CHIRPZT');
+
+if nargin > 1  && ~isempty(K)
+   if ~isreal(K) || ~isscalar(K) || rem(K,1)~=0
+      error('%s: K must be a real integer.',upper(mfilename))
+   end
+else
+   K = size(f,1);
+end
+
+if nargin > 2  && ~isempty(fdiff)
+   if ~isreal(K) || ~isscalar(K)
+      error('%s: fdiff must be a real scalar.',upper(mfilename))
+   end
+else
+   fdiff = 1/K;
+end
+
+if nargin > 3  && ~isempty(foff)
+   if ~isreal(K) || ~isscalar(K)
+      error('%s: foff must be a real scalar.',upper(mfilename))
+   end
+else
+   foff = 0;
+end
+
+if nargin > 4  && ~isempty(fs)
+   if ~isreal(fs) || ~isscalar(fs)
+      error('%s: fs must be a real scalar.',upper(mfilename))
+   end
+else
+   fs = 1;
+end
+
+
+c = comp_chirpzt(f,K,2*pi*fdiff/fs,2*pi*foff/fs);
+
+
+permutedsize(1)=K;
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/convolve.m b/inst/fourier/convolve.m
new file mode 100644
index 0000000..da98664
--- /dev/null
+++ b/inst/fourier/convolve.m
@@ -0,0 +1,73 @@
+function h=convolve(f,g,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} convolve
+%@verbatim
+%CONVOLVE  Convolution
+%   Usage:  h=convolve(f,g);
+%
+%   CONVOLVE(f,g) will convolve two vectors f and g. The
+%   convolution is not periodic, so the output will have a length of :
+%
+%     output_len = length(f)+length(g)-1;
+%
+%   This function works entirely similar to the Matlab routine conv
+%   using instead a fast FFT algorithm, making it much faster if one or
+%   more of the signals are long.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/convolve.php}
+%@seealso{pconv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.dim=[];
+
+[flags,kv,L,dim]=ltfatarghelper({'L','dim'},definput,varargin);
+
+[f,L1,Lf,Wf,dimout,permutedsize_f,order_f]=assert_sigreshape_pre(f,L,dim,'CONVOLVE');
+[g,L2,Lg,Wg,dimout,permutedsize_g,order_g]=assert_sigreshape_pre(g,L,dim,'CONVOLVE');
+
+Lh=Lf+Lg-1;
+
+if (Wf>1) && (Wg>1)
+  error('%s: Only one of the inputs can be multi-dimensional.',upper(mfilename));
+end;
+
+W=max(Wf,Wg);
+if Wf<W
+  f=repmat(f,1,W);
+end;
+
+if Wg<W
+  g=repmat(g,1,W);
+end;
+
+if isreal(f) && isreal(g)
+  h=comp_ifftreal(comp_fftreal(postpad(f,Lh)).*...
+                  comp_fftreal(postpad(g,Lh)),Lh);
+else
+  h=ifft(fft(postpad(f,Lh)).*...
+         fft(postpad(g,Lh)));
+  
+end;
+
diff --git a/inst/fourier/dcti.m b/inst/fourier/dcti.m
new file mode 100644
index 0000000..fd3473a
--- /dev/null
+++ b/inst/fourier/dcti.m
@@ -0,0 +1,135 @@
+function c=dcti(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dcti
+%@verbatim
+%DCTI  Discrete Cosine Transform type I
+%   Usage:  c=dcti(f);
+%           c=dcti(f,L);
+%           c=dcti(f,[],dim);
+%           c=dcti(f,L,dim);
+%
+%   DCTI(f) computes the discrete cosine transform of type I of the
+%   input signal f. If f is a matrix then the transformation is applied to
+%   each column. For N-D arrays, the transformation is applied to the first
+%   non-singleton dimension.
+%
+%   DCTI(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DCTI(f,[],dim) or DCTI(f,L,dim) applies the transformation along
+%   dimension dim.
+%   
+%   The transform is real (output is real if input is real) and
+%   it is orthonormal.
+%
+%   This transform is its own inverse.
+%
+%   Let f be a signal of length L, let c=dcti(f) and define the vector
+%   w of length L by  
+%
+%      w = [1/sqrt(2) 1 1 1 1 ...1/sqrt(2)]
+%
+%   Then 
+%
+%                              L-1
+%     c(n+1) = sqrt(2/(L-1)) * sum w(n+1)*w(m+1)*f(m+1)*cos(pi*n*m/(L-1)) 
+%                              m=0 
+%
+%   The implementation of this functions uses a simple algorithm that require
+%   an FFT of length 2L-2, which might potentially be the product of a large
+%   prime number. This may cause the function to sometimes execute slowly.
+%   If guaranteed high speed is a concern, please consider using one of the
+%   other DCT transforms.
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DCTI of
+%   length 20:
+%
+%     % The dcti is its own adjoint.
+%     F=dcti(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dcti.php}
+%@seealso{dctii, dctiv, dsti}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DCTI
+  
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DCTI');
+    
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+
+if L==1
+  c=f;
+else
+  c = comp_dct(f,1);
+%   c=zeros(L,W,assert_classname(f));
+%   
+%   f2=[f;flipud(f(2:L-1,:))]/sqrt(2);
+%   f2(1,:)=f2(1,:)*sqrt(2);
+%   f2(L,:)=f2(L,:)*sqrt(2);
+%   
+%   % Do DFT.
+%   s1=fft(f2)/sqrt(2*L-2);
+% 
+%   % This could be done by a repmat instead.
+%   for w=1:W
+%     c(:,w)=s1(1:L,w)+[0;s1(2*L-2:-1:L+1,w);0];
+%   end;
+% 
+%   c(2:L-1,:)=c(2:L-1,:)/sqrt(2);
+%   
+%   if isreal(f)
+%     c=real(c);
+%   end;
+
+end;
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/dctii.m b/inst/fourier/dctii.m
new file mode 100644
index 0000000..772e9e9
--- /dev/null
+++ b/inst/fourier/dctii.m
@@ -0,0 +1,129 @@
+function c=dctii(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dctii
+%@verbatim
+%DCTII  Discrete Consine Transform type II
+%   Usage:  c=dctii(f);
+%           c=dctii(f,L);
+%           c=dctii(f,[],dim);
+%           c=dctii(f,L,dim);
+%
+%   DCTII(f) computes the discrete cosine transform of type II of the
+%   input signal f. If f is multi-dimensional, the transformation is
+%   applied along the first non-singleton dimension.
+%
+%   DCTII(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DCTII(f,[],dim) or DCTII(f,L,dim) applies the transformation along
+%   dimension dim.
+%
+%   The transform is real (output is real if input is real) and orthonormal.
+%
+%   This is the inverse of DCTIII.
+%
+%   Let f be a signal of length L, let c=DCTII(f) and define the
+%   vector w of length L by
+%
+%      w = [1/sqrt(2) 1 1 1 1 ...]
+%
+%   Then 
+%
+%                          L-1
+%     c(n+1) = sqrt(2/L) * sum w(n+1)*f(m+1)*cos(pi*n*(m+.5)/L) 
+%                          m=0 
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DCTII of
+%   length 20:
+%
+%     % The dctiii is the adjoint of dctii.
+%     F=dctiii(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dctii.php}
+%@seealso{dctiii, dctiv, dstii}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DCTII
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DCTII');
+
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+  c=comp_dct(f,2);
+% c=zeros(L,W,assert_classname(f));
+% 
+% m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+% m1(1)=1;
+% 
+% m2=1/sqrt(2)*exp((1:L-1)*pi*i/(2*L)).';
+% 
+% s1=fft([f;flipud(f)]);
+% 
+% % This could be done by a repmat instead.
+% for w=1:W
+%   c(:,w)=s1(1:L,w).*m1+[0;s1(2*L:-1:L+2,w).*m2];
+% end;
+% 
+% c=c/sqrt(L)/2;
+
+if isreal(f)
+  c=real(c);
+end;
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+% This is a slow, but convenient way of expressing the algorithm.
+%R=1/sqrt(2)*[diag(exp((0:L-1)*pi*i/(2*L)));...
+%	     zeros(1,L); ...
+%	     [zeros(L-1,1),flipud(diag(exp(-(1:L-1)*pi*i/(2*L))))]];
+
+%R(1,1)=1;
+
+%c=R'*fft([f;flipud(f)])/sqrt(L)/2;
+
diff --git a/inst/fourier/dctiii.m b/inst/fourier/dctiii.m
new file mode 100644
index 0000000..6dc9196
--- /dev/null
+++ b/inst/fourier/dctiii.m
@@ -0,0 +1,130 @@
+function c=dctiii(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dctiii
+%@verbatim
+%DCTIII  Discrete Consine Transform type III
+%   Usage:  c=dctiii(f);
+%           c=dctiii(f,L);
+%           c=dctiii(f,[],dim);
+%           c=dctiii(f,L,dim);
+%
+%   DCTIII(f) computes the discrete cosine transform of type III of the
+%   input signal f. If f is multi-dimensional, the transformation is
+%   applied along the first non-singleton dimension.
+%
+%   DCTIII(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DCTIII(f,[],dim) or DCTIII(f,L,dim) applies the transformation along
+%   dimension dim.
+%
+%   The transform is real (output is real if input is real) and orthonormal.
+%
+%   This is the inverse of DCTII.
+%
+%   Let f be a signal of length L, let c=DCTIII(f) and define the vector
+%   w of length L by  
+%
+%       w = [1/sqrt(2) 1 1 1 1 ...]
+%
+%   Then 
+%
+%                          L-1
+%     c(n+1) = sqrt(2/L) * sum w(m+1)*f(m+1)*cos(pi*(n+.5)*m/L) 
+%                          m=0 
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DCTIII of
+%   length 20:
+%
+%     % The dctii is the adjoint of dctiii.
+%     F=dctii(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dctiii.php}
+%@seealso{dctii, dctiv, dstii}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DCTIII
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DCTIII');
+
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+c=comp_dct(f,3);
+% c=zeros(2*L,W,assert_classname(f));
+% 
+% m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+% m1(1)=1;
+%   
+% m2=1/sqrt(2)*exp((L-1:-1:1)*pi*i/(2*L)).';
+% 
+% for w=1:W
+%   c(:,w)=[m1.*f(:,w);0;m2.*f(L:-1:2,w)];
+% end;
+% 
+% c=fft(c)/sqrt(L);
+% 
+% c=c(1:L,:);
+% 
+% if isreal(f)
+%   c=real(c);
+% end;
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+% This is a slow, but convenient way of expressing the above algorithm.
+%R=1/sqrt(2)*[diag(exp(-(0:L-1)*pi*i/(2*L)));...
+%	     zeros(1,L); ...
+%	     [zeros(L-1,1),flipud(diag(exp((1:L-1)*pi*i/(2*L))))]];
+
+%R(1,1)=1;
+
+%c=fft(R*f)/sqrt(L);
+
+%c=c(1:L,:);
+
diff --git a/inst/fourier/dctiv.m b/inst/fourier/dctiv.m
new file mode 100644
index 0000000..6e05f83
--- /dev/null
+++ b/inst/fourier/dctiv.m
@@ -0,0 +1,118 @@
+function c=dctiv(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dctiv
+%@verbatim
+%DCTIV  Discrete Consine Transform type IV
+%   Usage:  c=dctiv(f);
+%
+%   DCTIV(f) computes the discrete cosine transform of type IV of the
+%   input signal f. If f is multi-dimensional, the transformation is
+%   applied along the first non-singleton dimension.
+%
+%   DCTIV(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DCTIV(f,[],dim) or DCTIV(f,L,dim) applies the transformation along
+%   dimension dim.
+%
+%   The transform is real (output is real if input is real) and
+%   orthonormal.  It is its own inverse.
+%
+%   Let f be a signal of length L and let c=DCTIV(f). Then
+%
+%                          L-1
+%     c(n+1) = sqrt(2/L) * sum f(m+1)*cos(pi*(n+.5)*(m+.5)/L) 
+%                          m=0 
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DCTIV of
+%   length 20:
+%
+%     % The dctiv is its own adjoint.
+%     F=dctiv(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dctiv.php}
+%@seealso{dctii, dctiii, dstii}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DCTIV
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DCTIV');
+
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+c = comp_dct(f,4);
+% s1=zeros(2*L,W,assert_classname(f));
+% c=zeros(L,W,assert_classname(f));
+% 
+% m1=1/sqrt(2)*exp(-(0:L-1)*pi*i/(2*L)).';
+% m2=1/sqrt(2)*exp((1:L)*pi*i/(2*L)).';
+% 
+% for w=1:W
+%   s1(:,w)=[m1.*f(:,w);flipud(m2).*f(L:-1:1,w)];
+% end;
+%   
+% s1=exp(-pi*i/(4*L))*fft(s1)/sqrt(2*L);
+% 
+% % This could be done by a repmat instead.
+% for w=1:W
+%   c(:,w)=s1(1:L,w).*m1+s1(2*L:-1:L+1,w).*m2;
+% end;
+% 
+% if isreal(f)
+%   c=real(c);
+% end;
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+% This is a slow, but convenient way of expressing the algorithm.
+%R=1/sqrt(2)*[diag(exp(-(0:L-1)*pi*i/(2*L)));...
+%	     flipud(diag(exp((1:L)*pi*i/(2*L))))];
+  
+%c=exp(-pi*i/(4*L))*R.'*fft(R*f)/sqrt(2*L);
+
diff --git a/inst/fourier/dctresample.m b/inst/fourier/dctresample.m
new file mode 100644
index 0000000..a01fc76
--- /dev/null
+++ b/inst/fourier/dctresample.m
@@ -0,0 +1,65 @@
+function f=dctresample(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dctresample
+%@verbatim
+%DCTRESAMPLE   Resample signal using Fourier interpolation
+%   Usage:  h=dctresample(f,L);
+%           h=dctresample(f,L,dim);
+%
+%   DCTRESAMPLE(f,L) returns a discrete cosine interpolation of the signal f*
+%   to length L. If the function is applied to a matrix, it will apply
+%   to each column.
+%
+%   DCTRESAMPLE(f,L,dim) does the same along dimension dim.
+%
+%   If the input signal is not a periodic signal (or close to), this method
+%   will give much better results than FFTRESAMPLE at the endpoints, as
+%   this method assumes than the signal is even a the endpoints.
+%
+%   The algorithm uses a DCT type iii.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dctresample.php}
+%@seealso{fftresample, middlepad, dctiii}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+  
+% ------- Checking of input --------------------
+error(nargchk(2,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DCTRESAMPLE');
+
+wasreal=isreal(f);
+
+% The 'dim=1' below have been added to avoid dct and middlepad being
+% smart about choosing the dimension.
+f=dctiii(postpad(dctii(f,[],1),L))*sqrt(L/Ls);
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
+if wasreal
+  f=real(f);
+end;
+
+
diff --git a/inst/fourier/dfracft.m b/inst/fourier/dfracft.m
new file mode 100644
index 0000000..e126531
--- /dev/null
+++ b/inst/fourier/dfracft.m
@@ -0,0 +1,87 @@
+function frf=dfracft(f,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} dfracft
+%@verbatim
+%DFRACFT  Discrete Fractional Fourier transform
+%   Usage:  V=dfracft(f,a,p);
+%           V=dfracft(f,a);
+%
+%   DFRACFT(f,a) computes the discrete fractional Fourier Transform of the
+%   signal f to the power a. For a=1 it corresponds to the ordinary
+%   discrete Fourier Transform. If f is multi-dimensional, the
+%   transformation is applied along the first non-singleton dimension.
+%
+%   DFRACFT(f,a,dim) does the same along dimension dim.   
+%
+%   DFRACFT(f,a,[],p) or DFRACFT(f,a,dim,p) allows to choose the order
+%   of approximation of the second difference operator (default: p=2*).
+%
+%
+%   References:
+%     A. Bultheel and S. Martinez. Computation of the Fractional Fourier
+%     Transform. Appl. Comput. Harmon. Anal., 16(3):182-202, 2004.
+%     
+%     H. M. Ozaktas, Z. Zalevsky, and M. A. Kutay. The Fractional Fourier
+%     Transform. John Wiley and Sons, 2001.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dfracft.php}
+%@seealso{ffracft, dft, hermbasis, pherm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Christoph Wiesmeyr 
+%   TESTING: TEST_HERMBASIS
+%   REFERENCE: OK
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.p   = 2;
+definput.keyvals.dim = [];
+[flags,keyvals,dim,p]=ltfatarghelper({'dim','p'},definput,varargin);
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,upper(mfilename));
+
+H = hermbasis(L,p);
+
+% set up the eigenvalues
+k=0:L-1;
+lam = exp(-1i*k*a*pi/2);
+lam=lam(:);
+
+% correction for even signal lengths
+if ~rem(L,2)
+    lam(end)=exp(-1i*L*a*pi/2);
+end
+
+% shuffle the eigenvalues in the right order
+even=~mod(L,2);
+cor=2*floor(L/4)+1;
+for k=(cor+1):2:(L-even)
+    lam([k,k+1])=lam([k+1,k]);
+end
+
+frf =H*(bsxfun(@times,lam,H'*f));
+
+frf=assert_sigreshape_post(frf,dim,permutedsize,order);
+
+
+
+
diff --git a/inst/fourier/dft.m b/inst/fourier/dft.m
new file mode 100644
index 0000000..220a8e6
--- /dev/null
+++ b/inst/fourier/dft.m
@@ -0,0 +1,57 @@
+function f=dft(f,N,dim);
+%-*- texinfo -*-
+%@deftypefn {Function} dft
+%@verbatim
+%DFT   Normalized Discrete Fourier Transform
+%   Usage: f=dft(f);
+%          f=dft(f,N,dim);
+%
+%   DFT computes a normalized discrete Fourier transform. This is nothing
+%   but a scaled version of the output from fft. The function takes exactly
+%   the same arguments as fft. See the help on fft for a thorough
+%   description.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dft.php}
+%@seealso{idft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];  
+end;
+
+if nargin<2
+  N=[];
+end;
+
+[f,N,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,N,dim,'DFT');
+
+% Force FFT along dimension 1, since we have permuted the dimensions
+% manually
+f=fft(f,N,1)/sqrt(N);
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/dsti.m b/inst/fourier/dsti.m
new file mode 100644
index 0000000..9847f5c
--- /dev/null
+++ b/inst/fourier/dsti.m
@@ -0,0 +1,111 @@
+function c=dsti(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dsti
+%@verbatim
+%DSTI  Discrete Sine Transform type I
+%   Usage:  c=dsti(f);
+%           c=dsti(f,L);
+%           c=dsti(f,[],dim);
+%           c=dsti(f,L,dim);
+%
+%   DSTI(f) computes the discrete sine transform of type I of the
+%   input signal f. If f is multi-dimensional, the transformation is
+%   applied along the first non-singleton dimension.
+%
+%   DSTI(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DSTI(f,[],dim) or DSTI(f,L,dim) applies the transformation along
+%   dimension dim.
+%
+%   The transform is real (output is real if input is real) and orthonormal.
+%
+%   This transform is its own inverse.
+%
+%   Let f be a signal of length L and let c=DSTI(f). Then 
+%
+%                              L-1
+%     c(n+1) = sqrt(2/(L+1)) * sum sin(pi*(n+1)*(m+1)/(L+1)) 
+%                              m=0 
+%   The implementation of this functions uses a simple algorithm that requires
+%   an FFT of length 2N+2, which might potentially be the product of a large
+%   prime number. This may cause the function to sometimes execute slowly.
+%   If guaranteed high speed is a concern, please consider using one of the
+%   other DST transforms.
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DSTI of
+%   length 20:
+%
+%     % The dsti is its own adjoint.
+%     F=dsti(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dsti.php}
+%@seealso{dcti, dstiii, dstiv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DSTI
+
+  
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DSTI');
+
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+
+if L==1
+  c=f;
+ 
+else
+
+  c = comp_dst(f,1);
+
+end;
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/dstii.m b/inst/fourier/dstii.m
new file mode 100644
index 0000000..dab3aae
--- /dev/null
+++ b/inst/fourier/dstii.m
@@ -0,0 +1,111 @@
+function c=dstii(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dstii
+%@verbatim
+%DSTII  Discrete Sine Transform type II
+%   Usage:  c=dstii(f);
+%           c=dstii(f,L);
+%           c=dstii(f,[],dim);
+%           c=dstii(f,L,dim);
+%
+%   DSTII(f) computes the discrete sine transform of type II of the
+%   input signal f. If f is multi-dimensional, the transformation is
+%   applied along the first non-singleton dimension.
+%
+%   DSTII(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DSTII(f,[],dim) or DSTII(f,L,dim) applies the transformation along
+%   dimension dim.
+%
+%   The transform is real (output is real if input is real) and orthonormal.
+%
+%   The inverse transform of DSTII is DSTIII.
+%
+%   Let f be a signal of length L, let c=DSTII(f) and define the vector
+%   w of length L by
+%
+%      w = [1 1 1 1 ... 1/sqrt(2)]
+%
+%   Then 
+%
+%                          L-1
+%     c(n+1) = sqrt(2/L) * sum w(n+1)*f(m+1)*sin(pi*n*(m+.5)/L) 
+%                          m=0 
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DSTII of
+%   length 20:
+%
+%     % The dstiii is the adjoint of dstii.
+%     F=dstiii(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dstii.php}
+%@seealso{dctii, dstiii, dstiv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DSTII
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+   
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DSTII');
+ 
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+
+c = comp_dst(f,2);
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+% This is a slow, but convenient way of expressing the above algorithm.
+%R=1/sqrt(2)*[zeros(1,L); ...
+%	     diag(exp((1:L)*pi*i/(2*L)));...	     
+%	     [flipud(diag(-exp(-(1:L-1)*pi*i/(2*L)))),zeros(L-1,1)]];
+%R(L+1,L)=i;
+
+%c=i*(R'*fft([f;-flipud(f)])/sqrt(L)/2);
+
+
diff --git a/inst/fourier/dstiii.m b/inst/fourier/dstiii.m
new file mode 100644
index 0000000..d40d351
--- /dev/null
+++ b/inst/fourier/dstiii.m
@@ -0,0 +1,114 @@
+function c=dstiii(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dstiii
+%@verbatim
+%DSTIII  Discrete sine transform type III
+%   Usage:  c=dstiii(f);
+%           c=dstiii(f,L);
+%           c=dstiii(f,[],dim);
+%           c=dstiii(f,L,dim);
+%
+%   DSTIII(f) computes the discrete sine transform of type III of the
+%   input signal f. If f is multi-dimensional, the transformation is
+%   applied along the first non-singleton dimension.
+%
+%   DSTIII(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DSTIII(f,[],dim) or DSTIII(f,L,dim) applies the transformation along
+%   dimension dim.
+%
+%   The transform is real (output is real if input is real) and orthonormal.
+%
+%   This is the inverse of DSTII.
+%
+%   Let f be a signal of length L, let c=DSTIII(f) and define the vector
+%   w of length L by  
+%
+%       w = [1 1 1 1 ... 1/sqrt(2)]
+%
+%   Then 
+%
+%                          L-1
+%     c(n+1) = sqrt(2/L) * sum w(m+1)*f(m+1)*sin(pi*(n+.5)*m/L) 
+%                          m=0 
+%
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DSTIII of
+%   length 20:
+%
+%     % The dstii is the adjoint of dstiii.
+%     F=dstii(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dstiii.php}
+%@seealso{dctii, dstii, dstiv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DSTIII
+
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DSTIII');
+
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+
+c = comp_dst(f,3);
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+% This is a slow, but convenient way of expressing the above algorithm.
+%R=1/sqrt(2)*[zeros(1,L); ...
+%	     diag(exp((1:L)*pi*i/(2*L)));...	     
+%	     [flipud(diag(-exp(-(1:L-1)*pi*i/(2*L)))),zeros(L-1,1)]];
+%R(L+1,L)=i;
+%
+%c2=-sqrt(L)*2*i*ifft(R*f);
+%
+%c=c2(1:L,:);
+
+
diff --git a/inst/fourier/dstiv.m b/inst/fourier/dstiv.m
new file mode 100644
index 0000000..a666ba3
--- /dev/null
+++ b/inst/fourier/dstiv.m
@@ -0,0 +1,104 @@
+function c=dstiv(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} dstiv
+%@verbatim
+%DSTIV  Discrete Sine Transform type IV
+%   Usage:  c=dstiv(f);
+%           c=dstiv(f,L);
+%           c=dstiv(f,[],dim);
+%           c=dstiv(f,L,dim);
+%
+%   DSTIV(f) computes the discrete sine transform of type IV of the input
+%   signal f. If f is a matrix, then the transformation is applied to
+%   each column. For N-D arrays, the transformation is applied to the first
+%   non-singleton dimension.
+%
+%   DSTIV(f,L) zero-pads or truncates f to length L before doing the
+%   transformation.
+%
+%   DSTIV(f,[],dim) applies the transformation along dimension dim. 
+%   DSTIV(f,L,dim) does the same, but pads or truncates to length L.
+%   
+%   The transform is real (output is real if input is real) and
+%   it is orthonormal. It is its own inverse.
+%
+%   Let f be a signal of length L and let c=DSTIV(f). Then
+%
+%                          L-1
+%     c(n+1) = sqrt(2/L) * sum f(m+1)*sin(pi*(n+.5)*(m+.5)/L) 
+%                          m=0 
+%
+%   Examples:
+%   ---------
+%
+%   The following figures show the first 4 basis functions of the DSTIV of
+%   length 20:
+%
+%     % The dstiv is its own adjoint.
+%     F=dstiv(eye(20));
+%
+%     for ii=1:4
+%       subplot(4,1,ii);
+%       stem(F(:,ii));
+%     end;
+%
+%
+%   References:
+%     K. Rao and P. Yip. Discrete Cosine Transform, Algorithms, Advantages,
+%     Applications. Academic Press, 1990.
+%     
+%     M. V. Wickerhauser. Adapted wavelet analysis from theory to software.
+%     Wellesley-Cambridge Press, Wellesley, MA, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/dstiv.php}
+%@seealso{dstii, dstiii, dctii}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PUREFREQ
+%   REFERENCE: REF_DSTIV
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+if nargin<2
+  L=[];
+end;
+    
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DSTIV');
+
+if ~isempty(L)
+  f=postpad(f,L);
+end;
+
+c = comp_dst(f,4);
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+% This is a slow, but convenient way of expressing the algorithm.
+%R=1/sqrt(2)*[diag(exp(-(0:L-1)*pi*i/(2*L)));...
+%	     flipud(diag(-exp((1:L)*pi*i/(2*L))))];
+
+%c=i*(exp(-pi*i/(4*L))*R.'*fft(R*f)/sqrt(2*L));
+
+
diff --git a/inst/fourier/expwave.m b/inst/fourier/expwave.m
new file mode 100644
index 0000000..844f754
--- /dev/null
+++ b/inst/fourier/expwave.m
@@ -0,0 +1,53 @@
+function h=expwave(L,m,cent);
+%-*- texinfo -*-
+%@deftypefn {Function} expwave
+%@verbatim
+%EXPWAVE   Complex exponential wave
+%   Usage:  h=expwave(L,m);
+%           h=expwave(L,m,cent);
+%
+%   EXPWAVE(L,m) returns an exponential wave revolving m times around the
+%   origin. The collection of all waves with wave number m=0,...,L-1
+%   forms the basis of the discrete Fourier transform.
+%
+%   The wave has absolute value 1 everywhere. To get an exponential wave
+%   with unit l^2-norm, divide the wave by sqrt(L). This is the
+%   normalization used in the DFT function.
+%
+%   EXPWAVE(L,m,cent) makes it possible to shift the sampling points by
+%   the amount cent. Default is cent=0.
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/expwave.php}
+%@seealso{dft, pchirp}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+error(nargchk(2,3,nargin));
+
+if nargin==2
+  cent=0;
+end;
+
+h = exp(2*pi*i*((0:L-1)+cent)/L*m).';
+
+
diff --git a/inst/fourier/ffracft.m b/inst/fourier/ffracft.m
new file mode 100644
index 0000000..b494eb8
--- /dev/null
+++ b/inst/fourier/ffracft.m
@@ -0,0 +1,144 @@
+function frf=ffracft(f,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ffracft
+%@verbatim
+%FFRACFT Approximate fast fractional Fourier transform
+%   Usage:  frf=ffracft(f,a)
+%           frf=ffracft(f,a,dim)
+%
+%   FFRACFT(f,a) computes an approximation of the fractional Fourier
+%   transform of the signal f to the power a. If f is
+%   multi-dimensional, the transformation is applied along the first
+%   non-singleton dimension.
+%
+%   FFRACFT(f,a,dim) does the same along dimension dim.   
+%
+%   FFRACFT takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'origin'    Rotate around the origin of the signal. This is the
+%                 same action as the DFT, but the signal will split in
+%                 the middle, which may not be the correct action for
+%                 data signals. This is the default.
+%
+%     'middle'    Rotate around the middle of the signal. This will not
+%                 break the signal in the middle, but the DFT cannot be
+%                 obtained in this way.
+%
+%   Examples:
+%   ---------
+%
+%   The following example shows a rotation of the LTFATLOGO test
+%   signal:
+%
+%      sgram(ffracft(ltfatlogo,.3,'middle'),'lin','nf');
+%
+%
+%   References:
+%     A. Bultheel and S. Martinez. Computation of the Fractional Fourier
+%     Transform. Appl. Comput. Harmon. Anal., 16(3):182-202, 2004.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/ffracft.php}
+%@seealso{dfracft, hermbasis, pherm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Christoph Wiesmeyr
+%   TESTING: ??
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.p      = 2;
+definput.keyvals.dim    = [];
+definput.flags.center = {'origin','middle'};
+[flags,keyvals,dim,p]=ltfatarghelper({'dim','p'},definput,varargin);
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,upper(mfilename));
+
+% correct input
+a=mod(a,4);
+
+if flags.do_middle
+    f=fftshift(f);
+end;
+
+% special cases
+switch(a)
+  case 0
+    frf=f;
+  case 1      
+    frf=fft(f)/sqrt(L);
+  case 2
+    frf=flipud(f);
+  case 3
+    frf=fft(flipud(f));
+  otherwise
+
+    % reduce to interval 0.5 < a < 1.5
+    if (a>2.0), a = a-2; f = flipud(f); end
+    if (a>1.5), a = a-1; f = fft(f)/sqrt(L); end
+    if (a<0.5), a = a+1; f = ifft(f)*sqrt(L); end
+    
+    % general setting
+    alpha = a*pi/2;
+    tana2 = tan(alpha/2);
+    sina = sin(alpha);
+    
+    % oversample and zero pad f (sinc interpolation)
+    
+    m=norm(f);
+    f=ifft(middlepad(fft(f),2*L))*sqrt(2);
+    f=middlepad(f,4*L);
+    
+    % chirp multiplication
+    
+    chrp = fftshift(exp(-i*pi/L*tana2/4*((-2*L):(2*L-1))'.^2));
+    f=f.*chrp;
+    
+    % chirp convolution
+    
+    c = pi/L/sina/4;
+    chrp2=fftshift(exp(i*c*((-2*L):(2*L-1))'.^2));
+    frf=(pconv(middlepad(chrp2,8*L),middlepad(f,8*L)));
+    frf(2*L+1:6*L)=[];
+    
+    % chirp multiplication
+    
+    frf=frf.*chrp;
+    
+    % normalize and downsample
+    frf(L+1:3*L)=[];
+    ind=ceil(L/2);
+    ft=fft(frf);
+    ft(ind+1:ind+L)=[];
+    frf=ifft(ft);
+    frf = exp(-i*(1-a)*pi/4)*frf;
+    frf=normalize(frf)*m;
+    
+end;
+
+if flags.do_middle
+    frf=ifftshift(frf);
+end;
+
+frf=assert_sigreshape_post(frf,dim,permutedsize,order);
+
diff --git a/inst/fourier/fftindex.m b/inst/fourier/fftindex.m
new file mode 100644
index 0000000..b72856d
--- /dev/null
+++ b/inst/fourier/fftindex.m
@@ -0,0 +1,55 @@
+function n=fftindex(N,nyquestzero)
+%-*- texinfo -*-
+%@deftypefn {Function} fftindex
+%@verbatim
+%FFTINDEX  Frequency index of FFT modulations
+%   Usage: n=fftindex(N);
+%
+%   FFTINDEX(N) returns the index of the frequencies of the standard FFT of
+%   length N as the are ordered in the output from the fft routine. The
+%   numbers returned are in the range -ceil(N/2)+1:floor(N/2)
+%
+%   FFTINDEX(N,0) does as above, but sets the Nyquist frequency to zero.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/fftindex.php}
+%@seealso{dft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+  
+error(nargchk(1,2,nargin));
+
+if nargin ==1
+  if rem(N,2)==0
+    n=[0:N/2,-N/2+1:-1].';
+  else
+    n=[0:(N-1)/2,-(N-1)/2:-1].';
+  end;
+else
+  if rem(N,2)==0
+    n=[0:N/2-1,0,-N/2+1:-1].';
+  else
+    n=[0:(N-1)/2,-(N-1)/2:-1].';
+  end;  
+end;
+
diff --git a/inst/fourier/fftreal.m b/inst/fourier/fftreal.m
new file mode 100644
index 0000000..b2029df
--- /dev/null
+++ b/inst/fourier/fftreal.m
@@ -0,0 +1,66 @@
+function f=fftreal(f,N,dim);
+%-*- texinfo -*-
+%@deftypefn {Function} fftreal
+%@verbatim
+%FFTREAL   FFT for real valued input data
+%   Usage: f=fftreal(f);
+%          f=fftreal(f,N,dim);
+%
+%   FFTREAL(f) computes the coefficients corresponding to the positive
+%   frequencies of the FFT of the real valued input signal f.
+%   
+%   The function takes exactly the same arguments as fft. See the help on
+%   fft for a thorough description.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/fftreal.php}
+%@seealso{ifftreal, dft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR    : Peter L. Soendergaard
+%   TESTING   : TEST_PUREFREQ
+%   REFERENCE : OK
+  
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];  
+end;
+
+if nargin<2
+  N=[];
+end;
+
+if ~isreal(f)
+  error('Input signal must be real.');
+end;
+
+
+[f,N,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,N,dim,'FFTREAL');
+
+N2=floor(N/2)+1;
+
+f=comp_fftreal(f);
+
+% Set the new size in the first dimension.
+permutedsize(1)=N2;
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/fftresample.m b/inst/fourier/fftresample.m
new file mode 100644
index 0000000..622f292
--- /dev/null
+++ b/inst/fourier/fftresample.m
@@ -0,0 +1,63 @@
+function f=fftresample(f,L,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} fftresample
+%@verbatim
+%FFTRESAMPLE   Resample signal using Fourier interpolation
+%   Usage:  h=fftresample(f,L);
+%           h=fftresample(f,L,dim);
+%
+%   FFTRESAMPLE(f,L) returns a Fourier interpolation of the signal f*
+%   to length L. If the function is applied to a matrix, it will apply
+%   to each column.  
+%
+%   FFTRESAMPLE(f,L,dim) does the same along dimension dim.
+%
+%   If the input signal is *not* a periodic signal (or close to), the
+%   DCTRESAMPLE method gives much better results at the endpoints.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/fftresample.php}
+%@seealso{dctresample, middlepad}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+  
+% ------- Checking of input --------------------
+error(nargchk(2,3,nargin));
+
+if nargin<3
+  dim=[];
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'FFTRESAMPLE');
+
+wasreal=isreal(f);
+
+% The 'dim=1' below have been added to avoid fft and middlepad being
+% smart about choosing the dimension.
+if isreal(f)
+  L2=floor(L/2)+1;
+  f=ifftreal(postpad(fftreal(f,[],1),L2,1),L,1)/Ls*L;;
+else
+  f=ifft(middlepad(fft(f,[],1),L,1))/Ls*L;
+end;
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/fir2long.m b/inst/fourier/fir2long.m
new file mode 100644
index 0000000..e85a378
--- /dev/null
+++ b/inst/fourier/fir2long.m
@@ -0,0 +1,64 @@
+function gout=fir2long(gin,Llong);
+%-*- texinfo -*-
+%@deftypefn {Function} fir2long
+%@verbatim
+%FIR2LONG   Extend FIR window to LONG
+%   Usage:  g=fir2long(g,Llong);
+%
+%   FIR2LONG(g,Llong) will extend the FIR window g to a length Llong*
+%   window by inserting zeros. Note that this is a slightly different
+%   behaviour than MIDDLEPAD.
+%
+%   FIR2LONG can also be used to extend a FIR window to a longer FIR
+%   window, for instance in order to satisfy the usual requirement that the
+%   window length should be divisible by the number of channels.
+%
+%   If the input to FIR2LONG is a cell, FIR2LONG will recurse into
+%   the cell array.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/fir2long.php}
+%@seealso{long2fir, middlepad}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(2,2,nargin));
+
+if iscell(gin)
+    gout=cellfun(@(x) fir2long(x,Llong),gin,'UniformOutput',false);    
+else
+    
+    Lfir=length(gin);
+    
+    if Lfir>Llong
+        error('Llong must be larger than length of window.');
+    end;
+    
+    if rem(Lfir,2)==0
+        % HPE middlepad works the same way as the FIR extension (e.g. just
+        % inserting zeros) for even-length signals.
+        gout=middlepad(gin,Llong,'hp');
+    else
+        % WPE middlepad works the same way as the FIR extension (e.g. just
+        % inserting zeros) for odd-length signals.
+        gout=middlepad(gin,Llong);
+    end;
+    
+end;
+
+
diff --git a/inst/fourier/firfilter.m b/inst/fourier/firfilter.m
new file mode 100644
index 0000000..1532ee6
--- /dev/null
+++ b/inst/fourier/firfilter.m
@@ -0,0 +1,117 @@
+function gout=firfilter(name,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} firfilter
+%@verbatim
+%FIRFILTER  Construct an FIR filter
+%   Usage:  g=firfilter(name,M);
+%           g=firfilter(name,M,...);
+%
+%   FIRFILTER(name,M) creates an FIR filter of length M. This is
+%   exactly the same as calling FIRWIN. The name must be one of the
+%   accepted window types of FIRWIN.
+%
+%   FIRFILTER(name,M,fc) constructs a filter with a centre
+%   frequency of fc measured in normalized frequencies.
+%
+%   If one of the inputs is a vector, the output will be a cell array
+%   with one entry in the cell array for each element in the vector. If
+%   more input are vectors, they must have the same size and shape and the
+%   the filters will be generated by stepping through the vectors. This
+%   is a quick way to create filters for FILTERBANK and UFILTERBANK.
+%
+%   FIRFILTER accepts the following optional parameters:
+%
+%     'fs',fs     If the sampling frequency fs is specified then the length
+%                 M is specified in seconds and the centre frequency
+%                 fc in Hz.
+%
+%     'complex'   Make the filter complex valued if the centre frequency
+%                 is non-zero. This is the default.
+%
+%     'real'      Make the filter real-valued if the centre frequency
+%                 is non-zero.
+%
+%     'delay',d   Set the delay of the filter. Default value is zero.
+%
+%     'causal'    Create a causal filter starting at the first sample. If
+%                 specified, this flag overwrites the delay setting.
+%
+%   It is possible to normalize the impulse response of the filter by
+%   passing any of the flags from the NORMALIZE function. The default
+%   normalization is 'energy'.
+%
+%   The filter can be used in the PFILT routine to filter a signal, or
+%   in can be placed in a cell-array for use with FILTERBANK or UFILTERBANK.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/firfilter.php}
+%@seealso{blfilter, firwin, pfilt, filterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% XXX Implement passing additional parameters to firwin
+
+% Define initial value for flags and key/value pairs.
+definput.import={'normalize'};
+definput.importdefaults={'energy'};
+definput.keyvals.delay=0;
+definput.keyvals.fc=0;
+definput.keyvals.fs=[];
+definput.flags.delay={'delay','causal'};
+definput.flags.real={'complex','real'};
+
+[flags,kv]=ltfatarghelper({'fc'},definput,varargin);
+
+[M,kv.fc,kv.delay]=scalardistribute(M,kv.fc,kv.delay);
+
+if ~isempty(kv.fs)
+    M=round(M*kv.fs);
+    kv.fc=kv.fc/kv.fs*2;
+end;
+
+Nfilt=numel(M);
+gout=cell(1,Nfilt);
+for ii=1:Nfilt
+    g=struct();
+    
+    if flags.do_causal
+        g.offset=0;
+        smallshift=0;
+    else
+        d=floor(kv.delay);
+        smallshift=d-floor(d);
+        g.offset=d-floor(M/2);
+    end;
+
+    g.h=fftshift(firwin(name,M(ii),'shift',smallshift(ii),flags.norm));
+    g.fc=kv.fc(ii);
+    g.realonly=flags.do_real;
+    g.fs=kv.fs;
+        
+    gout{ii}=g;
+end;
+if Nfilt==1
+    gout=g;
+end;
+
+
+
+
+
+
+
diff --git a/inst/fourier/firkaiser.m b/inst/fourier/firkaiser.m
new file mode 100644
index 0000000..58003c4
--- /dev/null
+++ b/inst/fourier/firkaiser.m
@@ -0,0 +1,147 @@
+function g=firkaiser(L,beta,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} firkaiser
+%@verbatim
+%FIRKAISER  Kaiser-Bessel window
+%   Usage:  g=firkaiser(L,beta);
+%           g=firkaiser(L,beta,...);
+%
+%   FIRKAISER(L,beta) computes the Kaiser-Bessel window of length L with
+%   parameter beta. The smallest element of the window is set to zero when
+%   the window has an even length. This gives the window perfect whole-point
+%   even symmetry, and makes it possible to use the window for a Wilson
+%   basis.
+%
+%   FIRKAISER takes the following flags at the end of the input arguments:
+%
+%     'normal'   Normal Kaiser-Bessel window. This is the default.
+%
+%     'derived'  Derived Kaiser-Bessel window.
+%
+%     'wp'       Generate a whole point even window. This is the default.
+%
+%     'hp'       Generate half point even window.
+%  
+%   Additionally, FIRKAISER accepts flags to normalize the output. Please
+%   see the help of NORMALIZE. Default is to use 'peak' normalization.
+%
+%
+%   References:
+%     A. V. Oppenheim and R. W. Schafer. Discrete-time signal processing.
+%     Prentice Hall, Englewood Cliffs, NJ, 1989.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/firkaiser.php}
+%@seealso{firwin, normalize}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('Too few input arguments.');
+end;
+
+if numel(beta)>1
+  error('beta must be a scalar.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.import={'normalize'};
+definput.importdefaults={'null'};
+definput.flags.centering={'wp','hp'};
+definput.flags.stype={'normal','derived'};
+
+[flags,keyvals]=ltfatarghelper({},definput,varargin);
+
+cent=0;
+if flags.do_hp
+  cent=.5;
+end;
+
+if flags.do_normal
+  
+  if (L == 1)
+    g = 1;
+  else
+    m = L - 1;
+    k = (0:L-1)'+rem(L,2)/2-.5+cent;
+    k = 2*beta/(L-1)*sqrt(k.*(L-1-k));
+    g = besseli(0,k)/besseli(0,beta);
+  end;
+
+  g=ifftshift(g);
+  
+  if ((flags.do_wp && rem(L,2)==0) || ...
+      (flags.do_hp && rem(L,2)==1))
+    
+    % Explicitly zero last element. This is done to get the right
+    % symmetry, and because that element sometimes turn negative.
+    g(floor(L/2)+1)=0;
+  end;
+  
+else
+  
+  if rem(L,2)==1    
+    error('The length of the choosen window must be even.');
+  end;
+  
+  if flags.do_wp 
+    if rem(L,4)==0
+      L2=L/2+2;
+    else
+      L2=L/2+1;
+    end;
+  else
+    L2=floor((L+1)/2);
+  end;
+  
+  % Compute a normal Kaiser window
+  g_normal=fftshift(firkaiser(L2,beta,flags.centering));
+  
+  g1=sqrt(cumsum(g_normal(1:L2))./sum(g_normal(1:L2)));
+  
+  if flags.do_wp 
+    if rem(L,2)==0
+      g=[flipud(g1);...
+         g1(2:L/2)];
+    else
+      g=[flipud(g1);...
+         g1(1:floor(L/2))];
+    end;    
+  else
+    g=[flipud(g1);...
+       g1];
+  end;
+
+    if ((flags.do_wp && rem(L,2)==0) || ...
+      (flags.do_hp && rem(L,2)==1))
+    
+    % Explicitly zero last element. This is done to get the right
+    % symmetry, and because that element sometimes turn negative.
+    g(floor(L/2)+1)=0;
+  end;
+
+  
+end;
+
+% The besseli computation sometimes generates a zero imaginary component.
+g=real(g);
+
+g=normalize(g,flags.norm);
+
+
diff --git a/inst/fourier/firwin.m b/inst/fourier/firwin.m
new file mode 100644
index 0000000..69e0384
--- /dev/null
+++ b/inst/fourier/firwin.m
@@ -0,0 +1,384 @@
+function [g,info]=firwin(name,M,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} firwin
+%@verbatim
+%FIRWIN  FIR window
+%   Usage:  g=firwin(name,M);
+%           g=firwin(name,M,...);
+%           g=firwin(name,x);
+%           
+%   FIRWIN(name,M) will return an FIR window of length M of type name.
+%
+%   All windows are symmetric and generate zero delay and zero phase
+%   filters. They can be used for the Wilson and WMDCT transform, except
+%   when noted otherwise.
+%
+%   FIRWIN(name,x) where x is a vector will sample the window
+%   definition as the specified points. The normal sampling interval for
+%   the windows is -.5< x <.5.
+%
+%   In the following PSL means "Peak Sidelobe level", and the main lobe
+%   width is measured in normalized frequencies.
+%
+%   If a window g forms a "partition of unity" (PU) it means specifically
+%   that:
+%
+%     g+fftshift(g)==ones(L,1);
+%
+%   A PU can only be formed if the window length is even, but some windows
+%   may work for odd lengths anyway.
+%
+%   If a window is the square root of a window that forms a PU, the window
+%   will generate a tight Gabor frame / orthonormal Wilson/WMDCT basis if
+%   the number of channels is less than M.
+%
+%   The windows available are:
+%
+%     'hann'       von Hann window. Forms a PU. The Hann window has a
+%                  mainlobe with of 8/M, a PSL of -31.5 dB and decay rate
+%                  of 18 dB/Octave.
+%
+%     'sine'       Sine window. This is the square root of the Hanning
+%                  window. The sine window has a mainlobe width of 8/M,
+%                  a  PSL of -22.3 dB and decay rate of 12 dB/Octave.
+%                  Aliases: 'cosine', 'sqrthann'
+%
+%     'rect'       (Almost) rectangular window. The rectangular window has a
+%                  mainlobe width of 4/M, a  PSL of -13.3 dB and decay
+%                  rate of 6 dB/Octave. Forms a PU. Alias: 'square'
+%
+%     'sqrtrect'   Square root of the rectangular window.
+%
+%     'tria'       (Almost) triangular window. Forms a PU. Alias: 'bartlett'
+%
+%     'sqrttria'   Square root of the triangular window.
+%
+%     'hamming'    Hamming window. Forms a PU that sums to 1.08 instead
+%                  of 1.0 as usual. The Hamming window has a
+%                  mainlobe width of 8/M, a  PSL of -42.7 dB and decay
+%                  rate of 6 dB/Octave. This window should not be used for
+%                  a Wilson basis, as a reconstruction window cannot be
+%                  found by WILDUAL.
+%
+%     'blackman'   Blackman window. The Blackman window has a
+%                  mainlobe width of 12/M, a PSL of -58.1 dB and decay
+%                  rate of 18 dB/Octave.
+%
+%     'blackman2'  Alternate Blackman window. This window has a
+%                  mainlobe width of 12/M, a PSL of -68.24 dB and decay
+%                  rate of 6 dB/Octave.
+%
+%     'itersine'   Iterated sine window. Generates an orthonormal
+%                  Wilson/WMDCT basis. This window is described in 
+%                  Wesfreid and Wickerhauser (1993) and is used in  the
+%                  ogg sound codec. Alias: 'ogg'
+%
+%     'nuttall'    Nuttall window. The Nuttall window has a
+%                  mainlobe width of 16/M, a PSL of -93.32 dB and decay
+%                  rate of 18 dB/Octave.
+%
+%     'nuttall10'  2-term Nuttall window with 1 continuous derivative. 
+%                  Alias: 'hann', 'hanning'.
+%
+%     'nuttall01'  2-term Nuttall window with 0 continuous derivatives. 
+%                  This is a slightly improved Hamming window. It has a
+%                  mainlobe width of 8/M, a  PSL of -43.19 dB and decay
+%                  rate of 6 dB/Octave.
+%
+%     'nuttall20'  3-term Nuttall window with 3 continuous derivatives. 
+%                  The window has a mainlobe width of 12/M, a PSL of 
+%                  -46.74 dB and decay rate of 30 dB/Octave.
+%
+%     'nuttall11'  3-term Nuttall window with 1 continuous derivative. 
+%                  The window has a mainlobe width of 12/M, a PSL of 
+%                  -64.19 dB and decay rate of 18 dB/Octave.
+%
+%     'nuttall02'  3-term Nuttall window with 0 continuous derivatives. 
+%                  The window has a mainlobe width of 12/M, a PSL of 
+%                  -71.48 dB and decay rate of 6 dB/Octave.
+%
+%     'nuttall30'  4-term Nuttall window with 5 continuous derivatives. 
+%                  The window has a mainlobe width of 16/M, a PSL of 
+%                  -60.95 dB and decay rate of 42 dB/Octave.
+%
+%     'nuttall21'  4-term Nuttall window with 3 continuous derivatives. 
+%                  The window has a mainlobe width of 16/M, a PSL of 
+%                  -82.60 dB and decay rate of 30 dB/Octave.
+%
+%     'nuttall12'  4-term Nuttall window with 1 continuous derivatives. 
+%                  Alias: 'nuttall'.
+%
+%     'nuttall03'  4-term Nuttall window with 0 continuous derivatives. 
+%                  The window has a mainlobe width of 16/M, a PSL of 
+%                  -98.17 dB and decay rate of 6 dB/Octave.
+%
+%   FIRWIN understands the following flags at the end of the list of input
+%   parameters:
+%
+%     'shift',s    Shift the window by s samples. The value can be a
+%                  fractional number.
+%
+%     'wp'         Output is whole point even. This is the default. It
+%                  corresponds to a shift of s=0.
+%
+%     'hp'         Output is half point even, as most Matlab filter
+%                  routines. This corresponds to a shift of s=-.5
+%                   
+%
+%     'taper',t    Extend the window by a flat section in the middle. The
+%                  argument t is the ratio of the rising and falling
+%                  parts as compared to the total length of the
+%                  window. The default value of 1 means no
+%                  tapering. Accepted values lie in the range from 0 to 1.
+%
+%   Additionally, FIRWIN accepts flags to normalize the output. Please see
+%   the help of NORMALIZE. Default is to use 'peak' normalization,
+%   which is useful for using the output from FIRWIN for windowing in the
+%   time-domain. For filtering in the time-domain, a normalization of '1'
+%   or 'area' is preferable.
+%
+%   Examples:
+%   ---------
+%
+%   The following plot shows the magnitude response for some common
+%   windows:
+%
+%     hold all; 
+%     L=30;
+%     dr=110;
+%
+%     magresp(firwin('hanning',L,'1'),'fir','dynrange',dr);
+%     magresp(firwin('hamming',L,'1'),'fir','dynrange',dr);
+%     magresp(firwin('blackman',L,'1'),'fir','dynrange',dr);
+%     magresp(firwin('nuttall',L,'1'),'fir','dynrange',dr);
+%     magresp(firwin('itersine',L,'1'),'fir','dynrange',dr);
+%
+%     legend('Hann','Hamming','Blackman','Nuttall','Itersine');
+%
+%
+%   References:
+%     A. V. Oppenheim and R. W. Schafer. Discrete-time signal processing.
+%     Prentice Hall, Englewood Cliffs, NJ, 1989.
+%     
+%     A. Nuttall. Some windows with very good sidelobe behavior. IEEE Trans.
+%     Acoust. Speech Signal Process., 29(1):84-91, 1981.
+%     
+%     F. Harris. On the use of windows for harmonic analysis with the
+%     discrete Fourier transform. Proceedings of the IEEE, 66(1):51 - 83, jan
+%     1978.
+%     
+%     E. Wesfreid and M. Wickerhauser. Adapted local trigonometric transforms
+%     and speech processing. IEEE Trans. Signal Process., 41(12):3596-3600,
+%     1993.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/firwin.php}
+%@seealso{pgauss, pbspline, firkaiser, normalize}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+%   AUTHORS : Peter L. Soendergaard, Nicki Holighaus.
+%   REFERENCE: NA
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~ischar(name)
+  error('%s: First input argument must the name of a window.',upper(mfilename));
+end;
+  
+
+% Always set to this
+info.isfir=1;
+
+% Default values, may be overwritten later in the code
+info.ispu=0;
+info.issqpu=0;
+
+name=lower(name);
+
+% Define initial value for flags and key/value pairs.
+definput.import={'normalize'};
+definput.importdefaults={'null'};
+definput.flags.centering={'wp','hp','shift'};
+definput.keyvals.shift=0;
+
+definput.keyvals.taper=1;
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_wp
+  kv.shift=0;
+end;
+
+if flags.do_hp
+  kv.shift=0.5;
+end;
+
+if M==0
+  g=[];
+  return;
+end;
+
+if numel(M)==1
+    
+    % Deal with tapering
+    if kv.taper<1
+        if kv.taper==0
+            % Window is only tapering, do this and bail out, because subsequent
+            % code may fail.
+            g=ones(M,1);
+            return;
+        end;
+        
+        % Modify M to fit with tapering
+        Morig=M;
+        M=round(M*kv.taper);
+        Mtaper=Morig-M;
+        
+        p1=round(Mtaper/2);
+        p2=Mtaper-p1;
+        
+        % Switch centering if necessary
+        if flags.do_wp && p1~=p2
+            kv.shift=.5;
+        end;
+        
+        if flags.do_hp && p1~=p2
+            kv.shift=1;
+        end;
+        
+    end;
+    
+    % This is the normally used sampling vector.
+    
+    if mod(M,2) == 0 % For even M the sampling interval is [-.5,.5-1/M]
+        x = [0:1/M:.5-1/M,-.5:1/M:-1/M]';
+    else % For odd M the sampling interval is [-.5+1/(2M),.5-1/(2M)]
+        x = [0:1/M:.5-.5/M,-.5+.5/M:1/M:-1/M]';
+    end
+    
+    x = x+kv.shift/M;
+    
+else
+    % Use sampling vector specified by the user
+    x=M;
+end;
+
+
+do_sqrt=0;
+switch name    
+ case {'hanning','hann','nuttall10'}
+  g=(0.5+0.5*cos(2*pi*x));
+  info.ispu=1;
+  
+ case {'sine','cosine','sqrthann'}
+  g=firwin('hanning',M,varargin{:});
+  info.issqpu=1;
+  do_sqrt=1;
+  
+ case 'hamming'
+  g=0.54+0.46*cos(2*pi*(x));
+
+  % This is the definition taken from the Harris paper
+  %case 'hammingacc'
+  %g=25/46+21/46*cos(2*pi*(x));
+
+ case 'nuttall01'
+  g=0.53836+0.46164*cos(2*pi*(x));
+
+ case {'square','rect'} 
+  g=double(abs(x) < .5);
+  
+ case {'halfsquare','halfrect'} 
+  g=double(abs(x) < .25);
+  g(abs(x) == .25) = .5;
+  info.ispu=1;
+  
+ case {'sqrthalfsquare','sqrthalfrect'}
+  g=firwin('halfsquare',M,varargin{:});
+  info.issqpu=1;
+  do_sqrt=1;
+  
+ case {'tria','triangular','bartlett'}
+  g=1-2*abs(x);
+  info.ispu=1;
+  
+ case {'sqrttria'}
+  g=firwin('tria',M,flags.centering);
+  info.issqpu=1;
+  do_sqrt=1;
+
+  % Rounded version of blackman2
+ case {'blackman'}
+  g=0.42+0.5*cos(2*pi*(x))+0.08*cos(4*pi*(x));
+
+ case {'blackman2'}
+  g=7938/18608+9240/18608*cos(2*pi*(x))+1430/18608*cos(4*pi*(x));
+
+ case {'nuttall','nuttall12'}
+  g = 0.355768+0.487396*cos(2*pi*(x))+0.144232*cos(4*pi*(x)) ...
+      +0.012604*cos(6*pi*(x));
+  
+ case {'itersine','ogg'}
+  g=sin(pi/2*cos(pi*x).^2);
+  info.issqpu=1;
+  
+ case {'nuttall20'}
+  g=3/8+4/8*cos(2*pi*(x))+1/8*cos(4*pi*(x));
+
+ case {'nuttall11'}
+  g=0.40897+0.5*cos(2*pi*(x))+0.09103*cos(4*pi*(x));
+  
+ case {'nuttall02'}
+   g=0.4243801+0.4973406*cos(2*pi*(x))+0.0782793*cos(4*pi*(x));
+   
+ case {'nuttall30'}
+  g = 10/32+15/32*cos(2*pi*(x))+6/32*cos(4*pi*(x))+1/32*cos(6*pi*(x));
+  
+ case {'nuttall21'}
+  g = 0.338946+0.481973*cos(2*pi*(x))+0.161054*cos(4*pi*(x)) ... 
+      +0.018027*cos(6*pi*(x));
+
+ case {'nuttall03'}
+  g=0.3635819+0.4891775*cos(2*pi*(x))+0.1365995*cos(4*pi*(x)) ...
+      +0.0106411*cos(6*pi*(x));
+  
+ otherwise
+  error('Unknown window: %s.',name);
+end;
+
+% Force the window to 0 outside (-.5,.5)
+g = g.*(abs(x) < .5);    
+
+if numel(M) == 1 && kv.taper<1
+
+    % Perform the actual tapering.
+    g=[ones(p1,1);g;ones(p2,1)];  
+    
+end;   
+
+% Do sqrt if needed. 
+if do_sqrt
+  g=sqrt(g);
+end;
+
+g=normalize(g,flags.norm);
+
+
diff --git a/inst/fourier/floor23.m b/inst/fourier/floor23.m
new file mode 100644
index 0000000..184c535
--- /dev/null
+++ b/inst/fourier/floor23.m
@@ -0,0 +1,118 @@
+function [nfft,tableout]=floor23(n)
+%-*- texinfo -*-
+%@deftypefn {Function} floor23
+%@verbatim
+%FLOOR23  Previous number with only 2,3 factors
+%   Usage: nceil=floor23(n);
+%
+%   FLOOR23(n) returns the first number less than or equal to n,
+%   which can be written as a product of powers of 2 and 3.
+%
+%   The algorithm will look up the best size in a table, which is computed
+%   the first time the function is run. If the input size is larger than the
+%   largest value in the table, the input size will be reduced by factors of
+%   2, until it is in range.
+%
+%   [nceil,table]=FLOOR23(n) additionally returns the table used for lookup.
+%
+%   Examples:
+%   ---------
+%
+%   Return the first number smaller or equal to 26 that can be written
+%   solely as products of powers of 2 and 3*:
+% 
+%     floor23(26)
+%
+%   This plot shows the behaviour of FLOOR23 and CEIL23 for numbers
+%   up to 100:
+%
+%     x=1:100;
+%     plot(x,floor23(x),x,ceil23(x));
+%     legend('floor23','ceil23','Location','Northwest');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/floor23.php}
+%@seealso{ceil23, floor235, nextfastfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+  
+  
+persistent table;
+  
+maxval=2^20;
+
+if isempty(table)
+    % Compute the table for the first time, it is empty.
+    l2=log(2);
+    l3=log(3);
+    l5=log(5);
+    lmaxval=log(maxval);
+    table=zeros(143,1);
+    ii=1;
+    prod2=1;
+    for i2=0:floor(lmaxval/l2)
+        prod3=prod2;
+        for i3=0:floor((lmaxval-i2*l2)/l3)               
+            table(ii)=prod3; 
+            prod3=prod3*3;
+            ii=ii+1;
+        end;
+        prod2=prod2*2;            
+    end;
+    table=sort(table);
+end;
+
+% Copy input to output. This allows us to efficiently work in-place.
+nfft=n;
+
+% Handle input of any shape by Fortran indexing.
+for ii=1:numel(n)
+  n2reduce=0;
+  
+  if n(ii)>maxval
+    % Reduce by factors of 2 to get below maxval
+    n2reduce=ceil(log2(nfft(ii)/maxval));
+    nfft(ii)=nfft(ii)/2^n2reduce;
+  end;
+  
+  % Use a simple bisection method to find the answer in the table.
+  from=1;
+  to=numel(table);
+  while from<=to
+    mid = round((from + to)/2);    
+    diff = table(mid)-nfft(ii);
+    if diff<0
+      from=mid+1;
+    else
+      to=mid-1;                       
+    end
+  end
+  if nfft(ii)~=table(from)
+      nfft(ii)=table(from-1);
+  end;
+  
+  % Add back the missing factors of 2 (if any)
+  nfft(ii)=nfft(ii)*2^n2reduce;
+  
+end;
+
+tableout=table;
+
+
diff --git a/inst/fourier/floor235.m b/inst/fourier/floor235.m
new file mode 100644
index 0000000..830913a
--- /dev/null
+++ b/inst/fourier/floor235.m
@@ -0,0 +1,121 @@
+function [nfft,tableout]=floor235(n)
+%-*- texinfo -*-
+%@deftypefn {Function} floor235
+%@verbatim
+%FLOOR235  Previous number with only 2,3 and 5 factors
+%   Usage: nfloor=floor235(n);
+%
+%   FLOOR235(n)  returns the next number greater than or equal to n,
+%   which can be written as a product of powers of 2, 3 and 5.
+%
+%   The algorithm will look up the best size in a table, which is computed
+%   the first time the function is run. If the input size is larger than the
+%   largest value in the table, the input size will be reduced by factors of
+%   2, until it is in range.
+%
+%   [nfloor,table]=FLOOR235(n) additionally returns the table used for lookup.
+%
+%   Examples:
+%   ---------
+%
+%   Return the first number smaller or equal to 26 that can be written
+%   solely as products of powers of 2, 3 and 5*:
+% 
+%     floor235(26)
+%
+%   This plot shows the behaviour of FLOOR235 and CEIL235 for numbers
+%   up to 100:
+%
+%     x=1:100;
+%     plot(x,floor235(x),x,ceil235(x));
+%     legend('floor235','ceil235','Location','Northwest');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/floor235.php}
+%@seealso{floor23, ceil235, nextfastfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard
+    
+persistent table;
+  
+maxval=2^20;
+
+if isempty(table)
+    % Compute the table for the first time, it is empty.
+    l2=log(2);
+    l3=log(3);
+    l5=log(5);
+    lmaxval=log(maxval);
+    table=zeros(511,1);
+    ii=1;
+    prod2=1;
+    for i2=0:floor(lmaxval/l2)
+        prod3=prod2;
+        for i3=0:floor((lmaxval-i2*l2)/l3)               
+            prod5=prod3;
+            for i5=0:floor((lmaxval-i2*l2-i3*l3)/l5)
+                table(ii)=prod5; 
+                prod5=prod5*5;
+                ii=ii+1;
+            end;
+            prod3=prod3*3;
+        end;
+        prod2=prod2*2;            
+    end;
+    table=sort(table);
+end;
+
+% Copy input to output. This allows us to efficiently work in-place.
+nfft=n;
+
+% Handle input of any shape by Fortran indexing.
+for ii=1:numel(n)
+  n2reduce=0;
+  
+  if n(ii)>maxval
+    % Reduce by factors of 2 to get below maxval
+    n2reduce=ceil(log2(nfft(ii)/maxval));
+    nfft(ii)=nfft(ii)/2^n2reduce;
+  end;
+  
+  % Use a simple bisection method to find the answer in the table.
+  from=1;
+  to=numel(table);
+  while from<=to
+    mid = round((from + to)/2);    
+    diff = table(mid)-nfft(ii);
+    if diff<0
+      from=mid+1;
+    else
+      to=mid-1;                       
+    end
+  end
+  if nfft(ii)~=table(from)
+      nfft(ii)=table(from-1);
+  end;
+  
+  % Add back the missing factors of 2 (if any)
+  nfft(ii)=nfft(ii)*2^n2reduce;
+  
+end;
+
+tableout=table;
+
+
diff --git a/inst/fourier/fourierinit.m b/inst/fourier/fourierinit.m
new file mode 100644
index 0000000..ee4551b
--- /dev/null
+++ b/inst/fourier/fourierinit.m
@@ -0,0 +1,27 @@
+status=1;
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} fourierinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/fourierinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/fourier/gga.m b/inst/fourier/gga.m
new file mode 100644
index 0000000..20d9bf5
--- /dev/null
+++ b/inst/fourier/gga.m
@@ -0,0 +1,145 @@
+function c = gga(f,fvec,fs,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} gga
+%@verbatim
+%GGA Generalized Goertzel algorithm
+%   Usage:  c = gga(x,fvec)
+%           c = gga(x,fvec,fs)
+%
+%   Input parameters:
+%         x      : Input data.
+%         fvec   : Indices to calculate. 
+%         fs     : Sampling frequency.
+%
+%   Output parameters:
+%         c      : Coefficient vector.
+%
+%   c=GGA(f,fvec) computes the discrete-time fourier transform DTFT of
+%   f at frequencies in fvec as c(k)=F(2pi f_{vec}(k)) where
+%   F=DTFT(f), k=1,dots K and K=length(fvec) using the generalized
+%   second-order Goertzel algorithm. Thanks to the generalization, values
+%   in fvec can be arbitrary numbers in range 0-1 and not restricted to
+%   l/Ls, l=0,dots Ls-1 (usual DFT samples) as the original Goertzel 
+%   algorithm is. Ls is the length of the first non-singleton dimension
+%   of f. If fvec is empty or ommited, fvec is assumed to be
+%   (0:Ls-1)/Ls and results in the same output as fft.
+%
+%   c=GGA(f,fvec,fs) computes the same with fvec in Hz relative to fs.
+%
+%   The input f is processed along the first non-singleton dimension or
+%   along dimension dim if specified.
+%
+%   *Remark:**
+%   Besides the generalization the algorithm is also shortened by one
+%   iteration compared to the conventional Goertzel.
+%
+%   Examples:
+%   ---------
+%   
+%   Calculating DTFT samples of interest:
+% 
+%     % Generate input signal
+%     fs = 8000;
+%     L = 2^10;
+%     k = (0:L-1).';
+%     freq = [400,510,620,680,825];
+%     phase = [pi/4,-pi/4,-pi/8,pi/4,-pi/3];
+%     amp = [5,3,4,1,2];
+%     f = arrayfun(@(a,f,p) a*sin(2*pi*k*f/fs+p),...
+%                  amp,freq,phase,'UniformOutput',0);
+%     f = sum(cell2mat(f),2);
+% 
+%     % This is equal to fft(f)
+%     ck = gga(f);
+% 
+%     %GGA to FFT error:
+%     norm(ck-fft(f))
+% 
+%     % DTFT samples at 400,510,620,680,825 Hz
+%     ckchzt = gga(f,freq,fs);
+% 
+%     % Plot modulus of coefficients
+%     figure(1);
+%     hold on;
+%     stem(k/L*fs,abs(ck),'k');
+%     stem(freq,abs(ckchzt),'r:');
+%     set(gca,'XLim',[freq(1)-50,freq(end)+50]);
+%     set(gca,'YLim',[0 3*L]);
+%     xlabel('f[Hz]');
+%     ylabel('|ck|');
+% 
+%     % Plot phase of coefficients
+%     figure(2);
+%     hold on;
+%     stem(k/L*fs,angle(ck),'k');
+%     stem(freq,angle(ckchzt),'r:');
+%     set(gca,'XLim',[freq(1)-50,freq(end)+50]);
+%     set(gca,'YLim',[-pi pi]);
+%     xlabel('f[Hz]');
+%     ylabel('angle(ck)');
+%
+%
+%   References:
+%     P. Sysel and P. Rajmic. Goertzel algorithm generalized to non-integer
+%     multiples of fundamental frequency. EURASIP Journal on Advances in
+%     Signal Processing, 2012(1):56, 2012.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/gga.php}
+%@seealso{chirpzt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+       
+% The original copyright goes to
+% 2013 Pavel Rajmic, Brno University of Technology, Czech Rep.
+
+
+%% Check the input arguments
+if nargin < 1
+    error('%s: Not enough input arguments.',upper(mfilename))
+end
+
+if isempty(f)
+    error('%s: X must be a nonempty vector or a matrix.',upper(mfilename))
+end
+
+if nargin<4
+  dim=[];  
+end;
+
+if nargin<3 || isempty(fs)
+  fs=1;  
+end;
+
+[f,~,Ls,~,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,'GGA');
+
+if nargin > 1 && ~isempty(fvec)
+   if ~isreal(fvec) || ~isvector(fvec)
+      error('%s: INDVEC must be a real vector.',upper(mfilename))
+   end
+else
+   fvec = (0:Ls-1)/Ls;
+end
+
+c = comp_gga(f,fvec/fs*Ls);
+
+permutedsize(1)=numel(fvec);
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/hermbasis.m b/inst/fourier/hermbasis.m
new file mode 100644
index 0000000..e4dd647
--- /dev/null
+++ b/inst/fourier/hermbasis.m
@@ -0,0 +1,162 @@
+function [V,D]=hermbasis(L,p)
+%-*- texinfo -*-
+%@deftypefn {Function} hermbasis
+%@verbatim
+%HERMBASIS  Orthonormal basis of discrete Hermite functions
+%   Usage:  V=hermbasis(L,p);
+%           V=hermbasis(L);
+%           [V,D]=hermbasis(...);
+%
+%   HERMBASIS(L,p) computes an orthonormal basis of discrete Hermite
+%   functions of length L. The vectors are returned as columns in the
+%   output. p is the order of approximation used to construct the
+%   position and difference operator.
+%
+%   All the vectors in the output are eigenvectors of the discrete Fourier
+%   transform, and resemble samplings of the continuous Hermite functions
+%   to some degree (for low orders).
+%
+%   [V,D]=HERMBASIS(...) also returns the eigenvalues D of the Discrete
+%   Fourier Transform corresponding to the Hermite functions.
+%
+%   Examples:
+%   ---------
+%
+%   The following plot shows the spectrograms of 4 Hermite functions of
+%   length 200 with order 1, 10, 100, and 190:
+%
+%     H=hermbasis(200);
+%   
+%     subplot(2,2,1);
+%     sgram(H(:,1),'nf','tc','lin','nocolorbar'); axis('square');
+%
+%     subplot(2,2,2);
+%     sgram(H(:,10),'nf','tc','lin','nocolorbar'); axis('square');
+%    
+%     subplot(2,2,3);
+%     sgram(H(:,100),'nf','tc','lin','nocolorbar'); axis('square');
+%    
+%     subplot(2,2,4);
+%     sgram(H(:,190),'nf','tc','lin','nocolorbar'); axis('square');
+%
+%
+%   References:
+%     A. Bultheel and S. Martinez. Computation of the Fractional Fourier
+%     Transform. Appl. Comput. Harmon. Anal., 16(3):182-202, 2004.
+%     
+%     H. M. Ozaktas, Z. Zalevsky, and M. A. Kutay. The Fractional Fourier
+%     Transform. John Wiley and Sons, 2001.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/hermbasis.php}
+%@seealso{dft, pherm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Christoph Wiesmeyr, A. Bultheel 
+%   TESTING: TEST_HERMBASIS
+ 
+if nargin==1
+    p=2;
+end
+
+% compute vector with values for side diagonals
+
+d2 = [1 -2 1]; 
+d_p = 1; 
+s = 0; 
+st = zeros(1,L);
+for k = 1:p/2,
+    d_p = conv(d2,d_p);
+    st([L-k+1:L,1:k+1]) = d_p; st(1) = 0;
+    temp = [1:k;1:k]; temp = temp(:)'./[1:2*k];
+    s = s + (-1)^(k-1)*prod(temp)*2/k^2*st;       
+end;
+
+% build discrete Hamiltonian
+
+P2=toeplitz(s);
+X2=diag(real(fft(s)));
+H =P2+X2; 
+
+% Construct transformation matrix V (even and odd vectors)
+
+r = floor(L/2);
+even = ~rem(L,2);
+T1 = (eye(L-1) + flipud(eye(L-1))) / sqrt(2);
+T1(L-r:end,L-r:end) = -T1(L-r:end,L-r:end);
+if (even), T1(r,r) = 1; end
+T = eye(L); T(2:L,2:L) = T1;
+
+% Compute eigenvectors of two banded matrices
+
+THT = T*H*T';
+E = zeros(L);
+Ev = THT(1:r+1,1:r+1);
+[ve,ee] = eig(Ev);
+Od = THT(r+2:L,r+2:L);
+[vo,eo] = eig(Od); 
+%
+% malab eig returns sorted eigenvalues
+% if different routine gives unsorted eigvals, then sort first
+%
+% [d,inde] = sort(diag(ee));      [d,indo] = sort(diag(eo));
+% ve = ve(:,inde');               vo = vo(:,indo');
+%
+
+V(1:r+1,1:r+1) = fliplr(ve);
+V(r+2:L,r+2:L) = fliplr(vo);
+V = T*V;
+
+% shuffle eigenvectors
+
+ind = [1:r+1;r+2:2*r+2]; 
+ind = ind(:);
+if (even)
+    ind([L,L+2]) = [];
+else 
+    ind(L+1) = []; 
+end
+
+cor=2*floor(L/4)+1;
+for k=(cor+1):2:(L-even)
+    ind([k,k+1])=ind([k+1,k]);
+end
+
+V = V(:,ind');
+
+if nargout>1
+    % set up the eigenvalues
+    k=0:L-1;
+    D = exp(-1i*k*pi/2);
+    D=D(:);
+    
+    % correction for even signal lengths
+    if ~rem(L,2)
+        D(end)=exp(-1i*L*pi/2);
+    end
+
+    % shuffle the eigenvalues in the right order
+    even=~mod(L,2);
+    cor=2*floor(L/4)+1;
+    for k=(cor+1):2:(L-even)
+        D([k,k+1])=D([k+1,k]);
+    end
+
+end;
+
diff --git a/inst/fourier/idft.m b/inst/fourier/idft.m
new file mode 100644
index 0000000..48f1cdb
--- /dev/null
+++ b/inst/fourier/idft.m
@@ -0,0 +1,57 @@
+function f=idft(f,N,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} idft
+%@verbatim
+%IDFT  Inverse DFT
+%   Usage: f=idft(f);
+%          f=idft(f,N,dim);
+%
+%   This function computes a normalized inverse discrete Fourier transform.
+%   This is nothing but a scaled version of the output from ifft. The
+%   function takes exactly the same arguments as ifft. See the help on ifft
+%   for a thorough description.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/idft.php}
+%@seealso{dft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+error(nargchk(1,3,nargin));
+
+if nargin<3
+  dim=[];  
+end;
+
+if nargin<2
+  N=[];
+end;
+
+[f,N,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,N,dim,'IDFT');
+
+% Force IFFT along dimension 1, since we have permuted the dimensions
+% manually
+f=ifft(f,N,1)*sqrt(N);
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/ifftreal.m b/inst/fourier/ifftreal.m
new file mode 100644
index 0000000..26df0e2
--- /dev/null
+++ b/inst/fourier/ifftreal.m
@@ -0,0 +1,58 @@
+function f=ifftreal(c,N,dim);
+%-*- texinfo -*-
+%@deftypefn {Function} ifftreal
+%@verbatim
+%IFFTREAL  Inverse FFT for real valued signals
+%   Usage: f=ifftreal(c,N);
+%          f=ifftreal(c,N,dim);
+%
+%   IFFTREAL(c,N) computes an inverse FFT of the positive frequency
+%   Fourier coefficients c. The length N must always be specified,
+%   because the correct transform length cannot be determined from the
+%   size of c.
+%
+%   IFFTREAL(c,N,dim) does the same along dimension dim.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/ifftreal.php}
+%@seealso{fftreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+error(nargchk(2,3,nargin));
+
+if nargin==2
+  dim=[];  
+end;
+
+N2=floor(N/2)+1;
+
+[c,N2,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(c,N2,dim,'IFFTREAL');
+
+% Clean for safety
+c(1,:)=real(c(1,:));
+
+f=comp_ifftreal(c,N);
+
+% Restore the full size in the first dimension.
+permutedsize(1)=N;
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
diff --git a/inst/fourier/involute.m b/inst/fourier/involute.m
new file mode 100644
index 0000000..fe50a4a
--- /dev/null
+++ b/inst/fourier/involute.m
@@ -0,0 +1,76 @@
+function f=involute(f,dim);
+%-*- texinfo -*-
+%@deftypefn {Function} involute
+%@verbatim
+%INVOLUTE  Involution 
+%   Usage: finv=involute(f);
+%          finv=involute(f,dim);
+%
+%   INVOLUTE(f) will return the involution of f.
+%
+%   INVOLUTE(f,dim) will return the involution of f along dimension dim.
+%   This can for instance be used to calculate the 2D involution:
+%
+%     f=involute(f,1);
+%     f=involute(f,2);
+%
+%   The involution finv of f is given by:
+%
+%     finv(l+1)=conj(f(mod(-l,L)+1));
+%
+%   for l=0,...,L-1.
+%
+%   The relation between conjugation, Fourier transformation and involution
+%   is expressed by:
+%
+%     conj(dft(f)) == dft(involute(f))
+%
+%   for all signals f. The inverse discrete Fourier transform can be
+%   expressed by:
+%
+%     idft(f) == conj(involute(dft(f)));
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/involute.php}
+%@seealso{dft, pconv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Assert correct input.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_INVOLUTE
+%   REFERENCE: OK
+
+error(nargchk(1,2,nargin));
+
+if nargin==1
+  dim=[];
+end;
+
+L=[];
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'INVOLUTE');
+
+% This is where the calculation is performed.
+% The reshape(...,size(f) ensures that f will keep its
+% original shape if it is multidimensional.
+f=reshape(conj([f(1,:); ...
+	  flipud(f(2:L,:))]),size(f));
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
diff --git a/inst/fourier/isevenfunction.m b/inst/fourier/isevenfunction.m
new file mode 100644
index 0000000..90fa5e8
--- /dev/null
+++ b/inst/fourier/isevenfunction.m
@@ -0,0 +1,85 @@
+function t=isevenfunction(f,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} isevenfunction
+%@verbatim
+%ISEVENFUNCTION  True if function is even
+%   Usage:  t=isevenfunction(f);
+%           t=isevenfunction(f,tol);
+%
+%   ISEVENFUNCTION(f) returns 1 if f is whole point even. Otherwise it
+%   returns 0.
+%
+%   ISEVENFUNCTION(f,tol) does the same, using the tolerance tol to measure
+%   how large the error between the two parts of the vector can be. Default
+%   is 1e-10.
+%
+%   Adding the flag 'hp' as the last argument does the same for half point
+%   even functions.
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/isevenfunction.php}
+%@seealso{middlepad, peven}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+if nargin<1
+  error('Too few input parameters.');
+end;
+
+if size(f,2)>1
+  if size(f,1)>1
+    error('f must be a vector');
+  else
+    % f was a row vector.
+    f=f(:);
+  end;
+end;
+
+% Define initial values for flags
+definput.flags.centering = {'wp','hp'};
+definput.keyvals.tol     = 1e-10; 
+
+[flags,keyvals,tol]=ltfatarghelper({'tol'},definput,varargin);
+
+L=size(f,1);
+
+if flags.do_wp
+  % Determine middle point of sequence.
+  if rem(L,2)==0
+    middle=L/2;
+  else
+    middle=(L+1)/2;
+  end;
+  
+  % Relative norm of difference between the parts of the signal.
+  d=norm(f(2:middle)-conj(flipud(f(L-middle+2:L))))/norm(f);
+else
+  
+  middle=floor(L/2);
+  
+  d=norm(f(1:middle)-conj(flipud(f(L-middle+1:L))))/norm(f);
+
+end;
+
+% Return true if d less than tolerance.
+t=d<=tol;
+
diff --git a/inst/fourier/long2fir.m b/inst/fourier/long2fir.m
new file mode 100644
index 0000000..ab7000c
--- /dev/null
+++ b/inst/fourier/long2fir.m
@@ -0,0 +1,91 @@
+function g=long2fir(g,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} long2fir
+%@verbatim
+%LONG2FIR   Cut LONG window to FIR
+%   Usage:  g=long2fir(g,L);
+%
+%   LONG2FIR(g,L) will cut the LONG window g to a length L FIR window by
+%   cutting out the middle part. Note that this is a slightly different
+%   behaviour than MIDDLEPAD.
+%
+%   LONG2FIR(g,L,'wp') or LONG2FIR(g,L,'hp') does the same assuming the
+%   input window is a whole-point even or half-point even window,
+%   respectively.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/long2fir.php}
+%@seealso{fir2long, middlepad}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.flags.centering = {'unsymmetric','wp','hp'};
+definput.keyvals.L      = [];
+definput.keyvals.cutrel = [];
+
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+W=length(g);
+
+if W<L
+  error('L must be smaller than length of window.');
+end;
+
+if ~isempty(kv.cutrel)
+  maxval=max(abs(g));
+  mask=abs(g)>maxval*kv.cutrel;
+  L=W-2*min(abs(find(mask)-L/2));
+end;
+
+if isempty(L)
+    error(['%s: You must specify a way to shorten the window, either by ' ...
+           'specifying the length or through a flag.'],upper(mfilename));
+end;
+
+if flags.do_unsymmetric
+  % No assumption on the symmetry of the window.
+
+  if rem(L,2)==0
+    % HPE middlepad works the same way as the FIR cutting (e.g. just
+    % removing middle points) for even values of L.
+    g=middlepad(g,L,'hp');
+  else
+    % WPE middlepad works the same way as the FIR cutting (e.g. just
+    % removing middle points) for odd values of L.
+    g=middlepad(g,L);
+  end;
+  
+else
+  if flags.do_wp
+    g=middlepad(g,L);
+    if rem(L,2)==0
+      g(L/2+1)=0;
+    end;
+  else
+    g=middlepad(g,L,'hp');
+    if rem(L,2)==1
+      g(ceil(L/2))=0;
+    end;
+  end;
+end;
+
+
diff --git a/inst/fourier/magresp.m b/inst/fourier/magresp.m
new file mode 100644
index 0000000..ee348fc
--- /dev/null
+++ b/inst/fourier/magresp.m
@@ -0,0 +1,195 @@
+function magresp(g,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} magresp
+%@verbatim
+%MAGRESP   Magnitude response plot of window
+%   Usage:   magresp(g,...);
+%            magresp(g,fs,...);
+%            magresp(g,fs,dynrange,....);
+%
+%   MAGRESP(g) will display the magnitude response of the window on a log
+%   scale (dB);
+%
+%   MAGRESP(g,fs) does the same for windows that are intended to be used
+%   with signals with sampling rate fs. The x-axis will display Hz.
+%
+%   MAGRESP(g,fs,dynrange) will limit the dynamic range (see below).
+%   
+%   MAGRESP takes the following parameters at the end of the line of
+%   input arguments.
+%
+%     'dynrange',r  Limit the dynamic range of the plot to r dB.
+%
+%     'fir'         Indicate that the input is an FIR window. MAGRESP will
+%                   zero-extend the window to display a smooth magnitude
+%                   response.
+%
+%     'L',L         Zero-extend the window to length L.
+%
+%     'posfreq'     Show only positive frequencies.
+%
+%     'nf'          Show also negative frequencies
+%
+%     'autoposfreq'  Show positive frequencies for real-valued signals,
+%                    otherwise show also the negative frequencies. This is
+%                    the default.
+%
+%     'opts',op     Pass options onto the plot command. The extra options
+%                   op are specified as a cell array
+%
+%   In addition to these flags, it is possible to speficy any of the
+%   normalization flags from NORMALIZE to normalize the input before
+%   calculation of the magnitude response. Specifying '1' or 'area' will
+%   display a magnitude response which peaks at 0 dB.
+%
+%   Examples:
+%   ---------
+%
+%   The following will display the magnitude response of a Hann window
+%   of length 20 normalized to a peak of 0 dB:
+%
+%     magresp({'hann',20},'1');
+%
+%   The following will display the magnitude response of a Gaussian window
+%   of length 100:
+%
+%     magresp('gauss','L',100)
+%
+%   The following passes additional options to the plot command to draw
+%   in red:
+%
+%     magresp({'nuttall11',30},'opts',{'r'});
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/magresp.php}
+%@seealso{demo_gabfir}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+if nargin<1
+  error('Too few input arguments.');
+end;
+
+L=[];
+fs=[];
+donf=0;
+
+% Define initial value for flags and key/value pairs.
+
+definput.flags.posfreq={'autoposfreq','posfreq','nf'};
+
+definput.import={'normalize'};
+definput.importdefaults={'null'};
+definput.keyvals.fs=[];
+definput.keyvals.opts={};
+definput.keyvals.L=[];
+definput.flags.wintype={'notype','fir','long'};
+definput.keyvals.dynrange=[];
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+[g,info] = comp_fourierwindow(g,kv.L,'MAGRESP');
+
+do_real=flags.do_posfreq;
+if flags.do_autoposfreq
+  do_real=info.wasreal;
+end;
+
+if flags.do_fir
+  info.isfir=1;
+end;
+
+if isempty(kv.L) 
+  if info.isfir
+    % Choose a strange length, such that we don't accidentically hit all
+    % the zeros in the response.
+    kv.L=info.gl*13+47;
+  else
+      if isempty(info.gl)
+          % Default value
+          kv.L=4177;
+      else          
+          kv.L=info.gl;
+      end;
+  end;
+end;
+
+if (isstruct(g)) && isfield(g,'fs') && (~isempty(g.fs)) && (isempty(fs))
+    fs=g.fs;
+end;
+
+g=pfilt([1;zeros(kv.L-1,1)],g);
+
+g=normalize(g,flags.norm);
+if do_real
+
+  % Compute spectrum and normalize
+  FF=abs(fftreal(real(g)));
+    
+  % Convert to dB. Add eps to avoid log of zero.
+  FF=20*log10(FF+realmin);
+
+  xmin=0;
+
+else
+
+  % Compute spectrum and normalize. fftshift to center correctly for plotting.
+  FF=fftshift(abs(fft(g)));
+  
+  % Convert to dB. Add eps to avoid log of zero.
+  FF=20*log10(FF+realmin);
+
+  xmin=-1;
+end;
+
+ymax=max(FF);
+if ~isempty(kv.dynrange)
+  ymin=ymax-kv.dynrange;
+else
+  ymin=min(FF);
+end;
+
+Lplot=length(FF);
+
+% Only plot positive frequencies for real-valued signals.
+if isempty(fs)
+  xrange=linspace(xmin,1,Lplot).';
+  axisvec=[xmin 1 ymin ymax];
+else
+  xrange=linspace(xmin*floor(fs/2),floor(fs/2),Lplot).';
+  axisvec=[xmin*fs/2 fs/2 ymin ymax];
+end;
+
+plot(xrange,FF,kv.opts{:});
+set(gca,'yscale','linear');
+axis(axisvec);
+ylabel('Magnitude response (dB)');
+
+if isempty(fs)
+  xlabel('Frequency (normalized) ');
+else
+  xlabel('Frequency (Hz)');
+end;
+
+legend('off');
+
+
diff --git a/inst/fourier/middlepad.m b/inst/fourier/middlepad.m
new file mode 100644
index 0000000..f2541f4
--- /dev/null
+++ b/inst/fourier/middlepad.m
@@ -0,0 +1,189 @@
+function f=middlepad(f,L,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} middlepad
+%@verbatim
+%MIDDLEPAD  Symmetrically zero-extends or cuts a function
+%   Usage:  h=middlepad(f,L);
+%           h=middlepad(f,L,dim);
+%           h=middlepad(f,L,...);
+%
+%   MIDDLEPAD(f,L) cuts or zero-extends f to length L by inserting
+%   zeros in the middle of the vector, or by cutting in the middle
+%   of the vector.
+%
+%   If f is whole-point even, MIDDLEPAD(f,L) will also be whole-point
+%   even.
+%
+%   MIDDLEPAD(f,L,dim) does the same along dimension dim.
+%   
+%   If f has even length, then f will not be purely zero-extended, but
+%   the last element will be repeated once and multiplied by 1/2.
+%   That is, the support of f will increase by one!
+%
+%   Adding the flag 'wp' as the last argument will cut or extend whole point
+%   even functions.  Adding 'hp' will do the same for half point even
+%   functions.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/middlepad.php}
+%@seealso{isevenfunction, fir2long, fftresample}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+
+if nargin<2  
+  error('Too few input parameters.');
+end;
+
+if  (numel(L)~=1 || ~isnumeric(L))
+  error('L must be a scalar');
+end;
+
+if rem(L,1)~=0
+    error('L must be an integer.');
+end;
+
+if L<1
+  error('L must be larger than 0.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.flags.centering = {'wp','hp'};
+definput.keyvals.dim     = [];
+
+[flags,keyvals,dim]=ltfatarghelper({'dim'},definput,varargin);
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'MIDDLEPAD');
+
+Lorig=Ls;
+
+% Skip the main section if there is nothing to do. This is necessary
+% because some of the code below cannot handle the case of 'nothing to do'
+if L~=Ls
+  if flags.do_wp
+    
+    % ---------------   WPE case --------------------------------------
+    
+    if Lorig==1
+      % Rather trivial case
+      f=[f(1,:);zeros(L-1,W,assert_classname(f))];
+      
+    else
+      if Lorig>L
+        % Cut
+        
+        if mod(L,2)==0
+          
+          % L even. Use average of endpoints.
+          f=[f(1:L/2,:);(f(L/2+1,:)+f(Lorig-L/2+1,:))/2;f(Lorig-L/2+2:Lorig,:)];
+          
+        else
+          
+          % No problem, just cut.
+          f=[f(1:(L+1)/2,:);f(Lorig-(L-1)/2+1:Lorig,:)];
+          
+        end;     
+        
+      else
+        
+        d=L-Lorig;
+        
+        % Extend
+        if mod(Lorig,2)==0
+          
+          % Lorig even. We must split a value.
+          
+          f=[f(1:Lorig/2,:);...
+             f(Lorig/2+1,:)/2;...
+             zeros(d-1,W,assert_classname(f));...
+             f(Lorig/2+1,:)/2;...
+             f(Lorig/2+2:Lorig,:)];
+          
+        else
+          % Lorig is odd, we can just insert zeros.
+          f=[f(1:(Lorig+1)/2,:);zeros(d,W,assert_classname(f));f((Lorig+3)/2:Lorig,:)];
+          
+        end;
+        
+      end;
+    end;
+    
+  else
+    
+    % ------------------ HPE case ------------------------------------
+    
+    if Lorig==1
+      
+    else
+      if Lorig>L
+        
+        d=Lorig-L;
+        % Cut
+        
+        if mod(L,2)==0
+          % L even
+          
+          % No problem, just cut.
+          f=[f(1:L/2,:);...
+             f(Lorig-L/2+1:Lorig,:);];
+          
+        else
+          
+          % Average of endpoints.
+          f=[f(1:(L-1)/2,:);(f((L+1)/2,:)+f(Lorig-(L-1)/2,:))/2;...
+             f(Lorig-(L-1)/2+1:Lorig,:);];
+          
+        end;
+        
+      else
+        
+        d=L-Lorig;
+        
+        % Extend
+        if mod(Lorig,2)==0
+          
+          % Lorig even. We can just insert zeros in the middle.
+          
+          f=[f(1:Lorig/2,:);...
+             zeros(d,W,assert_classname(f));...
+             f(Lorig/2+1:Lorig,:)];
+          
+        else
+          % Lorig odd. We need to split a value in two
+          f=[f(1:(Lorig-1)/2,:);...
+             f((Lorig+1)/2,:)/2;...
+             zeros(d-1,W,assert_classname(f));...
+             f((Lorig+1)/2,:)/2;...
+             f((Lorig-1)/2+2:Lorig,:)];
+          
+        end;
+        
+      end;
+      
+    end;
+  end;
+  
+end;
+
+f=assert_sigreshape_post(f,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/modcent.m b/inst/fourier/modcent.m
new file mode 100644
index 0000000..1602bdb
--- /dev/null
+++ b/inst/fourier/modcent.m
@@ -0,0 +1,37 @@
+function x=modcent(x,r);
+%-*- texinfo -*-
+%@deftypefn {Function} modcent
+%@verbatim
+%MODCENT  Centered modulo
+%   Usage:  y=modcent(x,r);
+%
+%   MODCENT(x,r) computes the modulo of x in the range [-r/2,r/2[.
+%
+%   As an example, to compute the modulo of x in the range [-pi,pi[ use
+%   the call:
+%
+%     y = modcent(x,2*pi);
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/modcent.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+x=mod(x,r);  
+idx=x>r/2;
+x(idx)=x(idx)-r;
+
diff --git a/inst/fourier/nextfastfft.m b/inst/fourier/nextfastfft.m
new file mode 100644
index 0000000..99ef9ca
--- /dev/null
+++ b/inst/fourier/nextfastfft.m
@@ -0,0 +1,130 @@
+function [nfft,tableout]=nextfastfft(n)
+%-*- texinfo -*-
+%@deftypefn {Function} nextfastfft
+%@verbatim
+%NEXTFASTFFT  Next higher number with a fast FFT
+%   Usage: nfft=nextfastfft(n);
+%
+%   NEXTFASTFFT(n) returns the next number greater than or equal to n,
+%   for which the computation of an FFT is fast. Such a number is solely
+%   comprised of small prime-factors of 2, 3, 5 and 7.
+%
+%   NEXTFASTFFT is intended as a replacement of nextpow2, which is often
+%   used for the same purpose. However, a modern FFT implementation (like
+%   FFTW) usually performs well for sizes which are powers or 2,3,5 and 7,
+%   and not only just for powers of 2.
+%
+%   The algorithm will look up the best size in a table, which is computed
+%   the first time the function is run. If the input size is larger than the
+%   largest value in the table, the input size will be reduced by factors of
+%   2, until it is in range.
+%
+%   [n,nfft]=NEXTFASTFFT(n) additionally returns the table used for
+%   lookup.
+%
+%
+%
+%   References:
+%     J. Cooley and J. Tukey. An algorithm for the machine calculation of
+%     complex Fourier series. Math. Comput, 19(90):297-301, 1965.
+%     
+%     M. Frigo and S. G. Johnson. The design and implementation of FFTW3.
+%     Proceedings of the IEEE, 93(2):216-231, 2005. Special issue on "Program
+%     Generation, Optimization, and Platform Adaptation".
+%     
+%     P. L. Soendergaard. LTFAT-note 17: Next fast FFT size. Technical report,
+%     Technical University of Denmark, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/nextfastfft.php}
+%@seealso{ceil23, ceil235, demo_nextfastfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR: Peter L. Soendergaard and Johan Sebastian Rosenkilde Nielsen
+  
+  
+persistent table;
+  
+maxval=2^20;
+
+if isempty(table)
+  % Compute the table for the first time, it is empty.
+  l2=log(2);
+  l3=log(3);
+  l5=log(5);
+  l7=log(7);
+  lmaxval=log(maxval);
+  table=zeros(1286,1);
+  ii=1;
+  prod2=1;
+  for i2=0:floor(lmaxval/l2)
+    prod3=prod2;
+    for i3=0:floor((lmaxval-i2*l2)/l3)               
+      prod5=prod3;
+      for i5=0:floor((lmaxval-i2*l2-i3*l3)/l5)
+        prod7=prod5;
+        for i7=0:floor((lmaxval-i2*l2-i3*l3-i5*l5)/l7)
+          table(ii)=prod7; 
+          prod7=prod7*7;
+          ii=ii+1;
+        end;
+        prod5=prod5*5;                    
+      end;
+      prod3=prod3*3;
+    end;
+    prod2=prod2*2;            
+  end;
+  table=sort(table);
+end;
+
+% Copy input to output. This allows us to efficiently work in-place.
+nfft=n;
+
+% Handle input of any shape by Fortran indexing.
+for ii=1:numel(n)
+  n2reduce=0;
+  
+  if n(ii)>maxval
+    % Reduce by factors of 2 to get below maxval
+    n2reduce=ceil(log2(nfft(ii)/maxval));
+    nfft(ii)=nfft(ii)/2^n2reduce;
+  end;
+  
+  % Use a simple bisection method to find the answer in the table.
+  from=1;
+  to=numel(table);
+  while from<=to
+    mid = round((from + to)/2);    
+    diff = table(mid)-nfft(ii);
+    if diff<0
+      from=mid+1;
+    else
+      to=mid-1;                       
+    end
+  end
+  nfft(ii)=table(from);
+  
+  % Add back the missing factors of 2 (if any)
+  nfft(ii)=nfft(ii)*2^n2reduce;
+  
+end;
+
+tableout=table;
+
+
diff --git a/inst/fourier/pbspline.m b/inst/fourier/pbspline.m
new file mode 100644
index 0000000..912703d
--- /dev/null
+++ b/inst/fourier/pbspline.m
@@ -0,0 +1,490 @@
+function [g,nlen] = pbspline(L,order,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pbspline
+%@verbatim
+%PBSPLINE   Periodized B-spline
+%   Usage:   g=pbspline(L,order,a,...);
+%            [g,nlen]=pbspline(L,order,a,...);
+%
+%   Input parameters:
+%         L      : Length of window.
+%         order  : Order of B-spline.
+%         a      : Time-shift parameter for partition of unity.
+%   Output parameters:
+%         g      : Fractional B-spline.
+%         nlen   : Number of non-zero elements in out.
+%
+%   PBSPLINE(L,order,a) computes a (slightly modified) B-spline of order
+%   order of total length L.
+%
+%   If shifted by the distance a, the returned function will form a
+%   partition of unity. The result is normalized such that the functions sum
+%   to 1/sqrt(a).
+%
+%   PBSPLINE takes the following flags at the end of the input arguments:
+%
+%     'ed'     Even discrete fractional spline. This is the default
+%
+%     'xd'     'flat' discrete fractional spline.
+%
+%     'stard'  'pointy' discrete fractional spline
+%
+%     'ec'     Even fractional spline by sampling.
+%
+%     'xc'     'flat' fractional spline by sampling.
+%
+%     'starc'  'pointy' fractional spline by sampling.
+%
+%     'wp'     Generate whole point centered splines. This is the default.
+%
+%     'hp'     Generate half point centered splines.
+%
+%   The different types are accurately described in the referenced paper.
+%   Generally, the 'd' types of splines are very fast to compute, while
+%   the 'c' types are samplings of the continuous splines. The 'e' types
+%   coincides with the regular B-splines for integer orders. The 'x' types
+%   do not coincide, but generate Gabor frames with favorable frame
+%   bounds. The default type is 'ed' to guarantee fast computation and a
+%   familiar shape of the splines.
+%
+%   [out,nlen]=PBSPLINE(...) will additionally compute the number of
+%   non-zero elements in out.
+%
+%   If nlen = L, the function returned will be a periodization of a
+%   B-spline.
+%
+%   If nlen < L, you can choose to remove the additional zeros by calling
+%   g=middlepad(g,nlen).
+%
+%   Additionally, PBSPLINE accepts flags to normalize the output. Please
+%   see the help of NORMALIZE. Default is to use 'peak' normalization.
+%
+%
+%
+%   References:
+%     P. L. Soendergaard. Symmetric, discrete fractional splines and Gabor
+%     systems. preprint, 2008.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pbspline.php}
+%@seealso{pgauss, firwin, middlepad, normalize, demo_pbspline}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_PBSPLINE
+%   REFERENCE: OK
+
+% FIXME: In some very special cases, a spline that should be compactly
+% supported is not. See this output from test_pbspline
+%   PBSPLINE NLEN ec HPE L: 15 a:  3 o:  3 0.00063001 FAILED
+%   PBSPLINE NLEN starc HPE L: 15 a:  3 o:  3 0.00063001 FAILED
+  
+%  --------- checking of input parameters ---------------
+
+  if nargin<3
+    error('Too few input arguments.');
+  end;
+
+  if prod(size(L))~=1
+    error('L must be a scalar');
+  end;
+  
+  if rem(L,1)~=0
+    error('L must be an integer.')
+  end;
+  
+  if prod(size(L))~=1
+    error('a must be a scalar');
+  end;
+  
+  if rem(a,1)~=0
+    error('a must be an integer.')
+  end;
+  
+  if size(a,1)>1 || size(a,2)>1
+    error('order must be a scalar');
+  end;
+    
+  % Define initial value for flags and key/value pairs.
+  definput.import={'normalize'};
+  definput.importdefaults={'inf'};
+  definput.flags.centering={'wp','hp'};
+  definput.flags.stype={'ed','xd','stard','ec','xc','starc'};
+  
+[flags,keyvals]=ltfatarghelper({},definput,varargin);
+
+
+  
+dodisc=1;
+splinetype=3;
+switch(lower(flags.stype))
+  %case {'+d'}
+  %  dodisc=1;
+  %  splinetype=0;
+  case {'stard'}
+    dodisc=1;
+    splinetype=1;
+  case {'xd'}
+    dodisc=1;
+    splinetype=2;
+  case {'ed'}
+    dodisc=1;
+    splinetype=3;
+  %case {'+c'}
+  %  dodisc=0;
+  %  splinetype=0;
+  case {'starc'}
+    dodisc=0;
+    splinetype=1;
+  case {'xc'}
+    dodisc=0;
+    splinetype=2;
+  case {'ec'}
+    dodisc=0;
+    splinetype=3;
+end;
+
+
+% --------  compute the function --------------
+
+N=L/a;
+
+if dodisc
+
+  if flags.do_wp
+    if order<=-1
+      error('Order must be larger than -1 for this type of spline.');
+    end;
+  else
+    if order<0
+      error('Order must be larger than or equal to zero for this type of spline.');
+    end;  
+  end;
+
+  % -------- compute the discrete fractional splines -----------
+  
+  % Constuct a rectangular function in the odd case,
+  % and a rectangular function with 0.5 in both ends
+  % in the even case. This is always WPE
+  s1=middlepad(ones(a,1),L);
+
+  switch splinetype
+      
+    %case 0
+      % Asymmeteric spline
+      
+      % If a=3,7,11,... then the Nyquist frequency will have a negative
+      % coefficient, and generate a complex spline. 
+	
+    %  if cent==0
+	
+    %	g = real(ifft(fft(s1).^(order+1)));
+	
+    %  else
+    %	s2=middlepad([ones(a,1)],L,'hp');
+    %	g = real(ifft(fft(s1).^order.*fft(s2)));
+	
+    %  end;
+	
+    case 1
+      
+      % Unsers symmetric spline (signed power)
+
+      if flags.do_wp
+	g = real(ifft(abs(fft(s1)).^(order+1)));
+      else
+
+	% Producing the unsigned power spline of order zero is slightly
+	% complicated in this case.
+        s2=middlepad([ones(a,1)],L,'hp');
+	
+	l=(0:L-1).';
+	minv=exp(-pi*i*l/L);
+	m=exp(pi*i*l/L);
+	
+	h1=fft(s2).*minv;
+	h3=[abs(h1(1:floor(L/2)+1));...
+	    -abs(h1(floor(L/2)+2:L))];
+	%h5=real(ifft(h3.*m));
+	
+	gf=abs(fft(s1)).^order.*h3;
+	g = ifft(gf.*m);
+	g=real(g);
+        
+      end;
+    
+    case 2
+
+      % unsigned power spline.
+      
+      if flags.do_wp
+	
+	% We must remove the zero imaginary part from s, otherwise
+	% it will confuse the sign function.
+	s=real(fft(s1));
+	g = real(ifft(sign(s).*abs(s).^(order+1)));
+      else
+	s2=middlepad([ones(a,1)],L,'hp');
+	g = real(ifft(abs(fft(s1)).^order.*fft(s2)));
+      end;
+
+    case 3
+
+      % even spline
+
+      if flags.do_wp
+	g = ifftreal(real(fftreal(s1)).^(order+1),L);
+      else
+	s2=middlepad([ones(a,1)],L,'hp');
+	g=real(ifft(real(fft(s1).^order).*fft(s2)));
+
+      end;
+      
+  end
+
+  % Scale such that the elements will form a partition of unity.
+  g=g./a.^order;
+
+  % Normalize
+  %g=g/sqrt(a);
+
+
+else
+
+  % -------- compute the sampled and periodized continuous splines -------
+
+  if order<0
+    error('Order must be larger than or equal to zero for this type of spline.');
+  end;
+
+  if flags.do_hp
+
+    % Handle all HPE splines by subsampling the WPE spline of double the size
+    % and double a.
+    g=pbspline(2*L,order,2*a,flags.stype);
+    g=sqrt(2)*g(2:2:2*L);
+
+  else
+
+    % Check for order 0
+    if order==0
+      if splinetype==1
+	error('The zero-th order spline of type starc cannot be sampled and periodized.');
+      else
+	% Compute it explicitly.
+	g=middlepad(ones(a,1),L)/sqrt(a);
+	
+      end;
+    else 
+      
+      
+      gf=zeros(L,1);
+      switch splinetype
+	  
+	%case 0
+	  
+	%  % Asymmetric spline
+
+	%  if rem(a,2)==0
+
+	%    wt1=(-1)^(-order-1);
+	%    for m=1:L/2
+	%      z1=myhzeta(order+1,1-m/L);
+	%      z2=myhzeta(order+1,m/L);
+	%      s=sin(pi*m/N)^(order+1);	      
+	%      gf(m+1)=(sin(pi*m/N)/(pi*a)).^(order+1)*(wt1*z1+z2);
+	%    end;    
+	%  else
+	    
+	%    wt1=(-1)^(-order-1);
+	%    wt2=(-1)^(order+1);
+	%    for m=1:L/2
+	      
+	%      z1=wt1*myhzeta(order+1, 1 - m/(2*L));
+	%      z2=    myhzeta(order+1,     m/(2*L));
+	%      z3=    myhzeta(order+1,.5 - m/(2*L));
+	%      z4=wt2*myhzeta(order+1,.5 + m/(2*L));
+	%      gf(m+1)=(sin(pi*m/N)/(2*pi*a)).^(order+1)*(z1+z2+z3+z4);
+	%    end;
+	%  end;
+	  
+	case 1
+	  % Unsers symmetric spline (unsigned power)
+	  for m=1:L/2
+	    gf(m+1)=(abs(sin(pi*m/N)/(pi*a))).^(order+1)*(myhzeta(order+1,1-m/L)+myhzeta(order+1,m/L));	    
+	  end;    
+	
+	case 2      
+	  % Signed power spline
+
+	  if rem(a,2)==0
+	    for m=1:L/2
+	      gf(m+1)=(sin(pi*m/N)*abs(sin(pi*m/N)).^order)*(-myhzeta(order+1,1-m/L)+myhzeta(order+1,m/L));	    
+	    end;    
+	    % Scale
+	    gf=gf/((pi*a).^(order+1));
+	  
+	  else
+	    for m=1:L/2	      
+	      z1=-myhzeta(order+1,1-m/(2*L));
+	      z2=myhzeta(order+1,m/(2*L));
+	      z3=myhzeta(order+1,.5-m/(2*L));
+	      z4=-myhzeta(order+1,.5+m/(2*L));	      	      
+	      gf(m+1)=(sin(pi*m/N)*abs(sin(pi*m/N)).^order)*(z1+z2+z3+z4);	    
+	    end;   
+	    % Scale
+	    gf=gf/((2*pi*a).^(order+1));
+	  
+	  end;
+          
+	case 3
+
+	  % Real part spline.
+	  if rem(a,2)==0
+  
+	    wt1=(-1)^(-order-1);
+
+	    for m=1:L/2
+
+	      z1=myhzeta(order+1,1-m/L);
+	      z2=myhzeta(order+1,m/L);
+	      s=sin(pi*m/N)^(order+1);	      
+	      gf(m+1)=real((sin(pi*m/N)/(pi*a)).^(order+1)*(wt1*z1+z2));
+	    end;    
+	  else
+
+	  wt1=(-1)^(-order-1);
+	  wt2=(-1)^(order+1);
+	  
+	  for m=1:L/2
+	    	    
+	    z1=wt1*myhzeta(order+1,1-m/(2*L));
+	    z2=myhzeta(order+1,m/(2*L));
+	    z3=myhzeta(order+1,.5-m/(2*L));
+	    z4=wt2*myhzeta(order+1,.5+m/(2*L));
+	    gf(m+1)=real((sin(pi*m/N)/(2*pi*a)).^(order+1)*(z1+z2+z3+z4));
+	    
+	  end;
+          
+	end;
+      end;
+
+      gf(1)=1;
+      
+      % This makes it even by construction!
+      gf(floor(L/2)+2:L)=conj(flipud(gf(2:ceil(L/2))));      
+      g=real(ifft(gf));
+          
+      % Normalize it correctly.
+      g=g*sqrt(a);
+
+    end; % order < 0
+    
+  end;
+
+
+end;
+
+% Calculate the length of the spline
+% If order is a fraction then nlen==L
+if rem(order,1)~=0
+  nlen=L;
+else
+  if flags.do_wp
+
+    if dodisc          
+      if rem(a,2)==0  
+	nlen=a*(order+1)+1;
+      else
+	nlen=(a-1)*(order+1)+1;
+      end;      
+    else      
+      if rem(a,2)==0  
+	nlen=a*(order+1)-1;
+      else
+	nlen=(a-1)*(order+1)+3;
+      end;
+    end;      
+  else
+    aeven=floor(a/2)*2;
+    if dodisc          
+      if rem(a,2)==0  
+	nlen=aeven*(order+1);
+      else
+	nlen=aeven*(order+1)+2;
+      end;      
+    else      
+      if rem(a,2)==0  
+	nlen=aeven*(order+1);
+      else
+	nlen=aeven*(order+1)+2;
+      end;            
+    end;      
+
+    
+  end;     
+
+  if (((splinetype==1) && (rem(order,2)==0)) || ...
+      ((splinetype==2) && (rem(order,2)==1)))
+    % The unsigned/signed power splines generate infinitely
+    % supported splines in these cases
+    nlen=L;
+  end;
+
+end;
+
+
+
+% nlen cannot be larger that L
+nlen=min(L,nlen);
+
+g=normalize(g,flags.norm);
+
+function Z=myhzeta(z,v);
+  
+
+  if isoctave
+    
+    Z=hzeta(z,v);
+    
+  else
+    
+    % Matlab does not have a true zeta function. Instead it calls Maple.
+    % Unfortunately, the zeta function it Matlab does not provide access
+    % to the full functionality of the Maple zeta function, so we need
+    % to call it directly.
+    % The following line assures that numbers are converted at full
+    % precision, and that we avoid a lot of overhead in converting
+    % double -> sym -> char
+
+
+    %expr1 = maple('Zeta',sym(0),sym(z),sym(v));    
+    %Z=double(maple('evalf',expr1));
+
+    out=maplemex(['Zeta(0,',num2str(z,16),',',num2str(v,16),');']);
+    Z=double(sym(out));
+
+    if isempty(Z)
+      error(['Zeta ERROR: ',out]);
+    end;
+
+  end;
+
+
diff --git a/inst/fourier/pchirp.m b/inst/fourier/pchirp.m
new file mode 100644
index 0000000..b7e3a24
--- /dev/null
+++ b/inst/fourier/pchirp.m
@@ -0,0 +1,90 @@
+function g=pchirp(L,n)
+%-*- texinfo -*-
+%@deftypefn {Function} pchirp
+%@verbatim
+%PCHIRP  Periodic chirp
+%   Usage:  g=pchirp(L,n);
+%
+%   PCHIRP(L,n) returns a periodic, discrete chirp of length L that
+%   revolves n times around the time-frequency plane in frequency. n must be
+%   an integer number.
+%
+%   To get a chirp that revolves around the time-frequency plane in time,
+%   use :
+%
+%     dft(pchirp(L,N));  
+%
+%   The chirp is computed by:
+%   
+%       g(l+1) = exp(pi*i*n*(l-ceil(L/2))^2*(L+1)/L) for l=0,...,L-1
+%
+%   The chirp has absolute value 1 everywhere. To get a chirp with unit
+%   l^2-norm, divide the chirp by sqrt L.
+%
+%   Examples:
+%   ---------
+%
+%   A spectrogram on a linear scale of an even length chirp:
+%
+%     sgram(pchirp(40,2),'lin');
+%
+%   The DFT of the same chirp, now revolving around in time:
+%
+%     sgram(dft(pchirp(40,2)),'lin');
+%
+%   An odd-length chirp. Notice that the chirp starts at a frequency between
+%   two sampling points:
+%
+%     sgram(pchirp(41,2),'lin');
+%   
+%
+%   References:
+%     H. G. Feichtinger, M. Hazewinkel, N. Kaiblinger, E. Matusiak, and
+%     M. Neuhauser. Metaplectic operators on c^n. The Quarterly Journal of
+%     Mathematics, 59(1):15-28, 2008.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pchirp.php}
+%@seealso{dft, expwave}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+error(nargchk(2,2,nargin));
+
+if ~isnumeric(L) || ~isscalar(L)
+  error('%s: L must be a scalar',upper(mfilename));
+end;
+
+if ~isnumeric(n) || ~isscalar(n)
+  error('%s: n must be a scalar',upper(mfilename));
+end;
+
+if rem(L,1)~=0
+  error('%s: L must be an integer',upper(mfilename));
+end;
+
+if rem(n,1)~=0
+  error('%s: n must be an integer',upper(mfilename));
+end;
+
+g=comp_pchirp(L,n);
+
diff --git a/inst/fourier/pconv.m b/inst/fourier/pconv.m
new file mode 100644
index 0000000..a167405
--- /dev/null
+++ b/inst/fourier/pconv.m
@@ -0,0 +1,89 @@
+function h=pconv(f,g,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pconv
+%@verbatim
+%PCONV  Periodic convolution
+%   Usage:  h=pconv(f,g)
+%           h=pconv(ptype,f,g); 
+%
+%   PCONV(f,g) computes the periodic convolution of f and g. The convolution
+%   is given by
+%
+%               L-1
+%      h(l+1) = sum f(k+1) * g(l-k+1)
+%               k=0
+%
+%   PCONV('r',f,g) computes the convolution where g is reversed
+%   (involuted) given by
+%
+%               L-1
+%      h(l+1) = sum f(k+1) * conj(g(k-l+1))
+%               k=0
+%
+%   This type of convolution is also known as cross-correlation.
+%
+%   PCONV('rr',f,g) computes the alternative where both f and g are
+%   reversed given by
+%
+%               L-1
+%      h(l+1) = sum conj(f(-k+1)) * conj(g(k-l+1))
+%               k=0
+%     
+%   In the above formulas, l-k, k-l and -k are computed modulo L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pconv.php}
+%@seealso{dft, involute}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_PCONV
+%   REFERENCE: REF_PCONV
+
+% Assert correct input.
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~all(size(f)==size(g))
+  error('f and g must have the same size.');
+end;
+
+definput.flags.type={'default','r','rr'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_default
+    h=ifft(fft(f).*fft(g));
+end;
+
+if flags.do_r
+  h=ifft(fft(f).*conj(fft(g)));
+end;
+
+if flags.do_rr
+  h=ifft(conj(fft(f)).*conj(fft(g)));
+end;
+
+% Clean output if input was real-valued
+if isreal(f) && isreal(g)
+  h=real(h);
+end;
+
+
diff --git a/inst/fourier/pderiv.m b/inst/fourier/pderiv.m
new file mode 100644
index 0000000..9ad3490
--- /dev/null
+++ b/inst/fourier/pderiv.m
@@ -0,0 +1,81 @@
+function fd=pderiv(f,dim,difforder)
+%-*- texinfo -*-
+%@deftypefn {Function} pderiv
+%@verbatim
+%PDERIV   Derivative of smooth periodic function
+%   Usage:  fd=pderiv(f);
+%           fd=pderiv(f,dim);
+%           fd=pderiv(f,dim,difforder);
+%
+%   PDERIV(f) will compute the derivative of f using a using a 4th order
+%   centered finite difference scheme. f must have been obtained by a
+%   regular sampling. If f is a matrix, the derivative along the columns
+%   will be found.
+%
+%   PDERIV(f,dim) will do the same along dimension dim.
+%
+%   PDERIV(f,dim,difforder) uses a centered finite difference scheme of
+%   order difforder instead of the default.
+%
+%   PDERIV(f,dim,Inf) will compute the spectral derivative using a DFT.
+%
+%   PDERIV assumes that f is a regular sampling of a function on the
+%   torus [0,1). The derivative of a function on a general torus [0,T)
+%   can be found by scaling the output by 1/T. 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pderiv.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Assert correct input.
+
+error(nargchk(1,3,nargin));
+
+if nargin==1
+  dim=[];
+end;
+
+if nargin<3
+  difforder=4;
+end;
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,'PDERIV');
+
+switch(difforder)
+ case 2
+  fd = L*(circshift(f,-1)-circshift(f,1))/2;
+ case 4
+  fd = L*(-circshift(f,-2)+8*circshift(f,-1)-8*circshift(f,1)+ ...
+          circshift(f,2))/12;
+ case Inf
+  n=fftindex(L,0);
+  n=repmat(n,1,W);
+  
+  fd=2*pi*ifft(i*n.*fft(f));
+
+  if isreal(f)
+    fd=real(fd);
+  end;
+
+ otherwise
+  error('The specified differentation order is not implemented.');
+end;
+
+fd=assert_sigreshape_post(fd,dim,permutedsize,order);
+
+
diff --git a/inst/fourier/peven.m b/inst/fourier/peven.m
new file mode 100644
index 0000000..72daf21
--- /dev/null
+++ b/inst/fourier/peven.m
@@ -0,0 +1,40 @@
+function f=peven(f,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} peven
+%@verbatim
+%PEVEN   Even part of periodic function
+%   Usage:  fe=peven(f);
+%           fe=peven(f,dim);
+%
+%   PEVEN(f) returns the even part of the periodic sequence f.
+%
+%   PEVEN(f,dim) does the same along dimension dim.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/peven.php}
+%@seealso{podd, dft, involute, pconv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin==1
+  f=(f+involute(f))/2;
+else
+  f=(f+involute(f,dim))/2;
+end;
+
+
diff --git a/inst/fourier/pfilt.m b/inst/fourier/pfilt.m
new file mode 100644
index 0000000..ba945da
--- /dev/null
+++ b/inst/fourier/pfilt.m
@@ -0,0 +1,98 @@
+function c=pfilt(f,g,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pfilt
+%@verbatim
+%PFILT  Apply filter with periodic boundary conditions
+%   Usage:  h=pfilt(f,g);
+%           h=pfilt(f,g,a,dim);
+%
+%   PFILT(f,g) applies the filter g to the input f. If f is a
+%   matrix, the filter is applied along each column.
+%
+%   PFILT(f,g,a) does the same, but downsamples the output keeping only
+%   every a'th sample (starting with the first one).
+%
+%   PFILT(f,g,a,dim) filters along dimension dim. The default value of
+%   [] means to filter along the first non-singleton dimension.
+%
+%   The filter g can be a vector, in which case the vector is treated
+%   as a zero-delay FIR filter.
+%
+%   The filter g can be a cell array. The following options are
+%   possible:
+%
+%      If the first element of the cell array is the name of one of the
+%       windows from FIRWIN, the whole cell array is passed onto
+%       FIRFILTER.
+%
+%      If the first element of the cell array is 'bl', the rest of the
+%       cell array is passed onto BLFILTER.
+%
+%      If the first element of the cell array is 'pgauss', 'psech',
+%       the rest of the parameters is passed onto the respective
+%       function. Note that you do not need to specify the length L.
+%
+%   The coefficients obtained from filtering a signal f by a filter g are
+%   defined by
+%
+%               L-1
+%      c(n+1) = sum f(l+1) * g(an-l+1)
+%               l=0
+%
+%   where an-l is computed modulo L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pfilt.php}
+%@seealso{pconv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+% Assert correct input.
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'pfilt'};
+definput.keyvals.a=1;
+definput.keyvals.dim=[];
+[flags,kv,a,dim]=ltfatarghelper({'a','dim'},definput,varargin);
+
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,upper(mfilename));
+
+[g,info] = comp_fourierwindow(g,L,upper(mfilename));
+
+
+outIsReal = isreal(f) &&...
+              (isfield(g,'h') && isreal(g.h) && ~(isfield(g,'fc') && g.fc~=0) || isfield(g,'H') && g.realonly);
+
+g = comp_filterbank_pre({g},a,L,kv.crossover);
+
+
+c = comp_filterbank(f,g,a);
+c = c{1};
+
+permutedsize(1)=size(c,1);
+  
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+if outIsReal
+   c = real(c);
+end
+
+
diff --git a/inst/fourier/pgauss.m b/inst/fourier/pgauss.m
new file mode 100644
index 0000000..6d445c6
--- /dev/null
+++ b/inst/fourier/pgauss.m
@@ -0,0 +1,198 @@
+function [g,tfr]=pgauss(L,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pgauss
+%@verbatim
+%PGAUSS  Sampled, periodized Gaussian
+%   Usage: g=pgauss(L);
+%          g=pgauss(L,tfr);
+%          g=pgauss(L,...);
+%          [g,tfr]=pgauss( ... );
+% 
+%   Input parameters:
+%         L    : Length of vector.
+%         tfr  : ratio between time and frequency support.
+%
+%   Output parameters:
+%         g    : The periodized Gaussian.
+%
+%   PGAUSS(L,tfr) computes samples of a periodized Gaussian. The function
+%   returns a regular sampling of the periodization of the function
+%   exp(-pi*(x.^2/tfr)).
+%
+%   The l^2 norm of the returned Gaussian is equal to 1.
+%
+%   The parameter tfr determines the ratio between the effective support
+%   of g and the effective support of the DFT of g. If tfr>1 then g*
+%   has a wider support than the DFT of g.
+%
+%   PGAUSS(L) does the same setting tfr=1.
+%
+%   [g,tfr] = PGAUSS( ... ) will additionally return the time-to-frequency
+%   support ratio. This is useful if you did not specify it (i.e. used the
+%   'width' or 'bw' flag).
+%
+%   The function is whole-point even. This implies that fft(PGAUSS(L,tfr))
+%   is real for any L and tfr. The DFT of g is equal to
+%   PGAUSS(L,1/tfr).
+%
+%   In addition to the 'width' flag, PGAUSS understands the following
+%   flags at the end of the list of input parameters:
+%
+%     'fs',fs     Use a sampling rate of fs Hz as unit for specifying the
+%                 width, bandwidth, centre frequency and delay of the
+%                 Gaussian. Default is fs=[] which indicates to measure
+%                 everything in samples.
+%
+%     'width',s   Set the width of the Gaussian such that it has an
+%                 effective support of s samples. This means that
+%                 approx. 96% of the energy or 79% of the area
+%                 under the graph is contained within s samples. This 
+%                 corresponds to a -6 db cutoff. This is equivalent to
+%                 calling PGAUSS(L,s^2/L).
+%
+%     'bw',bw     As for the 'width' argument, but specifies the width
+%                 in the frequency domain. The bandwidth is measured in 
+%                 normalized frequencies, unless the 'fs' value is given.
+%
+%     'cf',cf     Set the centre frequency of the Gaussian to fc.  
+%
+%     'wp'        Output is whole point even. This is the default.
+%
+%     'hp'        Output is half point even, as most Matlab filter
+%                 routines.
+%
+%     'delay',d   Delay the output by d. Default is zero delay.
+%
+%   In addition to these parameteres, PGAUSS accepts any of the flags
+%   from NORMALIZE. The output will be normalized as specified.
+%
+%   If this function is used to generate a window for a Gabor frame, then
+%   the window giving the smallest frame bound ratio is generated by
+%   PGAUSS(L,a*M/L).
+%
+%   Examples:
+%   ---------
+%
+%   This example creates a Gaussian function, and demonstrates that it is
+%   its own Discrete Fourier Transform:
+%
+%     g=pgauss(128);
+%
+%     % Test of DFT invariance: Should be close to zero.
+%     norm(g-dft(g))
+% 
+%   The next plot shows the Gaussian in the time domain:
+%
+%     plot(fftshift(pgauss(128)));
+% 
+%   The next plot shows the Gaussian in the frequency domain on a log scale:
+%
+%     magresp(pgauss(128),'dynrange',100);
+%     
+%   The next plot shows the Gaussian in the time-frequency plane:
+% 
+%     sgram(pgauss(128),'tc','nf','lin');
+%
+%
+%
+%   References:
+%     S. Mallat and Z. Zhang. Matching pursuits with time-frequency
+%     dictionaries. IEEE Trans. Signal Process., 41(12):3397-3415, 1993.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pgauss.php}
+%@seealso{dgtlength, psech, firwin, pbspline, normalize, demo_pgauss}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR : Peter L. Soendergaard.
+
+%   First reference on this found in mazh93 eq. 63
+
+if nargin<1
+  error('Too few input parameters.');
+end;
+
+if (prod(size(L,1))~=1 || ~isnumeric(L))
+  error('L must be a scalar');
+end;
+
+if rem(L,1)~=0
+  error('L must be an integer.')
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.import={'normalize'};
+
+definput.flags.centering={'wp','hp'};
+definput.flags.delay={'nodelay','delay'};
+definput.flags.width={'tfr','width','bw'};
+
+definput.keyvals.tfr=1;
+definput.keyvals.delay=0;
+definput.keyvals.width=0;
+definput.keyvals.fs=[];
+definput.keyvals.cf=0;
+definput.keyvals.bw=0;
+
+[flags,keyvals,tfr]=ltfatarghelper({'tfr'},definput,varargin);
+
+if (prod(size(tfr,1))~=1 || ~isnumeric(tfr))
+  error('tfr must be a scalar.');
+end;
+
+fs=keyvals.fs;
+
+if flags.do_wp
+  cent=0;
+else
+  cent=0.5;
+end;
+
+if isempty(fs)
+  
+  if flags.do_width
+    tfr=keyvals.width^2/L;
+  end;
+  
+  if flags.do_bw
+  tfr=L/(keyvals.bw*L/2)^2;
+  end;
+  
+  delay_s=keyvals.delay;
+  cf_s   =keyvals.cf;
+else
+  
+  if flags.do_width
+    tfr=(keyvals.width*fs)^2/L;
+  end;
+
+  if flags.do_bw
+    tfr=L/(keyvals.bw/fs*L)^2;
+  end;
+  
+  delay_s=keyvals.delay*fs;
+  cf_s   =keyvals.cf/fs*L;
+end;
+
+g=comp_pgauss(L,tfr,cent-delay_s,cf_s);
+
+g=normalize(g,flags.norm);
+
+
diff --git a/inst/fourier/pheaviside.m b/inst/fourier/pheaviside.m
new file mode 100644
index 0000000..23e2482
--- /dev/null
+++ b/inst/fourier/pheaviside.m
@@ -0,0 +1,63 @@
+function h=pheaviside(L)
+%-*- texinfo -*-
+%@deftypefn {Function} pheaviside
+%@verbatim
+%PHEAVISIDE  Periodic Heaviside function
+%   Usage: h=pheaviside(L);
+%
+%   PHEAVISIDE(L) returns a periodic Heaviside function. The periodic
+%   Heaviside function takes on the value 1 for indices corresponding to
+%   positive frequencies, 0 corresponding to negative frequencies and the
+%   value .5 for the zero and Nyquist frequencies.
+%
+%   To get a function that weights the negative frequencies by 1 and the
+%   positive by 0, use involute(PHEAVISIDE(L))
+%
+%   As an example, the PHEAVISIDE function can be use to calculate the
+%   Hilbert transform for a column vector f*:
+%
+%     h=2*ifft(fft(f).*pheaviside(length(f)));
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pheaviside.php}
+%@seealso{middlepad, involute, fftindex}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   REFERENCE: OK
+%   TESTING: OK
+  
+error(nargchk(1,1,nargin));
+  
+
+h=zeros(L,1);
+if L>0
+  % First term is .5
+  h(1)=.5;
+
+  % Set positive frequencies to 1.
+  h(2:ceil(L/2))=1;
+ 
+  % Last term (Nyquist frequency) is also .5, if it exists.
+  if rem(L,2)==0
+    h(L/2+1)=.5;
+  end;
+end;
+
+
diff --git a/inst/fourier/pherm.m b/inst/fourier/pherm.m
new file mode 100644
index 0000000..2e86e3c
--- /dev/null
+++ b/inst/fourier/pherm.m
@@ -0,0 +1,228 @@
+function [g,D]=pherm(L,order,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pherm
+%@verbatim
+%PHERM  Periodized Hermite function
+%   Usage: g=pherm(L,order);
+%          g=pherm(L,order,tfr);
+%          [g,D]=pherm(...);
+% 
+%   Input parameters:
+%      L     : Length of vector.
+%      order : Order of Hermite function.
+%      tfr   : ratio between time and frequency support.
+%   Output parameters:
+%      g     : The periodized Hermite function
+%
+%   PHERM(L,order,tfr) computes samples of a periodized Hermite function
+%   of order order. order is counted from 0, so the zero'th order
+%   Hermite function is the Gaussian.
+%
+%   The parameter tfr determines the ratio between the effective support
+%   of g and the effective support of the DFT of g. If tfr>1 then g*
+%   has a wider support than the DFT of g.
+%
+%   PHERM(L,order) does the same setting tfr=1.
+%
+%   If order is a vector, PHERM will return a matrix, where each column
+%   is a Hermite function with the corresponding order.
+%
+%   [g,D]=PHERM(...) also returns the eigenvalues D of the Discrete
+%   Fourier Transform corresponding to the Hermite functions.
+%
+%   The returned functions are eigenvectors of the DFT. The Hermite
+%   functions are orthogonal to all other Hermite functions with a
+%   different eigenvalue, but eigenvectors with the same eigenvalue are
+%   not orthogonal (but see the flags below).
+%
+%   PHERM takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'accurate'  Use a numerically very accurate that computes each
+%                 Hermite function individually. This is the default.
+%
+%     'fast'      Use a less accurate algorithm that calculates all the
+%                 Hermite up to a given order at once.
+%
+%     'noorth'    No orthonormalization of the Hermite functions. This is
+%                 the default.
+%
+%     'polar'     Orthonormalization of the Hermite functions using the
+%                 polar decomposition orthonormalization method.
+%
+%     'qr'        Orthonormalization of the Hermite functions using the
+%                 Gram-Schmidt orthonormalization method (usign qr).
+%
+%   If you just need to compute a single Hermite function, there is no
+%   speed difference between the 'accurate' and 'fast' algorithm.
+%
+%   Examples:
+%   ---------
+%
+%   The following plot shows the spectrograms of 4 Hermite functions of
+%   length 200 with order 1, 10, 100, and 190:
+%
+%     subplot(2,2,1);
+%     sgram(pherm(200,1),'nf','tc','lin','nocolorbar'); axis('square');
+%
+%     subplot(2,2,2);
+%     sgram(pherm(200,10),'nf','tc','lin','nocolorbar'); axis('square');
+%    
+%     subplot(2,2,3);
+%     sgram(pherm(200,100),'nf','tc','lin','nocolorbar'); axis('square');
+%    
+%     subplot(2,2,4);
+%     sgram(pherm(200,190),'nf','tc','lin','nocolorbar'); axis('square');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pherm.php}
+%@seealso{hermbasis, pgauss, psech}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHORs: Thomasz Hrycak and Peter L. Soendergaard.
+% 
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.tfr=1;
+definput.flags.phase={'accurate','fast'};
+definput.flags.orthtype={'noorth','polar','qr'};
+[flags,kv,tfr]=ltfatarghelper({'tfr'},definput,varargin);
+  
+if size(L,1)>1 || size(L,2)>1
+  error('L must be a scalar');
+end;
+
+if rem(L,1)~=0
+  error('L must be an integer.')
+end;
+
+% Parse tfr and order.
+if sum(1-(size(tfr)==1))>1
+  error('tfr must be a scalar or vector');
+end;
+
+if sum(1-(size(order)==1))>1
+  error('"order" must be a scalar or vector');
+end;
+
+W=length(order);
+
+order=order(:);
+
+
+% Calculate W windows.
+if flags.do_accurate
+    % Calculate W windows.
+    g=zeros(L,W);
+    for w=1:W
+        
+        thisorder=order(w);
+        safe=get_safe(thisorder);
+
+        % Outside the interval [-safe,safe] then H(thisorder) is numerically zero.
+        nk=ceil(safe/sqrt(L/sqrt(tfr)));
+        
+        sqrtl=sqrt(L);
+        
+        lr=(0:L-1).';
+        for k=-nk:nk
+            xval=(lr/sqrtl-k*sqrtl)/sqrt(tfr);
+            g(:,w)=g(:,w)+comp_hermite(thisorder, sqrt(2*pi)*xval);
+        end;
+        
+    end;
+    
+else
+    
+    highestorder=max(order);
+    safe=get_safe(highestorder);
+
+    % Outside the interval [-safe,safe] then H(thisorder) is numerically zero.
+    nk=ceil(safe/sqrt(L/sqrt(tfr)));
+
+    g=zeros(L,highestorder+1);
+    sqrtl=sqrt(L);
+        
+    lr=(0:L-1).';
+    for k=-nk:nk
+        xval=(lr/sqrtl-k*sqrtl)/sqrt(tfr);
+        g=g+comp_hermite_all(highestorder+1, sqrt(2*pi)*xval);
+    end;
+
+    g=g(:,order+1);
+    
+end;
+
+if flags.do_polar
+    % Orthonormalize within each of the 4 eigenspaces
+    for ii=0:3
+        subidx=(rem(order,4)==ii);
+        gsub=g(:,subidx);
+        [U,S,V]=svd(gsub,0);
+        gsub=U*V';
+        g(:,subidx)=gsub;        
+    end;
+        
+end;
+
+if flags.do_qr
+    % Orthonormalize within each of the 4 eigenspaces
+    for ii=0:3
+        subidx=(rem(order,4)==ii);
+        gsub=g(:,subidx);
+        [Q,R]=qr(gsub,0);
+        g(:,subidx)=Q;        
+    end;       
+end;
+
+if flags.do_noorth
+    % Just normalize it, no orthonormalization
+    g=normalize(g);
+end;
+
+if nargout>1
+    % set up the eigenvalues
+    D = exp(-1i*order*pi/2);
+end;
+
+
+function safe=get_safe(order)
+% These numbers have been computed numerically.
+    if order<=6
+        safe=4;
+    else 
+        if order<=18
+            safe=5;
+        else 
+            if order<=31
+                safe=6;                
+            else 
+                if order<=46
+                    safe=7;
+                else
+                    % Anything else, use a high number.
+                    safe=12;
+                end;
+            end;
+        end;
+    end;
+    
diff --git a/inst/fourier/plotfft.m b/inst/fourier/plotfft.m
new file mode 100644
index 0000000..504a1d6
--- /dev/null
+++ b/inst/fourier/plotfft.m
@@ -0,0 +1,168 @@
+function plotfft(coef,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotfft
+%@verbatim
+%PLOTFFT  Plot the output from FFT
+%   Usage: plotfft(coef);
+%          plotfft(coef,fs);
+%
+%   PLOTFFT(coef) plots the output from the fft function. The
+%   frequency axis will use normalized frequencies between 0 and 1 (the
+%   Nyquist frequency).
+%
+%   PLOTFFT(coef,fs) does the same for the FFT of a signal sampled at
+%   a sampling rate of fs Hz.
+%
+%   PLOTFFT(coef,fs,dynrange) additionally limits the dynamic range of the
+%   plot. See the description of the 'dynrange' parameter below.
+%
+%   PLOTFFT accepts the following optional arguments:
+%
+%     'dynrange',r Limit the dynamical range to r by using a colormap in
+%                  the interval [chigh-r,chigh], where chigh is the highest
+%                  value in the plot. The default value of [] means to not
+%                  limit the dynamical range. 
+%
+%     'db'         Apply 20*log_{10} to the coefficients. This makes 
+%                  it possible to see very weak phenomena, but it might show 
+%                  too much noise. This is the default.
+%
+%     'dbsq'       Apply 10*log_{10} to the coefficients. Same as the
+%                  'db' option, but assumes that the input is already squared.  
+%
+%     'lin'        Show the coefficients on a linear scale. This will
+%                  display the raw input without any modifications. Only works for
+%                  real-valued input.
+%                 
+%     'linsq'      Show the square of the coefficients on a linear scale.
+%                 
+%     'linabs'     Show the absolute value of the coefficients on a linear
+%                  scale.
+%
+%     'nf'         Display negative frequencies, with the zero-frequency
+%                  centered in the middle. This is the default.
+%
+%     'posfreq'    Display only the positive frequencies.
+%
+%     'dim',dim  If coef is multidimensional, dim indicates the 
+%                dimension along which are the individual channels oriented.
+%                Value 1 indicates columns, value 2 rows.
+%
+%
+%   In addition to these parameters, PLOTFFT accepts any of the flags
+%   from NORMALIZE. The coefficients will be normalized as specified
+%   before plotting.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/plotfft.php}
+%@seealso{plotfftreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% if ~isvector(coef)
+%   error('%s: Can only plot vectors.',upper(mfilename));
+% end;
+
+definput.import={'ltfattranslate','normalize'};
+definput.importdefaults={'null'};
+
+definput.flags.log={'db','dbsq','lin','linsq','linabs'};
+definput.flags.posfreq={'nf','posfreq'};
+
+definput.keyvals.fs=[];
+definput.keyvals.dynrange=[];
+
+definput.keyvals.opts={};
+definput.keyvals.dim=[];
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+[coef,~,N]=assert_sigreshape_pre(coef,[],kv.dim,upper(mfilename));
+
+coef=normalize(coef,flags.norm);
+
+% Apply transformation to coefficients.
+if flags.do_db
+  coef=20*log10(abs(coef)+realmin);
+end;
+
+if flags.do_dbsq
+  coef=10*log10(abs(coef)+realmin);
+end;
+
+if flags.do_linsq
+  coef=abs(coef).^2;
+end;
+
+if flags.do_linabs
+  coef=abs(coef);
+end;
+
+if flags.do_lin
+  if ~isreal(coef)
+    error(['Complex valued input cannot be plotted using the "lin" flag.',...
+           'Please use the "linsq" or "linabs" flag.']);
+  end;
+end;
+  
+% 'dynrange' parameter is handled by thresholding the coefficients.
+if ~isempty(kv.dynrange)
+  maxclim=max(coef(:));
+  coef(coef<maxclim-kv.dynrange)=maxclim-kv.dynrange;
+end;
+
+if flags.do_nf
+  if rem(N,2)==0
+    xr=(-N/2+1:N/2)*2/N;  
+    % Subtract 1 in order to place the Nyquist frequency following the
+    % positive frequencies. That is why we do not use fftshift.
+    coef=circshift(coef,N/2-1);
+  else
+    xr=(-floor(N/2):floor(N/2))*2/N;  
+    coef=fftshift(coef);
+  end;
+else
+
+  N2=floor(N/2)+1;
+  coef=coef(1:N2,:);
+  xr=(0:N2-1)*2/N;  
+end;
+
+if ~isempty(kv.fs)
+  xr=xr*kv.fs/2;
+end;
+
+plot(xr,coef,kv.opts{:});
+xlim([xr(1) xr(end)]);
+
+if flags.do_db || flags.do_dbsq
+  ylabel(sprintf('%s (dB)',kv.magnitude));
+else
+  ylabel(sprintf('%s',kv.magnitude));
+end;
+
+if ~isempty(kv.fs)
+  xlabel(sprintf('%s (Hz)',kv.frequency));
+else
+  xlabel(sprintf('%s (%s)',kv.frequency,kv.normalized));
+end;
+
+
diff --git a/inst/fourier/plotfftreal.m b/inst/fourier/plotfftreal.m
new file mode 100644
index 0000000..b4a6f6a
--- /dev/null
+++ b/inst/fourier/plotfftreal.m
@@ -0,0 +1,163 @@
+function plotfftreal(coef,varargin)  
+%-*- texinfo -*-
+%@deftypefn {Function} plotfftreal
+%@verbatim
+%PLOTFFTREAL  Plot the output from FFTREAL  
+%   Usage: plotfftreal(coef);
+%          plotfftreal(coef,fs);
+%
+%   PLOTFFTREAL(coef) plots the output from the FFTREAL function. The
+%   frequency axis will use normalized frequencies between 0 and 1 (the
+%   Nyquist frequency). It is assumed that the length of the original
+%   transform was even.
+%
+%   PLOTFFTREAL(coef,fs) does the same for the FFTREAL of a signal
+%   sampled at a sampling rate of fs Hz.
+%
+%   PLOTFFTREAL(coef,fs,dynrange) additionally limits the dynamic range of the
+%   plot. See the description of the 'dynrange' parameter below.
+%
+%   PLOTFFTREAL accepts the following optional arguments:
+%
+%     'dynrange',r  Limit the dynamical range to r by using a colormap in
+%                   the interval [chigh-r,chigh], where chigh is the highest
+%                   value in the plot. The default value of [] means to not
+%                   limit the dynamical range. 
+%
+%     'db'      Apply 20*log_{10} to the coefficients. This makes 
+%               it possible to see very weak phenomena, but it might show 
+%               too much noise. This is the default.
+%
+%     'dbsq'    Apply 10*log_{10} to the coefficients. Same as the
+%               'db' option, but assumes that the input is already squared.  
+%
+%     'lin'     Show the coefficients on a linear scale. This will
+%               display the raw input without any modifications. Only works for
+%               real-valued input.
+%
+%     'linsq'   Show the square of the coefficients on a linear scale.
+%
+%     'linabs'  Show the absolute value of the coefficients on a linear
+%               scale.
+%     
+%     'N',N     Specify the transform length N. Use this if you are
+%               unsure if the original input signal was of even length.
+%
+%     'dim',dim  If coef is multidimensional, dim indicates the 
+%                dimension along which are the individual channels oriented.
+%                Value 1 indicates columns, value 2 rows.
+%
+%
+%   In addition to these parameters, PLOTFFTREAL accepts any of the flags
+%   from NORMALIZE. The coefficients will be normalized as specified
+%   before plotting.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/plotfftreal.php}
+%@seealso{plotfft, fftreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','normalize'};
+definput.importdefaults={'null'};
+
+definput.flags.log={'db','dbsq','lin','linsq','linabs'};
+
+definput.keyvals.fs=[];
+definput.keyvals.dynrange=[];
+definput.keyvals.opts={};
+
+definput.keyvals.N=[];
+definput.keyvals.dim=[];
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+% if ~isvector(coef)
+%   error('%s: Input is multidimensional.',upper(mfilename));
+% end;
+
+[coef,~,Lc]=assert_sigreshape_pre(coef,[],kv.dim,upper(mfilename));
+
+N=kv.N;
+if isempty(N)
+   N=2*(Lc-1);
+end
+
+N2=floor(N/2)+1;
+if N2~=Lc
+  error('%s: Size mismatch.',upper(mfilename));
+end;
+
+coef=normalize(coef,flags.norm);
+
+% Apply transformation to coefficients.
+if flags.do_db
+  coef=20*log10(abs(coef)+realmin);
+end;
+
+if flags.do_dbsq
+  coef=10*log10(abs(coef)+realmin);
+end;
+
+if flags.do_linsq
+  coef=abs(coef).^2;
+end;
+
+if flags.do_linabs
+  coef=abs(coef);
+end;
+
+if flags.do_lin
+  if ~isreal(coef)
+    error(['Complex valued input cannot be plotted using the "lin" flag.',...
+           'Please use the "linsq" or "linabs" flag.']);
+  end;
+end;
+  
+% 'dynrange' parameter is handled by thresholding the coefficients.
+if ~isempty(kv.dynrange)
+  maxclim=max(coef(:));
+  coef(coef<maxclim-kv.dynrange)=maxclim-kv.dynrange;
+end;
+
+xr=(0:N2-1)*2/N;
+if ~isempty(kv.fs)
+  xr=xr*kv.fs/2;
+end;
+
+plot(xr,coef,kv.opts{:});
+xlim([xr(1) xr(end)]);
+
+
+if flags.do_db || flags.do_dbsq
+  ylabel(sprintf('%s (dB)',kv.magnitude));
+else
+  ylabel(sprintf('%s',kv.magnitude));
+end;
+
+if ~isempty(kv.fs)
+  xlabel(sprintf('%s (Hz)',kv.frequency));
+else
+  xlabel(sprintf('%s (%s)',kv.frequency,kv.normalized));
+end;
+
+
diff --git a/inst/fourier/podd.m b/inst/fourier/podd.m
new file mode 100644
index 0000000..68a8c61
--- /dev/null
+++ b/inst/fourier/podd.m
@@ -0,0 +1,39 @@
+function f=podd(f,dim)
+%-*- texinfo -*-
+%@deftypefn {Function} podd
+%@verbatim
+%PODD   Odd part of periodic function
+%   Usage:  fe=podd(f);
+%           fe=podd(f,dim);
+%
+%   PODD(f) returns the odd part of the periodic sequence f.
+%
+%   PODD(f,dim) does the same along dimension dim.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/podd.php}
+%@seealso{peven, dft, involute, pconv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+if nargin==1 
+  f=(f-involute(f))/2;
+else
+  f=(f-involute(f,dim))/2;
+end;
+
diff --git a/inst/fourier/prect.m b/inst/fourier/prect.m
new file mode 100644
index 0000000..acb97b4
--- /dev/null
+++ b/inst/fourier/prect.m
@@ -0,0 +1,67 @@
+function f=prect(L,n)
+%-*- texinfo -*-
+%@deftypefn {Function} prect
+%@verbatim
+%PRECT   Periodic rectangle
+%   Usage:  f=prect(L,n);
+%
+%   psinc(L,n) computes the periodic rectangle (or square) function of
+%   length L supported on n samples. The DFT of the periodic
+%   rectangle function in the periodic sinc function, PSINC.
+%
+%    If n is odd, the output will be supported on exactly n samples
+%     centered around the first sample.
+%
+%    If n is even, the output will be supported on exactly n+1 samples
+%     centered around the first sample. The function value on the two
+%     samples on the edge of the function will have half the magnitude of
+%     the other samples.
+%
+%   Examples:
+%   ---------
+%
+%   This figure displays an odd length periodic rectangle:
+%
+%     stem(prect(30,11));
+%     ylim([-.2 1.2]);
+%
+%   This figure displays an even length periodic rectangle. Notice the
+%   border points:
+%
+%     stem(prect(30,12));
+%     ylim([-.2 1.2]);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/prect.php}
+%@seealso{psinc}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+error(nargchk(2,2,nargin));
+
+if ~(numel(L)==1) || ~(isnumeric(L)) || mod(L,1)~=0 || L<=0
+  error('%s: L has to be a positive integer.',upper(mfilename));
+end;
+
+if ~(numel(n)==1) || ~(isnumeric(L)) || mod(n,1)~=0 || n<=0
+  error('%s: n has to be a positive integer.',upper(mfilename));
+end;
+
+f=pbspline(L,0,n);
+
+
diff --git a/inst/fourier/psech.m b/inst/fourier/psech.m
new file mode 100644
index 0000000..a4b9911
--- /dev/null
+++ b/inst/fourier/psech.m
@@ -0,0 +1,157 @@
+function [g,tfr]=psech(L,p2,p3,p4)
+%-*- texinfo -*-
+%@deftypefn {Function} psech
+%@verbatim
+%PSECH  Sampled, periodized hyperbolic secant
+%   Usage: g=psech(L);
+%          g=psech(L,tfr);
+%          g=psech(L,s,'samples);
+%          [g,tfr]=psech( ... );
+%
+%   Input parameters:
+%      L   : Length of vector.
+%      tfr : ratio between time and frequency support.
+%   Output parameters:
+%      g   : The periodized hyperbolic cosine.
+%
+%   PSECH(L,tfr) computes samples of a periodized hyperbolic secant.
+%   The function returns a regular sampling of the periodization
+%   of the function sech(pi*x)
+%
+%   The returned function has norm equal to 1.
+%
+%   The parameter tfr determines the ratio between the effective support
+%   of g and the effective support of the DFT of g. If tfr>1 then g*
+%   has a wider support than the DFT of g.
+%
+%   PSECH(L) does the same setting tfr=1.
+%
+%   PSECH(L,s,'samples') returns a hyperbolic secant with an effective
+%   support of s samples. This means that approx. 96% of the energy or 74%
+%   or the area under the graph is contained within s samples. This is
+%   equivalent to PSECH(L,s^2/L).
+%
+%   [g,tfr] = PSECH( ... ) additionally returns the time-to-frequency
+%   support ratio. This is useful if you did not specify it (i.e. used
+%   the 'samples' input format).
+%
+%   The function is whole-point even.  This implies that fft(PSECH(L,tfr))
+%   is real for any L and tfr.
+%
+%   If this function is used to generate a window for a Gabor frame, then
+%   the window giving the smallest frame bound ratio is generated by
+%   PSECH(L,a*M/L).
+%
+%   Examples:
+%   ---------
+%
+%   This example creates a PSECH function, and demonstrates that it is
+%   its own Discrete Fourier Transform:
+%
+%     g=psech(128);
+%
+%     % Test of DFT invariance: Should be close to zero.
+%     norm(g-dft(g))
+% 
+%   The next plot shows the PSECH in the time domain compared to the Gaussian:
+%
+%     plot((1:128)',fftshift(pgauss(128)),...
+%          (1:128)',fftshift(psech(128)));
+%     legend('pgauss','psech');
+% 
+%   The next plot shows the PSECH in the frequency domain on a log
+%   scale compared to the Gaussian:
+%
+%     hold all;
+%     magresp(pgauss(128),'dynrange',100);
+%     magresp(psech(128),'dynrange',100);
+%     legend('pgauss','psech');
+%     
+%   The next plot shows PSECH in the time-frequency plane:
+% 
+%     sgram(psech(128),'tc','nf','lin');
+%
+%
+%   References:
+%     A. J. E. M. Janssen and T. Strohmer. Hyperbolic secants yield Gabor
+%     frames. Appl. Comput. Harmon. Anal., 12(2):259-267, 2002.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/psech.php}
+%@seealso{pgauss, pbspline, pherm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(1,4,nargin));
+
+if nargin==1
+  tfr=1;
+end;
+
+if size(L,1)>1 || size(L,2)>1
+  error('L must be a scalar');
+end;
+
+if rem(L,1)~=0
+  error('L must be an integer.')
+end;
+
+switch(nargin)
+ case 1
+  tfr=1;
+  cent=0;
+ case 2
+  tfr=p2;
+  cent=0;
+ case 3
+  if ischar(p3)
+    switch(lower(p3))
+     case {'s','samples'}
+      tfr=p2^2/L;
+     otherwise
+      error('Unknown argument %s',p3);
+    end;
+    cent=0;
+  else
+    tfr=p2;
+    cent=p3;
+  end;
+ case 4
+  tfr=p2^2/L;
+  cent=p4;
+end;
+
+safe=12;
+
+g=zeros(L,1);
+sqrtl=sqrt(L);
+
+w=tfr;
+
+% Outside the interval [-safe,safe] then sech(pi*x) is numerically zero.
+nk=ceil(safe/sqrt(L/sqrt(w)));
+
+lr=(0:L-1).';
+for k=-nk:nk  
+  g=g+sech(pi*(lr/sqrtl-k*sqrtl)/sqrt(w));
+end;
+
+% Normalize it.
+g=g*sqrt(pi/(2*sqrt(L*w)));
+
diff --git a/inst/fourier/psinc.m b/inst/fourier/psinc.m
new file mode 100644
index 0000000..a03cbe0
--- /dev/null
+++ b/inst/fourier/psinc.m
@@ -0,0 +1,62 @@
+function f=psinc(L,n)
+%-*- texinfo -*-
+%@deftypefn {Function} psinc
+%@verbatim
+%PSINC   Periodic Sinc function (Dirichlet function)
+%   Usage:  f=psinc(L,n);
+%
+%   PSINC(L,n) computes the periodic Sinc function of length L with
+%   n-1 local extrema. The DFT of the periodic Sinc function is the
+%   periodic rectangle, PRECT, of length n.
+%
+%   Examples:
+%   ---------
+%
+%   This figure displays a the periodic sinc function with 6 local extremas:
+%
+%     plot(psinc(30,7));
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/psinc.php}
+%@seealso{prect}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+error(nargchk(2,2,nargin));
+
+if ~(numel(L)==1) || ~(isnumeric(L)) || mod(L,1)~=0 || L<=0
+  error('%s: L has to be a positive integer.',upper(mfilename));
+end;
+
+if ~(numel(n)==1) || ~(isnumeric(L)) || mod(n,1)~=0 || n<=0
+  error('%s: n has to be a positive integer.',upper(mfilename));
+end;
+  
+x=(2*pi*(0:L-1)/L).';
+  
+n_odd = n-(1-mod(n,2));
+
+f = sin(n_odd.*x./2)./(n_odd.*sin(x./2));
+
+f(1)  = 1;
+
+if (mod(n,2))==0;
+  f = f+cos(x*n/2)/n_odd;
+end;
+
+
diff --git a/inst/fourier/pxcorr.m b/inst/fourier/pxcorr.m
new file mode 100644
index 0000000..5ef9119
--- /dev/null
+++ b/inst/fourier/pxcorr.m
@@ -0,0 +1,68 @@
+function h=pxcorr(f,g,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pxcorr
+%@verbatim
+%PXCORR  Periodic cross correlation
+%   Usage:  h=pxcorr(f,g)
+%
+%   PXCORR(f,g) computes the periodix cross correlation of the input
+%   signals f and g. The cross correlation is defined by
+%
+%               L-1
+%      h(l+1) = sum f(k+1) * conj(g(k-l+1))
+%               k=0
+%
+%   In the above formula, k-l is computed modulo L.
+%
+%   PXCORR(f,g,'normalize') does the same, but normalizes the output by
+%   the product of the l^2-norm of f and g.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/pxcorr.php}
+%@seealso{dft, pfilt, involute}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+
+% Assert correct input.
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~all(size(f)==size(g))
+  error('f and g must have the same size.');
+end;
+
+definput.flags.type={'nonormalize','normalize'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+L=length(f);
+
+if isreal(f) && isreal(g)
+  h = ifftreal(fftreal(f).*conj(fftreal(g)),L);
+else
+  h = ifft(fft(f).*conj(fft(g)));
+end;
+
+if flags.do_normalize
+  h = h/(norm(f)*norm(g));  
+end;
+
+
diff --git a/inst/fourier/shah.m b/inst/fourier/shah.m
new file mode 100644
index 0000000..2736a1f
--- /dev/null
+++ b/inst/fourier/shah.m
@@ -0,0 +1,70 @@
+function f=shah(L,a);
+%-*- texinfo -*-
+%@deftypefn {Function} shah
+%@verbatim
+%SHAH  Discrete Shah-distribution
+%   Usage: f=shah(L,a);
+% 
+%   SHAH(L,a) computes the discrete, normalized Shah-distribution of
+%   length L with a distance of a between the spikes.
+%
+%   The Shah distribution is defined by 
+%
+%      f(n*a+1)=1/sqrt(L/a) 
+%
+%   for integer n, otherwise f is zero.
+% 
+%   This is also known as an impulse train or as the comb function, because
+%   the shape of the function resembles a comb. It is the sum of unit
+%   impulses ('diracs') with the distance a.
+% 
+%   If a divides L, then the DFT of SHAH(L,a) is SHAH(L,L/a).
+% 
+%   The Shah function has an extremely bad time-frequency localization.
+%   It does not generate a Gabor frame for any L and a.
+%
+%   Examples:
+%   ---------
+%
+%   A simple spectrogram of the Shah function (includes the negative
+%   frequencies to display the whole TF-plane):
+%
+%     sgram(shah(256,16),'dynrange',80,'nf')
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/shah.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+if nargin~=2
+  error('Wrong number of input parameters.');
+end;
+
+%if mod(L,a)~=0
+%  error('a must divide L.');
+%end;
+
+f=zeros(L,1);
+
+f(1:a:L)=1/sqrt(L/a);
+
+
diff --git a/inst/fourier/transferfunction.m b/inst/fourier/transferfunction.m
new file mode 100644
index 0000000..b201c98
--- /dev/null
+++ b/inst/fourier/transferfunction.m
@@ -0,0 +1,37 @@
+function H=transferfunction(g,L)
+%-*- texinfo -*-
+%@deftypefn {Function} transferfunction
+%@verbatim
+%TRANSFERFUNCTION  The transferfunction of a filter
+%   Usage:  H=transferfunction(g,L);
+%
+%   TRANSFERFUNCTION(g,L) computes the transferfunction of length L*
+%   of the filter defined by g.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/transferfunction.php}
+%@seealso{pfilt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(2,2,nargin));
+
+[g,info] = comp_fourierwindow(g,L,upper(mfilename));
+
+H=comp_transferfunction(g,L);
+
diff --git a/inst/fourier/warpedblfilter.m b/inst/fourier/warpedblfilter.m
new file mode 100644
index 0000000..28810fd
--- /dev/null
+++ b/inst/fourier/warpedblfilter.m
@@ -0,0 +1,124 @@
+function gout=warpedblfilter(winname,fsupp,fc,fs,freqtoscale,scaletofreq,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} warpedblfilter
+%@verbatim
+%WARPEDBLFILTER  Construct a warped band-limited filter
+%   Usage:  g=warpedblfilter(winname,fsupp,fc,fs,freqtoscale);
+%           g=warpedblfilter(winname,fsupp,fc,...);
+%
+%   Input parameters:
+%      winname     : Name of prototype.
+%      fsupp       : Support length of the prototype (in scale units).
+%      fc          : Centre frequency (in Hz).
+%      fs          : Sampling rate
+%      freqtoscale : Function handle to convert Hz to scale units
+%      scaletofreq : Function to convert scale units into Hz.
+%
+%   Output parameters:
+%      g           : Filter definition, see BLFILTER.
+%
+%   WARPEDBLFILTER(winname,fsupp) constructs a band-limited filter that is
+%   warped on a given frequency scale. The parameter winname specifies the basic
+%   shape of the frequency response. The name must be one of the shapes
+%   accepted by FIRWIN. The support of the frequency response measured on
+%   the selected frequency scale is specified by fsupp, the centre
+%   frequency by fc and the scale by the function handle freqtoscale*
+%   of a function that converts Hz into the choosen scale.
+%
+%   If one of the inputs is a vector, the output will be a cell array
+%   with one entry in the cell array for each element in the vector. If
+%   more input are vectors, they must have the same size and shape and the
+%   the filters will be generated by stepping through the vectors. This
+%   is a quick way to create filters for FILTERBANK and UFILTERBANK.
+%
+%   WARPEDBLFILTER accepts the following optional parameters:
+%
+%     'complex'   Make the filter complex valued if the centre frequency
+%                 is non-zero.necessary. This is the default.
+%
+%     'real'      Make the filter real-valued if the centre frequency
+%                 is non-zero.
+%
+%     'delay',d   Set the delay of the filter. Default value is zero.
+%
+%     'scal',s    Scale the filter by the constant s. This can be
+%                 useful to equalize channels in a filterbank.
+%
+%   It is possible to normalize the transfer function of the filter by
+%   passing any of the flags from the NORMALIZE function. The default
+%   normalization is 'energy'.
+%
+%   The filter can be used in the PFILT routine to filter a signal, or
+%   in can be placed in a cell-array for use with FILTERBANK or
+%   UFILTERBANK.
+%
+%   The output format is the same as that of BLFILTER. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/fourier/warpedblfilter.php}
+%@seealso{blfilter, firwin, pfilt, filterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Define initial value for flags and key/value pairs.
+definput.import={'normalize'};
+definput.importdefaults={'energy'};
+definput.keyvals.delay=0;
+definput.keyvals.scal=1;
+definput.flags.real={'complex','real'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+[fsupp,fc,kv.delay,kv.scal]=scalardistribute(fsupp,fc,kv.delay,kv.scal);
+
+Nfilt=numel(fsupp);
+gout=cell(1,Nfilt);
+
+for ii=1:Nfilt
+    g=struct();
+    
+    
+    if flags.do_1 || flags.do_area 
+        g.H=@(L)    comp_warpedfreqresponse( winname,freqtoscale(fc(ii)), ...
+                                             fsupp(ii),fs,L,freqtoscale, ...
+                                             scaletofreq, flags.norm)*kv.scal(ii)*L;
+    end;
+    
+    if  flags.do_2 || flags.do_energy
+        g.H=@(L)    comp_warpedfreqresponse(winname,freqtoscale(fc(ii)), ...
+                                            fsupp(ii),fs,L,freqtoscale,scaletofreq, ...
+                                            flags.norm)*kv.scal(ii)*sqrt(L);
+    end;
+        
+    if flags.do_inf || flags.do_peak
+        g.H=@(L)    comp_warpedfreqresponse(winname,freqtoscale(fc(ii)), ...
+                                            fsupp(ii),fs,L,freqtoscale,scaletofreq, ...
+                                            flags.norm)*kv.scal(ii);
+    end;
+        
+    g.foff=@(L) comp_warpedfoff(freqtoscale(fc(ii)),fsupp(ii),fs,L,scaletofreq);
+    g.realonly=flags.do_real;
+    g.delay=kv.delay(ii);
+    g.fs=fs;
+    gout{ii}=g;
+end;
+
+if Nfilt==1
+    gout=g;
+end;
+
diff --git a/inst/frames/Contents.m b/inst/frames/Contents.m
new file mode 100644
index 0000000..864da44
--- /dev/null
+++ b/inst/frames/Contents.m
@@ -0,0 +1,61 @@
+% LTFAT - Frames
+%
+%  Peter L. Soendergaard, 2012 - 2014.
+%
+%  Creation of a frame object
+%    FRAME             - Construct a new frame
+%    FRAMEPAIR         - Construct a pair of frames
+%    FRAMEDUAL         - The canonical dual frame
+%    FRAMETIGHT        - The canonical tight frame
+%    FRAMEACCEL        - Precompute arrays for faster application
+%
+%  Linear operators
+%    FRANA             - Frame analysis
+%    FRSYN             - Frame synthesis
+%    FRSYNMATRIX       - Frame synthesis operator matrix
+%    FRAMEDIAG         - Diagonal of frame operator
+%    FRANAITER         - Iterative perfect reconstruction analysis
+%    FRSYNITER         - Iterative perfect reconstruction synthesis
+%
+%  Visualization
+%    PLOTFRAME         - Plot frame coefficients
+%    FRAMEGRAM         - Plot energy of signal in frame space
+%
+%  Information about a frame
+%    FRAMEBOUNDS       - Frame bounds
+%    FRAMERED          - Redundancy of frame
+%    FRAMELENGTH       - Length of frame to expand signal
+%    FRAMELENGTHCOEF   - Length of frame given a set of coefficients
+%
+%  Coefficients conversions
+%    FRAMECOEF2NATIVE  - Convert to native transform format
+%    FRAMENATIVE2COEF  - Convert native to column format
+%    FRAMECOEF2TF      - Convert to time-frequency plane layout
+%    FRAMETF2COEF      - Convert TF-plane layout to native
+%
+%  Non-linear analysis and synthesis
+%    FRANALASSO        - LASSO threshholding using Landweber iterations.
+%    FRANAGROUPLASSO   - Group LASSO threshholding.
+%    FRSYNABS          - Frame synthesis from magnitude of coefficients
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/frames/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/frames/frame.m b/inst/frames/frame.m
new file mode 100644
index 0000000..732e76e
--- /dev/null
+++ b/inst/frames/frame.m
@@ -0,0 +1,477 @@
+function F=frame(ftype,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} frame
+%@verbatim
+%FRAME  Construct a new frame
+%   Usage: F=frame(ftype,...);
+%
+%   F=FRAME(ftype,...) constructs a new frame object F of type
+%   ftype. Arguments following ftype are specific to the type of frame
+%   chosen.
+%
+%   Time-frequency frames
+%   ---------------------
+%
+%   FRAME('dgt',g,a,M) constructs a Gabor frame with window g,
+%   time-shift a and M channels. See the help on DGT for more
+%   information.
+%
+%   FRAME('dgtreal',g,a,M) constructs a Gabor frame for real-valued
+%   signals with window g, time-shift a and M channels. See the help
+%   on DGTREAL for more information.
+%
+%   FRAME('dwilt',g,M) constructs a Wilson basis with window g and M*
+%   channels. See the help on DWILT for more information.
+%
+%   FRAME('wmdct',g,M) constructs a windowed MDCT basis with window g*
+%   and M channels. See the help on WMDCT for more information.
+%
+%   FRAME('filterbank',g,a,M) constructs a filterbank with filters g,
+%   time-shifts of a and M channels. For the ease of implementation, it
+%   is necessary to specify M, even though it strictly speaking could be
+%   deduced from the size of the windows. See the help on FILTERBANK for
+%   more information on the parameters. Similarly, you can construct a
+%   uniform filterbank by selecting 'ufilterbank', a positive-frequency
+%   filterbank by selecting 'filterbankreal' or a uniform
+%   positive-frequency filterbank by selecting 'ufilterbankreal'.
+%
+%   FRAME('nsdgt',g,a,M) constructs a non-stationary Gabor frame with
+%   filters g, time-shifts of a and M channels. See the help on
+%   NSDGT for more information on the parameters. Similarly, you can
+%   construct a uniform NSDGT by selecting 'unsdgt', an NSDGT for
+%   real-valued signals only by selecting 'nsdgtreal' or a
+%   uniform NSDGT for real-valued signals by selecting 'unsdgtreal'.
+%
+%   Wavelet frames
+%   --------------
+%
+%   FRAME('fwt', w, J) constructs a wavelet frame with wavelet definition 
+%   w and J number of filterbank iterations. Similarly, a redundant time 
+%   invariant wavelet representation can be constructed by selecting 'ufwt'.
+%   See the help on FWT and UFWT for more information.
+%
+%   FRAME('wfbt', wt) constructs a wavelet filterbank tree defined by
+%   the wavelet filterbank tree definition wt. Similarly, an undecimated
+%   wavelet filterbank tree can be constructed by selecting 'uwfbt'. See the
+%   help on WFBT and UWFBT for more information.
+%
+%   FRAME('wpfbt', wt) constructs a wavelet packet filterbank tree 
+%   defined by the wavelet filterbank tree definition wt. Similarly, an
+%   undecimated wavelet packet filterbank tree can be constructed by selecting
+%   'uwpfbt'. See the help on WPFBT and UWPFBT for more information.
+%
+%   Pure frequency frames
+%   ---------------------
+%
+%   FRAME('dft') constructs a basis where the analysis operator is the
+%   DFT, and the synthesis operator is its inverse, IDFT. Completely
+%   similar to this, you can enter the name of any of the cosine or sine
+%   transforms DCTI, DCTII, DCTIII, DCTIV, DSTI, DSTII,
+%   DSTIII or DSTIV.
+%
+%   FRAME('dftreal') constructs a normalized FFTREAL basis for
+%   real-valued signals of even length only. The basis is normalized the
+%   DFT to ensure that is it orthonormal.
+%
+%   Special / general frames
+%   ------------------------
+%
+%   FRAME('gen',g) constructs an general frame with analysis matrix g.
+%   The frame atoms must be stored as column vectors in the matrices.
+%
+%   FRAME('identity') constructs the canonical orthornormal basis, meaning
+%   that all operators return their input as output, so it is the dummy
+%   operation.
+%
+%   FRAME('randn',red,seed) constructs a frame with redundancy red*
+%   consisting of random noise generated by randn. The optional parameter
+%   seed specifies the initial seed for the noise generation. All frame
+%   vectors are normalized to have unit energy / l^2-norm.
+%
+%   Container frames
+%   ----------------
+%
+%   FRAME('fusion',w,F1,F2,...) constructs a fusion frame, which is
+%   the collection of the frames specified by F1, F2,... The vector
+%   w contains a weight for each frame. If w is a scalar, this weight
+%   will be applied to all the sub-frames.
+%
+%   FRAME('tensor',F1,F2,...) constructs a tensor product frame, where the
+%   frames F1, F2,... are applied along the 1st, 2nd etc. dimensions. If
+%   you don't want any action along a specific dimension, use the identity
+%   frame along that dimension. Any remaining dimensions in the input
+%   signal are left alone.
+%  
+%   Examples
+%   --------
+%
+%   The following example creates a Modified Discrete Cosine Transform frame,
+%   analyses an input signal and plots the frame coefficients:
+%
+%      F=frame('wmdct','gauss',40);
+%      c=frana(F,greasy);
+%      plotframe(F,c);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frame.php}
+%@seealso{frana, frsyn, plotframe}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~ischar(ftype)
+  error(['%s: First argument must be a string denoting the type of ' ...
+         'frame.'],upper(mfilename));
+end;
+
+ftype=lower(ftype);
+
+% True if the frame only works with real-valued input.
+F.realinput=0;
+
+% Handle the windowed transforms
+switch(ftype)
+ case {'dgt','dwilt','wmdct','filterbank','ufilterbank',...
+       'nsdgt','unsdgt'}
+  F.g=varargin{1};
+  
+ case {'dgtreal','filterbankreal','ufilterbankreal',...
+      'nsdgtreal','unsdgtreal'}
+  F.g=varargin{1};
+  F.realinput=1;
+  
+end;
+
+% For parsing optional parameters to the transforms.
+vargs={};
+definput=struct();
+
+
+%% ---- Pre-optional parameters
+% Common operations to deal with the input parameters.
+
+switch(ftype)
+  case {'dgt','dgtreal'}
+    F.a=varargin{2};
+    F.M=varargin{3};
+    
+    vargs=varargin(4:end);
+    definput.keyvals.lt=[0 1];
+    definput.flags.phase={'freqinv','timeinv'};    
+
+  case {'dwilt','wmdct'}
+    F.M=varargin{2};
+  case {'filterbank','ufilterbank','filterbankreal','ufilterbankreal'}
+    F.a=varargin{2};
+    F.M=varargin{3};
+    
+    [F.a,~]=comp_filterbank_a(F.a,F.M,struct());
+    
+  case {'nsdgt','unsdgt','nsdgtreal','unsdgtreal'}
+    F.a=varargin{2};
+    F.M=varargin{3};
+    
+    % Sanitize 'a' and 'M'. Make M a column vector of length N,
+    % where N is determined from the length of 'a'
+    F.a=F.a(:);
+    F.N=numel(F.a);
+    F.M=bsxfun(@times,F.M(:),ones(F.N,1));
+    
+end;
+
+[F.flags,F.kv]=ltfatarghelper({},definput,vargs);
+
+F.type=ftype;
+F.origargs=varargin;
+
+
+%% ------ Post optional parameters
+
+% Default value, works for all bases
+F.red=1;
+
+% Default value, frame works for all lengths
+F.length=@(Ls) Ls;
+
+switch(ftype)
+  case 'gen'
+    F.g=varargin{1};
+    F.frana=@(insig) F.g'*insig;
+    F.frsyn=@(insig) F.g*insig;
+    F.length = @(Ls) size(F.g,1);
+    F.red = size(F.g,2)/size(F.g,1);
+      
+  case 'identity'
+    F.frana=@(insig) insig;
+    F.frsyn=@(insig) insig;
+    
+  case 'dft'
+    F.frana=@(insig) dft(insig,[],1);
+    F.frsyn=@(insig) idft(insig,[],1);
+
+  case 'dcti'
+    F.frana=@(insig) dcti(insig,[],1);
+    F.frsyn=@(insig) dcti(insig,[],1);
+
+  case 'dctii'
+    F.frana=@(insig) dctii(insig,[],1);
+    F.frsyn=@(insig) dctiii(insig,[],1);
+
+  case 'dctiii'
+    F.frana=@(insig) dctiii(insig,[],1);
+    F.frsyn=@(insig) dctii(insig,[],1);
+
+  case 'dctiv'
+    F.frana=@(insig) dctiv(insig,[],1);
+    F.frsyn=@(insig) dctiv(insig,[],1);
+
+  case 'dsti'
+    F.frana=@(insig) dsti(insig,[],1);
+    F.frsyn=@(insig) dsti(insig,[],1);
+
+  case 'dstii'
+    F.frana=@(insig) dstii(insig,[],1);
+    F.frsyn=@(insig) dstiii(insig,[],1);
+
+  case 'dstiii'
+    F.frana=@(insig) dstiii(insig,[],1);
+    F.frsyn=@(insig) dstii(insig,[],1);
+
+  case 'dstiv'
+    F.frana=@(insig) dstiv(insig,[],1);
+    F.frsyn=@(insig) dstiv(insig,[],1);
+
+  case 'dftreal'
+    F.frana=@(insig) fftreal(insig,[],1)/sqrt(size(insig,1));
+    F.frsyn=@(insig) ifftreal(insig,(size(insig,1)-1)*2,1)*sqrt((size(insig,1)-1)*2);
+    F.length=@(Ls) ceil(Ls/2)*2;
+    F.lengthcoef=@(Ncoef) (Ncoef-1)*2;
+    F.realinput=1;
+
+  case 'dgt'
+    F.coef2native=@(coef,s) reshape(coef,[F.M,s(1)/F.M,s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(comp_dgt(insig,F.g,F.a,F.M,F.kv.lt,F.flags.do_timeinv,0,0));
+    F.frsyn=@(insig) comp_idgt(F.coef2native(insig,size(insig)),F.g,F.a,F.kv.lt,F.flags.do_timeinv,0);    
+    F.length=@(Ls) dgtlength(Ls,F.a,F.M,F.kv.lt);
+    F.red=F.M/F.a;
+    
+  case 'dgtreal'
+    F.coef2native=@(coef,s) reshape(coef,[floor(F.M/2)+1,s(1)/(floor(F.M/ ...
+                                                      2)+1),s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(comp_dgtreal(insig,F.g,F.a,F.M,F.kv.lt,F.flags.do_timeinv));
+    F.frsyn=@(insig) comp_idgtreal(F.coef2native(insig,size(insig)),F.g,F.a,F.M,F.kv.lt,F.flags.do_timeinv);  
+    F.length=@(Ls) dgtlength(Ls,F.a,F.M,F.kv.lt);
+    F.red=F.M/F.a;
+    F.lengthcoef=@(Ncoef) Ncoef/(floor(F.M/2)+1)*F.a;
+    
+  case 'dwilt'
+    F.coef2native=@(coef,s) reshape(coef,[2*F.M,s(1)/F.M/2,s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(comp_dwilt(insig,F.g,F.M));
+    F.frsyn=@(insig) comp_idwilt(F.coef2native(insig,size(insig)),F.g);  
+    F.length=@(Ls) dwiltlength(Ls,F.M);
+    
+  case 'wmdct'
+    F.coef2native=@(coef,s) reshape(coef,[F.M,s(1)/F.M,s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(comp_dwiltiii(insig,F.g,F.M));
+    F.frsyn=@(insig) comp_idwiltiii(F.coef2native(insig,size(insig)),F.g);  
+    F.length=@(Ls) dwiltlength(Ls,F.M);        
+    
+  case 'filterbank'
+    F.red=sum(F.a(:,2)./F.a(:,1));
+    F.length=@(Ls) filterbanklength(Ls,F.a);
+    F.lengthcoef=@(Ncoef) Ncoef/F.red;
+    F.native2coef=@(coef) cell2mat(coef(:));
+    F.coef2native=@(coef,s) vect2cell(coef,round(s(1)/F.red*F.a(:,2)./F.a(:,1)));
+    F.frana=@(insig) F.native2coef(comp_filterbank(insig,F.g,F.a));
+    F.frsyn=@(insig) comp_ifilterbank(F.coef2native(insig,size(insig)),...
+                                      F.g,F.a,round(size(insig,1)/F.red));
+    F.destructor=@() clear('comp_filterbank','comp_ifilterbank');
+    
+  case 'filterbankreal'
+    F.red=2*sum(F.a(:,2)./F.a(:,1));
+    F.length=@(Ls) filterbanklength(Ls,F.a);
+    F.lengthcoef=@(Ncoef) 2*Ncoef/(F.red);
+    F.native2coef=@(coef) cell2mat(coef(:));
+    F.coef2native=@(coef,s) vect2cell(coef,round(2*s(1)/F.red*F.a(:,2)./F.a(:,1)));
+    F.frana=@(insig) F.native2coef(comp_filterbank(insig,F.g,F.a));
+    F.frsyn=@(insig) 2*real(comp_ifilterbank(F.coef2native(insig,size(insig)),F.g,F.a,...
+                                             2*round(size(insig,1)/F.red)));
+    F.destructor=@() clear('comp_filterbank','comp_ifilterbank');
+
+    
+  case 'ufilterbank'
+    F.red=sum(F.a(:,2)./F.a(:,1));
+    F.length=@(Ls) filterbanklength(Ls,F.a);
+    F.lengthcoef=@(Ncoef) round(Ncoef/F.red);
+    F.coef2native=@(coef,s) reshape(coef,[s(1)/F.M,F.M,s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(ufilterbank(insig,F.g,F.a));
+    F.frsyn=@(insig) ifilterbank(F.coef2native(insig,size(insig)),F.g,F.a);   
+    
+  case 'ufilterbankreal'
+    F.red=2*sum(F.a(:,2)./F.a(:,1));
+    F.length=@(Ls) filterbanklength(Ls,F.a);
+    F.lengthcoef=@(Ncoef) round(Ncoef/F.red*2);
+    F.coef2native=@(coef,s) reshape(coef,[s(1)/F.M,F.M,s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(ufilterbank(insig,F.g,F.a));
+    F.frsyn=@(insig) 2*real(ifilterbank(F.coef2native(insig,size(insig)),F.g, ...
+                                        F.a));
+    
+  case 'nsdgt'
+    F.coef2native=@(coef,s) mat2cell(coef,F.M,s(2));
+    F.native2coef=@(coef) cell2mat(coef(:));
+    F.length=@(Ncoef) sum(F.a);
+    F.lengthcoef=@(Ncoef) sum(F.a);
+    F.red=sum(F.M)/sum(F.a);
+    F.frana=@(insig) F.native2coef(nsdgt(insig,F.g,F.a,F.M));
+    F.frsyn=@(insig) insdgt(F.coef2native(insig,size(insig)),F.g,F.a);
+    
+  case 'unsdgt'
+    F.coef2native=@(coef,s) reshape(coef,[F.M(1),s(1)/F.M(1),s(2)]);
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(unsdgt(insig,F.g,F.a,F.M));
+    F.frsyn=@(insig) insdgt(F.coef2native(insig,size(insig)),F.g,F.a);
+    F.length=@(Ncoef) sum(F.a);
+    F.lengthcoef=@(Ncoef) sum(F.a);
+    F.red=sum(F.M)/sum(F.a);    
+
+  case 'nsdgtreal'
+    F.coef2native=@(coef,s) mat2cell(coef,floor(F.M/2)+1,s(2));
+    F.native2coef=@(coef) cell2mat(coef(:));
+    F.frana=@(insig) F.native2coef(nsdgtreal(insig,F.g,F.a,F.M));
+    F.frsyn=@(insig) insdgtreal(F.coef2native(insig,size(insig)),F.g,F.a,F.M);
+    F.length=@(Ncoef) sum(F.a);
+    F.lengthcoef=@(Ncoef) sum(F.a);
+    F.red=sum(F.M)/sum(F.a);    
+    
+  case 'unsdgtreal'
+    F.coef2native=@(coef,s) reshape(coef,floor(F.M(1)/2)+1,s(1)/ ...
+                                    (floor(F.M(1)/2)+1),s(2));
+    F.native2coef=@(coef)   reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(unsdgtreal(insig,F.g,F.a,F.M));
+    F.frsyn=@(insig) insdgtreal(F.coef2native(insig,size(insig)),F.g,F.a,F.M);
+    F.length=@(Ncoef) sum(F.a);
+    F.lengthcoef=@(Ncoef) sum(F.a);
+    F.red=sum(F.M)/sum(F.a);    
+                
+  case 'fusion'
+    F.w=varargin{1};
+    F.frames=varargin(2:end);
+    F.Nframes=numel(F.frames);
+    F.w=bsxfun(@times,F.w(:),ones(F.Nframes,1));    
+    F.length = @(Ls) comp_framelength_fusion(F,Ls);
+    F.red=sum(cellfun(@framered,F.frames));
+    
+    % These definitions binds F itself, so they must execute last
+    F.frana=@(insig) comp_frana_fusion(F,insig);
+    F.frsyn=@(insig) comp_frsyn_fusion(F,insig);
+
+    
+  case 'tensor'
+    % This frame type is currently broken. It must be reworked to reshape
+    % to the standard layout in order not to break all the assumptions.
+    F.frames=varargin;
+    F.Nframes=numel(F.frames);
+    for ii=1:F.Nframes
+        if F.frames{ii}.realinput
+            error(['It is not safe to embed a real-valued-input-only frame ' ...
+                   'into the tensor frame.']);
+        end;
+    end;
+    
+    F.frana=@(insig) comp_frana_tensor(F,insig);
+    F.frsyn=@(insig) comp_frsyn_tensor(F,insig);
+    
+    F.length=@(Ls) comp_framelength_tensor(F,Ls);
+
+    F.red=prod(cellfun(@framered,F.frames));
+    
+  case {'fwt'}
+    F.J=varargin{2};
+    F.g=fwtinit({'strict',varargin{1}});
+    F.red= 1/(F.g.a(1)^(F.J)) + sum(1./(F.g.a(1).^(0:F.J-1))*sum(1./F.g.a(2:end)));
+    F.frana=@(insig) fwt(insig,F.g,F.J);
+    F.frsyn=@(insig) ifwt(insig,F.g,F.J,size(insig,1)/F.red);
+    F.length=@(Ls) fwtlength(Ls,F.g,F.J);
+  case {'wfbt'}
+    F.g=wfbtinit({'strict',varargin{1}});
+    F.red = sum(1./treeSub(F.g));
+    F.wtPath = nodesBForder(F.g);
+    F.rangeLoc = rangeInLocalOutputs(F.wtPath,F.g);
+    F.rangeOut = rangeInOutputs(F.wtPath,F.g);
+    F.coef2native = @(coef,s) wavpack2cell(coef,wfbtclength(s(1)/F.red,F.g));
+    F.native2coef = @(coef) wavcell2pack(coef);
+    F.frana=@(insig) F.native2coef(comp_wfbt(insig,F.g.nodes(F.wtPath),F.rangeLoc,F.rangeOut,'per'));
+    F.frsyn=@(insig) iwfbt(F.coef2native(insig,size(insig)),F.g,size(insig,1)/F.red);
+    F.length=@(Ls) wfbtlength(Ls,F.g);
+  case {'wpfbt'}
+    F.g=wfbtinit({'strict',varargin{1}});
+    F.red = sum(cellfun(@(aEl) sum(1./aEl),nodeSub(nodesBForder(F.g),F.g)));
+    F.coef2native = @(coef,s) wavpack2cell(coef,...
+                    s(1)./cell2mat(cellfun(@(aEl) aEl(:),...
+                    reshape(nodeSub(nodesBForder(F.g),F.g),[],1),'UniformOutput',0))./F.red);
+    F.native2coef = @(coef) wavcell2pack(coef);
+
+    F.frana=@(insig) F.native2coef(wpfbt(insig,F.g));
+    F.frsyn=@(insig) iwpfbt(F.coef2native(insig,size(insig)),F.g,size(insig,1)/F.red);
+    F.length=@(Ls) wfbtlength(Ls,F.g);
+  case {'ufwt'}
+    F.J=varargin{2};
+    F.g=fwtinit({'strict',varargin{1}});
+    F.coef2native = @(coef,s) reshape(coef,[s(1)/(F.J*(numel(F.g.a)-1)+1),F.J*(numel(F.g.a)-1)+1,s(2)]);
+    F.native2coef = @(coef) reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(ufwt(insig,F.g,F.J));
+    F.frsyn=@(insig) iufwt(F.coef2native(insig,size(insig)),F.g,F.J);
+    F.length=@(Ls) Ls;
+    F.red=(F.J*(numel(F.g.a)-1)+1);
+  case {'uwfbt'}
+    F.g=wfbtinit({'strict',varargin{1}});
+    F.red = noOfOutputs(F.g);
+    F.coef2native = @(coef,s) reshape(coef,[s(1)/F.red,F.red,s(2)]);
+    F.native2coef = @(coef) reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(uwfbt(insig,F.g));
+    F.frsyn=@(insig) iuwfbt(F.coef2native(insig,size(insig)),F.g);
+    F.length=@(Ls) Ls;
+  case {'uwpfbt'}
+    F.g= wfbtinit({'strict',varargin{1}});
+    F.red = sum(cellfun(@(fEl) numel(fEl.g),F.g.nodes));
+    F.coef2native = @(coef,s) reshape(coef,[s(1)/F.red,F.red,s(2)]);
+    F.native2coef = @(coef) reshape(coef,[size(coef,1)*size(coef,2),size(coef,3)]);
+    F.frana=@(insig) F.native2coef(uwpfbt(insig,F.g));
+    F.frsyn=@(insig) iuwpfbt(F.coef2native(insig,size(insig)),F.g);
+    F.length=@(Ls) Ls;
+  otherwise
+    error('%s: Unknown frame type: %s',upper(mfilename),ftype);  
+
+end;
+
+% This one is placed at the end, to allow for F.red to be defined
+% first.
+if ~isfield(F,'lengthcoef')
+    F.lengthcoef=@(Ncoef) Ncoef/framered(F);
+end;
+
diff --git a/inst/frames/frameaccel.m b/inst/frames/frameaccel.m
new file mode 100644
index 0000000..2d45d59
--- /dev/null
+++ b/inst/frames/frameaccel.m
@@ -0,0 +1,120 @@
+function F=frameaccel(F,Ls);  
+%-*- texinfo -*-
+%@deftypefn {Function} frameaccel
+%@verbatim
+%FRAMEACCEL  Precompute structures
+%   Usage: F=frameaccel(F,L);
+%
+%   F=FRAMEACCEL(F,Ls) precomputes certain structures that makes the basic
+%   frame operations FRANA and FRSYN faster (like instantiating the
+%   window from a textual description). If you only need to call the
+%   routines once, calling FRAMEACCEL first will not provide any total
+%   gain, but if you are repeatedly calling these routines, for instance in
+%   an iterative algorithm, is will be a benefit.
+%
+%   Notice that you need to input the signal length Ls, so this routines
+%   is only a benefit if Ls stays fixed.
+%
+%   If FRAMEACCEL is called twice for the same transform length, no
+%   additional computations will be done.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frameaccel.php}
+%@seealso{frame, frana, framelength, framelengthcoef}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+L=framelength(F,Ls);
+
+if (isfield(F,'L') && (L==F.L))
+  % Quick return, we have already accelerated
+  return
+end;
+
+F.L=L;
+
+if strcmp(F.type,'fusion')
+    for ii=1:F.Nframes
+        accel_frames{ii}=frameaccel(F.frames{ii},Ls);
+    end;
+    F=frame('fusion',F.w,accel_frames{:});
+    F.L=L;
+    return;
+end;
+
+if strcmp(F.type,'tensor')
+    for ii=1:F.Nframes
+        accel_frames{ii}=frameaccel(F.frames{ii},Ls);
+    end;
+    F=frame('tensor',accel_frames{:});
+    F.L=L;
+    return;
+end;
+
+
+if ~isfield(F,'g')
+  % Quick exit, the frame does not use a window. In this case, the frame
+  % always has a factorization
+  
+  % Default values for a lot of transforms
+  F.isfac=1;
+
+  return;
+end;
+  
+% From this point and on, we are sure that F.g exists
+
+if ~isempty(F.g)
+    switch(F.type)
+      case 'gen'
+        F.isfac=~issparse(F.g);  
+      case {'dgt','dgtreal'}
+        [g, info] =  gabwin(F.g,F.a,F.M,L,F.kv.lt);
+        F = frame(F.type,g,F.origargs{2:end});
+        F.g_info = info;
+        F.isfac=1;
+      case {'dwilt','wmdct'}
+        [g, info] = wilwin(F.g,F.M,L,upper(mfilename));
+        F = frame(F.type,g,F.origargs{2:end});
+        F.g_info = info;
+        F.isfac=1;
+      case {'filterbank','ufilterbank'}
+        [g, info]  = filterbankwin(F.g,F.a,L);
+        kv = arg_pfilt();
+        g = comp_filterbank_pre(g,F.a,L,1000);
+        F = frame(F.type,g,F.origargs{2:end});
+        F.g_info = info;
+        F.isfac=F.g_info.isfac;
+      case {'filterbankreal','ufilterbankreal'}
+        [g,info]  = filterbankwin(F.g,F.a,L,'real');
+        kv = arg_pfilt();
+        g = comp_filterbank_pre(g,F.a,L,1000);
+        F = frame(F.type,g,F.origargs{2:end});
+        F.g_info = info;
+        F.isfac=F.g_info.isfac;
+      case {'nsdgt','unsdgt','nsdgtreal','unsdgtreal'}
+        [F.g,F.g_info]  = nsgabwin(F.g,F.a,F.M);
+        F.isfac=F.g_info.isfac;
+      case {'fwt','wfbt'}
+        F.isfac = 1; 
+    end;
+end;
+
+F.L=L;
+
+
diff --git a/inst/frames/framebounds.m b/inst/frames/framebounds.m
new file mode 100644
index 0000000..7fe5717
--- /dev/null
+++ b/inst/frames/framebounds.m
@@ -0,0 +1,215 @@
+function [AF,BF]=framebounds(F,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} framebounds
+%@verbatim
+%FRAMEBOUNDS  Frame bounds
+%   Usage: fcond=framebounds(F);
+%          [A,B]=framebounds(F);
+%
+%   FRAMEBOUNDS(F) calculates the ratio B/A of the frame bounds of the
+%   frame given by F.
+%
+%   FRAMEBOUNDS(F,Ls) additionally specifies a signal length for which
+%   the frame should work.
+%
+%   [A,B]=FRAMEBOUNDS(F) returns the frame bounds A and B instead of
+%   just their ratio.
+%
+%   'framebounds` accepts the following optional parameters:
+%
+%     'fac'        Use a factorization algorithm. The function will throw
+%                  an error if no algorithm is available.
+%
+%     'iter'       Call eigs to use an iterative algorithm.
+%
+%     'full'       Call eig to solve the full problem.
+%
+%     'auto'       Choose the fac method if possible, otherwise
+%                  use the full method for small problems and the
+%                  iter method for larger problems. This is the
+%                  default. 
+%
+%     'crossover',c
+%                  Set the problem size for which the 'auto' method
+%                  switches between full and iter. Default is 200.
+%
+%   The following parameters specifically related to the iter method: 
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'p',p        The number of Lanzcos basis vectors to use.  More vectors
+%                  will result in faster convergence, but a larger amount of
+%                  memory.  The optimal value of p is problem dependent and
+%                  should be less than L.  The default value is 2.
+% 
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framebounds.php}
+%@seealso{frame, framered}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% We handle the container frames first
+  if strcmp(F.type,'fusion')
+      AF=0;
+      BF=0;
+      for ii=1:F.Nframes
+          [A,B]=framebounds(F.frames{ii},varargin{:});
+          AF=AF+(A*F.w(ii)).^2;
+          BF=BF+(B*F.w(ii)).^2;
+      end;
+      AF=sqrt(AF);
+      BF=sqrt(BF);
+        
+      return;
+  end;    
+  
+  if strcmp(F.type,'tensor')
+    AF=1;
+    BF=1;
+    for ii=1:F.Nframes
+      [A,B]=framebounds(F.frames{ii},varargin{:});
+      AF=AF*A;
+      BF=BF*B;
+    end;
+    
+    return;
+  end;    
+    
+  definput.keyvals.Ls=1;
+  definput.keyvals.maxit=100;
+  definput.keyvals.tol=1e-9;
+  definput.keyvals.crossover=200;
+  definput.keyvals.p=4;
+  definput.flags.print={'quiet','print'};
+  definput.flags.method={'auto','fac','iter','full'};
+  
+  [flags,kv]=ltfatarghelper({'Ls'},definput,varargin);
+  
+  F=frameaccel(F,kv.Ls);
+  L=F.L;
+  
+  % Default values, works for the pure frequency transforms.
+  AF=1;
+  BF=1;
+  
+  % Simple heuristic: If F.g is defined, the frame uses windows.
+  if isfield(F,'g')
+      if isempty(F.g)
+          error('%s: No analysis frame is defined.', upper(mfilename));
+      end;
+      g=F.g;
+      op    = @frana;
+      opadj = @frsyn;
+  end;
+
+  F_isfac = isfield(F,'isfac') && F.isfac;
+  
+  if flags.do_fac && ~F_isfac
+    error('%s: The type of frame has no factorization algorithm.',upper(mfilename));
+  end;
+    
+  if (flags.do_auto && F_isfac) || flags.do_fac
+    switch(F.type)
+     case 'gen'
+      V=svd(g);
+      AF=min(V)^2;
+      BF=max(V)^2;
+     case {'dgt','dgtreal'}
+      [AF,BF]=gabframebounds(g,F.a,F.M,L); 
+     case {'dwilt','wmdct'}
+      [AF,BF]=wilbounds(g,F.M,L); 
+     case {'filterbank','ufilterbank'}
+      [AF,BF]=filterbankbounds(g,F.a,L);
+     case {'filterbankreal','ufilterbankreal'}
+      [AF,BF]=filterbankrealbounds(g,F.a,L); 
+     case 'fwt'
+      [AF,BF]=fwtbounds(g,F.J,L);
+     case 'wfbt'
+      [AF,BF]=wfbtbounds(g,L);
+    end;  
+  end;
+  
+  if (flags.do_auto && ~F_isfac && F.L>kv.crossover) || flags.do_iter
+    
+    if flags.do_print
+      opts.disp=1;
+    else
+      opts.disp=0;
+    end;
+    opts.isreal = false;
+    opts.maxit  = kv.maxit;
+    opts.tol    = kv.tol;
+    %opts.issym  = 1;
+    opts.p      = kv.p;
+    
+    %afun(1,F,op,opadj); 
+    % The inverse method does not work.
+    %AF = real(eigs(@afun,L,1,'SM',opts));
+    %BF = real(eigs(@afun,L,1,'LM',opts));
+    BF = real(eigs(@(x) opadj(F,op(F,x)),L,1,'LM',opts));
+    
+  end;
+  
+  if (flags.do_auto && ~F_isfac && F.L<=kv.crossover) || flags.do_full
+    % Compute thee transform matrix.
+    bigM=opadj(F,op(F,eye(L)));
+    
+    D=eig(bigM);
+    
+    % Clean the eigenvalues, we know they are real
+    D=real(D);
+    AF=min(D);
+    BF=max(D);
+  end;
+
+  if nargout<2
+    % Avoid the potential warning about division by zero.
+    if AF==0
+      AF=Inf;
+    else
+      AF=BF/AF;
+    end;
+  end;
+  
+end
+
+% The function has been written in this way, because Octave (at the time
+% of writing) does not accept additional parameters at the end of the
+% line of input arguments for eigs
+function y=afun(x,F_in,op_in,opadj_in)
+  persistent F;
+  persistent op;
+  persistent opadj;
+  
+  if nargin>1
+    F     = F_in; 
+    op    = op_in;
+    opadj = opadj_in;
+  else
+    y=opadj(F,op(F,x));
+  end;
+
+end
+
diff --git a/inst/frames/framecoef2native.m b/inst/frames/framecoef2native.m
new file mode 100644
index 0000000..8029c30
--- /dev/null
+++ b/inst/frames/framecoef2native.m
@@ -0,0 +1,46 @@
+function coef=framecoef2native(F,coef);
+%-*- texinfo -*-
+%@deftypefn {Function} framecoef2native
+%@verbatim
+%FRAMECOEF2NATIVE  Convert coefficients to native format
+%   Usage: cout=framecoef2native(F,cin);
+%
+%   FRAMECOEF2NATIVE(F,coef) converts the frame coefficients coef into the
+%   native coefficient format of the frame. The frame object F must have been
+%   created using FRAME.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framecoef2native.php}
+%@seealso{frame, framenative2coef, framecoef2tf}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First agument must be a frame definition structure.',upper(mfilename));
+end;
+
+[MN,W]=size(coef);
+
+if isfield(F,'coef2native')
+    coef=F.coef2native(coef,size(coef));
+end;
+
diff --git a/inst/frames/framecoef2tf.m b/inst/frames/framecoef2tf.m
new file mode 100644
index 0000000..65398e6
--- /dev/null
+++ b/inst/frames/framecoef2tf.m
@@ -0,0 +1,88 @@
+function coef=framecoef2tf(F,coef);
+%-*- texinfo -*-
+%@deftypefn {Function} framecoef2tf
+%@verbatim
+%FRAMECOEF2TF  Convert coefficients to time-frequency plane
+%   Usage: cout=framecoef2tf(F,cin);
+%
+%   FRAMECOEF2TF(F,coef) converts the frame coefficients coef into the
+%   time-frequency plane layout. The frame object F must have been
+%   created using FRAME.
+%
+%   The time-frequency plane layout is a matrix, where the first
+%   dimension indexes frequency and the second dimension time. This is
+%   similar to the output format from DGT and WMDCT.
+%
+%   Not all frame types support this coefficient layout. The supported frame
+%   types are: 'dgt', 'dgtreal', 'dwilt', 'wmdct' and
+%   'ufilterbank'.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framecoef2tf.php}
+%@seealso{frame, frametf2coef, framecoef2native}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First agument must be a frame definition structure.',upper(mfilename));
+end;
+
+switch(F.type)
+   case 'fwt'
+    coef = wavpack2cell(coef,fwtclength(floor(size(coef,1)/F.red),F.g,F.J));
+   case {'wfbt','wpfbt','filterbank','filterbankreal'}
+    coef = F.coef2native(coef,size(coef));   
+end
+
+
+switch(F.type)
+ case 'dgt'
+  [MN,W]=size(coef);
+  N=MN/F.M;
+  coef=reshape(coef,[F.M,N,W]);  
+ case 'dgtreal'
+  [MN,W]=size(coef);
+  M2=floor(F.M/2)+1;
+  N=MN/M2;
+  coef=reshape(coef,[M2,N,W]);  
+ case 'dwilt'
+  [MN,W]=size(coef);
+  N=MN/F.M;
+  coef=wil2rect(reshape(coef,[2*F.M,N/2,W]));  
+ case 'wmdct'
+  [MN,W]=size(coef);
+  N=MN/F.M;
+  coef=reshape(coef,[F.M,N,W]);  
+ case 'ufilterbank'
+  [MN,W]=size(coef);
+  M=numel(F.gs);
+  N=MN/M;
+  coef=permute(reshape(coef,[N,M,W]),[2,1,3]); 
+ case {'ufwt','uwfbt','uwpfbt'}
+  coef = permute(F.coef2native(coef,size(coef)),[2,1,3]); 
+ case {'fwt','wfbt','wpfbt','filterbank','filterbankreal'}
+  coef = comp_cellcoef2tf(coef);
+ otherwise
+  error('%s: TF-plane layout not supported for this transform.',upper(mfilename));
+end;
+
+
diff --git a/inst/frames/framediag.m b/inst/frames/framediag.m
new file mode 100644
index 0000000..95b87b7
--- /dev/null
+++ b/inst/frames/framediag.m
@@ -0,0 +1,67 @@
+function d=framediag(F,L);
+%-*- texinfo -*-
+%@deftypefn {Function} framediag
+%@verbatim
+%FRAMEDIAG  Compute the diagonal of the frame operator
+%   Usage: d=framediag(F,L);
+%
+%   FRAMEDIAG(F,L) computes the diagonal of the frame operator for a
+%   frame of type F of length L.
+%
+%   The diagonal of the frame operator can for instance be used as a
+%   preconditioner.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framediag.php}
+%@seealso{franaiter, frsyniter}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First agument must be a frame definition structure.',upper(mfilename));
+end;
+
+% Standard response, works for all tight and orthonormal systems
+d=ones(L,1);
+
+switch(F.type)
+  case 'gen'
+    d=diag(F.g*F.g');
+    
+  case {'dgt','dgtreal'}
+    d=gabframediag(F.g,F.a,F.M,L,F.vars{:});  
+  
+  case {'dwilt','wmdct'}
+    d=wilframediag(F.g,F.M,L);
+    
+  case {'filterbank','ufilterbank','filterbankreal','ufilterbankreal'}
+    error('Not implemented yet.');
+
+  case {'nsdgt','unsdgt','nsdgtreal','unsdgtreal'}
+    d=nsgabframediag(F.g,F.a,F.M);
+    
+  case 'fusion'
+    error('Not implemented yet.');
+end;
+
+
+
diff --git a/inst/frames/framedual.m b/inst/frames/framedual.m
new file mode 100644
index 0000000..55aa7d4
--- /dev/null
+++ b/inst/frames/framedual.m
@@ -0,0 +1,81 @@
+function Fd=framedual(F);
+%-*- texinfo -*-
+%@deftypefn {Function} framedual
+%@verbatim
+%FRAMEDUAL  Construct the canonical dual frame
+%   Usage: F=framedual(F);
+%
+%   Fd=FRAMEDUAL(F) returns the canonical dual frame of F.
+%
+%   The canonical dual frame can be used to get perfect reconstruction as in
+%   the following example:
+%
+%     % Create a frame and its canonical dual
+%     F=frame('dgt','hamming',32,64);
+%     Fd=framedual(F);
+%
+%     % Compute the frame coefficients and test for perfect
+%     % reconstruction
+%     f=gspi;
+%     c=frana(F,f);
+%     r=frsyn(Fd,c);
+%     norm(r(1:length(f))-f)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framedual.php}
+%@seealso{frame, framepair, frametight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% Default operation, work for a lot of frames
+Fd=F;
+
+% Handle the windowed transforms
+switch(F.type)
+  case {'dgt','dgtreal','dwilt','wmdct','filterbank','ufilterbank',...
+        'nsdgt','unsdgt','nsdgtreal','unsdgtreal',...
+        'fwt','ufwt','wfbt','uwfbt','wpfbt','uwpfbt'}
+    
+    Fd=frame(F.type,{'dual',F.g},F.origargs{2:end});
+    
+  case {'filterbankreal','ufilterbankreal'}
+    Fd=frame(F.type,{'realdual',F.g},F.origargs{2:end});
+    
+  case 'gen'
+    Fd=frame('gen',pinv(F.g)');
+    
+  case 'tensor'
+    for ii=1:F.Nframes
+        dual_frames{ii}=framedual(F.frames{ii});        
+    end;
+    Fd=frame('tensor',dual_frames{:});
+        
+  case 'fusion'
+    dual_w=1./(F.Nframes*F.w);
+    for ii=1:F.Nframes
+        dual_frames{ii}=framedual(F.frames{ii});        
+    end;
+    Fd=frame('fusion',dual_w,dual_frames{:});
+    
+      
+end;
+
diff --git a/inst/frames/framegram.m b/inst/frames/framegram.m
new file mode 100644
index 0000000..2c0b622
--- /dev/null
+++ b/inst/frames/framegram.m
@@ -0,0 +1,38 @@
+function framegram(F,x,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} framegram
+%@verbatim
+%FRAMEGRAM  Easy visualization of energy in frame space
+%   Usage: framegram(F,x);
+%
+%   FRAMEGRAM(F,x) plots the energy of the coefficients computed from
+%   the input signal x using the frame F for analysis. This is
+%   just a shorthand for:
+%
+%     plotframe(F,abs(frana(F,x)).^2);
+%
+%   Any additional arguments given to FRAMEGRAM are passed onto
+%   PLOTFRAME.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framegram.php}
+%@seealso{plotframe}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+plotframe(F,abs(frana(F,x)).^2,varargin{:});
diff --git a/inst/frames/framelength.m b/inst/frames/framelength.m
new file mode 100644
index 0000000..23c71e8
--- /dev/null
+++ b/inst/frames/framelength.m
@@ -0,0 +1,38 @@
+function L=framelength(F,Ls);
+%-*- texinfo -*-
+%@deftypefn {Function} framelength
+%@verbatim
+%FRAMELENGTH  Frame length from signal
+%   Usage: L=framelength(F,Ls);
+%
+%   FRAMELENGTH(F,Ls) returns the length of the frame F, such that
+%   F is long enough to expand a signal of length Ls.
+%
+%   If the frame length is longer than the signal length, the signal will be
+%   zero-padded by FRANA.
+%
+%   If instead a set of coefficients are given, call FRAMELENGTHCOEF.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framelength.php}
+%@seealso{frame, framelengthcoef}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+L=F.length(Ls);
+
diff --git a/inst/frames/framelengthcoef.m b/inst/frames/framelengthcoef.m
new file mode 100644
index 0000000..4bd668c
--- /dev/null
+++ b/inst/frames/framelengthcoef.m
@@ -0,0 +1,52 @@
+function L=framelengthcoef(F,Ncoef);
+%-*- texinfo -*-
+%@deftypefn {Function} framelengthcoef
+%@verbatim
+%FRAMELENGTHCOEF  Frame length from coefficients
+%   Usage: L=framelengthcoef(F,Ncoef);
+%
+%   FRAMELENGTHCOEF(F,Ncoef) returns the length of the frame F, such that
+%   F is long enough to expand the coefficients of length Ncoef.
+%
+%   If instead a signal is given, call FRAMELENGTH.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framelengthcoef.php}
+%@seealso{frame, framelength}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isscalar(Ncoef)
+  error('%s: Ncoef must be a scalar.',upper(mfilename));
+end;
+
+L = F.lengthcoef(Ncoef);
+% sprintf for Octave compatibility
+assert(abs(L-round(L))<1e-3,sprintf('%s: There is a bug. L=%d should be an integer.',upper(mfilename),L));
+L=round(L);
+    
+% Verify the computed length
+if ~(L==framelength(F,L))
+    error(['%s: The coefficient number given does not correspond to a valid ' ...
+           'set of coefficients for this type of frame.'],upper(mfilename));
+    
+end;
diff --git a/inst/frames/framenative2coef.m b/inst/frames/framenative2coef.m
new file mode 100644
index 0000000..9a93303
--- /dev/null
+++ b/inst/frames/framenative2coef.m
@@ -0,0 +1,42 @@
+function coef=framenative2coef(F,coef);
+%-*- texinfo -*-
+%@deftypefn {Function} framenative2coef
+%@verbatim
+%FRAMENATIVE2COEF  Convert coefficient from native format
+%   Usage: cout=framenative2coef(F,cin);
+%
+%   FRAMENATIVE2COEF(F,coef) convert frame coefficients from the native
+%   format of the transform into the common column format.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framenative2coef.php}
+%@seealso{frame, framecoef2native}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First agument must be a frame definition structure.',upper(mfilename));
+end;
+
+if isfield(F,'native2coef')
+   coef=F.native2coef(coef);
+end
diff --git a/inst/frames/framepair.m b/inst/frames/framepair.m
new file mode 100644
index 0000000..7c47f79
--- /dev/null
+++ b/inst/frames/framepair.m
@@ -0,0 +1,81 @@
+function [F1,F2]=framepair(ftype,g1,g2,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} framepair
+%@verbatim
+%FRAMEPAIR  Construct a new frame
+%   Usage: F=framepair(ftype,g1,g2,...);
+%
+%   [F1,F2]=FRAMEPAIR(ftype,g1,g2,...) constructs two new frame objects F1 
+%   and F2 of the same type ftype using the windows g1 and g2. The 
+%   windows are specific to choosen frame type. See the help on frame for the
+%   windows and arguments. 
+%
+%   This function makes it easy to create a pair of canonical dual frames:
+%   simply specify 'dual' as window if one frame should be the dual of the
+%   other.
+%
+%   This is most easily explained through some examples. The following
+%   example creates a Gabor frame for real-valued signals with a Gaussian
+%   analysis window and its canonical dual frame as the synthesis frame:
+%
+%      f=greasy;
+%      [Fa,Fs]=framepair('dgtreal','gauss','dual',20,294);
+%      c=frana(Fa,f);
+%      r=frsyn(Fs,c);
+%      norm(f-r)
+%
+%   The following example creates a Wilson basis with a Gaussian
+%   synthesis window, and its canonical dual frame as the analysis
+%   frame:
+% 
+%     [Fa,Fs]=framepair('dwilt','dual','gauss',20);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framepair.php}
+%@seealso{frame, framedual, frametight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~ischar(ftype)
+  error(['%s: First agument must be a string denoting the type of ' ...
+         'frame.'],upper(mfilename));
+end;
+
+ftype=lower(ftype);
+
+if ~strcmp(g1,'dual')
+    F1=frame(ftype,g1,varargin{:});
+end;
+
+if ~strcmp(g2,'dual')
+    F2=frame(ftype,g2,varargin{:});
+end;
+
+if strcmp(g1,'dual')
+    F1=framedual(F2);
+end;
+
+if strcmp(g2,'dual')
+    F2=framedual(F1);
+end;
+
diff --git a/inst/frames/framered.m b/inst/frames/framered.m
new file mode 100644
index 0000000..5bb5b7d
--- /dev/null
+++ b/inst/frames/framered.m
@@ -0,0 +1,49 @@
+function red=framered(F);
+%-*- texinfo -*-
+%@deftypefn {Function} framered
+%@verbatim
+%FRAMERED  Redundancy of a frame
+%   Usage  red=framered(F);
+%
+%   FRAMERED(F) computes the redundancy of a given frame F. If the
+%   redundancy is larger than 1 (one), the frame transform will produce more
+%   coefficients than it consumes. If the redundancy is exactly 1 (one),
+%   the frame is a basis.
+%
+%   Examples:
+%   ---------
+%
+%   The following simple example shows how to obtain the redundancy of a
+%   Gabor frame:
+%
+%     F=frame('dgt','gauss',30,40);
+%     framered(F)
+%
+%   The redundancy of a basis is always one:
+%
+%     F=frame('wmdct','gauss',40);
+%     framered(F)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framered.php}
+%@seealso{frame, frana, framebounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+red=F.red;
+  
diff --git a/inst/frames/framesinit.m b/inst/frames/framesinit.m
new file mode 100644
index 0000000..f45bca0
--- /dev/null
+++ b/inst/frames/framesinit.m
@@ -0,0 +1,25 @@
+status=1;
+
+%-*- texinfo -*-
+%@deftypefn {Function} framesinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/framesinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/frames/frametf2coef.m b/inst/frames/frametf2coef.m
new file mode 100644
index 0000000..0f70de7
--- /dev/null
+++ b/inst/frames/frametf2coef.m
@@ -0,0 +1,54 @@
+function coef=frametf2coef(F,coef);
+%-*- texinfo -*-
+%@deftypefn {Function} frametf2coef
+%@verbatim
+%FRAMETF2COEF  Convert coefficients from TF-plane format
+%   Usage: cout=frametf2coef(F,cin);
+%
+%   FRAMETF2COEF(F,coef) convert frame coefficients from the
+%   time-frequency plane layout into the common column format.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frametf2coef.php}
+%@seealso{frame, framecoef2tf, framecoef2native}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First agument must be a frame definition structure.',upper(mfilename));
+end;
+
+switch(F.type)
+ case {'dgt','dgtreal','wmdct'}
+  [M,N,W]=size(coef);
+  coef=reshape(coef,[M*N,W]); 
+ case {'dwilt','ufilterbank'}
+  coef=framenative2coef(F,rect2wil(coef));
+ case {'ufilterbank'}
+  coef=permute(coef,[2,1,3]);
+  [M,N,W]=size(coef);
+  coef=reshape(coef,[M*N,W]); 
+ otherwise
+  error('%s: TF-plane layout not supported for this transform.',upper(mfilename));
+end;
+
+
diff --git a/inst/frames/frametight.m b/inst/frames/frametight.m
new file mode 100644
index 0000000..41800f2
--- /dev/null
+++ b/inst/frames/frametight.m
@@ -0,0 +1,82 @@
+function Ft=frametight(F);
+%-*- texinfo -*-
+%@deftypefn {Function} frametight
+%@verbatim
+%FRAMETIGHT  Construct the canonical tight frame
+%   Usage: F=frametight(F);
+%          F=frametight(F,L);
+%
+%   Ft=FRAMETIGHT(F) returns the canonical tight frame of F.
+%
+%   The canonical tight frame can be used to get perfect reconstruction if
+%   it is used for both analysis and synthesis. This is demonstrated in the
+%   following example:
+%
+%     % Create a frame and its canonical tight
+%     F=frame('dgt','hamming',32,64);
+%     Ft=frametight(F);
+%
+%     % Compute the frame coefficients and test for perfect
+%     % reconstruction
+%     f=gspi;
+%     c=frana(Ft,f);
+%     r=frsyn(Ft,c);
+%     norm(r(1:length(f))-f)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frametight.php}
+%@seealso{frame, framepair, framedual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% Default operation, works for a lot of frames
+Ft=F;
+
+% Handle the windowed transforms
+switch(F.type)
+  case {'dgt','dgtreal','dwilt','wmdct','filterbank','ufilterbank',...
+        'nsdgt','unsdgt','nsdgtreal','unsdgtreal'}
+    
+    Ft=frame(F.type,{'tight',F.g},F.origargs{2:end});
+    
+  case {'filterbankreal','ufilterbankreal'}
+    Ft=frame(F.type,{'realtight',F.g},F.origargs{2:end});
+    
+  case 'gen'
+    [U,sv,V] = svd(F.g,'econ');    
+    Ft=frame('gen',U*V');
+
+  case 'tensor'
+    for ii=1:F.Nframes
+        tight_frames{ii}=frametight(F.frames{ii});
+    end;
+    F=frame('tensor',tight_frames{:});
+
+  case 'fusion'
+    tight_w=1./F.w;
+    for ii=1:F.Nframes
+        tight_frames{ii}=frametight(F.frames{ii});
+    end;
+    Ft=frame('fusion',tight_w,tight_frames{:});
+
+end;
+
diff --git a/inst/frames/frana.m b/inst/frames/frana.m
new file mode 100644
index 0000000..bfaa681
--- /dev/null
+++ b/inst/frames/frana.m
@@ -0,0 +1,91 @@
+function outsig=frana(F,insig);
+%-*- texinfo -*-
+%@deftypefn {Function} frana
+%@verbatim
+%FRANA  Frame analysis operator
+%   Usage: c=frana(F,f);
+%
+%   c=FRANA(F,f) computes the frame coefficients c of the input
+%   signal f using the frame F. The frame object F must have been
+%   created using FRAME or FRAMEPAIR.
+%
+%   If f is a matrix, the transform will be applied along the columns
+%   of f. If f is an N-D array, the transform will be applied along
+%   the first non-singleton dimension.
+%
+%   The output coefficients are stored as columns. This is usually
+%   *not* the same format as the 'native' format of the frame. As an
+%   examples, the output from FRANA for a gabor frame cannot be
+%   passed to IDGT without a reshape.
+%
+%   Examples:
+%   ---------
+%
+%   In the following example the signal bat is analyzed through a wavelet 
+%   frame. The result are the frame coefficients associated with the input  
+%   signal bat and the analysis frame 'fwt':
+%
+%      f = bat;
+%      w = 'sym8';
+%      J = 7;
+%      F = frame('fwt', w, J); 
+%      c = frana(F, f);
+%      % A plot of the frame coefficients
+%      plotframe(F, c, 'dynrange', 100);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frana.php}
+%@seealso{frame, framepair, frsyn, plotframe}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First argument must be a frame definition structure.',...
+        upper(mfilename));
+end;
+
+if size(insig,1) == 1
+    error('%s: Currently only column vectors are supported. See bug #59.',...
+          upper(mfilename));    
+end
+
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[insig,~,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(insig,[],[],upper(mfilename));
+ 
+F=frameaccel(F,Ls);
+
+insig=postpad(insig,F.L);
+
+%% ----- do the computation ----
+
+outsig=F.frana(insig);
+
+%% --- cleanup -----
+
+permutedsize=[size(outsig,1),permutedsize(2:end)];
+
+outsig=assert_sigreshape_post(outsig,dim,permutedsize,order);
+
+  
+
diff --git a/inst/frames/franagrouplasso.m b/inst/frames/franagrouplasso.m
new file mode 100644
index 0000000..8ed8dcc
--- /dev/null
+++ b/inst/frames/franagrouplasso.m
@@ -0,0 +1,210 @@
+function [tc,relres,iter,xrec] = franagrouplasso(F,insig,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} franagrouplasso
+%@verbatim
+%FRANAGROUPLASSO  Group LASSO regression in the TF-domain
+%   Usage: [tc,xrec] = franagrouplasso(F,x,group,lambda,C,maxit,tol)
+%
+%   Input parameters:
+%       F        : Frame definition
+%       x        : Input signal
+%       lambda   : Regularization parameter, controls sparsity of the
+%                  solution
+%   Output parameters:
+%      tc        : Thresholded coefficients
+%      relres    : Vector of residuals.
+%      iter      : Number of iterations done.
+%      xrec      : Reconstructed signal
+%
+%   FRANAGROUPLASSO(F,x) solves the group LASSO regression problem in the
+%   time-frequency domain: minimize a functional of the synthesis
+%   coefficients defined as the sum of half the l^2 norm of the
+%   approximation error and the mixed l^1 / l^2 norm of the coefficient
+%   sequence, with a penalization coefficient lambda.
+%  
+%   The matrix of time-frequency coefficients is labelled in terms of groups
+%   and members.  By default, the obtained expansion is sparse in terms of
+%   groups, no sparsity being imposed to the members of a given group. This
+%   is achieved by a regularization term composed of l^2 norm within a
+%   group, and l^1 norm with respect to groups. See the help on
+%   GROUPTHRESH for more information.
+%
+%   [tc,relres,iter] = FRANAGROUPLASSO(...) returns the residuals relres in
+%   a vector and the number of iteration steps done, maxit.
+%
+%   [tc,relres,iter,xrec] = FRANAGROUPLASSO(...) returns the reconstructed
+%   signal from the coefficients, xrec. Note that this requires additional
+%   computations.
+%
+%   The function takes the following optional parameters at the end of
+%   the line of input arguments:
+%
+%     'freq'     Group in frequency (search for tonal components). This is the
+%                default.
+%
+%     'time'     Group in time (search for transient components). 
+%
+%     'C',cval   Landweber iteration parameter: must be larger than
+%                square of upper frame bound. Default value is the upper
+%                frame bound.
+%
+%     'maxit',maxit
+%                Stopping criterion: maximal number of iterations. 
+%                Default value is 100.
+%
+%     'tol',tol  Stopping criterion: minimum relative difference between
+%                norms in two consecutive iterations. Default value is
+%                1e-2.
+%
+%     'print'    Display the progress.
+%
+%     'quiet'    Don't print anything, this is the default.
+%
+%     'printstep',p
+%                If 'print' is specified, then print every p'th
+%                iteration. Default value is 10;
+%
+%   In addition to these parameters, this function accepts all flags from
+%   the GROUPTHRESH and THRESH functions. This makes it possible to
+%   switch the grouping mechanism or inner thresholding type.
+%
+%   The parameters C, maxit and tol may also be specified on the
+%   command line in that order: FRANAGROUPLASSO(F,x,lambda,C,tol,maxit).
+%
+%   The solution is obtained via an iterative procedure, called Landweber
+%   iteration, involving iterative group thresholdings.
+%
+%   The relationship between the output coefficients is given by :
+%
+%     xrec = frsyn(F,tc);
+%
+%
+%   References:
+%     M. Kowalski. Sparse regression using mixed norms. Appl. Comput. Harmon.
+%     Anal., 27(3):303-324, 2009.
+%     
+%     M. Kowalski and B. Torresani. Sparsity and persistence: mixed norms
+%     provide simple signal models with dependent coefficients. Signal, Image
+%     and Video Processing, 3(3):251-264, 2009.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/franagrouplasso.php}
+%@seealso{franalasso, framebounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isvector(insig)
+    error('Input signal must be a vector.');
+end
+
+% Define initial value for flags and key/value pairs.
+definput.import={'thresh','groupthresh'};
+definput.flags.group={'freq','time'};
+
+definput.keyvals.C=[];
+definput.keyvals.maxit=100;
+definput.keyvals.tol=1e-2;
+definput.keyvals.printstep=10;
+definput.flags.print={'quiet','print'};
+
+[flags,kv]=ltfatarghelper({'C','tol','maxit'},definput,varargin);
+
+L=framelength(F,length(insig));
+
+F=frameaccel(F,L);
+
+if isempty(kv.C)
+  [~,kv.C] = framebounds(F,L);
+end;
+
+% Initialization of thresholded coefficients
+c0 = frana(F,insig);
+
+% We have to convert the coefficients to time-frequency layout to
+% discover their size
+tc = framecoef2tf(F,c0);
+[M,N]=size(tc);
+
+% Normalization to turn lambda to a value comparable to lasso
+%if flags.do_time
+%  lambda = lambda*sqrt(N);
+%else
+%  lambda = lambda*sqrt(M);
+%end
+
+% Various parameter initializations
+threshold = lambda/kv.C;
+
+
+
+tc0 = c0;
+relres = 1e16;
+iter = 0;
+
+% Choose the dimension to group along
+if flags.do_freq
+  kv.dim=2;
+else
+  kv.dim=1;
+end;
+
+if F.red==1
+        
+    tc=groupthresh(tc,threshold,kv.dim,flags.iofun);
+
+    % Convert back from TF-plane
+    tc=frametf2coef(F,tc);        
+
+else
+
+    % Main loop
+    while ((iter < kv.maxit)&&(relres >= kv.tol))
+        tc = c0 - frana(F,frsyn(F,tc0));
+        tc = tc0 + tc/kv.C;
+        
+        %  ------------ Convert to TF-plane ---------
+        tc = framecoef2tf(F,tc);
+        
+        tc = groupthresh(tc,threshold,'argimport',flags,kv);
+        
+        % Convert back from TF-plane
+        tc=frametf2coef(F,tc);
+        % -------------------------------------------
+        
+        relres = norm(tc(:)-tc0(:))/norm(tc0(:));
+        tc0 = tc;
+        iter = iter + 1;
+        if flags.do_print
+            if mod(iter,kv.printstep)==0        
+                fprintf('Iteration %d: relative error = %f\n',iter,relres);
+            end;
+        end;
+    end
+    
+end;
+
+% Reconstruction
+if nargout>3
+  xrec = frsyn(F,tc);
+end;
+
+
diff --git a/inst/frames/franaiter.m b/inst/frames/franaiter.m
new file mode 100644
index 0000000..a8be0dd
--- /dev/null
+++ b/inst/frames/franaiter.m
@@ -0,0 +1,140 @@
+function [outsig,relres,iter]=franaiter(F,insig,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} franaiter
+%@verbatim
+%FRANAITER  Iterative analysis
+%   Usage:  c=franaiter(F,f);
+%           [c,relres,iter]=franaiter(F,f,...);
+%
+%   Input parameters:
+%         F       : Frame.
+%         f       : Signal.
+%         Ls      : Length of signal.
+%   Output parameters:
+%         c       : Array of coefficients.    
+%         relres  : Vector of residuals.
+%         iter    : Number of iterations done.
+%
+%   c=FRANAITER(F,f) computes the frame coefficients c of the signal f*
+%   using an iterative method such that perfect reconstruction can be
+%   obtained using FRSYN. FRANAITER always works, even when FRANA
+%   cannot generate perfect reconstruction coefficients.
+%
+%   [c,relres,iter]=FRANAITER(...) additionally returns the relative
+%   residuals in a vector relres and the number of iteration steps iter.
+%  
+%   *Note:* If it is possible to explicitly calculate the canonical dual
+%   frame then this is usually a much faster method than invoking
+%   FRANAITER.
+%
+%   FRANAITER takes the following parameters at the end of the line of
+%   input arguments:
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 (1e-5 for single precision)
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'pg'        Solve the problem using the Conjugate Gradient
+%                  algorithm. This is the default.
+%
+%     'pcg'        Solve the problem using the Preconditioned Conjugate Gradient
+%                  algorithm.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%   Examples
+%   --------
+%
+%   The following example shows how to rectruct a signal without ever
+%   using the dual frame:
+%
+%      f=greasy;
+%      F=frame('dgtreal','gauss',40,60);
+%      [c,relres,iter]=franaiter(F,f,'tol',1e-14);
+%      r=frsyn(F,c);
+%      norm(f-r)/norm(f)
+%      semilogy(relres);
+%      title('Conversion rate of the CG algorithm');
+%      xlabel('No. of iterations');
+%      ylabel('Relative residual');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/franaiter.php}
+%@seealso{frame, frana, frsyn, frsyniter}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% AUTHORS: Peter L. Soendergaard
+    
+if nargin<2
+    error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+tolchooser.double=1e-9;
+tolchooser.single=1e-5;
+
+definput.keyvals.Ls=[];
+definput.keyvals.tol=tolchooser.(class(insig));
+definput.keyvals.maxit=100;
+definput.flags.alg={'cg','pcg'};
+definput.keyvals.printstep=10;
+definput.flags.print={'quiet','print'};
+
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[insig,~,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(insig,[],[],upper(mfilename));
+
+F=frameaccel(F,Ls);
+L=F.L;
+
+%% -- run the iteration 
+
+A=@(x) F.frsyn(F.frana(x));
+
+% An explicit postpad is needed for the pcg algorithm to not fail
+insig=postpad(insig,L);
+
+if flags.do_pcg
+    d=framediag(F,L);
+    M=spdiags(d,0,L,L);
+    
+    [fout,flag,~,iter,relres]=pcg(A,insig,kv.tol,kv.maxit,M);
+else
+    
+    [fout,flag,~,iter,relres]=pcg(A,insig,kv.tol,kv.maxit);          
+end;
+
+outsig=F.frana(fout);
+
+if nargout>1
+    relres=relres/norm(fout(:));
+end;
+
+
+%% --- cleanup -----
+
+permutedsize=[size(outsig,1),permutedsize(2:end)];
+
+outsig=assert_sigreshape_post(outsig,dim,permutedsize,order);
+
+
diff --git a/inst/frames/franalasso.m b/inst/frames/franalasso.m
new file mode 100644
index 0000000..9534956
--- /dev/null
+++ b/inst/frames/franalasso.m
@@ -0,0 +1,194 @@
+function [tc,relres,iter,frec] = franalasso(F,f,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} franalasso
+%@verbatim
+%FRANALASSO  Frame LASSO regression
+%   Usage: [tc,xrec] = franalasso(F,f,lambda,C,tol,maxit)
+%
+%   Input parameters:
+%       F        : Frame definition
+%       f        : Input signal
+%       lambda   : Regularization parameter, controls sparsity of the solution
+%   Output parameters:
+%       tc       : Thresholded coefficients
+%       relres   : Vector of residuals.
+%       iter     : Number of iterations done.  
+%       frec     : Reconstructed signal
+%
+%   FRANALASSO(F,f,lambda) solves the LASSO (or basis pursuit denoising)
+%   regression problem for a general frame: minimize a functional of the
+%   synthesis coefficients defined as the sum of half the l^2 norm of the
+%   approximation error and the l^1 norm of the coefficient sequence, with
+%   a penalization coefficient lambda.
+%
+%   The solution is obtained via an iterative procedure, called Landweber
+%   iteration, involving iterative soft thresholdings.
+%  
+%   [tc,relres,iter] = FRANALASSO(...) return thes residuals relres in a vector
+%   and the number of iteration steps done, maxit.
+%
+%   [tc,relres,iter,frec] = FRANALASSO(...) returns the reconstructed
+%   signal from the coefficients, frec. Note that this requires additional
+%   computations.
+%
+%   The relationship between the output coefficients is given by :
+%
+%     frec = frsyn(F,tc);
+%
+%   The function takes the following optional parameters at the end of
+%   the line of input arguments:
+%
+%     'C',cval   Landweber iteration parameter: must be larger than
+%                square of upper frame bound. Default value is the upper
+%                frame bound.
+%
+%     'tol',tol  Stopping criterion: minimum relative difference between
+%                norms in two consecutive iterations. Default value is
+%                1e-2.
+%
+%     'maxit',maxit
+%                Stopping criterion: maximal number of iterations to do. Default value is 100.
+%
+%     'print'    Display the progress.
+%
+%     'quiet'    Don't print anything, this is the default.
+%
+%     'printstep',p
+%                If 'print' is specified, then print every p'th
+%                iteration. Default value is 10;
+%
+%   The parameters C, itermax and tol may also be specified on the
+%   command line in that order: FRANALASSO(F,x,lambda,C,tol,maxit).
+%
+%   *Note**: If you do not specify C, it will be obtained as the upper
+%   framebound. Depending on the structure of the frame, this can be an
+%   expensive operation.
+%  
+%
+%   References:
+%     I. Daubechies, M. Defrise, and C. De Mol. An iterative thresholding
+%     algorithm for linear inverse problems with a sparsity constraint.
+%     Communications in Pure and Applied Mathematics, 57:1413-1457, 2004.
+%     
+%     A. Beck and M. Teboulle. A fast iterative shrinkage-thresholding
+%     algorithm for linear inverse problems. SIAM J. Img. Sci., 2(1):183-202,
+%     Mar. 2009.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/franalasso.php}
+%@seealso{frame, frsyn, framebounds, franagrouplasso}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Bruno Torresani.  
+%   TESTING: OK
+
+%   XXX Removed Remark: When the frame is an orthonormal basis, the solution
+%   is obtained by soft thresholding of the basis coefficients, with
+%   threshold lambda.  When the frame is a union of orthonormal bases, the
+%   solution is obtained by applying soft thresholding cyclically on the
+%   basis coefficients (BCR algorithm)
+%
+%   TO DO: Investigate necessity of equal norm atoms in F.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if sum(size(f)>1)>1
+  error('%s: Too many input channels.',upper(mfilename));    
+end
+
+
+% Define initial value for flags and key/value pairs.
+definput.keyvals.C=[];
+definput.keyvals.tol=1e-2;
+definput.keyvals.maxit=100;
+definput.keyvals.printstep=10;
+definput.flags.print={'print','quiet'};
+definput.flags.algorithm={'fista','ista'};
+definput.flags.startphase={'zero','rand','int'};
+
+[flags,kv]=ltfatarghelper({'C','tol','maxit'},definput,varargin);
+
+
+% Accelerate frame, we will need it repeatedly
+Ls = size(f,1);
+F=frameaccel(F,Ls);
+L=F.L;
+
+% Use the upper framebound as C
+if isempty(kv.C)
+  [~,kv.C] = framebounds(F,L);
+end;
+
+% Initialization of thresholded coefficients
+% frana is used instead of F.frana to get the correct zero padding of f
+c0 = frana(F,f);
+
+% Various parameter initializations
+threshold = lambda/kv.C;
+
+tc0 = c0;
+relres = 1e16;
+iter = 0;
+
+if flags.do_ista
+   % Main loop
+   while ((iter < kv.maxit)&&(relres >= kv.tol))
+       tc = c0 - F.frana(F.frsyn(tc0));
+       tc = tc0 + tc/kv.C;
+       tc = thresh(tc,threshold,'soft');
+       relres = norm(tc(:)-tc0(:))/norm(tc0(:));
+       tc0 = tc;
+       iter = iter + 1;
+       if flags.do_print
+         if mod(iter,kv.printstep)==0        
+           fprintf('Iteration %d: relative error = %f\n',iter,relres);
+         end;
+       end;
+   end
+elseif flags.do_fista
+   tz0 = c0;
+   tau0 = 1;
+   % Main loop
+   while ((iter < kv.maxit)&&(relres >= kv.tol))
+       tc = c0 - F.frana(F.frsyn(tz0));
+       tc = tz0 + tc/kv.C;
+       tc = thresh(tc,threshold,'soft');
+       
+       tau = 1/2*(1+sqrt(1+4*tau0^2));
+       tz0 = tc + (tau0-1)/tau*(tc-tc0);
+       relres = norm(tc(:)-tc0(:))/norm(tc0(:));
+       tc0 = tc;
+       tau0 = tau;
+       iter = iter + 1;
+       if flags.do_print
+         if mod(iter,kv.printstep)==0        
+           fprintf('Iteration %d: relative error = %f\n',iter,relres);
+         end;
+       end;
+   end   
+end
+
+% Reconstruction
+if nargout>3
+  frec = F.frsyn(tc);
+  frec = frec(1:Ls,:);
+end;
+
diff --git a/inst/frames/frsyn.m b/inst/frames/frsyn.m
new file mode 100644
index 0000000..4e846a4
--- /dev/null
+++ b/inst/frames/frsyn.m
@@ -0,0 +1,47 @@
+function outsig=frsyn(F,insig);
+%-*- texinfo -*-
+%@deftypefn {Function} frsyn
+%@verbatim
+%FRSYN  Frame synthesis operator
+%   Usage: f=frsyn(F,c);
+%
+%   f=FRSYN(F,c) constructs a signal f from the frame coefficients c*
+%   using the frame F. The frame object F must have been created using
+%   FRAME.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frsyn.php}
+%@seealso{frame, frana, plotframe}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(F)
+  error('%s: First agument must be a frame definition structure.',upper(mfilename));
+end;
+
+L=framelengthcoef(F,size(insig,1));
+
+F=frameaccel(F,L);
+
+outsig=F.frsyn(insig);
+
+
diff --git a/inst/frames/frsynabs.m b/inst/frames/frsynabs.m
new file mode 100644
index 0000000..a906209
--- /dev/null
+++ b/inst/frames/frsynabs.m
@@ -0,0 +1,241 @@
+function [f,relres,iter]=frsynabs(F,s,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} frsynabs
+%@verbatim
+%FRSYNABS  Reconstruction from magnitude of coefficients
+%   Usage:  f=frsynabs(F,s);
+%           f=frsynabs(F,s,Ls);
+%           [f,relres,iter]=frsynabs(...);
+%
+%   Input parameters:
+%         F       : Frame   
+%         s       : Array of coefficients.
+%         Ls      : length of signal.
+%   Output parameters:
+%         f       : Signal.
+%         relres  : Vector of residuals.
+%         iter    : Number of iterations done.
+%
+%   FRSYNABS(F,s) attempts to find a signal which has s as the absolute
+%   value of its frame coefficients :
+%
+%     s = abs(frana(F,f));
+%
+%   using an iterative method.
+%
+%   FRSYNABS(F,s,Ls) does as above but cuts or extends f to length Ls.
+%
+%   If the phase of the coefficients s is known, it is much better to use
+%   frsyn.
+%
+%   [f,relres,iter]=FRSYNABS(...) additionally returns the residuals in a
+%   vector relres and the number of iteration steps iter. The
+%   residuals are computed as:
+%
+%      relres = norm(abs(cn)-s,'fro')/norm(s,'fro') 
+%
+%   where c_n is the Gabor coefficients of the signal in iteration n.
+%
+%   Generally, if the absolute value of the frame coefficients has not been
+%   modified, the iterative algorithm will converge slowly to the correct
+%   result. If the coeffficients have been modified, the algorithm is not
+%   guaranteed to converge at all.
+%
+%   FRSYNABS takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'input'      Choose the starting phase as the phase of the input
+%                  s. This is the default
+%
+%     'zero'       Choose a starting phase of zero.
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%
+%   References:
+%     D. Griffin and J. Lim. Signal estimation from modified short-time
+%     Fourier transform. IEEE Trans. Acoust. Speech Signal Process.,
+%     32(2):236-243, 1984.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frsynabs.php}
+%@seealso{dgt, idgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Remi Decorsiere and Peter L. Soendergaard.
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+  
+definput.keyvals.Ls=[];
+definput.keyvals.tol=1e-6;
+definput.keyvals.maxit=100;
+definput.keyvals.printstep=10;
+definput.keyvals.alpha=0.99;
+definput.flags.print={'quiet','print'};
+definput.flags.startphase={'input','zero','rand'};
+definput.flags.method={'griflim','bfgs','fgriflim'};
+
+[flags,kv,Ls]=ltfatarghelper({'Ls','tol','maxit'},definput,varargin);
+
+% Determine the proper length of the frame
+L=framelengthcoef(F,size(s,1));   
+W=size(s,2);
+
+if flags.do_input
+  % Start with the phase given by the input.
+  c=s;
+end;
+
+if flags.do_zero
+  % Start with a phase of zero.
+  c=abs(s);
+end;
+
+if flags.do_rand
+  c=abs(s).*exp(2*pi*i*rand(size(s)));
+end;
+
+% Use only abs(s) in the residum evaluations
+s = abs(s);
+
+% For normalization purposes
+norm_s=norm(s,'fro');
+
+relres=zeros(kv.maxit,1);
+
+Fs=frameaccel(framedual(F),L);
+
+% Initialize windows to speed up computation
+F=frameaccel(F,L);
+
+if flags.do_griflim
+  for iter=1:kv.maxit
+    f=Fs.frsyn(c);
+    c=F.frana(f);
+    
+    relres(iter)=norm(abs(c)-s,'fro')/norm_s;
+
+    c=s.*exp(1i*angle(c));
+
+    if flags.do_print
+      if mod(iter,kv.printstep)==0
+        fprintf('FRSYNABS: Iteration %i, residual = %f.\n',iter,relres(iter));
+      end;    
+    end;
+    
+    if relres(iter)<kv.tol
+      relres=relres(1:iter);
+      break;
+    end;
+    
+  end;
+end;
+
+if flags.do_fgriflim
+  told=s;
+
+  for iter=1:kv.maxit
+    f=Fs.frsyn(c);
+    tnew=F.frana(f);
+
+    relres(iter)=norm(abs(tnew)-s,'fro')/norm_s;
+
+    tnew=s.*exp(1i*angle(tnew));
+    c=tnew+kv.alpha*(tnew-told);
+    
+
+    if flags.do_print
+      if mod(iter,kv.printstep)==0
+        fprintf('FRSYNABS: Iteration %i, residual = %f.\n',iter,relres(iter));
+      end;    
+    end;
+    
+    if relres(iter)<kv.tol
+      relres=relres(1:iter);
+      break;
+    end;
+    
+    told=tnew;
+    
+  end;
+end;
+
+if flags.do_bfgs
+    if exist('minFunc')~=2
+      error(['To use the BFGS method in ISGRAMREAL, please install the minFunc ' ...
+             'software from http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html.']);
+    end;
+    
+    % Setting up the options for minFunc
+    opts = struct;
+    opts.display = kv.printstep;
+    opts.maxiter = kv.maxit;
+    
+    % Don't limit the number of function evaluations, just the number of
+    % time-steps.
+    opts.MaxFunEvals = 1e9;
+    opts.usemex = 0;
+    
+    f0 = Fs.frsyn(c);
+    [f,fval,exitflag,output]=minFunc(@objfun,f0,opts,F,s);
+    % First entry of output.trace.fval is the objective function
+    % evaluated on the initial input. Skip it to be consistent.
+    relres = output.trace.fval(2:end)/norm_s;
+    iter = output.iterations;
+end;
+
+    
+% Cut or extend f to the correct length, if desired.
+if ~isempty(Ls)
+  f=postpad(f,Ls);
+else
+  Ls=L;
+end;
+
+f=comp_sigreshape_post(f,Ls,0,[0; W]);
+
+%  Subfunction to compute the objective function for the BFGS method.
+function [f,df]=objfun(x,F,s)
+  c=F.frana(x);
+  
+  inner = abs(c)-s;
+  f=norm(inner,'fro')^2;
+  
+  df = 4*real(conj(F.frsyn(inner.*c)));
+  
+
+
+
diff --git a/inst/frames/frsyniter.m b/inst/frames/frsyniter.m
new file mode 100644
index 0000000..08ab655
--- /dev/null
+++ b/inst/frames/frsyniter.m
@@ -0,0 +1,171 @@
+function [f,relres,iter]=frsyniter(F,c,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} frsyniter
+%@verbatim
+%FRSYNITER  Iterative synthesis
+%   Usage:  f=frsyniter(F,c);
+%
+%   Input parameters:
+%         F       : Frame   
+%         c       : Array of coefficients.
+%         Ls      : length of signal.
+%   Output parameters:
+%         f       : Signal.
+%         relres  : Vector of residuals.
+%         iter    : Number of iterations done.
+%
+%   f=FRSYNITER(F,c) iteratively inverts the analysis operator of F, so
+%   FRSYNITER always performs the inverse operation of FRANA, even
+%   when a perfect reconstruction is not possible by using FRSYN.
+%
+%   [f,relres,iter]=FRSYNITER(...) additionally returns the relative
+%   residuals in a vector relres and the number of iteration steps iter.
+%  
+%   *Note:* If it is possible to explicitly calculate the canonical dual
+%   frame then this is usually a much faster method than invoking
+%   FRSYNITER.
+%
+%   FRSYNITER takes the following parameters at the end of the line of
+%   input arguments:
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 (1e-5 for single precision)
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'cg'         Solve the problem using the Conjugate Gradient
+%                  algorithm. This is the default.
+%
+%     'pcg'        Solve the problem using the Preconditioned Conjugate Gradient
+%                  algorithm.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%   Examples
+%   --------
+%
+%   The following example shows how to rectruct a signal without ever
+%   using the dual frame:
+%
+%      F=frame('dgtreal','gauss',10,20);
+%      c=frana(F,bat);
+%      [r,relres]=frsyniter(F,c,'tol',1e-14);
+%      norm(bat-r)/norm(bat)
+%      semilogy(relres);
+%      title('Conversion rate of the CG algorithm');
+%      xlabel('No. of iterations');
+%      ylabel('Relative residual');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frsyniter.php}
+%@seealso{frame, frana, frsyn, franaiter}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% AUTHORS: Nicki Holighaus & Peter L. Soendergaard
+    
+  if nargin<2
+    error('%s: Too few input parameters.',upper(mfilename));
+  end;
+
+  tolchooser.double=1e-9;
+  tolchooser.single=1e-5;
+
+  definput.keyvals.Ls=[];
+  definput.keyvals.tol=tolchooser.(class(c));
+  definput.keyvals.maxit=100;
+  definput.flags.alg={'cg','pcg'};
+  definput.keyvals.printstep=10;
+  definput.flags.print={'quiet','print'};
+
+  [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+  
+  % Determine L from the first vector, it must match for all of them.
+  L=framelengthcoef(F,size(c,1));
+
+  F=frameaccel(F,L);
+  
+  A=@(x) F.frsyn(F.frana(x));
+
+  % It is possible to specify the initial guess, but this is not
+  % currently done
+  
+  if flags.do_pcg
+      d=framediag(F,L);
+      M=spdiags(d,0,L,L);
+      
+      [f,flag,~,iter,relres]=pcg(A,F.frsyn(c),kv.tol,kv.maxit,M);
+  else
+      
+      [f,flag,~,iter,relres]=pcg(A,F.frsyn(c),kv.tol,kv.maxit);          
+  end;
+  
+  if nargout>1
+      relres=relres/norm(c(:));
+  end;
+  
+      
+  % Cut or extend f to the correct length, if desired.
+  if ~isempty(Ls)
+      f=postpad(f,Ls);
+  else
+      Ls=L;
+  end;
+
+
+if 0
+    
+    % This code has been disabled, as the PCG algorithm is so much faster.
+      if flags.do_unlocbox
+
+      % Get the upper frame bound (Or an estimation bigger than the bound)
+      [~,B]=framebounds(F,L,'a'); 
+      
+      % Set the parameter for the fast projection on a B2 ball
+      param.At=@(x) frsyn(F,x);     % adjoint operator
+      param.A=@(x)  frana(F,x);     % direct operator
+      param.y=c;                    % coefficient
+      param.tight=0;                % It's not a tight frame
+      param.max_iter=kv.maxit;
+      param.tol=kv.tol; 
+      param.nu=B;
+      
+      % Display parameter 0 nothing, 1 summary at convergence, 2 all
+      % steps
+      if flags.do_print
+          param.verbose=1;
+      else
+          param.verbose=0;
+      end;
+      
+      % Make the projection. Requires UNLocBOX
+      [f, ~] = fast_proj_B2(zeros(L,1), 0, param);
+      
+      % compute the residue
+      res = param.A(f) - param.y; norm_res = norm(res(:), 2);
+      relres=norm_res/norm(c(:), 2);
+      
+      iter=0; % The code of the fast_proj_B2 is not yet compatible with this
+  end;
+
+end;
+
+    
+
diff --git a/inst/frames/frsynmatrix.m b/inst/frames/frsynmatrix.m
new file mode 100644
index 0000000..0c44792
--- /dev/null
+++ b/inst/frames/frsynmatrix.m
@@ -0,0 +1,95 @@
+function G=frsynmatrix(F,L);
+%-*- texinfo -*-
+%@deftypefn {Function} frsynmatrix
+%@verbatim
+%FRSYNMATRIX  Frame synthesis operator matrix
+%   Usage: G=frsynmatrix(F,L);
+%
+%   G=FRSYNMATRIX(F,L) returns the matrix representation G of the frame
+%   synthesis operator for a frame F of length L. The frame object F*
+%   must have been created using FRAME.
+%
+%   The frame synthesis operator matrix contains all the frame atoms as
+%   column vectors. It has dimensions L xNcoef, where Ncoef is the
+%   number of coefficients. The number of coefficients can be found as
+%   Ncoef=framered(F)*L. This means that the frame matrix is usually
+%   *very* large, and this routine should only be used for small values of
+%   L.
+%
+%   The action of the frame analysis operator FRANA is equal to
+%   multiplication with the Hermitean transpose of the frame
+%   matrix. Consider the following simple example:
+%
+%     L=200;
+%     F=frame('dgt','gauss',10,20);
+%     G=frsynmatrix(F,L);
+%     testsig = randn(L,1);
+%     res = frana(F,testsig)-G'*testsig;
+%     norm(res)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/frsynmatrix.php}
+%@seealso{frame, frana, frsyn}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+Lcheck=framelength(F,L);
+if Lcheck~=L
+    error('%s: Incompatible frame length.',upper(mfilename));
+end;
+
+if F.realinput
+    
+    %switch(F.type)
+    %  case 'dgtreal'
+        
+    %  This code correctly reproduces the matrix represenation of the
+    %  analysis operator, but not of the synthesis.
+    %
+    %    F2=frame('dgt',F.g,F.a,F.M);
+    %    G2=frsynmatrix(F2,L);
+    %    M2=floor(F.M/2)+1;
+    %    N=L/F.a;
+    %    G=zeros(L,M2*N);
+    %    for n=0:N-1
+    %        G(:,1+n*M2:(n+1)*M2)=G2(:,1+n*F.M:M2+n*F.M);
+    %    end;
+        
+    %  otherwise
+        error(['%s: The synthesis operator of real-valued-input frames does is ' ...
+               'non-linear and does not have a matrix represenation.']);
+        %end;
+else
+    
+  % Generic code handles all frames where there are no extra coefficients
+  % in the representation
+  Ncoef = framered(F)*L;
+  % sprintf for Octave compatibility
+  assert(abs(Ncoef-round(Ncoef))<1e-3,...
+         sprintf('%s: There is a bug. Ncoef=%d should be an integer.',...
+         upper(mfilename),Ncoef));
+  Ncoef=round(Ncoef);
+  coef=eye(Ncoef);
+  G = frsyn(F,coef);  
+end;
+
+
diff --git a/inst/frames/plotframe.m b/inst/frames/plotframe.m
new file mode 100644
index 0000000..4a71da8
--- /dev/null
+++ b/inst/frames/plotframe.m
@@ -0,0 +1,105 @@
+function outsig=plotframe(F,insig,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} plotframe
+%@verbatim
+%PLOTFRAME  Plot frame coefficients
+%   Usage: plotframe(F,insig,...);
+%
+%   PLOTFRAME(F,c) plots the frame coefficients c using the plot
+%   command associated to the frame F.
+%
+%   PLOTFRAME(F,c,...) passes any additional parameters to the native
+%   plot routine. Please see the help on the specific plot routine for a
+%   complete description. 
+%
+%   The following common set of parameters are supported by all plotting
+%   routines:
+%
+%     'dynrange',r
+%              Limit the dynamical range to r. The default value of []
+%              means to not limit the dynamical range.
+%
+%     'db'     Apply 20*log_{10} to the coefficients. This makes 
+%              it possible to see very weak phenomena, but it might show 
+%              too much noise. A logarithmic scale is more adapted to 
+%              perception of sound. This is the default.
+%
+%     'dbsq'   Apply 10*log_{10} to the coefficients. Same as the
+%              'db' option, but assume that the input is already squared.  
+%
+%     'lin'    Show the coefficients on a linear scale. This will
+%              display the raw input without any modifications. Only works for
+%              real-valued input.
+%
+%     'linsq'  Show the square of the coefficients on a linear scale.
+%
+%     'linabs'  Show the absolute value of the coefficients on a linear scale.
+%
+%     'clim',clim
+%              Only show values in between clim(1) and clim(2). This
+%              is usually done by adjusting the colormap. See the help on imagesc.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/frames/plotframe.php}
+%@seealso{frame, frana}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+switch(F.type)
+   case {'fwt','ufwt','wfbt','wpfbt','uwfbt','uwpfbt'}
+      info.fname = F.type;
+      info.wt = F.g;
+end;
+
+switch(F.type)
+ case 'dgt'
+  plotdgt(framecoef2native(F,insig),F.a,varargin{:}); 
+ case 'dgtreal'
+  outsig = plotdgtreal(framecoef2native(F,insig),F.a,F.M,varargin{:}); 
+ case 'dwilt'
+  plotdwilt(framecoef2native(F,insig),varargin{:}); 
+ case 'wmdct'
+  plotwmdct(framecoef2native(F,insig),varargin{:});
+ case 'gen'
+  error(['%s: There is no default way of visualizing general frame ' ...
+         'coefficients.'],upper(mfilename));
+ case 'dft'
+  plotfft(insig,varargin{:});
+ case {'dcti','dctii','dctiii','dctiv',...
+       'dsti','dstii','dstiii','dstiv'}
+  % FIXME : This is not strictly correct, as half the transforms use an
+  % odd frequency centering.
+  plotfftreal(insig,varargin{:});
+ case 'fwt'
+    info.Lc = fwtclength(size(insig,1)/F.red,F.g,F.J);
+    info.J = F.J;
+    info.dim = 1;
+    plotwavelets(insig,info,varargin{:});  
+ case 'ufwt'
+    info.J = F.J;
+    plotwavelets(framecoef2native(F,insig),info,varargin{:}); 
+ case {'wfbt','wpfbt'}
+    plotwavelets(framecoef2native(F,insig),info,varargin{:}); 
+ case {'uwfbt','uwpfbt'}
+    plotwavelets(framecoef2native(F,insig),info,varargin{:}); 
+    
+case {'filterbank','filterbankreal'}
+    plotfilterbank(framecoef2native(F,insig),F.a,[],varargin{:});
+end;
+
+  
diff --git a/inst/gabor/Contents.m b/inst/gabor/Contents.m
new file mode 100644
index 0000000..4414413
--- /dev/null
+++ b/inst/gabor/Contents.m
@@ -0,0 +1,107 @@
+% LTFAT - Gabor analysis
+%
+%  Peter L. Soendergaard, 2007 - 2014.
+%
+%  Basic Time/Frequency analysis
+%    TCONV          -  Twisted convolution
+%    DSFT           -  Discrete Symplectic Fourier Transform
+%    ZAK            -  Zak transform
+%    IZAK           -  Inverse Zak transform
+%    COL2DIAG       -  Move columns of a matrix to diagonals
+%    S0NORM         -  S0-norm
+%
+%  Gabor systems
+%    dgt            -  Discrete Gabor transform
+%    IDGT           -  Inverse discrete Gabor transform
+%    ISGRAM         -  Iterative reconstruction from spectrogram
+%    ISGRAMREAL     -  Iterative reconstruction from spectrogram (real signal)
+%    DGT2           -  2D Discrete Gabor transform
+%    IDGT2          -  2D Inverse discrete Gabor transform
+%    DGTREAL        -  DGT for real-valued signals
+%    IDGTREAL       -  IDGT for real-valued signals
+%    GABWIN         -  Evaluate Gabor window
+%    DGTLENGTH      -  Length of Gabor system to expand a signal
+%
+%  Wilson bases and WMDCT
+%    DWILT          -  Discrete Wilson transform
+%    IDWILT         -  Inverse discrete Wilson transform
+%    DWILT2         -  2-D Discrete Wilson transform
+%    IDWILT2        -  2-D inverse discrete Wilson transform
+%    WMDCT          -  Modified Discrete Cosine transform
+%    IWMDCT         -  Inverse WMDCT
+%    WMDCT2         -  2-D WMDCT
+%    IWMDCT2        -  2-D inverse WMDCT
+%    WIL2RECT       -  Rectangular layout of Wilson coefficients
+%    RECT2WIL       -  Inverse of WIL2RECT
+%    WILWIN         -  Evaluate Wilson window
+%    DWILTLENGTH    -  Length of Wilson/WMDCT system to expand a signal
+%
+%  Reconstructing windows
+%    GABDUAL        -  Canonical dual window
+%    GABTIGHT       -  Canonical tight window
+%    GABFIRDUAL     -  FIR optimized dual window 
+%    GABOPTDUAL     -  Optimized dual window
+%    GABFIRTIGHT    -  FIR optimized tight window
+%    GABOPTTIGHT    -  Optimized tight window
+%    GABCONVEXOPT   -  Optimized window
+%    GABPROJDUAL    -  Dual window by projection
+%    GABMIXDUAL     -  Dual window by mixing windows
+%    WILORTH        -  Window of Wilson/WMDCT orthonormal basis
+%    WILDUAL        -  Riesz dual window of Wilson/WMDCT basis 
+%
+%  Conditions numbers
+%    GABFRAMEBOUNDS -  Frame bounds of Gabor system
+%    GABRIESZBOUNDS -  Riesz sequence/basis bounds of Gabor system
+%    WILBOUNDS      -  Frame bounds of Wilson basis
+%    GABDUALNORM    -  Test if two windows are dual
+%    GABFRAMEDIAG   -  Diagonal of Gabor frame operator
+%    WILFRAMEDIAG   -  Diagonal of Wilson/WMDCT frame operator
+%
+%  Phase gradient methods and reassignment
+%    GABPHASEGRAD   -  Instantaneous time/frequency from signal
+%    GABREASSIGN    -  Reassign positive distribution
+%
+%  Phase conversions
+%    PHASELOCK      -  Phase Lock Gabor coefficients to time
+%    PHASEUNLOCK    -  Undo phase locking
+%    SYMPHASE       -  Convert to symmetric phase
+%
+%  Support for non-separable lattices
+%    MATRIX2LATTICETYPE - Matrix form to standard lattice description
+%    LATTICETYPE2MATRIX - Standard lattice description to matrix form
+%    SHEARFIND      -  Shears to transform a general lattice to a separable
+%    NOSHEARLENGTH  -  Next transform side not requiring a frequency side shear
+%
+%  Plots
+%    TFPLOT         -  Plot coefficients on the time-frequency plane
+%    PLOTDGT        -  Plot DGT coefficients
+%    PLOTDGTREAL    -  Plot DGTREAL coefficients
+%    PLOTDWILT      -  Plot DWILT coefficients
+%    PLOTWMDCT      -  Plot WMDCT coefficients
+%    SGRAM          -  Spectrogram based on DGT
+%    GABIMAGEPARS   -  Choose parameters for nice Gabor image
+%    RESGRAM        -  Reassigned spectrogram
+%    INSTFREQPLOT   -  Plot of the instantaneous frequency
+%    PHASEPLOT      -  Plot of STFT phase
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/gabor/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/gabor/col2diag.m b/inst/gabor/col2diag.m
new file mode 100644
index 0000000..fd10703
--- /dev/null
+++ b/inst/gabor/col2diag.m
@@ -0,0 +1,55 @@
+function cout=col2diag(cin)
+%-*- texinfo -*-
+%@deftypefn {Function} col2diag
+%@verbatim
+%COL2DIAG  Move columns of a matrix to diagonals
+%   Usage:  cout=col2diag(cin);
+%
+%   COL2DIAG(cin) will rearrange the elements in the square matrix cin so
+%   that columns of cin appears as diagonals. Column number n will appear
+%   as diagonal number -n and L-n, where L is the size of the matrix.
+%
+%   The function is its own inverse.
+%
+%   COL2DIAG performs the underlying coordinate transform for spreading
+%   function and Kohn-Nirenberg calculus in the finite, discrete setting.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/col2diag.php}
+%@seealso{spreadop, spreadfun, tconv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_SPREAD
+%   REFERENCE: OK
+
+% Assert correct input.
+error(nargchk(1,1,nargin));
+
+if ndims(cin)~=2 || size(cin,1)~=size(cin,2)
+  error('Input matrix must be square.');
+end;
+
+if ~isnumeric(cin)
+  error('Input must be numerical.');
+end;
+
+cout=comp_col2diag(full(cin));
+
+
diff --git a/inst/gabor/constructphase.m b/inst/gabor/constructphase.m
new file mode 100644
index 0000000..8f83aae
--- /dev/null
+++ b/inst/gabor/constructphase.m
@@ -0,0 +1,66 @@
+function c=constructphase(s,g,a)
+%-*- texinfo -*-
+%@deftypefn {Function} constructphase
+%@verbatim
+%CONSTRUCTPHASE  Construct the phase of a DGT
+%   Usage:  c=constructphase(s,g,a);
+%           c=constructphase(s,g,a,tol);
+%
+%   CONSTRUCTPHASE(s,g,a) will construct a suitable phase for the postive
+%   valued coefficients s. 
+%  
+%   If s is the absolute values of the Gabor coefficients of a signal
+%   obtained using the window g and time-shift a, i.e.:
+%
+%     c=dgt(f,g,a,M);
+%     s=abs(c);
+%
+%   then constuctphase(s,g,a) will attempt to reconstruct c.
+%
+%   The window g must be Gaussian, i.e. g must have the value 'gauss'
+%   or be a cell array {'gauss',tfr}.
+%
+%   CONSTRUCTPHASE(s,g,a,tol) does as above, but sets the phase of
+%   coefficients less than tol to zero phase. This speeds up the
+%   computation. By default, tol has the value 1e-10.
+%
+%   This function requires a computational subroutine that is only
+%   available in C. Use LTFATMEX to compile it.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/constructphase.php}
+%@seealso{dgt, gabphasegrad, ltfatmex, demo_constructphase}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% AUTHOR: Peter L. Soendergaard
+M=size(s,1);
+N=size(s,2);
+L=N*a;
+  
+% Obtain the vectors.
+[tgrad,fgrad] = gabphasegrad('abs',s,g,a);
+
+tol=1e-10;
+
+newphase=comp_heapint(s,tgrad,fgrad,a,tol);
+
+c=s.*exp(i*newphase);
+
+
diff --git a/inst/gabor/dgt.m b/inst/gabor/dgt.m
new file mode 100644
index 0000000..7a679e7
--- /dev/null
+++ b/inst/gabor/dgt.m
@@ -0,0 +1,221 @@
+function [c,Ls,g]=dgt(f,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} dgt
+%@verbatim
+%DGT  Discrete Gabor transform
+%   Usage:  c=dgt(f,g,a,M);
+%           c=dgt(f,g,a,M,L);
+%           c=dgt(f,g,a,M,'lt',lt);
+%           [c,Ls]=dgt(...);
+%
+%   Input parameters:
+%         f     : Input data.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of channels.
+%         L     : Length of transform to do.
+%         lt    : Lattice type (for non-separable lattices).
+%   Output parameters:
+%         c     : M xN array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   DGT(f,g,a,M) computes the Gabor coefficients (also known as a windowed
+%   Fourier transform) of the input signal f with respect to the window
+%   g and parameters a and M. The output is a vector/matrix in a
+%   rectangular layout.
+%
+%   The length of the transform will be the smallest multiple of a and M*
+%   that is larger than the signal. f will be zero-extended to the length of
+%   the transform. If f is a matrix, the transformation is applied to each
+%   column. The length of the transform done can be obtained by
+%   L=size(c,2)*a;
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%
+%   DGT(f,g,a,M,L) computes the Gabor coefficients as above, but does
+%   a transform of length L. f will be cut or zero-extended to length L before
+%   the transform is done.
+%
+%   [c,Ls]=DGT(f,g,a,M) or [c,Ls]=DGT(f,g,a,M,L) additionally returns the
+%   length of the input signal f. This is handy for reconstruction:
+%
+%               [c,Ls]=dgt(f,g,a,M);
+%               fr=idgt(c,gd,a,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, provided
+%   that gd is a dual window of g.
+%
+%   [c,Ls,g]=DGT(...) additionally outputs the window used in the
+%   transform. This is useful if the window was generated from a description
+%   in a string or cell array.
+%
+%   The Discrete Gabor Transform is defined as follows: Consider a window g*
+%   and a one-dimensional signal f of length L and define N=L/a.
+%   The output from c=DGT(f,g,a,M) is then given by:
+%
+%                   L-1 
+%      c(m+1,n+1) = sum f(l+1)*conj(g(l-a*n+1))*exp(-2*pi*i*m*l/M), 
+%                   l=0  
+%
+%   where m=0,...,M-1 and n=0,...,N-1 and l-an is computed
+%   modulo L.
+%
+%   Non-separable lattices:
+%   -----------------------
+%
+%   DGT(f,g,a,M,'lt',lt) computes the DGT for a non-separable lattice
+%   given by the time-shift a, number of channels M and lattice type
+%   lt. Please see the help of MATRIX2LATTICETYPE for a precise
+%   description of the parameter lt.
+%
+%   The non-separable discrete Gabor transform is defined as follows:
+%   Consider a window g and a one-dimensional signal f of length L and
+%   define N=L/a.  The output from c=DGT(f,g,a,M,L,lt) is then given
+%   by:
+%
+%                   L-1 
+%      c(m+1,n+1) = sum f(l+1)*conj(g(l-a*n+1))*exp(-2*pi*i*(m+w(n))*l/M), 
+%                   l=0  
+%
+%   where m=0,...,M-1 and n=0,...,N-1 and l-an are computed
+%   modulo L.  The additional offset w is given by w(n)=mod(n*lt_1,lt_2)/lt_2
+%   in the formula above.
+%
+%   Additional parameters:
+%   ----------------------
+%
+%   DGT takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'freqinv'  Compute a DGT using a frequency-invariant phase. This
+%                is the default convention described above.
+%
+%     'timeinv'  Compute a DGT using a time-invariant phase. This
+%                convention is typically used in FIR-filter algorithms.
+%
+%   Examples:
+%   ---------
+%
+%   In the following example we create a Hermite function, which is a
+%   complex-valued function with a circular spectrogram, and visualize
+%   the coefficients using both imagesc and PLOTDGT:
+%
+%     a=10;
+%     M=40;
+%     L=a*M;
+%     h=pherm(L,4); % 4th order hermite function.
+%     c=dgt(h,'gauss',a,M);
+%
+%     % Simple plot: The squared modulus of the coefficients on
+%     % a linear scale
+%     figure(1);
+%     imagesc(abs(c).^2);
+%
+%     % Better plot: zero-frequency is displayed in the middle, 
+%     % and the coefficients are show on a logarithmic scale.
+%     figure(2);
+%     plotdgt(c,a,'dynrange',50);
+%
+%
+% 
+%   References:
+%     K. Groechenig. Foundations of Time-Frequency Analysis. Birkhauser, 2001.
+%     
+%     H. G. Feichtinger and T. Strohmer, editors. Gabor Analysis and
+%     Algorithms. Birkhauser, Boston, 1998.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dgt.php}
+%@seealso{idgt, gabwin, dwilt, gabdual, phaselock, demo_dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: REF_DGT
+  
+%% ---------- Assert correct input.
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.keyvals.dim=[];
+definput.flags.phase={'freqinv','timeinv'};
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+%[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,upper(mfilename),0);
+[f,~,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim,upper(mfilename));
+
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+
+    % ----- step 2b : Verify a, M and get L from the signal length f----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+%% ----- step 4: final cleanup ---------------
+
+f=postpad(f,L);
+
+% If the signal is single precision, make the window single precision as
+% well to avoid mismatches.
+if isa(f,'single')
+  g=single(g);
+end;
+
+%% ------ call the computation subroutines 
+
+c=comp_dgt(f,g,a,M,kv.lt,flags.do_timeinv,0,0);
+
+order=assert_groworder(order);
+permutedsize=[M,L/a,permutedsize(2:end)];
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+if numel(size(c)>2) && size(c,1)==1
+   c = squeeze(c);
+end
+
+
diff --git a/inst/gabor/dgt2.m b/inst/gabor/dgt2.m
new file mode 100644
index 0000000..4f69357
--- /dev/null
+++ b/inst/gabor/dgt2.m
@@ -0,0 +1,122 @@
+function [c,Ls]=dgt2(f,g1,p3,p4,p5,p6)
+%-*- texinfo -*-
+%@deftypefn {Function} dgt2
+%@verbatim
+%DGT2  2-D Discrete Gabor transform
+%   Usage: c=dgt2(f,g,a,M);
+%          c=dgt2(f,g1,g2,[a1,a2],[M1,M2]);
+%          c=dgt2(f,g1,g2,[a1,a2],[M1,M2],[L1,L2]);
+%          [c,Ls]=dgt2(f,g1,g2,[a1,a2],[M1,M2]);
+%          [c,Ls]=dgt2(f,g1,g2,[a1,a2],[M1,M2],[L1,L2]);
+%
+%   Input parameters:
+%         f       : Input data, matrix.
+%         g,g1,g2 : Window functions.
+%         a,a1,a2 : Length of time shifts.
+%         M,M1,M2 : Number of modulations.
+%         L1,L2   : Length of transform to do 
+%
+%   Output parameters:
+%         c       : array of coefficients.
+%         Ls      : Original size of input matrix.
+%
+%   DGT2(f,g,a,M) will calculate a separable two-dimensional discrete
+%   Gabor transformation of the input signal f with respect to the window
+%   g and parameters a and M.
+%
+%   For each dimension, the length of the transform will be the smallest
+%   possible that is larger than the length of the signal along that dimension.
+%   f will be appropriately zero-extended.
+%
+%   DGT2(f,g,a,M,L) computes a Gabor transform as above, but does
+%   a transform of length L along each dimension. f will be cut or
+%   zero-extended to length L before the transform is done.
+%
+%   [c,Ls]=DGT2(f,g,a,M) or [c,Ls]=DGT2(f,g,a,M,L) additionally returns
+%   the length of the input signal f. This is handy for reconstruction:
+%
+%                [c,Ls]=dgt2(f,g,a,M);
+%                fr=idgt2(c,gd,a,Ls);
+%
+%   will reconstruct the signal f no matter what the size of f is, provided
+%   that gd is a dual window of g. 
+%
+%   DGT2(f,g1,g2,a,M) makes it possible to use a different window along the
+%   two dimensions. 
+%
+%   The parameters a, M, L and Ls can also be vectors of length 2.
+%   In this case the first element will be used for the first dimension
+%   and the second element will be used for the second dimension.
+%
+%   The output c has 4 or 5 dimensions. The dimensions index the
+%   following properties:
+%
+%   1. Number of translation along 1st dimension of input.
+%
+%   2. Number of channel along 1st dimension  of input
+%
+%   3. Number of translation along 2nd dimension of input.
+%
+%   4. Number of channel along 2nd dimension  of input
+%
+%   5. Plane number, corresponds to 3rd dimension of input. 
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dgt2.php}
+%@seealso{dgt, idgt2, gabdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(4,6,nargin));
+
+L=[];
+
+if prod(size(p3))>2
+  % Two windows was specified.
+  g2=p3;
+  a=p4;
+  M=p5;
+  if nargin==6
+    L=p6;
+  end;
+else
+  g2=g1;
+  a=p3;
+  M=p4;
+  if nargin==5
+    L=p5;
+  end;
+end;
+  
+if isempty(L)
+  L1=[];
+  L2=[];
+else
+  L1=L(1);
+  L2=L(2);
+end;
+
+% Expand 'a' and M if necessary to two elements
+a=bsxfun(@times,a,[1 1]);
+M=bsxfun(@times,M,[1 1]);
+
+Ls=size(f);
+Ls=Ls(1:2);
+
+c=dgt(f,g1,a(1),M(1),L1);
+c=dgt(c,g2,a(2),M(2),L2,'dim',3);
diff --git a/inst/gabor/dgtlength.m b/inst/gabor/dgtlength.m
new file mode 100644
index 0000000..4403eba
--- /dev/null
+++ b/inst/gabor/dgtlength.m
@@ -0,0 +1,125 @@
+function [L,tfr]=dgtlength(Ls,a,M,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} dgtlength
+%@verbatim
+%DGTLENGTH  DGT length from signal
+%   Usage: L=dgtlength(Ls,a,M);
+%          L=dgtlength(Ls,a,M,lt);
+%
+%   DGTLENGTH(Ls,a,M) returns the length of a Gabor system that is long
+%   enough to expand a signal of length Ls. Please see the help on
+%   DGT for an explanation of the parameters a and M.
+%
+%   If the returned length is longer than the signal length, the signal
+%   will be zero-padded by DGT.
+%
+%   A valid transform length must be divisable by both a and M. This
+%   means that the minumal admissable transform length is :
+%
+%     Lsmallest = lcm(a,M);
+%
+%   and all valid transform lengths are multipla of Lsmallest*
+%
+%   Non-separable lattices:
+%   -----------------------
+%
+%   DGTLENGTH(Ls,a,M,lt) does as above for a non-separable lattice with
+%   lattice-type lt. For non-separable lattices, there is the additinal
+%   requirement on the transform length, that the structure of the
+%   lattice must be periodic. This gives a minimal transform length of :
+%
+%     Lsmallest = lcm(a,M)*lt(2);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dgtlength.php}
+%@seealso{dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% This function takes some of the same input parameters as DGT. The phase
+% parameter is ignore, because it does not change the length of the
+% transform, but is included to not cause problem when dgtlength is
+% called via framelength.
+definput.keyvals.lt=[0 1];
+definput.flags.phase={'freqinv','timeinv'};
+[flags,kv,lt]=ltfatarghelper({'lt'},definput,varargin);
+
+if ~isnumeric(M) || ~isscalar(M)
+  error('%s: M must be a scalar',upper(mfilename));
+end;
+
+if ~isnumeric(a) || ~isscalar(a)
+  error('%s: "a" must be a scalar',upper(mfilename));
+end;
+
+if rem(M,1)~=0 || M<=0
+  error('%s: M must be a positive integer',upper(mfilename));
+end;
+
+if rem(a,1)~=0 || a<=0
+  error('%s: "a" must be a positive integer',upper(mfilename));
+end;
+
+if ~isnumeric(Ls)
+    error('%s: Ls must be numeric.',upper(mfilename));
+end;
+
+if ~isscalar(Ls)
+    error('%s: Ls must a scalar.',upper(mfilename));
+end;
+
+if nargin<4
+
+    Lsmallest=lcm(a,M);    
+
+else
+
+    if ~isnumeric(lt) || ~isvector(lt) || length(lt)~=2
+        error('%s: lt must be a vector of length 2.',upper(mfilename));
+    end;
+    
+
+    if (mod(lt(2),1)>0) || lt(2)<=0
+        error('%s: lt(2) must be a positive integer.',upper(mfilename));
+    end;
+    
+    if (mod(lt(1),1)>0) || lt(1)<0 || lt(1)>=lt(2)
+        error(['%s: lt(1)=%i must be a positive integer that is larger than 0 but ' ...
+               'smaller than lt(2)=%i.'],upper(mfilename),lt(1),lt(2));
+    end;
+
+    if lt(1)==0 && lt(2)~=1
+        error('%s: The rectangular lattice can only be specified by lt=[0 1].',upper(mfilename));
+    end;
+
+    if gcd(lt(1),lt(2))>1
+        error('%s: lt(1)/lt(2) must be an irriducible fraction.',upper(mfilename));
+    end;
+
+    Lsmallest=lcm(a,M)*lt(2);
+
+end;
+
+L=ceil(Ls/Lsmallest)*Lsmallest;
+
+
+
diff --git a/inst/gabor/dgtreal.m b/inst/gabor/dgtreal.m
new file mode 100644
index 0000000..a2733ee
--- /dev/null
+++ b/inst/gabor/dgtreal.m
@@ -0,0 +1,141 @@
+function [c,Ls,g]=dgtreal(f,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} dgtreal
+%@verbatim
+%DGTREAL  Discrete Gabor transform for real-valued signals
+%   Usage:  c=dgtreal(f,g,a,M);
+%           c=dgtreal(f,g,a,M,L);
+%           [c,Ls]=dgtreal(f,g,a,M);
+%           [c,Ls]=dgtreal(f,g,a,M,L);
+%
+%   Input parameters:
+%         f     : Input data
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         L     : Length of transform to do.
+%   Output parameters:
+%         c     : M*N array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   DGTREAL(f,g,a,M) computes the Gabor coefficients (also known as a
+%   windowed Fourier transform) of the real-valued input signal f with
+%   respect to the real-valued window g and parameters a and M. The
+%   output is a vector/matrix in a rectangular layout.
+%
+%   As opposed to DGT only the coefficients of the positive frequencies
+%   of the output are returned. DGTREAL will refuse to work for complex
+%   valued input signals.
+%
+%   The length of the transform will be the smallest multiple of a and M*
+%   that is larger than the signal. f will be zero-extended to the length of
+%   the transform. If f is a matrix, the transformation is applied to each
+%   column. The length of the transform done can be obtained by
+%   L=size(c,2)*a.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%
+%   DGTREAL(f,g,a,M,L) computes the Gabor coefficients as above, but does
+%   a transform of length L. f will be cut or zero-extended to length L before
+%   the transform is done.
+%
+%   [c,Ls]=DGTREAL(f,g,a,M) or [c,Ls]=DGTREAL(f,g,a,M,L) additionally
+%   returns the length of the input signal f. This is handy for
+%   reconstruction:
+%
+%     [c,Ls]=dgtreal(f,g,a,M);
+%     fr=idgtreal(c,gd,a,M,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, provided
+%   that gd is a dual window of g.
+%
+%   [c,Ls,g]=DGTREAL(...) additionally outputs the window used in the
+%   transform. This is useful if the window was generated from a description
+%   in a string or cell array.
+%
+%   See the help on DGT for the definition of the discrete Gabor
+%   transform. This routine will return the coefficients for channel
+%   frequencies from 0 to floor(M/2).
+%
+%   DGTREAL takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'freqinv'  Compute a DGTREAL using a frequency-invariant phase. This
+%                is the default convention described in the help for DGT.
+%
+%     'timeinv'  Compute a DGTREAL using a time-invariant phase. This
+%                convention is typically used in filter bank algorithms.
+%
+%   DGTREAL can be used to manually compute a spectrogram, if you
+%   want full control over the parameters and want to capture the output
+%   :
+%
+%     f=greasy;  % Input test signal
+%     fs=16000;  % The sampling rate of this particular test signal
+%     a=10;      % Downsampling factor in time
+%     M=200;     % Total number of channels, only 101 will be computed
+%
+%     % Compute the coefficients using a 20 ms long Hann window
+%     c=dgtreal(f,{'hann',0.02*fs'},a,M);
+%
+%     % Visualize the coefficients as a spectrogram
+%     dynrange=90; % 90 dB dynamical range for the plotting
+%     plotdgtreal(c,a,M,fs,dynrange);
+%     
+%
+%   References:
+%     K. Groechenig. Foundations of Time-Frequency Analysis. Birkhauser, 2001.
+%     
+%     H. G. Feichtinger and T. Strohmer, editors. Gabor Analysis and
+%     Algorithms. Birkhauser, Boston, 1998.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dgtreal.php}
+%@seealso{dgt, idgtreal, gabwin, dwilt, gabtight, plotdgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: OK
+  
+% Assert correct input.
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.flags.phase={'freqinv','timeinv'};
+definput.keyvals.lt=[0 1];
+[flags,kv]=ltfatarghelper({'L'},definput,varargin);
+
+[f,g,L,Ls] = gabpars_from_windowsignal(f,g,a,M,kv.L);
+
+if ~isreal(g)
+  error('The window must be real-valued.');  
+end;
+
+if kv.lt(2)>2
+  error('Only rectangular or quinqux lattices are supported.');  
+end;
+
+c=comp_dgtreal(f,g,a,M,kv.lt,flags.do_timeinv);
+
+
diff --git a/inst/gabor/dsft.m b/inst/gabor/dsft.m
new file mode 100644
index 0000000..0b94692
--- /dev/null
+++ b/inst/gabor/dsft.m
@@ -0,0 +1,71 @@
+function F=dsft(F);
+%-*- texinfo -*-
+%@deftypefn {Function} dsft
+%@verbatim
+%DSFT  Discrete Symplectic Fourier Transform
+%   Usage:  C=dsft(F);
+%
+%   DSFT(F) computes the discrete symplectic Fourier transform of F.
+%   F must be a matrix or a 3D array. If F is a 3D array, the 
+%   transformation is applied along the first two dimensions.
+%
+%   Let F be a K xL matrix. Then the DSFT of F is given by
+%
+%                                L-1 K-1
+%     C(m+1,n+1) = 1/sqrt(K*L) * sum sum F(k+1,l+1)*exp(2*pi*i(k*n/K-l*m/L))
+%                                l=0 k=0
+%
+%   for m=0,...,L-1 and n=0,...,K-1.
+%
+%   The DSFT is its own inverse.
+%
+%   References:
+%     H. G. Feichtinger, M. Hazewinkel, N. Kaiblinger, E. Matusiak, and
+%     M. Neuhauser. Metaplectic operators on c^n. The Quarterly Journal of
+%     Mathematics, 59(1):15-28, 2008.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dsft.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(1,1,nargin));
+
+D=ndims(F);
+
+if (D<2) || (D>3)
+  error('Input must be two/three dimensional.');
+end;
+
+W=size(F,3);
+
+if W==1
+  F=dft(idft(F).');
+else
+  % Apply to set of planes.
+  
+  R1=size(F,1);
+  R2=size(F,2);
+  Fo=zeros(R2,R1,W,assert_classname(F));
+  for w=1:W
+    Fo(:,:,w)=dft(idft(F(:,:,w).'));
+  end;
+  F=Fo;
+end;
+
+
diff --git a/inst/gabor/dwilt.m b/inst/gabor/dwilt.m
new file mode 100644
index 0000000..4430a19
--- /dev/null
+++ b/inst/gabor/dwilt.m
@@ -0,0 +1,193 @@
+function [c,Ls,g]=dwilt(f,g,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} dwilt
+%@verbatim
+%DWILT  Discrete Wilson transform
+%   Usage:  c=dwilt(f,g,M);
+%           c=dwilt(f,g,M,L);
+%           [c,Ls]=dwilt(...);
+%
+%   Input parameters:
+%         f     : Input data
+%         g     : Window function.
+%         M     : Number of bands.
+%         L     : Length of transform to do.
+%   Output parameters:
+%         c     : 2M xN array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   DWILT(f,g,M) computes a discrete Wilson transform with M bands and
+%   window g.
+%
+%   The length of the transform will be the smallest possible that is
+%   larger than the signal. f will be zero-extended to the length of the 
+%   transform. If f is a matrix, the transformation is applied to each column.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%
+%   DWILT(f,g,M,L) computes the Wilson transform as above, but does a
+%   transform of length L. f will be cut or zero-extended to length L*
+%   before the transform is done.
+%
+%   [c,Ls]=DWILT(f,g,M) or [c,Ls]=DWILT(f,g,M,L) additionally return the
+%   length of the input signal f. This is handy for reconstruction:
+%
+%     [c,Ls]=dwilt(f,g,M);
+%     fr=idwilt(c,gd,M,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, provided
+%   that gd is a dual Wilson window of g.
+%
+%   [c,Ls,g]=DWILT(...) additionally outputs the window used in the
+%   transform. This is useful if the window was generated from a description
+%   in a string or cell array.
+%
+%   A Wilson transform is also known as a maximally decimated, even-stacked
+%   cosine modulated filter bank.
+%
+%   Use the function WIL2RECT to visualize the coefficients or to work
+%   with the coefficients in the TF-plane.
+%
+%   Assume that the following code has been executed for a column vector f*:
+%
+%     c=dwilt(f,g,M);  % Compute a Wilson transform of f.
+%     N=size(c,2)*2;   % Number of translation coefficients.
+%
+%   The following holds for m=0,...,M-1 and n=0,...,N/2-1:
+%
+%   If m=0:
+%
+%                    L-1 
+%     c(m+1,n+1)   = sum f(l+1)*g(l-2*n*M+1)
+%                    l=0  
+%
+%
+%   If m is odd and less than M
+%
+%                    L-1 
+%     c(m+1,n+1)   = sum f(l+1)*sqrt(2)*sin(pi*m/M*l)*g(k-2*n*M+1)
+%                    l=0  
+% 
+%                    L-1 
+%     c(m+M+1,n+1) = sum f(l+1)*sqrt(2)*cos(pi*m/M*l)*g(k-(2*n+1)*M+1)
+%                    l=0  
+%
+%   If m is even and less than M
+%
+%                    L-1 
+%     c(m+1,n+1)   = sum f(l+1)*sqrt(2)*cos(pi*m/M*l)*g(l-2*n*M+1)
+%                    l=0  
+% 
+%                    L-1 
+%     c(m+M+1,n+1) = sum f(l+1)*sqrt(2)*sin(pi*m/M*l)*g(l-(2*n+1)*M+1)
+%                    l=0  
+%
+%   if m=M and M is even:
+%
+%                    L-1 
+%     c(m+1,n+1)   = sum f(l+1)*(-1)^(l)*g(l-2*n*M+1)
+%                    l=0
+%
+%   else if m=M and M is odd
+%
+%                    L-1 
+%     c(m+1,n+1)   = sum f(l+1)*(-1)^l*g(l-(2*n+1)*M+1)
+%                    l=0
+%
+%
+%   References:
+%     H. Boelcskei, H. G. Feichtinger, K. Groechenig, and F. Hlawatsch.
+%     Discrete-time Wilson expansions. In Proc. IEEE-SP 1996 Int. Sympos.
+%     Time-Frequency Time-Scale Analysis, june 1996.
+%     
+%     I. Daubechies, S. Jaffard, and J. Journe. A simple Wilson orthonormal
+%     basis with exponential decay. SIAM J. Math. Anal., 22:554-573, 1991.
+%     
+%     Y.-P. Lin and P. Vaidyanathan. Linear phase cosine modulated maximally
+%     decimated filter banks with perfectreconstruction. IEEE Trans. Signal
+%     Process., 43(11):2525-2539, 1995.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dwilt.php}
+%@seealso{idwilt, wilwin, wil2rect, dgt, wmdct, wilorth}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DWILT
+%   REFERENCE: REF_DWILT
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.dim=[];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,dummy,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim,upper(mfilename));
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+
+    % ----- step 2b : Verify a, M and get L from the signal length f----------
+    L=dwiltlength(Ls,M);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+    Luser=dwiltlength(L,M);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DWILTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=wilwin(g,M,L,upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+%% ----- step 4: final cleanup ---------------
+
+f=postpad(f,L);
+
+% If the signal is single precision, make the window single precision as
+% well to avoid mismatches.
+if isa(f,'single')
+  g=single(g);
+end;
+
+%% ----- Call the computational subroutines.
+c=comp_dwilt(f,g,M);
+
+%% ----- reorder coefficients to correct final layout
+order=assert_groworder(order);
+permutedsize=[2*M,L/(2*M),permutedsize(2:end)];
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
diff --git a/inst/gabor/dwilt2.m b/inst/gabor/dwilt2.m
new file mode 100644
index 0000000..015ea66
--- /dev/null
+++ b/inst/gabor/dwilt2.m
@@ -0,0 +1,131 @@
+function [c,Ls]=dwilt2(f,g1,p3,p4,p5)
+%-*- texinfo -*-
+%@deftypefn {Function} dwilt2
+%@verbatim
+%DWILT2  2D Discrete Wilson transform
+%   Usage: c=dwilt2(f,g,M); 
+%          c=dwilt2(f,g1,g2,[M1,M2]);
+%          c=dwilt2(f,g1,g2,[M1,M2],[L1,L2]);
+%          [c,Ls]=dwilt2(f,g1,g2,[M1,M2],[L1,L2]);
+%
+%   Input parameters:
+%         f        : Input data, matrix.
+%         g,g1,g2  : Window functions.
+%         M,M1,M2  : Number of bands.
+%         L1,L2    : Length of transform to do.
+%   Output parameters:
+%         c        : array of coefficients.
+%         Ls       : Original size of input matrix.
+%
+%   DWILT2(f,g,M) calculates a two dimensional discrete Wilson transform
+%   of the input signal f using the window g and parameter M along each
+%   dimension.
+%
+%   For each dimension, the length of the transform will be the smallest
+%   possible that is larger than the length of the signal along that dimension.
+%   f will be appropriately zero-extended.
+%
+%   All windows must be whole-point even.
+% 
+%   DWILT2(f,g,M,L) computes a Wilson transform as above, but does
+%   a transform of length L along each dimension. f will be cut or
+%   zero-extended to length L before the transform is done.
+%
+%   [c,Ls]=dwilt(f,g,M) or [c,Ls]=dwilt(f,g,M,L) additionally returns the
+%   length of the input signal f. This is handy for reconstruction.
+%
+%   c=DWILT2(f,g1,g2,M) makes it possible to use a different window along the
+%   two dimensions. 
+%
+%   The parameters L, M and Ls can also be vectors of length 2. In
+%   this case the first element will be used for the first dimension and the
+%   second element will be used for the second dimension.
+%
+%   The output c has 4 or 5 dimensions. The dimensions index the
+%   following properties:
+%
+%     1. Number of translations along 1st dimension of input.
+%
+%     2. Number of channels along 1st dimension  of input
+%
+%     3. Number of translations along 2nd dimension of input.
+%
+%     4. Number of channels along 2nd dimension  of input
+%
+%     5. Plane number, corresponds to 3rd dimension of input. 
+%
+%   Examples:
+%   ---------
+%
+%   The following example visualize the DWILT2 coefficients of a test
+%   image. For clarity, only the 50 dB largest coefficients are show:
+%
+%     c=dwilt2(cameraman,'itersine',16);
+%     c=reshape(c,256,256);
+%     
+%     figure(1);
+%     imagesc(cameraman), colormap(gray), axis('image');
+%
+%     figure(2);
+%     cc=dynlimit(20*log10(abs(c)),50);
+%     imagesc(cc), colormap(flipud(bone)), axis('image'), colorbar;
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dwilt2.php}
+%@seealso{dwilt, idwilt2, dgt2, wildual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+error(nargchk(3,5,nargin));
+
+L=[];
+
+if prod(size(p3))>2
+  % Two windows was specified.
+  g2=p3;
+  M=p4;
+  if nargin==5
+    L=p5;
+  end;
+else
+  g2=g1;
+  M=p3;
+  if nargin==4
+    L=p4;
+  end;
+end;
+  
+if isempty(L)
+  L1=[];
+  L2=[];
+else
+  L1=L(1);
+  L2=L(2);
+end;
+
+% Expand M if necessary to two elements
+M=bsxfun(@times,M,[1 1]);
+
+Ls=size(f);
+Ls=Ls(1:2);
+
+c=dwilt(f,g1,M(1),L1);
+c=dwilt(c,g2,M(2),L2,'dim',3);
+
diff --git a/inst/gabor/dwiltlength.m b/inst/gabor/dwiltlength.m
new file mode 100644
index 0000000..e588c96
--- /dev/null
+++ b/inst/gabor/dwiltlength.m
@@ -0,0 +1,70 @@
+function [L,tfr]=dwiltlength(Ls,M);
+%-*- texinfo -*-
+%@deftypefn {Function} dwiltlength
+%@verbatim
+%DWILTLENGTH  DWILT/WMDCT length from signal
+%   Usage: L=dwiltlength(Ls,M);
+%
+%   DWILTLENGTH(Ls,M) returns the length of a Wilson / WMDCT system with
+%   M channels system is long enough to expand a signal of length
+%   Ls. Please see the help on DWILT or WMDCT for an explanation of the
+%   parameter M.
+%
+%   If the returned length is longer than the signal length, the signal will
+%   be zero-padded by DWILT or WMDCT.
+%
+%   A valid transform length must be divisable by 2M. This
+%   means that the minumal admissable transform length is :
+%
+%     Lsmallest = 2*M;
+%
+%   and all valid transform lengths are multipla of Lsmallest*
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/dwiltlength.php}
+%@seealso{dwilt, wmdct}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(2,2,nargin));
+
+if ~isnumeric(M) || ~isscalar(M)
+  error('%s: M must be a scalar',upper(mfilename));
+end;
+
+if rem(M,1)~=0 || M<=0
+  error('%s: M must be a positive integer',upper(mfilename));
+end;
+
+if ~isnumeric(Ls)
+    error('%s: Ls must be numeric.',upper(mfilename));
+end;
+
+if ~isscalar(Ls)
+    error('%s: Ls must a scalar.',upper(mfilename));
+end;
+
+Lsmallest=2*M;
+
+L=ceil(Ls/Lsmallest)*Lsmallest;
+
+b=L/(2*M);
+tfr=M/b;
+
+
+
diff --git a/inst/gabor/gabconvexopt.m b/inst/gabor/gabconvexopt.m
new file mode 100644
index 0000000..7dfcbac
--- /dev/null
+++ b/inst/gabor/gabconvexopt.m
@@ -0,0 +1,683 @@
+function [gd,relres,iter] = gabconvexopt(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabconvexopt
+%@verbatim
+%GABCONVEXOPT Compute a window using convex optimization
+%   Usage: gout=gabconvexopt(g,a,M);
+%          gout=gabconvexopt(g,a,M, varagin);
+%
+%   Input parameters:
+%     g      : Window function /initial point (tight case)
+%     a      : Time shift
+%     M      : Number of Channels
+%
+%   Output parameters:
+%     gout   : Output window
+%     iter   : Number of iterations
+%     relres : Reconstruction error
+%
+%   GABCONVEXOPT(g,a,M) computes a window gout which is the optimal
+%   solution of the convex optimization problem below
+%
+%      gd  = argmin_x    || alpha x||_1 +  || beta Fx||_1  
+%
+%                      + || omega (x -g_l) ||_2^2 + delta || x ||_S0
+%
+%                      + gamma || nabla F x ||_2^2 + mu || nabla x ||_2^2
+%
+%          such that  x satifies the constraints
+%
+%   Three constraints are possible:
+%   
+%    x is dual with respect of g
+%
+%    x is tight
+%
+%    x is compactly supported on Ldual
+%
+%   *Note**: This function require the unlocbox. You can download it at
+%   http://unlocbox.sourceforge.net
+%
+%   The function uses an iterative algorithm to compute the approximate.
+%   The algorithm can be controlled by the following flags:
+%
+%     'alpha',alpha  Weight in time. If it is a scalar, it represent the
+%                  weights of the entire L1 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm (length: Ldual).
+%                  Default value is alpha=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-time constraint: alpha=0
+%
+%     'beta',beta  Weight in frequency. If it is a scalar, it represent the
+%                  weights of the entire L1 function in frequency. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm in frequency. (length: Ldual).
+%                  Default value is beta=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-frequency constraint: beta=0
+%
+%     'omega',omega  Weight in time of the L2-norm. If it is a scalar, it represent the
+%                  weights of the entire L2 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L2 norm (length: Ldual).
+%                  Default value is omega=0.
+%                  No L2-time constraint: omega=0
+%
+%     'glike',g_l  g_l is a windows in time. The algorithm try to shape
+%                  the dual window like g_l. Normalization of g_l is done
+%                  automatically. To use option omega should be different
+%                  from 0. By default g_d=0.
+%
+%     'mu', mu     Weight of the smooth constraint Default value is 1. 
+%                  No smooth constraint: mu=0
+%   
+%     'gamma', gamma  Weight of the smooth constraint in frequency. Default value is 1. 
+%                  No smooth constraint: gamma=0
+%   
+%     'delta', delta  Weight of the S0-norm. Default value is 0. 
+%                  No S0-norm: delta=0
+%
+%     'support' Ldual  Add a constraint on the support. The windows should
+%                  be compactly supported on Ldual.
+%
+%     'tight'      Look for a tight windows
+%
+%     'dual'       Look for a dual windows (default)
+%
+%     'painless'   Construct a starting guess using a painless-case
+%                  approximation. This is the default
+%
+%     'zero'       Choose a starting guess of zero.
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'tol',t      Stop if relative residual error is less than the 
+%                  specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations. default 200
+%
+%     'print'      Display the progress.
+%
+%     'debug'      Display all the progresses.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'fast'       Fast algorithm, this is the default.
+%
+%     'slow'       Safer algorithm, you can try this if the fast algorithm
+%                  is not working. Before using this, try to iterate more.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%     'hardconstraint' Force the projection at the end (default)
+%
+%     'softconstaint' Do not force the projection at the end
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabconvexopt.php}
+%@seealso{gaboptdual, gabdual, gabtight, gabfirtight, gabopttight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+   
+
+
+% Author: Nathanael Perraudin
+% Date  : 18 Feb 2014
+
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if numel(g)==1
+  error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.keyvals.tol=1e-6;
+definput.keyvals.maxit=200;
+definput.keyvals.printstep=10;
+definput.flags.print={'quiet','print','debug'};
+definput.flags.algo={'fast','slow'};
+definput.flags.constraint={'hardconstraint','softconstaint'};
+definput.flags.startphase={'painless','zero','rand'};
+definput.flags.type={'dual','tight'};
+
+definput.keyvals.alpha=0;
+definput.keyvals.omega=0;
+definput.keyvals.beta=0;
+definput.keyvals.mu=1;
+definput.keyvals.gamma=1;
+definput.keyvals.vart=0;
+definput.keyvals.varf=0;
+definput.keyvals.var2t=0;
+definput.keyvals.var2f=0;
+definput.keyvals.support=0;
+definput.keyvals.delta=0;
+definput.keyvals.deltaw=0;
+definput.keyvals.glike=zeros(size(g));
+
+[flags,kv]=ltfatarghelper({'L','tol','maxit'},definput,varargin);
+
+% Determine the window. The window /must/ be an FIR window, so it is
+% perfectly legal to specify L=[] when calling gabwin
+[g,info]=gabwin(g,a,M,[],kv.lt,'callfun',upper(mfilename));
+
+if kv.support
+    Ldual=kv.support;
+    % Determine L. L must be longer than L+Ldual+1 to make sure that no convolutions are periodic
+    L=dgtlength(info.gl+Ldual+1,a,M);
+else
+    L=length(g);
+    Ldual=L;
+end
+
+b=L/M;
+
+% Determine the initial guess
+if flags.do_zero
+  gd_initial=zeros(Ldual,1);
+end;
+
+if flags.do_rand
+  gd_initial=rand(size(g));
+end;
+
+if flags.do_painless
+  gsmall=long2fir(g,M);
+  gdsmall=gabdual(gsmall,a,M);
+  gd_initial=fir2long(gdsmall,Ldual);
+end;
+
+% -------- do the convex optimization stuff
+
+% Define the long original window
+glong=fir2long(g,L);
+
+
+
+
+%gabframebounds(g,a,M)
+
+
+% Initial point
+xin=gd_initial;
+xin=fir2long(xin,L);
+
+
+% -- * Setting the different prox for ppxa *--
+% ppxa will minimize all different proxes
+
+% value test for the selection constraint
+nb_priors=0;
+
+% - variance -
+    if kv.vart % constraint in time
+        if flags.do_debug
+            param_l1.verbose=1; % display the results
+        else
+            param_l1.verbose=0; % do not display anything
+        end
+        
+         % alpha is a scalar
+        if mod(L,2)
+             w=[0:1:(L-1)/2,(L-1)/2:-1:1]';
+        else
+             w=[0:1:L/2-1,L/2:-1:1]';
+        end
+        w=w.^2/L;
+        
+        param_l1.weights=w;
+        nb_priors=nb_priors+1;
+        g11.prox= @(x,T) prox_l1(x,kv.vart*T,param_l1); % define the prox_l1 as operator
+        g11.eval= @(x) kv.vart*norm(w.*x,1); % the objectiv function is the l1 norm
+    else % no L1 in time constraint
+        g11.prox= @(x,T) x; 
+        g11.eval= @(x) 0; 
+    end
+
+% - variance -
+    if kv.varf % constraint in time
+        
+        param_l1_fourier.A= @(x) 1/sqrt(L)*fft(x); % Fourier operator
+        param_l1_fourier.At= @(x) sqrt(L)*ifft(x); % adjoint of the Fourier operator
+        if flags.do_debug
+            param_l1_fourier.verbose=1; % display the results
+        else
+            param_l1_fourier.verbose=0; % do not display anything
+        end
+        
+        if mod(L,2)
+             w=[0:1:(L-1)/2,(L-1)/2:-1:1]';
+        else
+             w=[0:1:L/2-1,L/2:-1:1]';
+        end
+        w=w.^2/L;
+         
+        param_l1_fourier.weights=w;
+        nb_priors=nb_priors+1;
+        g12.prox= @(x,T) prox_l1(x,kv.varf*T,param_l1_fourier); % define the prox_l1 as operator
+        g12.eval= @(x) kv.varf*norm(w.*x,1); % the objectiv function is the l1 norm
+    else % no L1 in time constraint
+        g12.prox= @(x,T) x; 
+        g12.eval= @(x) 0; 
+    end 
+
+% - variance2 -
+    if kv.var2t % constraint in time
+        if flags.do_debug
+            param_l2.verbose=1; % display the results
+        else
+            param_l2.verbose=0; % do not display anything
+        end
+        
+         % alpha is a scalar
+        if mod(L,2)
+             w=[0:1:(L-1)/2,(L-1)/2:-1:1]';
+        else
+             w=[0:1:L/2-1,L/2:-1:1]';
+        end
+        w=w/sqrt(L);
+        
+        param_l2.weights=w;
+        nb_priors=nb_priors+1;
+        g13.prox= @(x,T) prox_l2(x,kv.var2t*T,param_l2); % define the prox_l1 as operator
+        g13.eval= @(x) kv.var2t*norm(w.*x,2)^2; % the objectiv function is the l1 norm
+    else % no L1 in time constraint
+        g13.prox= @(x,T) x; 
+        g13.eval= @(x) 0; 
+    end
+
+% - variance2 -
+    if kv.var2f % constraint in time
+        
+        param_l2_fourier.A= @(x) 1/sqrt(L)*fft(x); % Fourier operator
+        param_l2_fourier.At= @(x) sqrt(L)*ifft(x); % adjoint of the Fourier operator
+        if flags.do_debug
+            param_l2_fourier.verbose=1; % display the results
+        else
+            param_l2_fourier.verbose=0; % do not display anything
+        end
+        
+        if mod(L,2)
+             w=[0:1:(L-1)/2,(L-1)/2:-1:1]';
+        else
+             w=[0:1:L/2-1,L/2:-1:1]';
+        end
+        w=w/sqrt(L);
+         
+        param_l2_fourier.weights=w;
+        nb_priors=nb_priors+1;
+        g14.prox= @(x,T) prox_l2(x,kv.var2f*T,param_l2_fourier); % define the prox_l1 as operator
+        g14.eval= @(x) kv.var2f*norm(w.*x,2)^2; % the objectiv function is the l1 norm
+    else % no L1 in time constraint
+        g14.prox= @(x,T) x; 
+        g14.eval= @(x) 0; 
+    end    
+    
+% - small L1 norm in coefficient domain -
+    if kv.alpha % constraint in time
+        if flags.do_debug
+            param_l1.verbose=1; % display the results
+        else
+            param_l1.verbose=0; % do not display anything
+        end
+        
+        if length(kv.alpha)==1 % alpha is a scalar
+            kv.alpha=ones(size(xin))*kv.alpha;
+        end
+        param_l1.weights=kv.alpha;
+        nb_priors=nb_priors+1;
+        g1.prox= @(x,T) prox_l1(x,T,param_l1); % define the prox_l1 as operator
+        g1.eval= @(x) norm(kv.alpha.*x,1); % the objectiv function is the l1 norm
+    else % no L1 in time constraint
+        g1.prox= @(x,T) x; 
+        g1.eval= @(x) 0; 
+    end
+
+% - small L1 norm in Fourier domain -
+    if kv.beta %frequency constraint
+        param_l1_fourier.A= @(x) 1/sqrt(L)*fft(x); % Fourier operator
+        param_l1_fourier.At= @(x) sqrt(L)*ifft(x); % adjoint of the Fourier operator
+        if flags.do_debug
+            param_l1_fourier.verbose=1; % display the results
+        else
+            param_l1_fourier.verbose=0; % Do not display anything
+        end
+        
+        
+
+        if length(kv.beta)==1 % alpha is a scalar
+            kv.beta=ones(size(xin))*kv.beta;
+        end
+
+        param_l1_fourier.weights=kv.beta;
+        % Here are the step for the prox
+        %   2) go into the Fourier domain (prox_l1)
+        %   3) soft thresholding (prox_l1)
+        %   4) back in the time domain (prox_l1)
+        nb_priors=nb_priors+1;
+        g3.prox= @(x,T) prox_l1(x,T,param_l1_fourier);   
+
+        g3.eval= @(x) norm(kv.beta.*fft(x),1); % objectiv function
+    else % no L1 in frequency constraint
+        g3.prox= @(x,T) x;   
+        g3.eval= @(x) 0; % objectiv function
+        
+    end
+
+
+% - DUAL OR TIGHT?-    
+if flags.do_tight
+    % tight windows
+    g2.prox= @(x,T) gabtight(x,a,M); % set the prox
+    g2.eval= @(x) norm(x-gabdual(x,a,M,L)); % objectiv function
+else
+% - projection on a B2 ball -
+    % Frame-type matrix of the adjoint lattice
+    %G=tfmat('dgt',glong,M,a);
+    Fal=frame('dgt',glong,M,a);
+    G=framematrix(Fal,L);
+    d=[a/M;zeros(a*b-1,1)];
+    
+    % Using a B2 ball projection
+    % || Gcut' x - b ||_2 < epsilon
+%     param_proj.A = @(x) G'*x; % forward operator
+%     param_proj.At = @(x) G*x; % adjoint operator
+%     param_proj.y = d;            
+%     param_proj.maxit = 200;      % maximum of iteration
+%     param_proj.tight=0;         % not a tight frame
+%     param_proj.nu=norm(G)^2; % frame bound on Gcut'
+%     param_proj.verbose=0;       % diplay summary at the end
+%     param_proj.epsilon=10*eps;       % radius of the B2 ball
+%     g2.prox= @(x,T) fast_proj_b2(x,T,param_proj); % set the prox
+
+    % Using a direct projection (better solution)
+    param_proj.verbose=flags.do_debug;
+    param_proj.y=d;
+    param_proj.A=G';
+    param_proj.AAtinv=(G'*G)^(-1);
+    g2.prox= @(x,T) proj_dual(x,T,param_proj); % set the prox
+    g2.eval= @(x) norm(G'*x-d); % objectiv function
+end
+    
+
+% SUPPORT CONSTRAINT
+if kv.support
+% - set null coefficient    
+    g4.prox = @(x,T) forceeven(fir2long(long2fir(x,Ldual),L));
+    g4.eval = @(x) 0;
+
+% - function apply the two projections thanks to a poc algorithm.
+    if flags.do_tight
+
+        G={g2,g4};
+        paramPOCS.tol=20*eps;
+        paramPOCS.maxit=5000;
+        paramPOCS.verbose=flags.do_print+flags.do_debug;
+        paramPOCS.abs_tol=1;
+        g5.prox = @(x,T) pocs(x,G,paramPOCS);
+        % g5.prox = @(x,T) ppxa(x,G,paramPOCS);
+        % g5.prox = @(x,T) douglas_rachford(x,g2,g4,paramPOCS);
+        % g5.prox = @(x,T) pocs2(x,g2,g4,20*eps,2000, flags.do_print+flags.do_debug);
+        g5.eval = @(x) 0;
+
+    else
+        Fal=frame('dgt',glong,M,a);
+        G=framematrix(Fal,L);
+        d=[a/M;zeros(a*b-1,1)];
+        Lfirst=ceil(Ldual/2);
+        Llast=Ldual-Lfirst;
+        Gcut=G([1:Lfirst,L-Llast+1:L],:);
+        param_proj2.verbose=flags.do_debug;
+        param_proj2.y=d;
+        param_proj2.A=Gcut';
+        param_proj2.AAtinv=pinv(Gcut'*Gcut);
+        g5.prox= @(x,T) fir2long(proj_dual(long2fir(x,Ldual),T,param_proj2),L); % set the prox
+        g5.eval= @(x) norm(G'*x-d); % objectiv function
+    end
+    
+else
+    g4.prox= @(x,T) x;   
+    g4.eval= @(x) 0; % objectiv function
+    g5=g2;
+end
+% - function apply the two projections thanks to a douglas rachford algorithm.
+%     param_douglas.verbose=1;
+%     param_douglas.abs_tol=1;
+%     param_douglas.maxit=2000;
+%     param_douglas.tol=20*eps;
+%     g6.prox = @(x,T) douglas_rachford(x,g2,g4,param_douglas);
+%     g6.eval = @(x) 0;
+
+
+
+% - small gradient norm - 
+% this is the smoothing parameter
+    if kv.mu
+        if flags.do_debug
+            param_l2grad.verbose=1; % display the results
+        else
+            param_l2grad.verbose=0; % Do not display anything
+        end
+        nb_priors=nb_priors+1;
+        g7.prox = @(x,T) prox_l2grad(fir2long(x,L),kv.mu*T,param_l2grad);
+        g7.eval = @(x) norm(gradient(x))^2;
+    else
+        g7.prox = @(x,T) x;
+        g7.eval = @(x) 0;
+    end
+
+    
+    
+% - small gradient norm in fourrier- 
+% this is the smoothing parameter
+    if kv.gamma
+        if flags.do_debug
+            param_l2grad.verbose=1; % display the results
+        else
+            param_l2grad.verbose=0; % Do not display anything
+        end
+        nb_priors=nb_priors+1;
+        g9.prox = @(x,T) prox_l2gradfourier(fir2long(x,L),kv.gamma*T,param_l2grad);
+        g9.eval = @(x) norm(gradient(1/sqrt(L)*fft(x)))^2;
+    else
+        g9.prox = @(x,T) x;
+        g9.eval = @(x) 0;
+    end
+    
+    
+    
+% - small L2 norm in coefficient domain -
+    if kv.omega % constraint in time
+        if flags.do_debug
+            param_l2.verbose=1; % display the results
+        else
+            param_l2.verbose=0; % do not display anything
+        end
+        
+        if length(kv.omega)==1 % alpha is a scalar
+            kv.alpha=ones(size(xin))*kv.omega;
+        end
+        param_l2.weights=kv.omega;
+        if sum(kv.glike)
+           kv.glike=fir2long(kv.glike,L);
+
+           glike=kv.glike/norm(kv.glike)*norm(gabdual(g,a,M));
+           param_l2.y=fir2long(glike,L);
+        end
+        nb_priors=nb_priors+1;
+        g8.prox= @(x,T) prox_l2(x,T,param_l2); % define the prox_l2 as operator
+        g8.eval= @(x) norm(kv.omega.*x-kv.glike,'fro')^2; % the objectiv function is the l2 norm
+    else % no L1 in time constraint
+        g8.prox= @(x,T) x; 
+        g8.eval= @(x) 0; 
+    end    
+
+
+    
+    
+% - small S0 norm -
+    if kv.delta %frequency constraint
+        gauss=pgauss(L,1);
+
+        [A,B]=gabframebounds(gauss,1,L);
+        AB=(A+B)/2;
+        param_S0.A= @(x) dgt(x,gauss,1,L)/sqrt(AB);
+        param_S0.At= @(x) idgt(x,gauss,1,L)/sqrt(AB);
+        if flags.do_debug
+            param_S0.verbose=1; % display the results
+        else
+            param_S0.verbose=0; % Do not display anything
+        end
+        
+        nb_priors=nb_priors+1;
+        g10.prox= @(x,T) prox_l1(x,T*kv.delta,param_S0);   
+
+        g10.eval= @(x) kv.delta*norm(reshape(dgt(x,gauss,1,L),[],1),1); % objectiv function
+    else % no L1 in frequency constraint
+        g10.prox= @(x,T) x;   
+        g10.eval= @(x) 0; % objectiv function
+        
+    end
+    
+% - small weighted S0 norm -
+    if kv.deltaw %frequency constraint
+        gauss=pgauss(L,1);
+
+        [A,B]=gabframebounds(gauss,1,L);
+        AB=(A+B)/2;
+        param_S0.A= @(x) dgt(x,gauss,1,L)/sqrt(AB);
+        param_S0.At= @(x) idgt(x,gauss,1,L)/sqrt(AB);
+        if flags.do_debug
+            param_S0.verbose=1; % display the results
+        else
+            param_S0.verbose=0; % Do not display anything
+        end
+        
+        if mod(L,2)
+             w=[0:1:(L-1)/2,(L-1)/2:-1:1]';
+        else
+             w=[0:1:L/2-1,L/2:-1:1]';
+        end
+        w=w/sqrt(L);
+        
+        %W=w*w';
+        
+        W=repmat(w,1,L).^2+repmat(w',L,1).^2;
+        
+        
+        W=sqrt(W);
+        
+        param_S0.weights=W;
+        nb_priors=nb_priors+1;
+        g15.prox= @(x,T) prox_l1(x,T*kv.deltaw,param_S0);   
+
+        g15.eval= @(x) kv.deltaw*norm(reshape(dgt(x,gauss,1,L),[],1),1); % objectiv function
+    else % no L1 in frequency constraint
+        g15.prox= @(x,T) x;   
+        g15.eval= @(x) 0; % objectiv function
+        
+    end
+    
+    
+    
+% -- * PPXA function, the solver * --
+
+
+% parameter for the solver
+    param.maxit=kv.maxit; % maximum number of iteration
+    param.tol=kv.tol;
+    if flags.do_quiet
+        param.verbose=0;
+    end
+    
+    % Definition of the function f (the order is important)
+    if flags.do_fast && flags.do_tight
+        F={g1, g3,g7,g9,g8, g2, g4,g10,g11,g12,g13,g14,g15}; 
+        
+    else
+        F={g1, g3,g7,g9,g8, g5,g10,g11,g12,g13,g14,g15};
+    end
+
+    
+    % solving the problem
+    
+    if nb_priors
+        [gd,iter,~]=ppxa(xin,F,param);
+        
+        % Force the hard constraint
+        if flags.do_hardconstraint
+            % In case of use of the douglas rachford algo instead of POCS
+            %  gd=g6.prox(gd,0); % force the constraint
+
+             gd=g5.prox(gd,0);
+        end
+    else
+        fprintf( ' Warning!!! No prior selected! -- Only perform a projection. \n')
+        gd=g5.prox(xin,0);
+    end
+    
+    % compute the error
+    if flags.do_tight
+        relres=gabdualnorm(gd,gd,a,M,L);
+    else
+        relres=gabdualnorm(g,gd,a,M,L);
+    end
+    
+
+   if kv.support
+        % set the good size
+        gd=long2fir(gd,Ldual);
+   end
+
+end
+
+
+% function x=pocs2(x,g1,g2,tol,maxii,flagp)
+% % this function implement a POCS algorithm, projection onto convex Set
+% % using the differents projection of the algorithm.
+% tola=1;
+% ii=0;
+% tola_old=tola;
+% while (tola>tol)
+%     x=g2.prox(g1.prox(x,0),0);
+%     tola=g1.eval(x);
+%     ii=ii+1;
+%     if (logical(1-logical(mod(ii,50))) && flagp)
+%        fprintf('      POCS sub-iteration: %i  -- Tol : %g\n',ii,tola)
+%     end
+%     if ii> maxii
+%         break;
+%     end
+%     if abs(tola_old-tola)/tola<tol % avoid infinite loop
+%         break;
+%     end
+%     tola_old=tola;
+% end
+% end
+
+function x=forceeven(x)
+% this function force the signal to be even
+   x=  (x+involute(x))/2;
+end
diff --git a/inst/gabor/gabdual.m b/inst/gabor/gabdual.m
new file mode 100644
index 0000000..a0010d0
--- /dev/null
+++ b/inst/gabor/gabdual.m
@@ -0,0 +1,223 @@
+function gd=gabdual(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabdual
+%@verbatim
+%GABDUAL  Canonical dual window of Gabor frame
+%   Usage:  gd=gabdual(g,a,M);
+%           gd=gabdual(g,a,M,L);
+%           gd=gabdual(g,a,M,'lt',lt);
+%
+%   Input parameters:
+%         g     : Gabor window.
+%         a     : Length of time shift.
+%         M     : Number of channels.
+%         L     : Length of window. (optional)
+%         lt    : Lattice type (for non-separable lattices).
+%   Output parameters:
+%         gd : Canonical dual window.
+%
+%   GABDUAL(g,a,M) computes the canonical dual window of the discrete Gabor
+%   frame with window g and parameters a, M.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%
+%   If the length of g is equal to M, then the input window is assumed
+%   to be an FIR window. In this case, the canonical dual window also has
+%   length of M. Otherwise the smallest possible transform length is chosen
+%   as the window length.
+%
+%   GABDUAL(g,a,M,L) returns a window that is the dual window for a system
+%   of length L. Unless the dual window is a FIR window, the dual window
+%   will have length L.
+%
+%   GABDUAL(g,a,M,'lt',lt) does the same for a non-separable lattice
+%   specified by lt. Please see the help of MATRIX2LATTICETYPE for a
+%   precise description of the parameter lt.
+%
+%   If a>M then the dual window of the Gabor Riesz sequence with window
+%   g and parameters a and M will be calculated.
+%
+%   Examples:
+%   ---------
+%
+%   The following example shows the canonical dual window of the Gaussian
+%   window:
+%
+%     a=20;
+%     M=30;
+%     L=300;
+%     g=pgauss(L,a*M/L);
+%     gd=gabdual(g,a,M);
+%     
+%     % Simple plot in the time-domain
+%     figure(1);
+%     plot(gd);
+%
+%     % Frequency domain
+%     figure(2);
+%     magresp(gd,'dynrange',100);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabdual.php}
+%@seealso{gabtight, gabwin, fir2long, dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: REF_GABDUAL.
+  
+%% ---------- Assert correct input.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.keyvals.nsalg=0;
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    if isnumeric(g)
+        % Use the window length
+        Ls=length(g);
+    else
+        % Use the smallest possible length
+        Ls=1;
+    end;
+
+    % ----- step 2b : Verify a, M and get L from the window length ----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+R=size(g,2);
+% -------- Are we in the Riesz sequence of in the frame case
+
+scale=1;
+if a>M*R
+  % Handle the Riesz basis (dual lattice) case.
+  % Swap a and M, and scale differently.
+  scale=a/M;
+  tmp=a;
+  a=M;
+  M=tmp;
+end;
+
+% -------- Compute ------------- 
+
+if kv.lt(2)==1
+    % Rectangular case
+    if (info.gl<=M) && (R==1)
+        
+        % Diagonal of the frame operator
+        d = gabframediag(g,a,M,L);
+        gd=g./long2fir(d,info.gl);
+                
+    else
+        
+        % Long window case
+        
+        % Just in case, otherwise the call is harmless. 
+        g=fir2long(g,L);
+        
+        gd=comp_gabdual_long(g,a,M)*scale;
+        
+    end;
+
+else
+    % Non-separable case
+    g=fir2long(g,L);
+
+    if (kv.nsalg==1) || (kv.nsalg==0 && kv.lt(2)<=2) 
+        
+        mwin=comp_nonsepwin2multi(g,a,M,kv.lt,L);
+        
+        gdfull=comp_gabdual_long(mwin,a*kv.lt(2),M)*scale;
+        
+        % We need just the first vector
+        gd=gdfull(:,1);
+            
+    else        
+        
+        [s0,s1,br] = shearfind(L,a,M,kv.lt);        
+        
+        if s1 ~= 0
+            p1 = comp_pchirp(L,s1);
+            g = p1.*g;                
+        end
+        
+        b=L/M;
+        Mr = L/br;
+        ar = a*b/br;
+        
+        if s0 == 0
+            gd=comp_gabdual_long(g,ar,Mr);
+        else                
+            p0=comp_pchirp(L,-s0);
+            g = p0.*fft(g);
+            gd=comp_gabdual_long(g,L/Mr,L/ar)*L;
+            gd = ifft(conj(p0).*gd);                                 
+        end
+        
+        if s1 ~= 0
+            gd = conj(p1).*gd;
+        end
+        
+    end;
+
+    if (info.gl<=M) && (R==1)
+        gd=long2fir(gd,M);
+    end;
+        
+end;
+    
+% --------- post process result -------
+
+if isreal(g) && (kv.lt(2)==1 || kv.lt(2)==2)
+  % If g is real and the lattice is either rectangular or quinqux, then
+  % the output is known to be real.
+  gd=real(gd);
+end;
+
+if info.wasrow
+  gd=gd.';
+end;
+
diff --git a/inst/gabor/gabdualnorm.m b/inst/gabor/gabdualnorm.m
new file mode 100644
index 0000000..58e9231
--- /dev/null
+++ b/inst/gabor/gabdualnorm.m
@@ -0,0 +1,152 @@
+function [o1,o2]=gabdualnorm(g,gamma,a,M,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} gabdualnorm
+%@verbatim
+%GABDUALNORM  Measure of how close a window is to being a dual window
+%   Usage:  dn=gabdualnorm(g,gamma,a,M);
+%           dn=gabdualnorm(g,gamma,a,M,L);
+%           dn=gabdualnorm(g,gamma,a,M,'lt',lt);
+%           [scal,res]=gabdualnorm(...);
+%
+%   Input parameters:
+%         gamma  : input window..
+%         g      : window function.
+%         a      : Length of time shift.
+%         M      : Number of modulations.
+%         L      : Length of transform to consider
+%   Output parameters:
+%         dn     : dual norm.
+%         scal   : Scaling factor
+%         res    : Residual
+%
+%   GABDUALNORM(g,gamma,a,M) calculates how close gamma is to being a
+%   dual window of the Gabor frame with window g and parameters a and M.
+%
+%   The windows g and gamma may be vectors of numerical values, text strings
+%   or cell arrays. See the help of GABWIN for more details.
+%
+%   [scal,res]=GABDUALNORM(...) computes two entities: scal determines
+%   if the windows are scaled correctly, it must be 1 for the windows to be
+%   dual. res is close to zero if the windows (scaled correctly) are dual
+%   windows.
+%
+%   GABDUALNORM(g,gamma,a,M,L) does the same, but considers a transform
+%   length of L.
+%
+%   GABDUALNORM(g,gamma,a,M,'lt',lt) does the same for a non-separable
+%   lattice specified by lt. Please see the help of MATRIX2LATTICETYPE
+%   for a precise description of the parameter lt.
+%
+%   GABDUALNORM can be used to get the maximum relative reconstruction
+%   error when using the two specified windows. Consider the following code
+%   for some signal f, windows g, gamma, parameters a and M and 
+%   transform-length L (See help on DGT on how to obtain L*):
+%
+%     fr=idgt(dgt(f,g,a,M),gamma,a); 
+%     er=norm(f-fr)/norm(f);
+%     eest=gabdualnorm(g,gamma,a,M,L);
+%
+%   Then  er<eest for all possible input signals f.
+%
+%   To get a similar estimate for an almost tight window gt, simply use :
+%  
+%     eest=gabdualnorm(gt,gt,a,M,L);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabdualnorm.php}
+%@seealso{gabframebounds, dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+%% ---------- Assert correct input.
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    % Minimum transform length by default.
+    Ls=1;
+    
+    % Use the window lengths, if any of them are numerical
+    if isnumeric(g)
+        Ls=max(length(g),Ls);
+    end;
+
+    if isnumeric(gamma)
+        Ls=max(length(gamma),Ls);
+    end;
+
+    % ----- step 2b : Verify a, M and get L from the window length ----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser)
+    end;
+
+end;
+
+[g,    info_g]     = gabwin(g,    a,M,L,kv.lt,'callfun',upper(mfilename));
+[gamma,info_gamma] = gabwin(gamma,a,M,L,kv.lt,'callfun',upper(mfilename));
+ 
+% gamma must have the correct length, otherwise dgt will zero-extend it
+% incorrectly using postpad instead of fir2long
+gamma=fir2long(gamma,L);
+g    =fir2long(g,L);
+
+% Handle the Riesz basis (dual lattice) case.
+if a>M
+
+  % Calculate the right-hand side of the Wexler-Raz equations.
+  rhs=dgt(gamma,g,a,M,L,'lt',kv.lt);
+  scalconst=1;
+  
+else
+  
+  % Calculate the right-hand side of the Wexler-Raz equations.
+  rhs=dgt(gamma,g,M,a,L,'lt',kv.lt);
+  
+  scalconst=a/M;
+  
+end;
+
+if nargout<2
+  % Subtract from the first element to make it zero, if the windows are
+  % dual.
+  rhs(1)=rhs(1)-scalconst;
+
+  o1=norm(rhs(:),1);
+else
+  % Scale the first element to make it one, if the windows are dual.
+  o1=rhs(1)/scalconst;
+  o2=norm(rhs(2:end),1);
+end;
+
diff --git a/inst/gabor/gabfirdual.m b/inst/gabor/gabfirdual.m
new file mode 100644
index 0000000..0d81b09
--- /dev/null
+++ b/inst/gabor/gabfirdual.m
@@ -0,0 +1,147 @@
+function [gd,relres,iter]=gabfirdual(Ldual,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabfirdual
+%@verbatim
+%GABFIRDUAL  Compute FIR dual window
+%   Usage: gd=gabfirdual(Ldual,g,a,M);
+%          gd=gabfirdual(Ldual,g,a,M, varagin);
+%
+%   Input parameters:
+%     Ldual  : Length of dual window
+%     g      : Window function
+%     a      : Time shift
+%     M      : Number of Channels
+%     alpha1 : Weight of l^1-norm in the time domain
+%     alpha2 : Weight of l^1-norm in the freq. domain
+%
+%   Output parameters:
+%     gd     : Dual window
+%
+%   GABFIRDUAL(Ldual,g,a,M) computes an FIR window gd which is an
+%   approximate dual window of the Gabor system defined by g, a and
+%   M. The FIR dual window will be supported on Ldual samples.
+%
+%   This function solve a convex optimization problem that can be written
+%   as:
+%
+%      gd  = argmin_x    || alpha x||_1 +  || beta Fx||_1  
+%
+%                      + || omega (x -g_l) ||_2^2 + delta || x ||_S0
+%
+%                      + gamma || nabla F x ||_2^2 + mu || nabla x ||_2^2
+%
+%          such that  x is a dual windows of g
+%
+%   *Note**: This function require the unlocbox. You can download it at
+%   http://unlocbox.sourceforge.net
+%   
+%   The function uses an iterative algorithm to compute the approximate
+%   FIR dual. The algorithm can be controlled by the following flags:
+%
+%     'alpha',alpha  Weight in time. If it is a scalar, it represent the
+%                  weights of the entire L1 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm (length: Ldual).
+%                  Default value is alpha=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-time constraint: alpha=0
+%
+%     'beta',beta  Weight in frequency. If it is a scalar, it represent the
+%                  weights of the entire L1 function in frequency. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm in frequency. (length: Ldual).
+%                  Default value is beta=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-frequency constraint: beta=0
+%
+%     'omega',omega  Weight in time of the L2-norm. If it is a scalar, it represent the
+%                  weights of the entire L2 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L2 norm (length: Ldual).
+%                  Default value is omega=0.
+%                  No L2-time constraint: omega=0
+%
+%     'glike',g_l  g_l is a windows in time. The algorithm try to shape
+%                  the dual window like g_l. Normalization of g_l is done
+%                  automatically. To use option omega should be different
+%                  from 0. By default g_d=0.
+%
+%     'mu',mu      Weight of the smooth constraint Default value is 1. 
+%                  No smooth constraint: mu=0
+%   
+%     'gamma',gamma  Weight of the smooth constraint in frequency. Default value is 1. 
+%                    No smooth constraint: gamma=0
+%   
+%     'delta',delta  Weight of the S0-norm. Default value is 0. 
+%                    No S0-norm: delta=0
+%
+%     'dual'       Look for a dual windows (default)
+%
+%     'painless'   Construct a starting guess using a painless-case
+%                  approximation. This is the default
+%
+%     'zero'       Choose a starting guess of zero.
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'tol',t      Stop if relative residual error is less than the 
+%                  specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations. default 200
+%
+%     'print'      Display the progress.
+%
+%     'debug'      Display all the progresses.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'fast'       Fast algorithm, this is the default.
+%
+%     'slow'       Safer algorithm, you can try this if the fast algorithm
+%                  is not working. Before using this, try to iterate more.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%     'hardconstraint' Force the projection at the end (default)
+%
+%     'softconstaint' Do not force the projection at the end
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabfirdual.php}
+%@seealso{gaboptdual, gabdual, gabtight, gabfirtight, gaboptdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+
+
+% Author: Nathanael Perraudin
+% Date  : 18 Feb 2014
+
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% l=length(varargin);
+% varargin(l+1)=cellstr('support');
+% varargin(l+2)=num2cell(Ldual);
+
+[gd,relres,iter]=gabconvexopt(g,a,M,varargin{:}, 'support',Ldual);
diff --git a/inst/gabor/gabfirtight.m b/inst/gabor/gabfirtight.m
new file mode 100644
index 0000000..dd99b6a
--- /dev/null
+++ b/inst/gabor/gabfirtight.m
@@ -0,0 +1,142 @@
+function [gt,relres,iter]=gabfirtight(Lsupport,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabfirtight
+%@verbatim
+%GABFIRTIGHT  Compute FIR tight window
+%   Usage: gt=gabfirtight(Lsupport,g,a,M);
+%          gt=gabfirtight(Lsupport,g,a,M, varagin);
+%
+%   Input parameters:
+%     Lsupport  : Length of the tight window
+%     g      : Initial window function
+%     a      : Time shift
+%     M      : Number of Channels
+%
+%   Output parameters:
+%     gt     : Tight window
+%
+%   GABFIRTIGHT(Lsupport,g,a,M) computes an FIR window gd which is tight. 
+%   The FIR dual window will be supported on Lsupport samples.
+%
+%   This function solve a convex optimization problem that can be written
+%   as:
+%
+%      gd  = argmin_x    || alpha x||_1 +  || beta Fx||_1  
+%
+%                      + || omega (x -g_l) ||_2^2 + delta || x ||_S0
+%
+%                      + gamma || nabla F x ||_2^2 + mu || nabla x ||_2^2
+%
+%          such that  x is a tight FIR windows
+%
+%   *Note**: This function require the unlocbox. You can download it at
+%   http://unlocbox.sourceforge.net
+%
+%   The function uses an iterative algorithm to compute the approximate
+%   FIR tight windows. Warning The algorithm solve a non convex problem and
+%   might be stack in bad local minima. The algorithm can be controlled by
+%   the following flags: 
+%
+%     'alpha',alpha  Weight in time. If it is a scalar, it represent the
+%                  weights of the entire L1 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm (length: Ldual).
+%                  Default value is alpha=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-time constraint: alpha=0
+%
+%     'beta',beta  Weight in frequency. If it is a scalar, it represent the
+%                  weights of the entire L1 function in frequency. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm in frequency. (length: Ldual).
+%                  Default value is beta=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-frequency constraint: beta=0
+%
+%     'omega',omega
+%                  Weight in time of the L2-norm. If it is a scalar,
+%                  it represent the
+%                  weights of the entire L2 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L2 norm (length: Ldual).
+%                  Default value is omega=0.
+%                  No L2-time constraint: omega=0
+%
+%     'glike',g_l  g_l is a windows in time. The algorithm try to shape
+%                  the dual window like g_l. Normalization of g_l is done
+%                  automatically. To use option omega should be different
+%                  from 0. By default g_d=0.
+%
+%     'mu',mu      Weight of the smooth constraint Default value is 1. 
+%                  No smooth constraint: mu=0
+%   
+%     'gamma',gamma  Weight of the smooth constraint in frequency.
+%                    Default value is 1. No smooth constraint: gamma=0
+%   
+%     'delta',delta  Weight of the S0-norm. Default value is 0. 
+%                    No S0-norm: delta=0
+%
+%     'dual'       Look for a dual windows (default)
+%
+%     'painless'   Construct a starting guess using a painless-case
+%                  approximation. This is the default
+%
+%     'zero'       Choose a starting guess of zero.
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'tol',t      Stop if relative residual error is less than the 
+%                  specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations. default 200
+%
+%     'print'      Display the progress.
+%
+%     'debug'      Display all the progresses.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'fast'       Fast algorithm, this is the default.
+%
+%     'slow'       Safer algorithm, you can try this if the fast algorithm
+%                  is not working. Before using this, try to iterate more.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%     'hardconstraint' Force the projection at the end (default)
+%
+%     'softconstaint' Do not force the projection at the end
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabfirtight.php}
+%@seealso{gaboptdual, gabdual, gabtight, gabfirdual, gabconvexopt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+
+% Author: Nathanael Perraudin
+% Date  : 18 Feb 2014
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+[gt,relres,iter]=gabconvexopt(g,a,M,varargin{:}, 'support',Lsupport,'tight');
diff --git a/inst/gabor/gabframebounds.m b/inst/gabor/gabframebounds.m
new file mode 100644
index 0000000..7387b89
--- /dev/null
+++ b/inst/gabor/gabframebounds.m
@@ -0,0 +1,151 @@
+function [AF,BF]=gabframebounds(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabframebounds
+%@verbatim
+%GABFRAMEBOUNDS  Calculate frame bounds of Gabor frame
+%   Usage:  fcond=gabframebounds(g,a,M);
+%           [A,B]=gabframebounds(g,a,M);
+%           [A,B]=gabframebounds(g,a,M,L);
+%           [A,B]=gabframebounds(g,a,M,'lt',lt);
+%
+%   Input parameters:
+%           g     : The window function.
+%           a     : Length of time shift.
+%           M     : Number of channels.
+%           L     : Length of transform to consider.
+%           lt    : Lattice type (for non-separable lattices).
+%   Output parameters:
+%           fcond : Frame condition number (B/A)
+%           A,B   : Frame bounds.
+%          
+%   GABFRAMEBOUNDS(g,a,M) calculates the ratio B/A of the frame bounds
+%   of the Gabor system with window g, and parameters a, M.
+%
+%   [A,B]=GABFRAMEBOUNDS(...) returns the frame bounds A and B*
+%   instead of just the ratio.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%  
+%   GABFRAMEBOUNDS(g,a,M,L) will cut or zero-extend the window to length
+%   L.
+%
+%   GABFRAMEBOUNDS(g,a,M,'lt',lt) does the same for a non-separable
+%   lattice specified by lt. Please see the help of MATRIX2LATTICETYPE
+%   for a precise description of the parameter lt.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabframebounds.php}
+%@seealso{gabrieszbounds, gabwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+%% ---------- Assert correct input.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    if isnumeric(g)
+        % Use the window length
+        Ls=length(g);
+    else
+        % Use the smallest possible length
+        Ls=1;
+    end;
+
+    % ----- step 2b : Verify a, M and get L from the window length ----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+%% ----- actual computation ------------
+
+g=fir2long(g,L);
+R=size(g,2);
+
+if kv.lt(2)==1
+    % Rectangular case
+    % Get the factorization of the window.
+    gf=comp_wfac(g,a,M);
+    
+    % Compute all eigenvalues.
+    lambdas=comp_gfeigs(gf,L,a,M);
+    s=size(lambdas,1);
+    
+else
+    
+    % Convert to multi-window
+    mwin=comp_nonsepwin2multi(g,a,M,kv.lt,L);
+    
+    % Get the factorization of the window.
+    gf=comp_wfac(mwin,a*kv.lt(2),M);
+
+    % Compute all eigenvalues.
+    lambdas=comp_gfeigs(gf,L,a*kv.lt(2),M);
+    s=size(lambdas,1);
+        
+end;
+    
+% Min and max eigenvalue.
+if a>M*R
+    % This can is not a frame, so A is identically 0.
+    AF=0;
+else
+    AF=lambdas(1);
+end;
+
+BF=lambdas(s);
+
+if nargout<2
+    % Avoid the potential warning about division by zero.
+    if AF==0
+        AF=Inf;
+    else
+        AF=BF/AF;
+    end;
+end;
+
+
diff --git a/inst/gabor/gabframediag.m b/inst/gabor/gabframediag.m
new file mode 100644
index 0000000..0a719be
--- /dev/null
+++ b/inst/gabor/gabframediag.m
@@ -0,0 +1,83 @@
+function d=gabframediag(g,a,M,L,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabframediag
+%@verbatim
+%GABFRAMEDIAG  Diagonal of Gabor frame operator
+%   Usage:  d=gabframediag(g,a,M,L);
+%           d=gabframediag(g,a,M,L,'lt',lt);
+%
+%   Input parameters:
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of channels.
+%         L     : Length of transform to do.
+%         lt    : Lattice type (for non-separable lattices).
+%   Output parameters:
+%         d     : Diagonal stored as a column vector
+%
+%   GABFRAMEDIAG(g,a,M,L) computes the diagonal of the Gabor frame operator
+%   with respect to the window g and parameters a and M. The
+%   diagonal is stored a as column vector of length L.
+%
+%   The diagonal of the frame operator can for instance be used as a
+%   preconditioner.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabframediag.php}
+%@seealso{dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.lt=[0 1];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% ----- step 2a : Verify a, M and get L
+
+Luser=dgtlength(L,a,M,kv.lt);
+if Luser~=L
+    error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+           'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+          upper(mfilename),L,Luser);
+end;
+
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+%%  compute the diagonal 
+
+glong2=abs(fir2long(g,L)).^2;
+N=L/a;
+
+d=zeros(L,1,assert_classname(glong2));
+
+% The diagonal is a-periodic, so compute a single period by summing up
+% glong2 in slices. 
+d=repmat(sum(reshape(glong2,a,N),2),N,1)*M;
+
+
+
diff --git a/inst/gabor/gabimagepars.m b/inst/gabor/gabimagepars.m
new file mode 100644
index 0000000..1a10af1
--- /dev/null
+++ b/inst/gabor/gabimagepars.m
@@ -0,0 +1,97 @@
+function [a,M,L,N,Ngood]=gabimagepars(Ls,x,y)
+%-*- texinfo -*-
+%@deftypefn {Function} gabimagepars
+%@verbatim
+%GABIMAGEPARS  Find Gabor parameters to generate image
+%   Usage: [a,M,L,N,Ngood]=gabimagepars(Ls,x,y);
+%
+%   [a,M,L,N,Ngood]=GABIMAGEPARS(Ls,x,y) will compute a reasonable set of
+%   parameters a, M and L to produce a nice Gabor 'image' of a signal
+%   of length Ls. The approximate number of pixels in the time direction is
+%   given as x and the number of pixels in the frequency direction is given
+%   as y.
+%
+%   The output parameter Ngood contains the number of time steps (columns
+%   in the coefficients matrix) that contains relevant information. The
+%   columns from Ngood until N only contains information from a
+%   zero-extension of the signal.
+%
+%   If you use this function to calculate a grid size for analysis of a
+%   real-valued signal (using DGTREAL), please input twice of the desired
+%   size y. This is because DGTREAL only returns half as many
+%   coefficients in the frequency direction as DGT.
+%
+%   An example: We wish to compute a Gabor image of a real valued signal f*
+%   of length 7500. The image should have an approximate resolution of
+%   800 x600 pixels:
+%
+%     [f,fs]=linus; f=f(4001:4000+7500);
+%     [a,M,L,N,Ngood] = gabimagepars(7500,800,2*600);
+%     c = dgtreal(f,'gauss',a,M);
+%     plotdgtreal(c,a,M,fs,90);
+%
+%   The size of c is N x(M/2)+1 equal to 801 x600 pixels. 
+%
+%   For this function to work properly, the specified numbers for x and
+%   y must not be large prime numbers.
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabimagepars.php}
+%@seealso{dgt, dgtreal, sgram}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if min(x,y)>Ls
+  % Small values case, just do an STFT
+  M=Ls;
+  N=Ls;
+  a=1;
+  Ngood=N;
+  L=Ls;
+else
+
+  % Set M and N to be what the user specified
+  M=y;
+  N=x;
+
+  % Determine the minimum transform size.
+  K=lcm(M,N);
+    
+  % This L is good, but is it not the same as DGT will choose.
+  Llong=ceil(Ls/K)*K;
+  
+  % Fix a from the long L
+  a=Llong/N;
+  
+  % Now we have fixed a and M, so we can use the standard method of choosing L
+  Lsmallest=lcm(a,M);
+  L=ceil(Ls/Lsmallest)*Lsmallest;
+  
+  % We did not get N as desired.
+  N=L/a;
+  
+  % Number of columns to display
+  Ngood=ceil(Ls/a);
+  
+  if M<=a
+    error('LTFAT:noframe',['Cannot generate a frame, the signal is too long as compared ' ...
+           'to the size of the image. Increase x and y.']);
+  end;
+  
+end;
+
diff --git a/inst/gabor/gabmixdual.m b/inst/gabor/gabmixdual.m
new file mode 100644
index 0000000..4638e91
--- /dev/null
+++ b/inst/gabor/gabmixdual.m
@@ -0,0 +1,107 @@
+function gamma=gabmixdual(g1,g2,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabmixdual
+%@verbatim
+%GABMIXDUAL  Computes the mixdual of g1
+%   Usage: gamma=mixdual(g1,g2,a,M)
+%
+%   Input parameters:
+%        g1     : Window 1
+%        g2     : Window 2
+%        a      : Length of time shift.
+%        M      : Number of modulations.
+%
+%   Output parameters:
+%        gammaf : Mixdual of window 1.
+%
+%   GABMIXDUAL(g1,g2,a,M) computes a dual window of g1 from a mix of the
+%   canonical dual windows of g1 and g2.
+%
+%
+%
+%   References:
+%     T. Werther, Y. Eldar, and N. Subbana. Dual Gabor Frames: Theory and
+%     Computational Aspects. IEEE Trans. Signal Process., 53(11), 2005.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabmixdual.php}
+%@seealso{gabdual, gabprojdual, demo_gabmixdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+% Assert correct input.
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.flags.phase={'freqinv','timeinv'};
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    % Minimum transform length by default.
+    Ls=1;
+    
+    % Use the window lengths, if any of them are numerical
+    if isnumeric(g1)
+        Ls=max(length(g1),Ls);
+    end;
+
+    if isnumeric(g2)
+        Ls=max(length(g2),Ls);
+    end;
+
+    % ----- step 2b : Verify a, M and get L from the window length ----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser)
+    end;
+
+end;
+
+[g1,info_g1] = gabwin(g1,a,M,L,kv.lt,'callfun',upper(mfilename));
+[g2,info_g2] = gabwin(g2,a,M,L,kv.lt,'callfun',upper(mfilename));
+ 
+% gm must have the correct length, otherwise dgt will zero-extend it
+% incorrectly using postpad instead of fir2long
+g1=fir2long(g1,L);
+g2=fir2long(g2,L);
+
+gf1=comp_wfac(g1,a,M);
+gf2=comp_wfac(g2,a,M);
+
+gammaf=comp_gabmixdual_fac(gf1,gf2,L,a,M);
+
+gamma=comp_iwfac(gammaf,L,a,M);
+
diff --git a/inst/gabor/gaboptdual.m b/inst/gabor/gaboptdual.m
new file mode 100644
index 0000000..73501db
--- /dev/null
+++ b/inst/gabor/gaboptdual.m
@@ -0,0 +1,137 @@
+function [gd,relres,iter]=gaboptdual(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gaboptdual
+%@verbatim
+%GABOPTDUAL  Compute dual window
+%   Usage: gd=gaboptdual(g,a,M);
+%          gd=gaboptdual(g,a,M, varagin);
+%
+%   Input parameters:
+%     g      : Window function
+%     a      : Time shift
+%     M      : Number of Channels
+%
+%   Output parameters:
+%     gd     : Dual window
+%
+%   GABOPTDUAL(g,a,M) computes a window gd which is an
+%   approximate dual window of the Gabor system defined by g, a and
+%   M. 
+%
+%   This function solve a convex optimization problem that can be written
+%   as:
+%
+%      gd  = argmin_x    || alpha x||_1 +  || beta Fx||_1  
+%
+%                      + || omega (x -g_l) ||_2^2 + delta || x ||_S0
+%
+%                      + gamma || nabla F x ||_2^2 + mu || nabla x ||_2^2
+%
+%          such that  x is a dual windows of g
+%
+%   *Note**: This function require the unlocbox. You can download it at
+%   http://unlocbox.sourceforge.net
+%
+%   The function uses an iterative algorithm to compute the approximate
+%   optimized dual. The algorithm can be controlled by the following flags:
+%
+%     'alpha',alpha  Weight in time. If it is a scalar, it represent the
+%                  weights of the entire L1 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm (length: Ldual).
+%                  Default value is alpha=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-time constraint: alpha=0
+%
+%     'beta',beta  Weight in frequency. If it is a scalar, it represent the
+%                  weights of the entire L1 function in frequency. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm in frequency. (length: Ldual).
+%                  Default value is beta=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-frequency constraint: beta=0
+%
+%     'omega',omega  Weight in time of the L2-norm. If it is a scalar, it represent the
+%                  weights of the entire L2 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L2 norm (length: Ldual).
+%                  Default value is omega=0.
+%                  No L2-time constraint: omega=0
+%
+%     'glike',g_l  g_l is a windows in time. The algorithm try to shape
+%                  the dual window like g_l. Normalization of g_l is done
+%                  automatically. To use option omega should be different
+%                  from 0. By default g_d=0.
+%
+%     'mu',mu      Weight of the smooth constraint Default value is 1. 
+%                  No smooth constraint: mu=0
+%   
+%     'gamma',gamma  Weight of the smooth constraint in frequency. Default value is 1. 
+%                    No smooth constraint: gamma=0
+%   
+%     'delta',delta  Weight of the S0-norm. Default value is 0. 
+%                    No S0-norm: delta=0
+%
+%     'dual'       Look for a dual windows (default)
+%
+%     'painless'   Construct a starting guess using a painless-case
+%                  approximation. This is the default
+%
+%     'zero'       Choose a starting guess of zero.
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'tol',t      Stop if relative residual error is less than the 
+%                  specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations. default 200
+%
+%     'print'      Display the progress.
+%
+%     'debug'      Display all the progresses.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'fast'       Fast algorithm, this is the default.
+%
+%     'slow'       Safer algorithm, you can try this if the fast algorithm
+%                  is not working. Before using this, try to iterate more.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%     'hardconstraint' Force the projection at the end (default)
+%
+%     'softconstaint' Do not force the projection at the end
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gaboptdual.php}
+%@seealso{gabfirdual, gabdual, gabtight, gabopttight, gaboptdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Author: Nathanael Perraudin
+% Date  : 18 Feb 2014 
+    
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+[gd,relres,iter]=gabconvexopt(g,a,M,varargin{:});
diff --git a/inst/gabor/gabopttight.m b/inst/gabor/gabopttight.m
new file mode 100644
index 0000000..7e60229
--- /dev/null
+++ b/inst/gabor/gabopttight.m
@@ -0,0 +1,156 @@
+function [gt,relres,iter]=gabopttight(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabopttight
+%@verbatim
+%GABOPTTIGHT  Compute a optimized tight window
+%   Usage: gt=gabopttight(Ltight,g,a,M);
+%          gt=gabopttight(Ltight,g,a,M, varagin);
+%
+%   Input parameters:
+%     g      : Initial window function
+%     a      : Time shift
+%     M      : Number of Channels
+%
+%   Output parameters:
+%     gt     : Tight window
+%
+%   GABOPTTIGHT(g,a,M) computes a tight window gt for a frame of
+%   parameter a and M
+%
+%   This function solves a convex optimization problem that can be written
+%   as:
+%
+%      gd  = argmin_x    || alpha x||_1 +  || beta Fx||_1  
+%
+%                      + || omega (x -g_l) ||_2^2 + delta || x ||_S0
+%
+%                      + gamma || nabla F x ||_2^2 + mu || nabla x ||_2^2
+%
+%          such that  x is a tight window
+%
+%   *Note**: This function require the unlocbox. You can download it at
+%   http://unlocbox.sourceforge.net
+%
+%   The function uses an iterative algorithm to compute the approximate
+%   optimized tight window. Warning The algorithm solve a non convex
+%   problem and might be stack in bad local minima.  The algorithm can be
+%   controlled by the following flags: 
+%
+%     'alpha',alpha  Weight in time. If it is a scalar, it represent the
+%                  weights of the entire L1 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm (length: Ldual).
+%                  Default value is alpha=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-time constraint: alpha=0
+%
+%     'beta',beta  Weight in frequency. If it is a scalar, it represent the
+%                  weights of the entire L1 function in frequency. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L1 norm in frequency. (length: Ldual).
+%                  Default value is beta=0.
+%                  *Warning**: this value should not be too big in order to
+%                  avoid the the L1 norm proximal operator kill the signal.
+%                  No L1-frequency constraint: beta=0
+%
+%     'omega',omega  Weight in time of the L2-norm. If it is a scalar, it represent the
+%                  weights of the entire L2 function in time. If it is a 
+%                  vector, it is the associated weight assotiated to each
+%                  component of the L2 norm (length: Ldual).
+%                  Default value is omega=0.
+%                  No L2-time constraint: omega=0
+%
+%     'glike',g_l  g_l is a windows in time. The algorithm try to shape
+%                  the dual window like g_l. Normalization of g_l is done
+%                  automatically. To use option omega should be different
+%                  from 0. By default g_d=0.
+%
+%     'mu', mu     Weight of the smooth constraint Default value is 1. 
+%                  No smooth constraint: mu=0
+%   
+%     'gamma', gamma  Weight of the smooth constraint in frequency. Default value is 1. 
+%                  No smooth constraint: gamma=0
+%   
+%     'delta', delta  Weight of the S0-norm. Default value is 0. 
+%                  No S0-norm: delta=0
+%
+%     'dual'       Look for a dual windows (default)
+%
+%     'painless'   Construct a starting guess using a painless-case
+%                  approximation. This is the default
+%
+%     'zero'       Choose a starting guess of zero.
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'tol',t      Stop if relative residual error is less than the 
+%                  specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations. default 200
+%
+%     'print'      Display the progress.
+%
+%     'debug'      Display all the progresses.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'fast'       Fast algorithm, this is the default.
+%
+%     'slow'       Safer algorithm, you can try this if the fast algorithm
+%                  is not working. Before using this, try to iterate more.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%     'hardconstraint' Force the projection at the end (default)
+%
+%     'softconstaint' Do not force the projection at the end
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabopttight.php}
+%@seealso{gabfirdual, gabdual, gabtight, gaboptdual, gabconvexopt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+
+
+% Author: Nathanael Perraudin
+% Date  : 18 Feb 2014
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if 0
+    gt=g;
+    for ii=1:50
+     gt=gabconvexopt(gt,a,M,varargin{:},'quiet','dual');
+     figure(1);
+     plot(abs(gt));
+     drawnow
+     
+     fprintf('Error at iteration %i: %g\n',ii,gabdualnorm(gt,gt,a,M,length(gt)));
+    end
+    gt=gabconvexopt(g,a,M,'alpha',0,'beta',0,'gamma',0,'mu',0,'omega',0, 'tight');
+else
+
+[gt,relres,iter]=gabconvexopt(g,a,M,varargin{:}, 'tight');
+
+end
+end
diff --git a/inst/gabor/gaborinit.m b/inst/gabor/gaborinit.m
new file mode 100644
index 0000000..761e196
--- /dev/null
+++ b/inst/gabor/gaborinit.m
@@ -0,0 +1,26 @@
+status=1;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} gaborinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gaborinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/gabor/gabphasegrad.m b/inst/gabor/gabphasegrad.m
new file mode 100644
index 0000000..629e6aa
--- /dev/null
+++ b/inst/gabor/gabphasegrad.m
@@ -0,0 +1,320 @@
+function [tgrad,fgrad,c]=gabphasegrad(method,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabphasegrad
+%@verbatim
+%GABPHASEGRAD   Phase gradient of the DGT
+%   Usage:  [tgrad,fgrad,c] = gabphasegrad('dgt',f,g,a,M);
+%           [tgrad,fgrad]   = gabphasegrad('phase',cphase,a);
+%           [tgrad,fgrad]   = gabphasegrad('abs',s,g,a);
+%
+%   [tgrad,fgrad]=GABPHASEGRAD(method,...) computes the time-frequency
+%   gradient of the phase of the DGT of a signal. The derivative in time
+%   tgrad is the instantaneous frequency while the frequency derivative
+%   fgrad is the local group delay.
+%
+%   tgrad and fgrad measure the deviation from the current time and
+%   frequency, so a value of zero means that the instantaneous frequency is
+%   equal to the center frequency of the considered channel.
+%
+%   tgrad is scaled such that distances are measured in samples. Similarly,
+%   fgrad is scaled such that the Nyquist frequency (the highest possible
+%   frequency) corresponds to a value of L/2.
+%
+%   The computation of tgrad and fgrad is inaccurate when the absolute
+%   value of the Gabor coefficients is low. This is due to the fact the the
+%   phase of complex numbers close to the machine precision is almost
+%   random. Therefore, tgrad and fgrad may attain very large random values
+%   when abs(c) is close to zero.
+%
+%   The computation can be done using three different methods.
+%
+%     'dgt'    Directly from the signal. This is the default method.
+% 
+%     'phase'  From the phase of a DGT of the signal. This is the
+%              classic method used in the phase vocoder.
+%
+%     'abs'    From the absolute value of the DGT. Currently this
+%              method works only for Gaussian windows.
+%
+%   [tgrad,fgrad]=GABPHASEGRAD('dgt',f,g,a,M) computes the time-frequency
+%   gradient using a DGT of the signal f. The DGT is computed using the
+%   window g on the lattice specified by the time shift a and the number
+%   of channels M. The algorithm used to perform this calculation computes
+%   several DGTs, and therefore this routine takes the exact same input
+%   parameters as DGT.
+%
+%   The window g may be specified as in DGT. If the window used is
+%   'gauss', the computation will be done by a faster algorithm.
+%
+%   [tgrad,fgrad,c]=GABPHASEGRAD('dgt',f,g,a,M) additionally returns the
+%   Gabor coefficients c, as they are always computed as a byproduct of the
+%   algorithm.
+%
+%   [tgrad,fgrad]=GABPHASEGRAD('phase',cphase,a) computes the phase
+%   gradient from the phase cphase of a DGT of the signal. The original DGT
+%   from which the phase is obtained must have been computed using a
+%   time-shift of a.
+%
+%   [tgrad,fgrad]=GABPHASEGRAD('abs',s,g,a) computes the phase gradient
+%   from the spectrogram s. The spectrogram must have been computed using
+%   the window g and time-shift a.
+%
+%   [tgrad,fgrad]=GABPHASEGRAD('abs',s,g,a,difforder) uses a centered finite
+%   diffence scheme of order difforder to perform the needed numerical
+%   differentiation. Default is to use a 4th order scheme.
+%
+%   Currently the 'abs' method only works if the window g is a Gaussian
+%   window specified as a string or cell array.
+%
+%
+%   References:
+%     F. Auger and P. Flandrin. Improving the readability of time-frequency
+%     and time-scale representations by the reassignment method. IEEE Trans.
+%     Signal Process., 43(5):1068-1089, 1995.
+%     
+%     E. Chassande-Mottin, I. Daubechies, F. Auger, and P. Flandrin.
+%     Differential reassignment. Signal Processing Letters, IEEE,
+%     4(10):293-294, 1997.
+%     
+%     J. Flanagan, D. Meinhart, R. Golden, and M. Sondhi. Phase Vocoder. The
+%     Journal of the Acoustical Society of America, 38:939, 1965.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabphasegrad.php}
+%@seealso{resgram, gabreassign, dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+% AUTHOR: Peter L. Soendergaard, 2008.
+  
+%error(nargchk(4,6,nargin));
+
+if ~ischar(method)
+    error(['First argument must be the method name, "dgt", "phase" or ' ...
+           '"abs".']);
+end;
+  
+switch(lower(method))
+ case 'dgt'
+  % ---------------------------  DGT method ------------------------
+
+  [f,g,a,M]=deal(varargin{1:4});
+  
+  definput.keyvals.L=[];
+  definput.keyvals.minlvl=eps;
+  definput.keyvals.lt=[0 1];
+  [flags,kv,L,minlvl]=ltfatarghelper({'L','minlvl'},definput,varargin(5:end));
+  
+  
+  %% ----- step 1 : Verify f and determine its length -------
+  % Change f to correct shape.
+  [f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,upper(mfilename),0);
+  
+  %% ------ step 2: Verify a, M and L
+  if isempty(L)
+      
+      % ----- step 2b : Verify a, M and get L from the signal length f----------
+      L=dgtlength(Ls,a,M,kv.lt);
+      
+  else
+      
+      % ----- step 2a : Verify a, M and get L
+      Luser=dgtlength(L,a,M,kv.lt);
+      if Luser~=L
+          error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+                 'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+                upper(mfilename),L,Luser);
+      end;
+      
+  end;
+  
+  %% ----- step 3 : Determine the window 
+  
+  [g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+  
+  if L<info.gl
+      error('%s: Window is too long.',upper(mfilename));
+  end;
+  
+  %% ----- step 4: final cleanup ---------------
+  
+  f=postpad(f,L);
+  
+  %% ------ algorithm starts --------------------
+  
+  % Compute the time weighted version of the window.
+  hg=fftindex(L).*g;
+  
+  % The computation done this way is insensitive to whether the dgt is
+  % phaselocked or not.
+  c   = comp_dgt(f,g,a,M,kv.lt,0,0,0);
+  c_h = comp_dgt(f,hg,a,M,kv.lt,0,0,0);
+  
+  c_s = abs(c).^2;
+  
+  % Remove small values because we need to divide by c_s
+  c_s = max(c_s,minlvl*max(c_s(:)));
+  
+  % Compute the group delay
+  fgrad=real(c_h.*conj(c)./c_s);
+  
+  if info.gauss
+    % The method used below only works for the Gaussian window, because the
+    % time derivative and the time multiplicative of the Gaussian are identical.
+    tgrad=imag(c_h.*conj(c)./c_s)/info.tfr;
+  else
+    
+    % The code below works for any window, and not just the Gaussian
+    
+    dg  = pderiv(g,[],Inf)/(2*pi);
+    c_d = comp_dgt(f,dg,a,M,kv.lt,0,0,0);
+    c_d = reshape(c_d,M,N,W);
+    
+    % Compute the instantaneous frequency
+    tgrad=-imag(c_d.*conj(c)./c_s);
+  end;
+  
+  
+ case 'phase'
+  % ---------------------------  phase method ------------------------
+
+  [cphase,a]=deal(varargin{1:2});
+  
+  if ~isreal(cphase)
+    error(['Input phase must be real valued. Use the "angle" function to ' ...
+           'compute the argument of complex numbers.']);
+  end;
+  
+  % --- linear method ---
+  [M,N,W]=size(cphase);
+  L=N*a;
+  b=L/M;
+  
+  if 0
+    
+    % This is the classic phase vocoder algorithm by Flanagan.
+    
+    tgrad = cphase-circshift(cphase,[0,-1]);
+    tgrad = tgrad- 2*pi*round(tgrad/(2*pi));
+    tgrad = -tgrad/(2*pi)*L;
+    
+    % Phase-lock the angles.
+    TimeInd = (0:(N-1))*a;
+    FreqInd = (0:(M-1))/M;
+    
+    phl = FreqInd'*TimeInd;
+    cphase = cphase+2*pi.*phl;
+    
+    fgrad = cphase-circshift(cphase,[1,0]);
+    fgrad = fgrad- 2*pi*round(fgrad/(2*pi));
+    fgrad = -fgrad/(2*pi)*L;
+    
+  end;
+  
+  
+  if 1
+    % This is the classic phase vocoder algorithm by Flanagan modified to
+    % yield a second order centered difference approximation.
+    
+    % Forward approximation
+    tgrad_1 = cphase-circshift(cphase,[0,-1]);
+    tgrad_1 = tgrad_1 - 2*pi*round(tgrad_1/(2*pi));
+    % Backward approximation
+    tgrad_2 = circshift(cphase,[0,1])-cphase;
+    tgrad_2 = tgrad_2 - 2*pi*round(tgrad_2/(2*pi));
+    % Average
+    tgrad = (tgrad_1+tgrad_2)/2;
+    
+    tgrad = -tgrad/(2*pi*a)*L;
+    
+    % Phase-lock the angles.
+    TimeInd = (0:(N-1))*a;
+    FreqInd = (0:(M-1))/M;
+    
+    phl = FreqInd'*TimeInd;
+    cphase = cphase+2*pi.*phl;
+    
+    % Forward approximation
+    fgrad_1 = cphase-circshift(cphase,[-1,0]);
+    fgrad_1 = fgrad_1 - 2*pi*round(fgrad_1/(2*pi));
+    % Backward approximation
+    fgrad_2 = circshift(cphase,[1,0])-cphase;
+    fgrad_2 = fgrad_2 - 2*pi*round(fgrad_2/(2*pi));
+    % Average
+    fgrad = (fgrad_1+fgrad_2)/2;
+    
+    fgrad = fgrad/(2*pi*b)*L;
+    
+  end;
+  
+  
+ case 'abs'
+  % ---------------------------  abs method ------------------------
+
+  [s,g,a]=deal(varargin{1:3});
+  if numel(varargin)>3
+    difforder=varargin{4};
+  else
+    difforder=4;
+  end;
+
+  if ~(all(s(:)>=0))
+    error('First input argument must be positive or zero.');
+  end;
+    
+  [M,N,W]=size(s);
+  
+  L=N*a;
+  tfr=1;
+
+  g
+  
+  [g,info]=gabwin(g,a,M,L,'callfun','GABPHASEGRAD');
+
+  info
+  
+  if ~info.gauss
+    error(['The window must be a Gaussian window (specified as a string or ' ...
+           'as a cell array).']);
+  end;
+  
+  L=N*a;
+  b=L/M;
+  
+  % We must avoid taking the log of zero.
+  % Therefore we add the smallest possible
+  % number
+  logs=log(s+realmin);
+  
+  % XXX REMOVE Add a small constant to limit the dynamic range. This should
+  % lessen the problem of errors in the differentiation for points close to
+  % (but not exactly) zeros points.
+  maxmax=max(logs(:));
+  tt=-11;
+  logs(logs<maxmax+tt)=tt;
+  
+  fgrad=pderiv(logs,2,difforder)/(2*pi)*info.tfr;
+  tgrad=pderiv(logs,1,difforder)/(2*pi*info.tfr);
+  
+  
+ otherwise
+  error(['First argument must be the method name, "dgt", "phase" or ' ...
+         '"abs".']);
+end;  
+
diff --git a/inst/gabor/gabprojdual.m b/inst/gabor/gabprojdual.m
new file mode 100644
index 0000000..7a13839
--- /dev/null
+++ b/inst/gabor/gabprojdual.m
@@ -0,0 +1,119 @@
+function gd=gabprojdual(gm,g,a,M,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} gabprojdual
+%@verbatim
+%GABPROJDUAL   Gabor Dual window by projection
+%   Usage:  gd=gabprojdual(gm,g,a,M)
+%           gd=gabprojdual(gm,g,a,M,L)
+%
+%   Input parameters:
+%         gm    : Window to project.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         L     : Length of transform to consider
+%   Output parameters:
+%         gd    : Dual window.
+%
+%   GABPROJDUAL(gm,g,a,M) calculates the dual window of the Gabor frame given
+%   by g, a and M closest to gm measured in the l^2 norm. The
+%   function projects the suggested window gm onto the subspace of
+%   admissable dual windows, hence the name of the function.
+%
+%   GABPROJDUAL(gm,g,a,M,L) first extends the windows g and gm to
+%   length L.
+%
+%   GABPROJDUAL(...,'lt',lt) does the same for a non-separable lattice
+%   specified by lt. Please see the help of MATRIX2LATTICETYPE for a
+%   precise description of the parameter lt.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabprojdual.php}
+%@seealso{gabdual, gabtight, gabdualnorm, fir2long}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard 
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.flags.phase={'freqinv','timeinv'};
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    % Minimum transform length by default.
+    Ls=1;
+    
+    % Use the window lengths, if any of them are numerical
+    if isnumeric(g)
+        Ls=max(length(g),Ls);
+    end;
+
+    if isnumeric(gm)
+        Ls=max(length(gm),Ls);
+    end;
+
+    % ----- step 2b : Verify a, M and get L from the window length ----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser)
+    end;
+
+end;
+
+[g, info_g]  = gabwin(g, a,M,L,kv.lt,'callfun',upper(mfilename));
+[gm,info_gm] = gabwin(gm,a,M,L,kv.lt,'callfun',upper(mfilename));
+ 
+% gm must have the correct length, otherwise dgt will zero-extend it
+% incorrectly using postpad instead of fir2long
+gm=fir2long(gm,L);
+
+% Calculate the canonical dual.
+gamma0=gabdual(g,a,M,'lt',kv.lt);
+  
+% Get the residual
+gres=gm-gamma0;
+
+% Calculate parts that lives in span of adjoint lattice.
+if isreal(gres) && isreal(gamma0) && isreal(g) && kv.lt(2)<=2
+    gk=idgtreal(dgtreal(gres,gamma0,M,a,'lt',kv.lt),g,M,a,'lt',kv.lt)*M/a;    
+else
+    gk=idgt(dgt(gres,gamma0,M,a,'lt',kv.lt),g,M,'lt',kv.lt)*M/a;
+end;
+    
+% Construct dual window
+gd=gamma0+(gres-gk);
+    
+    
+    
+
diff --git a/inst/gabor/gabreassign.m b/inst/gabor/gabreassign.m
new file mode 100644
index 0000000..2f270a4
--- /dev/null
+++ b/inst/gabor/gabreassign.m
@@ -0,0 +1,112 @@
+function sr=gabreassign(s,tgrad,fgrad,a,p5);
+%-*- texinfo -*-
+%@deftypefn {Function} gabreassign
+%@verbatim
+%GABREASSIGN  Reassign time-frequency distribution
+%   Usage:  sr = gabreassign(s,tgrad,fgrad,a);
+%           sr = gabreassign(s,tgrad,fgrad,a,'aa');
+%
+%   GABREASSIGN(s,tgrad,fgrad,a) reassigns the values of the positive
+%   time-frequency distribution s using the phase gradient given by fgrad*
+%   and tgrad. The lattice is determined by the time shift a and the number
+%   of channels deduced from the size of s.
+%
+%   fgrad and tgrad can be obtained by the routine GABPHASEGRAD.
+%
+%   Examples:
+%   ---------
+%
+%   The following example demonstrates how to manually create a
+%   reassigned spectrogram. An easier way is to just call RESGRAM:
+%
+%     % Create reassigned vector field of the bat signal.
+%     a=4;
+%     M=100
+%     [tgrad, fgrad, c] = gabphasegrad('dgt',bat,'gauss',a,M);
+%
+%     % Perform the actual reassignment
+%     sr = gabreassign(abs(c).^2,tgrad,fgrad,a);
+%
+%     % Display it using plotdgt
+%     plotdgt(sr,a,143000,50);
+%  
+%
+%   References:
+%     F. Auger and P. Flandrin. Improving the readability of time-frequency
+%     and time-scale representations by the reassignment method. IEEE Trans.
+%     Signal Process., 43(5):1068-1089, 1995.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabreassign.php}
+%@seealso{resgram, gabphasegrad}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR: Peter L. Soendergaard, 2008.
+  
+error(nargchk(4,5,nargin));
+
+
+sr=comp_gabreassign(s,tgrad,fgrad,a);
+
+
+
+
+% The following code is currently not actived. It calculates the
+% reassigment using anti-aliasing, but it make very little visual
+% difference, and it is slower.
+  %   [M,N,W]=size(s);
+  %   L=N*a;
+  %   b=L/M;
+    
+  %   freqpos=fftindex(M);  
+  %   tgrad=bsxfun(@plus,tgrad/b,freqpos);
+        
+  %   timepos=fftindex(N);
+  %   fgrad=bsxfun(@plus,fgrad/a,timepos.');
+    
+  %   tgrad=round(tgrad);
+  %   fgrad=round(fgrad);
+    
+  %   tgrad=mod(tgrad,M);
+  %   fgrad=mod(fgrad,N);  
+    
+  %   sr=zeros(M,N,W);
+    
+  %   fk=mod(floor(tgrad),M)+1;
+  %   ck=mod(ceil(tgrad),M)+1;
+  %   fn=mod(floor(fgrad),N)+1;
+  %   cn=mod(ceil(fgrad),N)+1;
+    
+  %   alpha = fgrad-floor(fgrad);
+  %   beta  = tgrad-floor(tgrad);
+  %   m1 =(1-alpha).*(1-beta).*s;
+  %   m2 =(1-alpha).*beta.*s;
+  %   m3 =alpha.*(1-beta).*s;
+  %   m4 =alpha.*beta.*s;
+  %   for ii=1:M
+  %     for jj=1:N
+  %       sr(fk(ii,jj),fn(ii,jj))=sr(fk(ii,jj),fn(ii,jj))+m1(ii,jj);
+  %       sr(ck(ii,jj),fn(ii,jj))=sr(ck(ii,jj),fn(ii,jj))+m2(ii,jj);
+  %       sr(fk(ii,jj),cn(ii,jj))=sr(fk(ii,jj),cn(ii,jj))+m3(ii,jj);
+  %       sr(ck(ii,jj),cn(ii,jj))=sr(ck(ii,jj),cn(ii,jj))+m4(ii,jj);
+        
+  %     end;
+  %   end;
+  % end;
+
diff --git a/inst/gabor/gabrieszbounds.m b/inst/gabor/gabrieszbounds.m
new file mode 100644
index 0000000..afed0da
--- /dev/null
+++ b/inst/gabor/gabrieszbounds.m
@@ -0,0 +1,82 @@
+function [AF,BF]=gabrieszbounds(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabrieszbounds
+%@verbatim
+%GABRIESZBOUNDS  Calculate Riesz sequence/basis bounds of Gabor frame
+%   Usage:  fcond=gabrieszbounds(g,a,M);
+%           [A,B]=gabrieszbounds(g,a,M);
+%           [A,B]=gabrieszbounds(g,a,M,L);
+%
+%   Input parameters:
+%           g     : The window function.
+%           a     : Length of time shift.
+%           M     : Number of channels.
+%           L     : Length of transform to consider.
+%   Output parameters:
+%           fcond : Frame condition number (B/A)
+%           A,B   : Frame bounds.
+%          
+%   GABRIESZBOUNDS(g,a,M) calculates the ratio B/A of the Riesz bounds
+%   of the Gabor system with window g, and parameters a, M.
+%
+%   [A,B]=GABRIESZBOUNDS(g,a,M) calculates the Riesz bounds A and B*
+%   instead of just the ratio.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%  
+%   If the optional parameter L is specified, the window is cut or
+%   zero-extended to length L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabrieszbounds.php}
+%@seealso{gabframebounds, gabwin, gabdualnorm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% AUTHOR: Peter L. Soendergaard.  
+  
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% The computation is done by computing the frame bounds of the Gabor
+% system on the dual lattice (interchange a and M) followed by an
+% appropriate scaling.
+%
+% See the note gabrieszbounds.pdf in the doc directory written by Monika
+% Dorfler.
+
+% Get a and M
+a=varargin{2};
+M=varargin{3};
+
+% Switch their role
+newargs=varargin;
+newargs{2}=M;
+newargs{3}=a;
+
+if nargout<2
+  AF=gabframebounds(newargs{:});
+else
+  [AF,BF]=gabframebounds(newargs{:});
+  AF=AF*M/a;
+  BF=BF*M/a;
+end;
+
+
diff --git a/inst/gabor/gabtight.m b/inst/gabor/gabtight.m
new file mode 100644
index 0000000..11ba2df
--- /dev/null
+++ b/inst/gabor/gabtight.m
@@ -0,0 +1,253 @@
+function gt=gabtight(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gabtight
+%@verbatim
+%GABTIGHT  Canonical tight window of Gabor frame
+%   Usage:  gt=gabtight(a,M,L);
+%           gt=gabtight(g,a,M);
+%           gt=gabtight(g,a,M,L);
+%           gd=gabtight(g,a,M,'lt',lt);
+%
+%   Input parameters:
+%         g     : Gabor window.
+%         a     : Length of time shift.
+%         M     : Number of modulations.
+%         L     : Length of window. (optional)
+%         lt    : Lattice type (for non-separable lattices).
+%   Output parameters:
+%         gt    : Canonical tight window, column vector.
+%
+%   GABTIGHT(a,M,L) computes a nice tight window of length L for a
+%   lattice with parameters a, M. The window is not an FIR window,
+%   meaning that it will only generate a tight system if the system
+%   length is equal to L.
+%
+%   GABTIGHT(g,a,M) computes the canonical tight window of the Gabor frame
+%   with window g and parameters a, M.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%  
+%   If the length of g is equal to M, then the input window is assumed to
+%   be a FIR window. In this case, the canonical dual window also has
+%   length of M. Otherwise the smallest possible transform length is
+%   chosen as the window length.
+%
+%   GABTIGHT(g,a,M,L) returns a window that is tight for a system of
+%   length L. Unless the input window g is a FIR window, the returned
+%   tight window will have length L.
+%
+%   GABTIGHT(g,a,M,'lt',lt) does the same for a non-separable lattice
+%   specified by lt. Please see the help of MATRIX2LATTICETYPE for a
+%   precise description of the parameter lt.
+%
+%   If a>M then an orthonormal window of the Gabor Riesz sequence with
+%   window g and parameters a and M will be calculated.
+%
+%   Examples:
+%   ---------
+%
+%   The following example shows the canonical tight window of the Gaussian
+%   window. This is calculated by default by GABTIGHT if no window is
+%   specified:
+%
+%     a=20;
+%     M=30;
+%     L=300;
+%     gt=gabtight(a,M,L);
+%     
+%     % Simple plot in the time-domain
+%     figure(1);
+%     plot(gt);
+%
+%     % Frequency domain
+%     figure(2);
+%     magresp(gt,'dynrange',100);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabtight.php}
+%@seealso{gabdual, gabwin, fir2long, dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: OK
+
+%% ------------ decode input parameters ------------
+
+if nargin<3
+    error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if numel(varargin{1})==1
+  % First argument is a scalar.
+
+  a=varargin{1};
+  M=varargin{2};
+
+  g='gauss';
+
+  varargin=varargin(3:end);  
+else    
+  % First argument assumed to be a vector.
+
+  g=varargin{1};
+  a=varargin{2};
+  M=varargin{3};
+
+  varargin=varargin(4:end);
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.keyvals.nsalg=0;
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    if isnumeric(g)
+        % Use the window length
+        Ls=length(g);
+    else
+        % Use the smallest possible length
+        Ls=1;
+    end;
+
+    % ----- step 2b : Verify a, M and get L from the window length ----------
+    L=dgtlength(Ls,a,M,kv.lt);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+
+    Luser=dgtlength(L,a,M,kv.lt);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+R=size(g,2);
+
+% -------- Are we in the Riesz sequence of in the frame case
+
+scale=1;
+if a>M*R
+  % Handle the Riesz basis (dual lattice) case.
+  % Swap a and M, and scale differently.
+  scale=sqrt(a/M);
+  tmp=a;
+  a=M;
+  M=tmp;
+end;
+
+% -------- Compute ------------- 
+
+if kv.lt(2)==1
+    % Rectangular case
+
+    if (info.gl<=M) && (R==1)
+
+        % Diagonal of the frame operator
+        d = gabframediag(g,a,M,L);
+        gt=g./sqrt(long2fir(d,info.gl));
+
+    else
+        
+        % Long window case
+        
+        % Just in case, otherwise the call is harmless. 
+        g=fir2long(g,L);
+        
+        gt=comp_gabtight_long(g,a,M)*scale;
+        
+    end;
+
+else
+    
+    % Just in case, otherwise the call is harmless. 
+    g=fir2long(g,L);
+
+    if (kv.nsalg==1) || (kv.nsalg==0 && kv.lt(2)<=2) 
+        
+        mwin=comp_nonsepwin2multi(g,a,M,kv.lt,L);
+        
+        gtfull=comp_gabtight_long(mwin,a*kv.lt(2),M)*scale;
+        
+        % We need just the first vector
+        gt=gtfull(:,1);
+            
+    else
+        
+        [s0,s1,br] = shearfind(L,a,M,kv.lt);        
+        
+        if s1 ~= 0
+            p1 = comp_pchirp(L,s1);
+            g = p1.*g;                
+        end
+        
+        b=L/M;
+        Mr = L/br;
+        ar = a*b/br;
+        
+        if s0 == 0
+            gt=comp_gabtight_long(g,ar,Mr);
+        else                
+            p0=comp_pchirp(L,-s0);
+            g = p0.*fft(g);
+            gt=comp_gabtight_long(g,L/Mr,L/ar)*sqrt(L);
+            gt = ifft(conj(p0).*gt);                                 
+        end
+        
+        if s1 ~= 0
+            gt = conj(p1).*gt;
+        end
+        
+    end;
+    
+    if (info.gl<=M) && (R==1)
+        gt=long2fir(gt,M);
+    end;
+    
+end;
+
+% --------- post process result -------
+
+if isreal(g) && (kv.lt(2)<=2)
+  % If g is real and the lattice is either rectangular or quinqux, then
+  % the output is known to be real.
+  gt=real(gt);
+end;
+
+if info.wasrow
+  gt=gt.';
+end;
+
diff --git a/inst/gabor/gabwin.m b/inst/gabor/gabwin.m
new file mode 100644
index 0000000..9f9916b
--- /dev/null
+++ b/inst/gabor/gabwin.m
@@ -0,0 +1,144 @@
+function [g,info] = gabwin(g,a,M,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} gabwin
+%@verbatim
+%GABWIN  Compute a Gabor window from text or cell array
+%   Usage: [g,info] = gabwin(g,a,M,L);
+%
+%   [g,info]=GABWIN(g,a,M,L) computes a window that fits well with the
+%   specified number of channels M, time shift a and transform length
+%   L. The window itself is specified by a text description or a cell array
+%   containing additional parameters.
+%
+%   The window can be specified directly as a vector of numerical
+%   values. In this case, GABWIN only checks assumptions about transform
+%   sizes etc.
+%
+%   [g,info]=GABWIN(g,a,M) does the same, but the window must be a FIR
+%   window, as the transform length is unspecified.
+%
+%   GABWIN(g,a,M,L,lt) or GABWIN(g,a,M,[],lt) does as above but for a
+%   non-separable lattice specified by lt. Please see the help of
+%   MATRIX2LATTICETYPE for a precise description of the parameter lt.
+%
+%   The window can be specified as one of the following text strings:
+%  
+%     'gauss'      Gaussian window fitted to the lattice,
+%                  i.e. tfr=a*M/L.
+%
+%     'dualgauss'  Canonical dual of Gaussian window.
+%
+%     'tight'      Tight window generated from a Gaussian.
+%
+%   In these cases, a long window is generated with a length of L.
+%
+%   It is also possible to specify one of the window names from FIRWIN. In
+%   such a case, GABWIN will generate the specified FIR window with a length
+%   of M.
+%
+%   The window can also be specified as cell array. The possibilities are:
+%
+%     {'gauss',...}
+%         Additional parameters are passed to PGAUSS.
+%
+%     {'dual',...}
+%         Canonical dual window of whatever follows. See the examples below.
+%
+%     {'tight',...} 
+%         Canonical tight window of whatever follows.
+%
+%   It is also possible to specify one of the window names from FIRWIN as
+%   the first field in the cell array. In this case, the remaining
+%   entries of the cell array are passed directly to FIRWIN.
+%
+%   Some examples: To compute a Gaussian window of length L fitted for a
+%   system with time-shift a and M channels use:
+%
+%     g=gabwin('gauss',a,M,L);
+%
+%   To compute Gaussian window with equal time and frequency support
+%   irrespective of a and M*:
+%
+%     g=gabwin({'gauss',1},a,M,L);
+%
+%   To compute the canonical dual of a Gaussian window fitted for a
+%   system with time-shift a and M channels:
+%
+%     gd=gabwin('gaussdual',a,M,L);
+%
+%   To compute the canonical tight window of the Gaussian window fitted
+%   for the system:
+%
+%     gd=gabwin({'tight','gauss'},a,M,L);
+%
+%   To compute the dual of a Hann window of length 20:  
+% 
+%     g=gabwin({'dual',{'hann',20}},a,M,L);
+%
+%   The structure info provides some information about the computed
+%   window:
+%
+%     info.gauss
+%        True if the window is a Gaussian.
+%
+%     info.tfr
+%        Time/frequency support ratio of the window. Set whenever it makes sense.
+%
+%     info.wasrow
+%        Input was a row window
+%
+%     info.isfir
+%        Input is an FIR window
+%
+%     info.isdual
+%        Output is the dual window of the auxiliary window.
+%
+%     info.istight
+%        Output is known to be a tight window.
+%
+%     info.auxinfo
+%        Info about auxiliary window.
+%   
+%     info.gl
+%        Length of window.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/gabwin.php}
+%@seealso{pgauss, firwin, wilwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% Assert correct input.
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.lt=[0 1];
+definput.keyvals.callfun='GABWIN';
+definput.flags.phase={'freqinv','timeinv'};
+[flags,kv,L,lt]=ltfatarghelper({'L','lt'},definput,varargin);
+
+[g,info] = comp_window(g,a,M,L,lt,kv.callfun);
+
+if (info.isfir)  
+  if info.istight
+      %g=g/sqrt(2);
+  end;  
+end;
+
diff --git a/inst/gabor/idgt.m b/inst/gabor/idgt.m
new file mode 100644
index 0000000..00e94d1
--- /dev/null
+++ b/inst/gabor/idgt.m
@@ -0,0 +1,191 @@
+function [f,g]=idgt(coef,g,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} idgt
+%@verbatim
+%IDGT  Inverse discrete Gabor transform
+%   Usage:  f=idgt(c,g,a);
+%           f=idgt(c,g,a,Ls);
+%           f=idgt(c,g,a,Ls,lt);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         Ls    : Length of signal.
+%         lt    : Lattice type (for non-separable lattices)
+%   Output parameters:
+%         f     : Signal.
+%
+%   IDGT(c,g,a) computes the Gabor expansion of the input coefficients
+%   c with respect to the window g and time shift a. The number of 
+%   channels is deduced from the size of the coefficients c.
+%
+%   IDGT(c,g,a,Ls) does as above but cuts or extends f to length Ls.
+%
+%   [f,g]=IDGT(...) additionally outputs the window used in the
+%   transform. This is useful if the window was generated from a description
+%   in a string or cell array.
+%
+%   For perfect reconstruction, the window used must be a dual window of the
+%   one used to generate the coefficients.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%
+%   If g is a row vector, then the output will also be a row vector. If c is
+%   3-dimensional, then IDGT will return a matrix consisting of one column
+%   vector for each of the TF-planes in c.
+%
+%   Assume that f=IDGT(c,g,a,L) for an array c of size M xN. 
+%   Then the following holds for k=0,...,L-1: 
+% 
+%               N-1 M-1          
+%     f(l+1)  = sum sum c(m+1,n+1)*exp(2*pi*i*m*l/M)*g(l-a*n+1)
+%               n=0 m=0          
+%
+%   Non-separable lattices:
+%   -----------------------
+%
+%   IDGT(c,g,a,'lt',lt) computes the Gabor expansion of the input
+%   coefficients c with respect to the window g, time shift a and
+%   lattice type lt. Please see the help of MATRIX2LATTICETYPE for a
+%   precise description of the parameter lt.
+%
+%   Assume that f=dgt(c,g,a,L,lt) for an array c of size MxN.
+%   Then the following holds for k=0,...,L-1:
+% 
+%               N-1 M-1          
+%     f(l+1)  = sum sum c(m+1,n+1)*exp(2*pi*i*m*l/M)*g(l-a*n+1)
+%               n=0 m=0          
+%
+%   Additional parameters:
+%   ----------------------
+%
+%   IDGT takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'freqinv'  Compute an IDGT using a frequency-invariant phase. This
+%                is the default convention described above.
+%
+%     'timeinv'  Compute an IDGT using a time-invariant phase. This
+%                convention is typically used in FIR-filter algorithms.
+%
+%   Examples:
+%   ---------
+%
+%   The following example demostrates the basic pricinples for getting
+%   perfect reconstruction (short version):
+%
+%     f=greasy;            % test signal
+%     a=32;                % time shift
+%     M=64;                % frequency shift
+%     gs={'blackman',128}; % synthesis window
+%     ga={'dual',gs};      % analysis window
+%
+%     [c,Ls]=dgt(f,ga,a,M);    % analysis
+%
+%     % ... do interesting stuff to c at this point ...
+%  
+%     r=idgt(c,gs,a,Ls); % synthesis
+%
+%     norm(f-r)          % test
+%
+%   The following example does the same as the previous one, with an
+%   explicit construction of the analysis and synthesis windows:
+%
+%     f=greasy;     % test signal
+%     a=32;         % time shift
+%     M=64;         % frequency shift
+%     Ls=length(f); % signal length
+%
+%     % Length of transform to do
+%     L=dgtlength(Ls,a,M);
+%
+%     % Analysis and synthesis window
+%     gs=firwin('blackman',128);
+%     ga=gabdual(gs,a,M,L);
+%
+%     c=dgt(f,ga,a,M); % analysis
+%
+%     % ... do interesting stuff to c at this point ...
+%  
+%     r=idgt(c,gs,a,Ls);  % synthesis
+%
+%     norm(f-r)  % test
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/idgt.php}
+%@seealso{dgt, gabwin, dwilt, gabtight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if numel(g)==1
+  error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
+end;
+
+definput.keyvals.Ls=[];
+definput.keyvals.lt=[0 1];
+definput.keyvals.dim=[];
+definput.flags.phase={'freqinv','timeinv'};
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+M=size(coef,1);
+N=size(coef,2);
+W=size(coef,3);
+
+if ~isnumeric(a) || ~isscalar(a)
+  error('%s: "a" must be a scalar',upper(mfilename));
+end;
+
+if rem(a,1)~=0
+  error('%s: "a" must be an integer',upper(mfilename));
+end;
+
+L=N*a;
+
+Ltest=dgtlength(L,a,M,kv.lt);
+
+if Ltest~=L
+    error(['%s: Incorrect size of coefficient array or "a" parameter. See ' ...
+           'the help of DGTLENGTH for the requirements.'], ...
+          upper(mfilename))
+end;
+
+g=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+f=comp_idgt(coef,g,a,kv.lt,flags.do_timeinv,0);
+
+% Cut or extend f to the correct length, if desired.
+if ~isempty(Ls)
+  f=postpad(f,Ls);
+else
+  Ls=L;
+end;
+
+f=comp_sigreshape_post(f,Ls,0,[0; W]);
+
diff --git a/inst/gabor/idgt2.m b/inst/gabor/idgt2.m
new file mode 100644
index 0000000..80cedd2
--- /dev/null
+++ b/inst/gabor/idgt2.m
@@ -0,0 +1,186 @@
+function [f]=idgt2(c,g1,p3,p4,p5)
+%-*- texinfo -*-
+%@deftypefn {Function} idgt2
+%@verbatim
+%IDGT2  2D Inverse discrete Gabor transform
+%   Usage: f=idgt2(c,g,a);
+%          f=idgt2(c,g1,g2,a);
+%          f=idgt2(c,g1,g2,[a1 a2]);
+%          f=idgt2(c,g,a,Ls);
+%          f=idgt2(c,g1,g2,a,Ls);
+%          f=idgt2(c,g1,g2,[a1 a2],Ls);
+%
+%   Input parameters:
+%         c       : Array of coefficients.
+%         g,g1,g2 : Window function(s).
+%         a,a1,a2 : Length(s) of time shift.
+%         Ls      : Length(s) of reconstructed signal (optional).
+%
+%   Output parameters:
+%         f       : Output data, matrix.
+%
+%   IDGT2(c,g,a,M) will calculate a separable two dimensional inverse
+%   discrete Gabor transformation of the input coefficients c using the
+%   window g and parameters a, along each dimension. The number of channels
+%   is deduced from the size of the coefficients c.
+%
+%   IDGT2(c,g1,g2,a) will do the same using the window g1 along the first
+%   dimension, and window g2 along the second dimension.
+%
+%   IDGT2(c,g,a,Ls) or IDGT2(c,g1,g2,a,Ls) will cut the signal to size Ls*
+%   after the transformation is done.
+%
+%   The parameters a and Ls can also be vectors of length 2.
+%   In this case the first element will be used for the first dimension
+%   and the second element will be used for the second dimension. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/idgt2.php}
+%@seealso{dgt2, gabdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+error(nargchk(3,5,nargin));
+
+if ndims(c)<4 || ndims(c)>5
+  error('c must be 4 or 5 dimensional.');
+end;
+
+doLs=0;
+
+switch nargin
+  case 3
+    g2=g1;
+    a=p3;
+  case 4
+    if prod(size(p3))>2
+      % Two windows was specified.
+      g2=p3;
+      a=p4;
+    else
+      g2=g1;
+      a=p3;
+      Ls=p4;
+      doLs=1;
+    end;
+  case 5
+    g2=p3;
+    a=p4;
+    Ls=p5;
+    doLs=1;
+end;
+
+if size(g1,2)>1
+  if size(g1,1)>1
+    error('g1 must be a vector');
+  else
+    % g1 was a row vector.
+    g1=g1(:);
+  end;
+end;
+
+if size(g2,2)>1
+  if size(g2,1)>1
+    error('g2 must be a vector');
+  else
+    % g2 was a row vector.
+    g2=g2(:);
+  end;
+end;
+
+if prod(size(a))>2 || prod(size(a))==0
+  error('a must be a scalar or 1x2 vector');
+end;
+
+if length(a)==2
+  a1=a(1);
+  a2=a(2);
+else
+  a1=a;
+  a2=a;
+end;
+
+Lwindow1=size(g1,1);
+Lwindow2=size(g2,1);
+
+M1=size(c,1);
+N1=size(c,2);
+M2=size(c,3);
+N2=size(c,4);
+W=size(c,5);
+
+L1=a1*N1;
+L2=a2*N2;
+
+% Length of window must be dividable by M.
+% We cannot automically zero-extend the window, as it can
+% possible break some symmetry properties of the window, and we don't
+% know which symmetries to preserve.
+if rem(Lwindow1,M1)~=0
+  error('Length of window no. 1 must be dividable by M1.')
+end;
+
+if rem(Lwindow2,M2)~=0
+  error('Length of window no. 2 must be dividable by M2.')
+end;
+    
+
+
+% --- first dimension
+
+% Change c to correct shape.
+c=reshape(c,M1,N1,M2*N2*W);
+
+c=comp_idgt(c,g1,a1,[0 1],0,0);
+
+% Check if Ls was specified.
+if doLs
+  c=postpad(c,Ls(1));
+else
+  Ls(1)=L1;
+end;
+
+% Change to correct size
+c=reshape(c,Ls(1),M2*N2,W);
+
+% Exchange first and second dimension.
+c=permute(c,[2,1,3]);
+
+% --- second dimension
+
+% Change c to correct shape.
+c=reshape(c,M2,N2,Ls(1)*W);
+
+c=comp_idgt(c,g2,a2,[0 1],0,0);
+
+% Check if Ls was specified.
+if doLs
+  c=postpad(c,Ls(2));
+else
+  Ls(2)=L2;
+end;
+
+% Change to correct size
+c=reshape(c,Ls(2),Ls(1),W);
+
+% Exchange first and second dimension.
+f=permute(c,[2,1,3]);
+
+
diff --git a/inst/gabor/idgtreal.m b/inst/gabor/idgtreal.m
new file mode 100644
index 0000000..503e1ef
--- /dev/null
+++ b/inst/gabor/idgtreal.m
@@ -0,0 +1,186 @@
+function [f,g]=idgtreal(coef,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} idgtreal
+%@verbatim
+%IDGTREAL  Inverse discrete Gabor transform for real-valued signals
+%   Usage:  f=idgtreal(c,g,a,M);
+%           f=idgtreal(c,g,a,M,Ls);
+%
+%   Input parameters:
+%         c     : Array of coefficients.
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of channels.
+%         Ls    : length of signal.
+%   Output parameters:
+%         f     : Signal.
+%
+%   IDGTREAL(c,g,a,M) computes the Gabor expansion of the input coefficients
+%   c with respect to the real-valued window g, time shift a and number of
+%   channels M. c is assumed to be the positive frequencies of the Gabor
+%   expansion of a real-valued signal.
+%
+%   It must hold that size(c,1)==floor(M/2)+1. Note that since the
+%   correct number of channels cannot be deduced from the input, IDGTREAL
+%   takes an additional parameter as opposed to IDGT.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of GABWIN for more details.
+%  
+%   IDGTREAL(c,g,a,M,Ls) does as above but cuts or extends f to length Ls.
+%
+%   [f,g]=IDGTREAL(...) additionally outputs the window used in the
+%   transform. This is usefull if the window was generated from a description
+%   in a string or cell array.
+%
+%   For perfect reconstruction, the window used must be a dual window of the
+%   one used to generate the coefficients.
+%
+%   If g is a row vector, then the output will also be a row vector. If c is
+%   3-dimensional, then IDGTREAL will return a matrix consisting of one column
+%   vector for each of the TF-planes in c.
+%
+%   See the help on IDGT for the precise definition of the inverse Gabor
+%   transform.
+%
+%   IDGTREAL takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'freqinv'  Use a frequency-invariant phase. This is the default
+%                convention described in the help for DGT.
+%
+%     'timeinv'  Use a time-invariant phase. This convention is typically 
+%                used in filter bank algorithms.
+%
+%   Examples:
+%   ---------
+%
+%   The following example demostrates the basic pricinples for getting
+%   perfect reconstruction (short version):
+%
+%     f=greasy;            % test signal
+%     a=32;                % time shift
+%     M=64;                % frequency shift
+%     gs={'blackman',128}; % synthesis window
+%     ga={'dual',gs};      %  analysis window
+%
+%     [c,Ls]=dgtreal(f,ga,a,M); % analysis
+%
+%     % ... do interesting stuff to c at this point ...
+%  
+%     r=idgtreal(c,gs,a,M,Ls); % synthesis
+%
+%     norm(f-r)                % test
+%
+%   The following example does the same as the previous one, with an
+%   explicit construction of the analysis and synthesis windows:
+%
+%     f=greasy;     % test signal
+%     a=32;         % time shift
+%     M=64;         % frequency shift
+%     Ls=length(f); % signal length
+%
+%     % Length of transform to do
+%     L=dgtlength(Ls,a,M);
+%
+%     % Analysis and synthesis window
+%     gs=firwin('blackman',128);
+%     ga=gabdual(gs,a,M,L);
+%
+%     c=dgtreal(f,ga,a,M);  % analysis
+%
+%     % ... do interesting stuff to c at this point ...
+%  
+%     r=idgtreal(c,gs,a,M,Ls); % synthesis
+%
+%     norm(f-r)       % test
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/idgtreal.php}
+%@seealso{idgt, gabwin, gabdual, dwilt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DGT
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+if nargin<4
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if prod(size(g))==1
+  error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.keyvals.Ls=[];
+definput.keyvals.lt=[0 1];
+definput.flags.phase={'freqinv','timeinv'};
+
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+N=size(coef,2);
+W=size(coef,3);
+
+% Make a dummy call to test the input parameters
+Lsmallest=dgtlength(1,a,M,kv.lt);
+
+M2=floor(M/2)+1;
+
+if M2~=size(coef,1)
+  error('Mismatch between the specified number of channels and the size of the input coefficients.');
+end;
+
+L=N*a;
+
+if rem(L,Lsmallest)>0
+    error('%s: Invalid size of coefficient array.',upper(mfilename));
+end;
+
+if kv.lt(2)>2
+  error('Only rectangular or quinqux lattices are supported.');  
+end;
+
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+if ~isreal(g)
+  error('%s: Window must be real-valued.',upper(mfilename));
+end;
+
+% Do the actual computation.
+f=comp_idgtreal(coef,g,a,M,kv.lt,flags.do_timeinv);
+
+% Cut or extend f to the correct length, if desired.
+if ~isempty(kv.Ls)
+  f=postpad(f,kv.Ls);
+else
+  kv.Ls=L;
+end;
+
+f=comp_sigreshape_post(f,Ls,0,[0; W]);
+
diff --git a/inst/gabor/idwilt.m b/inst/gabor/idwilt.m
new file mode 100644
index 0000000..7693874
--- /dev/null
+++ b/inst/gabor/idwilt.m
@@ -0,0 +1,93 @@
+function [f,g]=idwilt(c,g,Ls)
+%-*- texinfo -*-
+%@deftypefn {Function} idwilt
+%@verbatim
+%IDWILT  Inverse discrete Wilson transform
+%   Usage:  f=idwilt(c,g);
+%           f=idwilt(c,g,Ls);
+%
+%   Input parameters:
+%      c     : M xN array of coefficients.
+%      g     : Window function.
+%      Ls    : Final length of function (optional)
+%   Output parameters:
+%      f     : Input data
+%
+%   IDWILT(c,g) computes an inverse discrete Wilson transform with window g.
+%   The number of channels is deduced from the size of the coefficient array c.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%  
+%   IDWILT(f,g,Ls) does the same, but cuts of zero-extend the final
+%   result to length Ls.
+%
+%   [f,g]=IDWILT(...) additionally outputs the window used in the
+%   transform. This is usefull if the window was generated from a
+%   description in a string or cell array.
+%
+%
+%   References:
+%     H. Boelcskei, H. G. Feichtinger, K. Groechenig, and F. Hlawatsch.
+%     Discrete-time Wilson expansions. In Proc. IEEE-SP 1996 Int. Sympos.
+%     Time-Frequency Time-Scale Analysis, june 1996.
+%     
+%     Y.-P. Lin and P. Vaidyanathan. Linear phase cosine modulated maximally
+%     decimated filter banks with perfectreconstruction. IEEE Trans. Signal
+%     Process., 43(11):2525-2539, 1995.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/idwilt.php}
+%@seealso{dwilt, wilwin, dgt, wilorth}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DWILT
+%   REFERENCE: OK
+
+error(nargchk(2,3,nargin));
+
+M=size(c,1)/2;
+N=2*size(c,2);
+W=size(c,3);
+
+a=M;
+L=M*N;
+
+assert_L(L,0,L,a,2*M,'IDWILT');
+
+[g,info]=wilwin(g,M,L,'IDWILT');
+
+wasrow=0;
+if (ndims(c)==2 && info.wasrow)
+  wasrow=1;
+end;
+
+f=comp_idwilt(c,g);
+
+% Check if Ls was specified.
+if nargin==3
+  f=postpad(f,Ls);
+else
+  Ls=L;
+end;
+
+f=comp_sigreshape_post(f,Ls,wasrow,[0; W]);
+
+
diff --git a/inst/gabor/idwilt2.m b/inst/gabor/idwilt2.m
new file mode 100644
index 0000000..89d096e
--- /dev/null
+++ b/inst/gabor/idwilt2.m
@@ -0,0 +1,130 @@
+function [f]=idwilt2(c,g1,p3,p4)
+%-*- texinfo -*-
+%@deftypefn {Function} idwilt2
+%@verbatim
+%IDWILT2  2D Inverse Discrete Wilson transform
+%   Usage: f=idwilt2(c,g);
+%          f=idwilt2(c,g1,g2);
+%          f=idwilt2(c,g1,g2,Ls);
+%
+%   Input parameters:
+%         c       : Array of coefficients.
+%         g,g1,g2 : Window functions.
+%         Ls      : Size of reconstructed signal.
+%   Output parameters:
+%         f       : Output data, matrix.
+%
+%   IDWILT2(c,g) calculates a separable two dimensional inverse
+%   discrete Wilson transformation of the input coefficients c using the
+%   window g. The number of channels is deduced from the size of the
+%   coefficients c.
+%
+%   IDWILT2(c,g1,g2) does the same using the window g1 along the first
+%   dimension, and window g2 along the second dimension.
+%
+%   IDWILT2(c,g1,g2,Ls) cuts the signal to size Ls after the transformation
+%   is done.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/idwilt2.php}
+%@seealso{dwilt2, dgt2, wildual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+error(nargchk(2,4,nargin));
+
+Ls=[];
+
+switch nargin
+  case 2
+    g2=g1;
+  case 3
+    if prod(size(p3))>2
+      % Two windows was specified.
+      g2=p3;
+    else
+      g2=g1;
+      Ls=p3;
+    end;
+  case 4
+    g2=p3;
+    Ls=p4;
+end;
+  
+
+if ndims(c)<4 || ndims(c)>5
+  error('c must be 4 or 5 dimensional.');
+end;
+
+M1=size(c,1)/2;
+N1=size(c,2)*2;
+M2=size(c,3)/2;
+N2=size(c,4)*2;
+W=size(c,5);
+
+L1=M1*N1;
+L2=M2*N2;
+
+[g1,info]=wilwin(g1,M1,L1,'IDWILT2');
+[g2,info]=wilwin(g2,M2,L2,'IDWILT2');
+
+% If input is real, and window is real, output must be real as well.
+inputwasreal = (isreal(g1) && isreal(g2) && isreal(c));
+
+
+if isempty(Ls)
+  Ls(1)=L1;
+  Ls(2)=L2;
+else
+  Ls=bsxfun(@times,Ls,[1 1]);
+end;
+
+% --- first dimension
+
+% Change c to correct shape.
+c=reshape(c,2*M1,N1/2,L2*W);
+
+c=comp_idwilt(c,g1);
+
+c=postpad(c,Ls(1));
+
+c=reshape(c,Ls(1),L2,W);
+
+c=permute(c,[2,1,3]);
+
+% --- second dimension
+
+% Change c to correct shape.
+c=reshape(c,2*M2,N2/2,Ls(1)*W);
+
+c=comp_idwilt(c,g2);
+
+c=postpad(c,Ls(2));
+
+c=reshape(c,Ls(2),Ls(1),W);
+
+f=permute(c,[2,1,3]);
+
+% Clean signal if it is known to be real
+if inputwasreal
+  f=real(f);
+end;
+
+
diff --git a/inst/gabor/instfreqplot.m b/inst/gabor/instfreqplot.m
new file mode 100644
index 0000000..13d43d6
--- /dev/null
+++ b/inst/gabor/instfreqplot.m
@@ -0,0 +1,211 @@
+function []=instfreqplot(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} instfreqplot
+%@verbatim
+%INSTFREQPLOT  Plot of instantaneous frequency
+%   Usage: instfreqplot(f,op1,op2, ... );
+%          instfreqplot(f,fs,op1,op2, ... );
+%
+%   INSTFREQPLOT(f) plots the instantaneous frequency of f using a DGT.
+%
+%   INSTFREQPLOT(f,fs) does the same for a signal with sampling rate
+%   fs Hz.
+%
+%   The instantaneous frequency contains extreme spikes in regions
+%   where the spectrogram is close to zero. These points are usually
+%   uninteresting and destroy the visibility of the plot. Use the 'thr'
+%   or 'clim' or 'climsym' options (see below) to remove these points.
+%
+%   An example:
+%
+%     instfreqplot(greasy,16000,'thr',.03,'climsym',100);
+%
+%   will produce a nice instantaneous frequency plot of the GREASY
+%   signal.
+%
+%   INSTFREQPLOT accepts the following optional arguments:
+%
+%     'tfr',v     Set the ratio of frequency resolution to time resolution.
+%                 A value v=1 is the default. Setting v>1 will give better
+%                 frequency resolution at the expense of a worse time
+%                 resolution. A value of 0<v<1 will do the opposite.
+%  
+%     'wlen',s    Window length. Specifies the length of the window
+%                 measured in samples. See help of PGAUSS on the exact
+%                 details of the window length.
+%  
+%     'thr',r     Keep the coefficients with a magnitude larger than r*
+%                 times the largest magnitude. Set the instantaneous 
+%                 frequency of the rest of the coefficients to zero
+%  
+%     'nf'        Display negative frequencies, with the zero-frequency
+%                 centered in the middle. For real signals, this will just
+%                 mirror the upper half plane. This is standard for complex
+%                 signals.
+%  
+%     'tc'        Time centering. Move the beginning of the signal to the
+%                 middle of the plot. This is useful for visualizing the
+%                 window functions of the toolbox.
+%  
+%     'image'     Use imagesc to display the spectrogram. This is the
+%                 default.
+%  
+%     'dgt'       Use the 'dgt' method to compute the instantaneous
+%                 frequency. This is the default.
+%  
+%     'clim',clim  Use a colormap ranging from clim(1) to clim(2). These
+%                  values are passed to imagesc. See the help on imagesc.
+%  
+%     'climsym',cval  Use a colormap ranging from -cval to cval
+%  
+%     'fmax',y    Display y as the highest frequency.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/instfreqplot.php}
+%@seealso{sgram, resgram, phaseplot}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   REFERENCE: NA
+%   TESTING: NA
+  
+if nargin<1
+  error('Too few input arguments.');
+end;
+
+if sum(size(f)>1)>1
+  error('Input must be a vector.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.flags.wlen={'nowlen','wlen'};
+definput.flags.tc={'notc','tc'};
+definput.flags.method={'dgt','phase','abs'};
+definput.flags.clim={'noclim','clim','climsym'};
+
+if isreal(f)
+  definput.flags.posfreq={'posfreq','nf'};
+else
+  definput.flags.posfreq={'nf','posfreq'};
+end;
+
+definput.keyvals.tfr=1;
+definput.keyvals.wlen=0;
+definput.keyvals.thr=[];
+definput.keyvals.clim=[0,1];
+definput.keyvals.climsym=1;
+definput.keyvals.fmax=[];
+definput.keyvals.xres=800;
+definput.keyvals.yres=600;
+
+[flags,kv,fs]=ltfatarghelper({'fs'},definput,varargin);
+
+% Override the setting from tfplot, because INSTFREQPLOT does not support the
+% dB-settings
+flags.do_lin=1;
+flags.do_db=0;
+flags.do_dbsq=0;
+
+dofs=~isempty(fs);
+
+% Downsample
+if ~isempty(kv.fmax)
+  if ~isempty(kv.fs)
+    resamp=kv.fmax*2/fs;
+  else
+    resamp=kv.fmax*2/length(f);
+  end;
+
+  f=fftresample(f,round(length(f)*resamp));
+  kv.fs=2*kv.fmax;
+end;
+
+Ls=length(f);
+
+if flags.do_posfreq
+   kv.yres=2*kv.yres;
+end;
+
+try
+  [a,M,L,N,Ndisp]=gabimagepars(Ls,kv.xres,kv.yres);
+catch
+  err=lasterror;
+  if strcmp(err.identifier,'LTFAT:noframe')
+    error(sprintf(['The signal is too long. INSTFREQPLOT cannot visualize all the details.\n' ...
+                   'Try a shorter signal or increase the image resolution by calling:\n\n' ...
+                   '  sgram(...,''xres'',xres,''yres'',yres);\n\n' ...
+                   'for larger values of xres and yres.\n'...
+                   'The current values are:\n  xres=%i\n  yres=%i'],kv.xres,kv.yres));
+  else
+    rethrow(err);
+  end;
+end;
+
+
+b=L/N;
+
+% Set an explicit window length, if this was specified.
+if flags.do_wlen
+  kv.tfr=kv.wlen^2/L;
+end;
+
+g={'gauss',kv.tfr};
+
+if flags.do_dgt
+  [coef,fgrad,dgtcoef]=gabphasegrad('dgt',f,g,a,M);
+end;
+
+if flags.do_phase
+  dgtcoef=dgt(f,g,a,M);
+  [coef,fgrad]=gabphasegrad('phase',angle(dgtcoef),a);
+end;
+
+if flags.do_abs  
+  dgtcoef=dgt(f,g,a,M);
+  [coef,fgrad]=gabphasegrad('abs',abs(dgtcoef),g,a);
+end;
+
+if ~isempty(kv.thr)
+  % keep only the largest coefficients.
+  maxc=max(abs(dgtcoef(:)));
+  mask=abs(dgtcoef)<maxc*kv.thr;
+
+  coef(mask)=0;
+end
+
+% Cut away zero-extension.
+coef=coef(:,1:Ndisp);
+
+% Convert climsym into a normal clim
+if flags.do_climsym
+  flags.do_clim=1;
+  kv.clim=[-kv.climsym,kv.climsym];
+end;
+
+if flags.do_posfreq
+  coef=coef(1:floor(M/2)+1,:);
+  plotdgtreal(coef,a,M,'argimport',flags,kv);
+else
+  plotdgt(coef,a,'argimport',flags,kv);
+end;
+
+if nargout>0
+  varargout={coef};
+end;
+
diff --git a/inst/gabor/isgram.m b/inst/gabor/isgram.m
new file mode 100644
index 0000000..4a406d2
--- /dev/null
+++ b/inst/gabor/isgram.m
@@ -0,0 +1,294 @@
+function [f,relres,iter]=isgram(s,g,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} isgram
+%@verbatim
+%ISGRAM  Spectrogram inversion
+%   Usage:  f=isgram(s,g,a);
+%           f=isgram(s,g,a,Ls);
+%           [f,relres,iter]=isgram(...);
+%
+%   Input parameters:
+%         c       : Array of coefficients.
+%         g       : Window function.
+%         a       : Length of time shift.
+%         Ls      : length of signal.
+%   Output parameters:
+%         f       : Signal.
+%         relres  : Vector of residuals.
+%         iter    : Number of iterations done.
+%
+%   ISGRAM(s,g,a) attempts to invert a spectrogram computed by :
+%
+%     s = abs(dgt(f,g,a,M)).^2;
+%
+%   using an iterative method.
+%
+%   ISGRAM(c,g,a,Ls) does as above but cuts or extends f to length Ls.
+%
+%   If the phase of the spectrogram is known, it is much better to use
+%   idgt.
+%
+%   [f,relres,iter]=ISGRAM(...) additionally return the residuals in a
+%   vector relres and the number of iteration steps iter.
+%
+%   Generally, if the spectrogram has not been modified, the iterative
+%   algorithm will converge slowly to the correct result. If the
+%   spectrogram has been modified, the algorithm is not guaranteed to
+%   converge at all.  
+%
+%   ISGRAM takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'lt',lt      Specify the lattice type. See the help on MATRIX2LATTICETYPE.
+%
+%     'zero'       Choose a starting phase of zero. This is the default
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'int'        Construct a starting phase by integration. Only works
+%                  for Gaussian windows.
+%
+%     'griflim'    Use the Griffin-Lim iterative method, this is the
+%                  default.
+%
+%     'bfgs'       Use the limited-memory Broyden Fletcher Goldfarb
+%                  Shanno (BFGS) method.  
+%
+%     'tol',t      Stop if relative residual error is less than the specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'printstep',p  If 'print' is specified, then print every p'th
+%                    iteration. Default value is p=10;
+%
+%   To use the BFGS method, please install the minFunc software from
+%   http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html.
+%
+%   Examples:
+%   ---------
+%
+%   To reconstruct the phase of 'greasy', use the following:
+%
+%     % Setup the problem and the coefficients
+%     f=greasy;
+%     g='gauss';
+%     a=20; M=200;
+%     c=dgt(f,g,a,M);
+%     s=abs(c).^2;
+%     theta=angle(c);
+%
+%     % Reconstruct and get spectrogram and angle
+%     r=isgram(s,g,a);
+%     c_r=dgt(r,g,a,M);
+%     s_r=abs(c_r).^2;
+%     theta_r=angle(c_r);
+%
+%     % Compute the angular difference
+%     d1=abs(theta-theta_r);
+%     d2=2*pi-d1;
+%     anglediff=min(d1,d2);
+%
+%     % Plot the difference in spectrogram and phase
+%     figure(1);
+%     plotdgt(s./s_r,a,16000,'clim',[-10,10]);
+%     colormap([bone;flipud(bone)])
+%     title('Relative difference in spectrogram');
+%
+%     figure(2);
+%     plotdgt(anglediff,a,16000,'lin');
+%     colormap(bone);
+%     title('Difference in angle');
+%
+%
+%   References:
+%     R. Decorsiere and P. L. Soendergaard. Modulation filtering using an
+%     optimization approach to spectrogram reconstruction. In Proceedings of
+%     the Forum Acousticum, 2011.
+%     
+%     D. Griffin and J. Lim. Signal estimation from modified short-time
+%     Fourier transform. IEEE Trans. Acoust. Speech Signal Process.,
+%     32(2):236-243, 1984.
+%     
+%     D. Liu and J. Nocedal. On the limited memory BFGS method for large
+%     scale optimization. Mathematical programming, 45(1):503-528, 1989.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/isgram.php}
+%@seealso{isgramreal, frsynabs, dgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Remi Decorsiere and Peter L. Soendergaard.
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+  if nargin<3
+    error('%s: Too few input parameters.',upper(mfilename));
+  end;
+  
+  if numel(g)==1
+    error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
+  end;
+  
+  definput.keyvals.Ls=[];
+  definput.keyvals.lt=[0 1];
+  definput.keyvals.tol=1e-6;
+  definput.keyvals.maxit=100;
+  definput.keyvals.printstep=10;
+  definput.flags.method={'griflim','bfgs'};
+  definput.flags.print={'quiet','print'};
+  definput.flags.startphase={'zero','rand','int'};
+  
+  [flags,kv,Ls]=ltfatarghelper({'Ls','tol','maxit'},definput,varargin);
+
+  M=size(s,1);
+  N=size(s,2);
+  W=size(s,3);
+  
+  if ~isnumeric(a) || ~isscalar(a)
+      error('%s: "a" must be a scalar',upper(mfilename));
+  end;
+  
+  if rem(a,1)~=0
+      error('%s: "a" must be an integer',upper(mfilename));
+  end;
+  
+  L=N*a;
+  
+  Ltest=dgtlength(L,a,M,kv.lt);
+  
+  if Ltest~=L
+      error(['%s: Incorrect size of coefficient array or "a" parameter. See ' ...
+             'the help of DGTLENGTH for the requirements.'], ...
+            upper(mfilename))
+  end;
+  
+  
+  sqrt_s=sqrt(s);
+  
+  if flags.do_zero
+    % Start with a phase of zero.
+    c=sqrt_s;
+  end;
+  
+  if flags.do_rand
+    c=sqrt_s.*exp(2*pi*i*rand(M,N));
+  end;
+  
+  if flags.do_int
+      if kv.lt(2)>1
+          error(['%s: The integration initilization is not implemented for ' ...
+                 'non-sep lattices.'],upper(mfilename));
+      end;
+          
+      c=constructphase(s,g,a);
+  end;
+
+  % gabwin is called after constructphase above, because constructphase
+  % needs the window as a string/cell
+  g=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+    
+  
+  gd = gabdual(g,a,M,L);
+    
+  % For normalization purposes
+  norm_s=norm(s,'fro');
+  
+  relres=zeros(kv.maxit,1);
+  if flags.do_griflim
+    
+    for iter=1:kv.maxit
+        %c = comp_dgt_proj(c,g,gd,a,M,L);
+        if kv.lt(2)==1
+            f=comp_idgt(c,gd,a,kv.lt,0,0);
+            c=comp_dgt(f,g,a,M,kv.lt,0,0,0);
+        else
+            f=comp_idgt(c,gd,a,kv.lt,0,0);
+            c=comp_dgt(f,g,a,M,kv.lt,0,0,0);            
+        end;
+      
+      relres(iter)=norm(abs(c).^2-s,'fro')/norm_s;
+      
+      c=sqrt_s.*exp(i*angle(c));
+      
+      if flags.do_print
+        if mod(iter,kv.printstep)==0
+          fprintf('ISGRAM: Iteration %i, residual = %f\n',iter,relres(iter));
+        end;    
+      end;
+      
+      if relres(iter)<kv.tol
+        relres=relres(1:iter);
+        break;
+      end;
+      
+    end;
+    
+    f=comp_idgt(c,gd,a,kv.lt,0,0);
+  end;
+  
+  if flags.do_bfgs
+    if exist('minFunc')~=2
+      error(['To use the BFGS method in ISGRAMREAL, please install the minFunc ' ...
+             'software from http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html.']);
+    end;
+    
+    % Setting up the options for minFunc
+    opts = struct;
+    opts.display = kv.printstep;
+    opts.maxiter = kv.maxit;
+    
+    % Don't limit the number of function evaluations, just the number of
+    % time-steps.
+    opts.MaxFunEvals = 1e9;
+    opts.usemex = 0;
+    
+    f0 = comp_idgt(c,gd,a,kv.lt,0,0);
+    [f,fval,exitflag,output]=minFunc(@objfun,f0,opts,g,a,M,s,kv.lt);
+    % First entry of output.trace.fval is the objective function
+    % evaluated on the initial input. Skip it to be consistent.
+    relres = output.trace.fval(2:end)/norm_s;
+    iter = output.iterations;
+  end;
+
+    
+  % Cut or extend f to the correct length, if desired.
+  if ~isempty(Ls)
+    f=postpad(f,Ls);
+  else
+    Ls=L;
+  end;
+  
+  f=comp_sigreshape_post(f,Ls,0,[0; W]);
+
+%  Subfunction to compute the objective function for the BFGS method.
+function [f,df]=objfun(x,g,a,M,s,lt);
+  L=size(s,2)*a;
+  c=comp_dgt(x,g,a,M,lt,0,0,0);
+  
+  inner=abs(c).^2-s;
+  f=norm(inner,'fro')^2;
+  
+  df=4*real(conj(comp_idgt(inner.*c,g,a,lt,0,0)));
+
+
diff --git a/inst/gabor/isgramreal.m b/inst/gabor/isgramreal.m
new file mode 100644
index 0000000..b9f6d9c
--- /dev/null
+++ b/inst/gabor/isgramreal.m
@@ -0,0 +1,265 @@
+function [f,relres,iter]=isgramreal(s,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} isgramreal
+%@verbatim
+%ISGRAMREAL  Spectrogram inversion (real signal)
+%   Usage:  f=isgramreal(s,g,a,M);
+%           f=isgramreal(s,g,a,M,Ls);
+%           [f,relres,iter]=isgramreal(...);
+%
+%   Input parameters:
+%         c       : Array of coefficients.
+%         g       : Window function.
+%         a       : Length of time shift.
+%         M       : Number of channels.
+%         Ls      : length of signal.
+%   Output parameters:
+%         f       : Signal.
+%         relres  : Vector of residuals.
+%         iter    : Number of iterations done.
+%
+%   ISGRAMREAL(s,g,a,M) attempts to invert a spectrogram computed by :
+%
+%     s = abs(dgtreal(f,g,a,M)).^2;
+%
+%   by an iterative method.
+%
+%   ISGRAMREAL(s,g,a,M,Ls) does as above but cuts or extends f to length Ls.
+%
+%   If the phase of the spectrogram is known, it is much better to use
+%   DGTREAL
+%
+%   f,relres,iter]=ISGRAMREAL(...) additionally returns the residuals in a
+%   vector relres and the number of iteration steps done.
+%
+%   Generally, if the spectrogram has not been modified, the iterative
+%   algorithm will converge slowly to the correct result. If the
+%   spectrogram has been modified, the algorithm is not guaranteed to
+%   converge at all.  
+%
+%   ISGRAMREAL takes the following parameters at the end of the line of
+%   input arguments:
+%
+%     'lt',lt      Specify the lattice type. See the help on
+%                  MATRIX2LATTICETYPE. Only the rectangular or quinqux
+%                  lattices can be specified.
+%
+%     'zero'       Choose a starting phase of zero. This is the default
+%
+%     'rand'       Choose a random starting phase.
+%
+%     'int'        Construct a starting phase by integration. Only works
+%                  for Gaussian windows.
+%
+%     'griflim'    Use the Griffin-Lim iterative method, this is the
+%                  default.
+%
+%     'bfgs'       Use the limited-memory Broyden Fletcher Goldfarb
+%                  Shanno (BFGS) method.  
+%
+%     'tol',t      Stop if relative residual error is less than the specified tolerance.  
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%     'printstep',p
+%                  If 'print' is specified, then print every p'th
+%                  iteration. Default value is p=10.
+%
+%   To use the BFGS method, please install the minFunc software from
+%   http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html
+%
+%
+%   References:
+%     R. Decorsiere and P. L. Soendergaard. Modulation filtering using an
+%     optimization approach to spectrogram reconstruction. In Proceedings of
+%     the Forum Acousticum, 2011.
+%     
+%     D. Griffin and J. Lim. Signal estimation from modified short-time
+%     Fourier transform. IEEE Trans. Acoust. Speech Signal Process.,
+%     32(2):236-243, 1984.
+%     
+%     D. Liu and J. Nocedal. On the limited memory BFGS method for large
+%     scale optimization. Mathematical programming, 45(1):503-528, 1989.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/isgramreal.php}
+%@seealso{dgtreal, idgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Remi Decorsiere and Peter L. Soendergaard.
+%   REFERENCE: OK
+
+% Check input paramameters.
+
+  if nargin<3
+    error('%s: Too few input parameters.',upper(mfilename));
+  end;
+  
+  if numel(g)==1
+    error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
+  end;
+  
+  definput.keyvals.Ls=[];
+  definput.keyvals.lt=[0 1];
+  definput.keyvals.tol=1e-6;
+  definput.keyvals.maxit=100;
+  definput.keyvals.printstep=10;
+  definput.flags.method={'griflim','bfgs'};
+  definput.flags.print={'print','quiet'};
+  definput.flags.startphase={'zero','rand','int'};
+  
+  [flags,kv,Ls]=ltfatarghelper({'Ls','tol','maxit'},definput,varargin);
+
+  N=size(s,2);
+  W=size(s,3);
+  
+  % Make a dummy call to test the input parameters
+  Lsmallest=dgtlength(1,a,M,kv.lt);
+  
+  M2=floor(M/2)+1;
+  
+  if M2~=size(s,1)
+      error('Mismatch between the specified number of channels and the size of the input coefficients.');
+  end;
+  
+  L=N*a;
+  
+  if rem(L,Lsmallest)>0
+      error('%s: Invalid size of coefficient array.',upper(mfilename));
+  end;
+  
+  %% ----- step 3 : Determine the window 
+  
+  [g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
+  
+  if L<info.gl
+      error('%s: Window is too long.',upper(mfilename));
+  end;
+  
+  if ~isreal(g)
+      error('%s: Window must be real-valued.',upper(mfilename));
+  end;
+  
+  %% Actual computation
+  
+  sqrt_s=sqrt(s);
+  
+  if flags.do_zero
+    % Start with a phase of zero.
+    c=sqrt(s);
+  end;
+  
+  if flags.do_rand
+    c=sqrt_s.*exp(2*pi*1i*rand(size(s)));
+  end;
+  
+  if flags.do_int
+      if kv.lt(2)>1
+          error(['%s: The integration initilization is not implemented for ' ...
+                 'non-sep lattices.'],upper(mfilename));
+      end;
+
+      
+    s2=zeros(M,N);
+    s2(1:M2,:)=s;
+    if rem(M,2)==0
+      s2(M2+1:M,:)=flipud(s(2:end-1,:));
+    else
+      s2(M2+1:M,:)=flipud(s(2:end));
+    end;
+    c=constructphase(s2,g,a);
+    c=c(1:M2,:);
+  end;
+    
+  gd = gabdual(g,a,M);
+    
+  % For normalization purposes
+  norm_s=norm(s,'fro');
+  
+  relres=zeros(kv.maxit,1);
+  if flags.do_griflim
+    for iter=1:kv.maxit
+      f=comp_idgtreal(c,gd,a,M,kv.lt,0);
+      c=comp_dgtreal(f,g,a,M,kv.lt,0);
+      
+      relres(iter)=norm(abs(c).^2-s,'fro')/norm_s;
+      
+      c=sqrt_s.*exp(1i*angle(c));
+      
+      if flags.do_print
+        if mod(iter,kv.printstep)==0
+          fprintf('ISGRAMREAL: Iteration %i, residual = %f.\n',iter,relres(iter));
+        end;    
+      end;
+      
+      if relres(iter)<kv.tol
+        relres=relres(1:iter);
+        break;
+      end;
+      
+    end;
+    
+  end;
+  
+  if flags.do_bfgs
+    if exist('minFunc')~=2
+      error(['To use the BFGS method in ISGRAMREAL, please install the minFunc ' ...
+             'software from http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html.']);
+    end;
+    
+    % Setting up the options for minFunc
+    opts = struct;
+    opts.display = kv.printstep;
+    opts.maxiter = kv.maxit;
+    opts.usemex = 0;
+
+    % Don't limit the number of function evaluations, just the number of
+    % time-steps.
+    opts.MaxFunEvals = 1e9;
+    
+    f0 = comp_idgtreal(c,gd,a,M,kv.lt,0);
+    [f,fval,exitflag,output]=minFunc(@objfun,f0,opts,g,a,M,s,kv.lt);
+    % First entry of output.trace.fval is the objective function
+    % evaluated on the initial input. Skip it to be consistent.
+    relres = sqrt(output.trace.fval(2:end))/norm_s;
+    iter = output.iterations;
+  end;
+  
+  % Cut or extend f to the correct length, if desired.
+  if ~isempty(Ls)
+    f=postpad(f,Ls);
+  else
+    Ls=L;
+  end;
+  
+  f=comp_sigreshape_post(f,Ls,0,[0; W]);
+  
+%  Subfunction to compute the objective function for the BFGS method.
+function [f,df]=objfun(x,g,a,M,s,lt);
+  c=comp_dgtreal(x,g,a,M,lt,0);
+  
+  inner=abs(c).^2-s;
+  f=norm(inner,'fro')^2;
+  
+  df=4*real(conj(comp_idgtreal(inner.*c,g,a,M,lt,0)));
+
diff --git a/inst/gabor/iwmdct.m b/inst/gabor/iwmdct.m
new file mode 100644
index 0000000..4f1fbad
--- /dev/null
+++ b/inst/gabor/iwmdct.m
@@ -0,0 +1,114 @@
+function [f,g]=iwmdct(c,g,Ls)
+%-*- texinfo -*-
+%@deftypefn {Function} iwmdct
+%@verbatim
+%IWMDCT  Inverse MDCT
+%   Usage:  f=iwmdct(c,g);
+%           f=iwmdct(c,g,Ls);
+%
+%   Input parameters:
+%         c     : M*N array of coefficients.
+%         g     : Window function.
+%         Ls    : Final length of function (optional)
+%   Output parameters:
+%         f     : Input data
+%
+%   IWMDCT(c,g) computes an inverse windowed MDCT with window g. The
+%   number of channels is deduced from the size of the coefficient array c.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%
+%   IWMDCT(f,g,Ls) does the same, but cuts or zero-extends the final
+%   result to length Ls.
+%
+%   [f,g]=IWMDCT(...) additionally outputs the window used in the
+%   transform. This is usefull if the window was generated from a
+%   description in a string or cell array.
+%
+%
+%   References:
+%     H. Boelcskei and F. Hlawatsch. Oversampled Wilson-type cosine modulated
+%     filter banks with linear phase. In Asilomar Conf. on Signals, Systems,
+%     and Computers, pages 998-1002, nov 1996.
+%     
+%     H. S. Malvar. Signal Processing with Lapped Transforms. Artech House
+%     Publishers, 1992.
+%     
+%     J. P. Princen and A. B. Bradley. Analysis/synthesis filter bank design
+%     based on time domain aliasing cancellation. IEEE Transactions on
+%     Acoustics, Speech, and Signal Processing, ASSP-34(5):1153-1161, 1986.
+%     
+%     J. P. Princen, A. W. Johnson, and A. B. Bradley. Subband/transform
+%     coding using filter bank designs based on time domain aliasing
+%     cancellation. Proceedings - ICASSP, IEEE International Conference on
+%     Acoustics, Speech and Signal Processing, pages 2161-2164, 1987.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/iwmdct.php}
+%@seealso{wmdct, wilwin, dgt, wildual, wilorth}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_WMDCT
+
+error(nargchk(2,3,nargin));
+
+wasrow=0;
+if isnumeric(g)
+  if size(g,2)>1
+    if size(g,1)>1
+      error('g must be a vector');
+    else
+      % g was a row vector.
+      g=g(:);
+      
+      % If the input window is a row vector, and the dimension of c is
+      % equal to two, the output signal will also
+      % be a row vector.
+      if ndims(c)==2
+        wasrow=1;
+      end;
+    end;
+  end;
+end;
+
+M=size(c,1);
+N=size(c,2);
+W=size(c,3);
+
+a=M;
+L=M*N;
+
+assert_L(L,0,L,a,2*M,'IWMDCT');
+
+g=wilwin(g,M,L,'IWMDCT');
+
+f=comp_idwiltiii(c,g);
+
+% Check if Ls was specified.
+if nargin==3
+  f=postpad(f,Ls);
+else
+  Ls=L;
+end;
+
+f=comp_sigreshape_post(f,Ls,wasrow,[0; W]);
+
+
diff --git a/inst/gabor/iwmdct2.m b/inst/gabor/iwmdct2.m
new file mode 100644
index 0000000..165c3cd
--- /dev/null
+++ b/inst/gabor/iwmdct2.m
@@ -0,0 +1,129 @@
+function [f]=iwmdct2(c,g1,p3,p4)
+%-*- texinfo -*-
+%@deftypefn {Function} iwmdct2
+%@verbatim
+%IWMDCT2  2D Inverse windowed MDCT transform
+%   Usage: f=iwmdct2(c,g);
+%          f=iwmdct2(c,g1,g2);
+%          f=iwmdct2(c,g1,g2,Ls);
+%
+%   Input parameters:
+%         c       : Array of coefficients.
+%         g,g1,g2 : Window functions.
+%         Ls      : Size of reconstructed signal.
+%   Output parameters:
+%         f       : Output data, matrix.
+%
+%   IWMDCT2(c,g) calculates a separable two dimensional inverse WMDCT
+%   transform of the input coefficients c using the window g. The number of
+%   channels is deduced from the size of the coefficients c.
+%
+%   IWMDCT2(c,g1,g2) does the same using the window g1 along the first
+%   dimension, and window g2 along the second dimension.
+%
+%   IWMDCT2(c,g1,g2,Ls) cuts the signal to size Ls after the transform
+%   is done.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/iwmdct2.php}
+%@seealso{wmdct2, dgt2, wildual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+
+error(nargchk(2,4,nargin));
+
+Ls=[];
+
+switch nargin
+  case 2
+    g2=g1;
+  case 3
+    if prod(size(p3))>2
+      % Two windows was specified.
+      g2=p3;
+    else
+      g2=g1;
+      Ls=p3;
+    end;
+  case 4
+    g2=p3;
+    Ls=p4;
+end;
+  
+
+if ndims(c)<4 || ndims(c)>5
+  error('c must be 4 or 5 dimensional.');
+end;
+
+M1=size(c,1);
+N1=size(c,2);
+M2=size(c,3);
+N2=size(c,4);
+W=size(c,5);
+
+L1=M1*N1;
+L2=M2*N2;
+
+[g1,info]=wilwin(g1,M1,L1,'IWMDCT2');
+[g2,info]=wilwin(g2,M2,L2,'IWMDCT2');
+
+% If input is real, and window is real, output must be real as well.
+inputwasreal = (isreal(g1) && isreal(g2) && isreal(c));
+
+
+if isempty(Ls)
+  Ls(1)=L1;
+  Ls(2)=L2;
+else
+  Ls=bsxfun(@times,Ls,[1 1]);
+end;
+
+% --- first dimension
+
+% Change c to correct shape.
+c=reshape(c,M1,N1,L2*W);
+
+c=comp_idwiltiii(c,g1);
+
+c=postpad(c,Ls(1));
+
+c=reshape(c,Ls(1),L2,W);
+
+c=permute(c,[2,1,3]);
+
+% --- second dimension
+
+% Change c to correct shape.
+c=reshape(c,M2,N2,Ls(1)*W);
+
+c=comp_idwiltiii(c,g2);
+
+c=postpad(c,Ls(2));
+
+c=reshape(c,Ls(2),Ls(1),W);
+
+f=permute(c,[2,1,3]);
+
+% Clean signal if it is known to be real
+if inputwasreal
+  f=real(f);
+end;
+
+
diff --git a/inst/gabor/izak.m b/inst/gabor/izak.m
new file mode 100644
index 0000000..1a62b36
--- /dev/null
+++ b/inst/gabor/izak.m
@@ -0,0 +1,63 @@
+function f=izak(c);
+%-*- texinfo -*-
+%@deftypefn {Function} izak
+%@verbatim
+%IZAK  Inverse Zak transform
+%   Usage:  f=izak(c);
+%
+%   IZAK(c) computes the inverse Zak transform of c. The parameter of
+%   the Zak transform is deduced from the size of c.
+%
+%
+%   References:
+%     A. J. E. M. Janssen. Duality and biorthogonality for discrete-time
+%     Weyl-Heisenberg frames. Unclassified report, Philips Electronics,
+%     002/94.
+%     
+%     H. Boelcskei and F. Hlawatsch. Discrete Zak transforms, polyphase
+%     transforms, and applications. IEEE Trans. Signal Process.,
+%     45(4):851-866, april 1997.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/izak.php}
+%@seealso{zak}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_ZAK
+%   REFERENCE: OK
+
+error(nargchk(1,1,nargin));
+
+a=size(c,1);
+N=size(c,2);
+W=size(c,3);
+
+L=a*N;
+
+% Create output matrix.
+f=zeros(L,W,assert_classname(c));
+
+for ii=1:W
+  % Iterate through third dimension of c.
+  % We use a normalized DFT, as this gives the correct normalization
+  % of the Zak transform.
+  f(:,ii)=reshape(idft(c(:,:,ii),[],2),L,1);
+end;
+
diff --git a/inst/gabor/latticetype2matrix.m b/inst/gabor/latticetype2matrix.m
new file mode 100644
index 0000000..6c7f005
--- /dev/null
+++ b/inst/gabor/latticetype2matrix.m
@@ -0,0 +1,54 @@
+function V=latticetype2matrix(L,a,M,lt);
+%-*- texinfo -*-
+%@deftypefn {Function} latticetype2matrix
+%@verbatim
+%LATTICETYPE2MATRIX  Convert lattice description to matrix form
+%   Usage: V=latticetype2matrix(L,a,M,lt);
+%
+%   V=LATTICETYPE2MATRIX(L,a,M,lt) converts a standard description of a
+%   lattice using the a, M and lt parameters into a 2x2
+%   integer matrix description. The conversion is only valid for the
+%   specified transform length L.
+%
+%   The output will be in lower triangular Hemite normal form.
+%
+%   For more information, see
+%   http://en.wikipedia.org/wiki/Hermite_normal_form.
+%
+%   An example:
+%
+%     V = latticetype2matrix(120,10,12,[1 2])
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/latticetype2matrix.php}
+%@seealso{matrix2latticetype}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+L2=dgtlength(L,a,M,lt);
+
+if L~=L2
+    error('%s: Invalid transform length.',upper(mfilename));
+end;
+
+b=L/M;
+s=b/lt(2)*lt(1);
+V=[a 0;...
+   s b];
+
+
diff --git a/inst/gabor/longpar.m b/inst/gabor/longpar.m
new file mode 100644
index 0000000..e9e7a15
--- /dev/null
+++ b/inst/gabor/longpar.m
@@ -0,0 +1,96 @@
+function [L,tfr]=longpar(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} longpar
+%@verbatim
+%LONGPAR  Parameters for LONG windows
+%   Usage:  [L,tfr]=longpar(Ls,a,M);
+%           [L,tfr]=longpar('dgt',Ls,a,M);
+%           [L,tfr]=longpar('dwilt',Ls,M);
+%           [L,tfr]=longpar('wmdct',Ls,M);
+%
+%   [L,tfr]=LONGPAR(Ls,a,M) or [L,tfr]=LONGPAR('dgt',Ls,a,M) calculates the 
+%   minimal transform length L for a DGT of a signal of length Ls with
+%   parameters a and M. L is always larger than Ls. The parameters tfr*
+%   describes the time-to-frequency ratio of the chosen lattice.
+%
+%   An example can most easily describe the use of LONGPAR. Assume that
+%   we wish to perform Gabor analysis of an input signal f with a 
+%   suitable Gaussian window and lattice given by a and M. The following
+%   code will always work:
+%
+%     Ls=length(f);
+%     [L,tfr]=longpar(Ls,a,M);
+%     g=pgauss(L,tfr);
+%     c=dgt(f,g,a,M);
+%
+%   [L,tfr]=LONGPAR('dwilt',Ls,M) and [L,tfr]=LONGPAR('wmdct',Ls,M) will
+%   do the same for a Wilson/WMDCT basis with M channels.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/longpar.php}
+%@seealso{dgt, dwilt, pgauss, psech, pherm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(3,4,nargin));
+
+if ischar(varargin{1})
+    ttype=varargin{1};
+    pstart=2;
+else
+    ttype='dgt';
+    pstart=1;
+end;
+
+Ls=varargin{pstart};
+
+if (numel(Ls)~=1 || ~isnumeric(Ls))
+  error('Ls must be a scalar.');
+end;
+if rem(Ls,1)~=0
+  error('Ls must be an integer.');
+end;
+
+
+switch(lower(ttype))
+    case 'dgt'
+        if nargin<pstart+2
+            error('Too few input parameters for DGT type.');
+        end;
+        
+        a=varargin{pstart+1};
+        M=varargin{pstart+2};
+        
+        smallest_transform=lcm(a,M);
+        L=ceil(Ls/smallest_transform)*smallest_transform;
+        b=L/M;
+        tfr=a/b;
+    case {'dwilt','wmdct'}
+        if nargin<pstart+1
+            error('Too few input parameters for DWILT/WMDCT type.');
+        end;
+        M=varargin{pstart+1};
+
+        smallest_transform=2*M;
+        L=ceil(Ls/smallest_transform)*smallest_transform;
+        b=L/(2*M);
+        tfr=M/b;
+    otherwise
+        error('Unknown transform type.');
+end;
+
diff --git a/inst/gabor/matrix2latticetype.m b/inst/gabor/matrix2latticetype.m
new file mode 100644
index 0000000..5520821
--- /dev/null
+++ b/inst/gabor/matrix2latticetype.m
@@ -0,0 +1,145 @@
+function [a,M,lt] = matrix2latticetype(L,V);
+%-*- texinfo -*-
+%@deftypefn {Function} matrix2latticetype
+%@verbatim
+%MATRIX2LATTICETYPE  Convert matrix form to standard lattice description
+%   Usage: [a,M,lt] = matrix2latticetype(L,V);
+%
+%   [a,M,lt]=MATRIX2LATTICETYPE(L,V) converts a 2x2 integer matrix
+%   description into the standard description of a lattice using the a,
+%   M and lt. The conversion is only valid for the specified transform
+%   length L.
+%
+%   The lattice type lt is a 1 x2 vector [lt_1,lt_2] denoting an
+%   irreducible fraction lt_1/lt_2. This fraction describes the distance
+%   in frequency (counted in frequency channels) that each coefficient is
+%   offset when moving in time by the time-shift of a. Some examples:
+%   lt=[0 1] defines a square lattice, lt=[1 2] defines the quinqux
+%   (almost hexagonal) lattice, lt=[1 3] describes a lattice with a
+%   1/3 frequency offset for each time shift and so forth.
+%
+%   An example:
+%
+%     [a,M,lt] = matrix2latticetype(120,[10 0; 5 10])
+%
+%   Coefficient layout:
+%   -------------------
+%
+%   The following code generates plots which show the coefficient layout
+%   and enumeration of the first 4 lattices in the time-frequecy plane:
+%
+%     a=6;
+%     M=6;
+%     L=36;
+%     b=L/M;
+%     N=L/a;
+%     cw=3;
+%     ftz=12;
+%     
+%     [x,y]=meshgrid(a*(0:N-1),b*(0:M-1));
+%
+%     lt1=[0 1 1 2];
+%     lt2=[1 2 3 3];
+%
+%     for fignum=1:4
+%       subplot(2,2,fignum);
+%       z=y;
+%       if lt2(fignum)>0
+%         z=z+mod(lt1(fignum)*x/lt2(fignum),b);
+%       end;
+%       for ii=1:M*N
+%         text(x(ii)-cw/4,z(ii),sprintf('%2.0i',ii),'Fontsize',ftz);
+%         rectangle('Curvature',[1 1], 'Position',[x(ii)-cw/2,z(ii)-cw/2,cw,cw]);
+%       end;
+%       axis([-cw L -cw L]);
+%       axis('square');
+%       title(sprintf('lt=[%i %i]',lt1(fignum),lt2(fignum)),'Fontsize',ftz);
+%     end;
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/matrix2latticetype.php}
+%@seealso{latticetype2matrix}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% The Hermite normal form code was originally written by Arno J. van Leest, 1999.
+% Positive determinant by Peter L. Soendergaard, 2004.
+% Unique form by Christoph Wiesmeyr, 2012
+
+if nargin~=2
+  error('%s: Wrong number of input arguments.',upper(mfilename));
+end;
+
+% Check if matrix has correct size.
+if size(V,1)~=2 || size(V,2)~=2
+  error('%s: V must be a 2x2 matrix.',upper(mfilename));
+end;
+
+% Integer values
+if norm(mod(V,1))~=0
+  error('%s: V must have all integer values.',upper(mfilename));
+end;
+
+% Convert to Arnos normal form.
+gcd1=gcd(V(1,1),V(1,2));
+gcd2=gcd(V(2,1),V(2,2));
+
+A=zeros(2);
+A(1,:)=V(1,:)/gcd1;
+A(2,:)=V(2,:)/gcd2;
+
+D = det(A);
+
+% Exchange vectors if determinant is negative.
+if D<0
+  D=-D;
+  A=fliplr(A);
+end;
+
+[g,h0,h1] = gcd(A(1,1),A(1,2));
+
+x = A(2,:)*[h0;h1];
+
+x = mod(x,D);
+
+% Octave does not automatically round the double division to integer
+% numbers, and this causes confusion later in the GCD computations. 
+a = gcd1;
+b = round(D*gcd2);
+s = round(x*gcd2);
+
+% compute nabs format of <a,s>
+b1 = gcd(s*lcm(a,L)/a,L);
+[a,k1] = gcd(a,L);
+s = k1*s;
+
+% update b
+b = gcd(b,gcd(b1,L));
+
+% update s
+s = mod(s,b);
+
+% conversion from nabs to latticetype
+M=L/b;
+
+k=gcd(s,b);
+lt=[s/k b/k];
+
+
+
+
diff --git a/inst/gabor/noshearlength.m b/inst/gabor/noshearlength.m
new file mode 100644
index 0000000..321dde8
--- /dev/null
+++ b/inst/gabor/noshearlength.m
@@ -0,0 +1,62 @@
+function L=noshearlength(Ls,a,M,lt)
+%-*- texinfo -*-
+%@deftypefn {Function} noshearlength
+%@verbatim
+%NOSHEARLENGTH  Transform length that does not require a frequency shear
+%   Usage: L=noshearlength(Ls,a,M,lt)
+%
+%   NOSHEARLENGTH(Ls,a,M,lt) computes the next larger transform length
+%   bigger or equal to Ls for which the shear algorithm does not require
+%   a frequency side shear for a non-separable Gabor system specified by
+%   a, M and lt. 
+%
+%   This property makes computation of the canonical dual and tight Gabor
+%   windows GABDUAL and GABTIGHT and the DGT for a full length window
+%   faster, if this transform length is choosen.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/noshearlength.php}
+%@seealso{matrix2latticetype, dgt, gabdual, gabtight}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Lmin=dgtlength(1,a,M,lt);
+
+if lt(1)==0
+    Lsmallest=Lmin;
+else
+    c=gcd(a,M);
+    
+    % if lt(1)>0 then ks is everything in c which is relatively prime to
+    % lt(2)
+        
+    kmax=c;
+    while 1
+        z=gcd(kmax,lt(2));
+        if z==1
+            break;
+        end;
+        kmax=kmax/z;
+    end;
+
+    Lsmallest=Lmin*c./kmax;
+
+end;
+
+L=ceil(Ls/Lsmallest)*Lsmallest;
+
diff --git a/inst/gabor/phaselock.m b/inst/gabor/phaselock.m
new file mode 100644
index 0000000..b20179f
--- /dev/null
+++ b/inst/gabor/phaselock.m
@@ -0,0 +1,103 @@
+function c = phaselock(c,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} phaselock
+%@verbatim
+%PHASELOCK  Phaselock Gabor coefficients
+%   Usage:  c=phaselock(c,a);
+%
+%   PHASELOCK(c,a) phaselocks the Gabor coefficients c. The coefficients
+%   must have been obtained from a DGT with parameter a.
+%
+%   Phaselocking the coefficients modifies them so as if they were obtained
+%   from a time-invariant Gabor system. A filter bank produces phase locked
+%   coefficients.
+%
+%   Phaselocking of Gabor coefficients correspond to the following transform:
+%   Consider a signal f of length L and define N=L/a.
+%   The output from c=PHASELOCK(dgt(f,g,a,M),a) is given by
+%
+%                  L-1 
+%     c(m+1,n+1) = sum f(l+1)*exp(-2*pi*i*m*(l-n*a)/M)*conj(g(l-a*n+1)), 
+%                  l=0  
+%
+%   where m=0,...,M-1 and n=0,...,N-1 and l-an is computed modulo L.
+%
+%   PHASELOCK(c,a,'lt',lt) does the same for a non-separable lattice
+%   specified by lt. Please see the help of MATRIX2LATTICETYPE for a
+%   precise description of the parameter lt.
+%
+%
+%   References:
+%     M. Puckette. Phase-locked vocoder. Applications of Signal Processing to
+%     Audio and Acoustics, 1995., IEEE ASSP Workshop on, pages 222 -225,
+%     1995.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/phaselock.php}
+%@seealso{dgt, phaseunlock, symphase}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR:    Christoph Wiesmeyr, Peter L. Soendergaard.
+%   TESTING:   test_phaselock
+%   REFERENCE: OK
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.lt=[0 1];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if  (prod(size(a))~=1 || ~isnumeric(a))
+  error('a must be a scalar');
+end;
+
+if rem(a,1)~=0
+  error('a must be an integer');
+end;
+
+M=size(c,1);
+N=size(c,2);
+L=N*a;
+b=L/M;
+
+if rem(b,1)~=0
+  error('Lattice error. The a parameter is probably incorrect.');
+end;
+
+TimeInd = (0:(N-1))*a;
+FreqInd = (0:(M-1));
+
+phase = FreqInd'*TimeInd;
+phase = mod(phase,M);
+phase = exp(2*1i*pi*phase/M);
+
+if kv.lt(1)>0 
+    % truly non-separable case
+    
+    for n=0:(N-1)
+        w = mod(n*kv.lt(1)/kv.lt(2),1);
+        phase(:,n+1) = phase(:,n+1)*exp(2*pi*1i*a*w*n/M);
+    end
+end
+
+% Handle multisignals
+c=bsxfun(@times,c,phase);
+
+
diff --git a/inst/gabor/phaseplot.m b/inst/gabor/phaseplot.m
new file mode 100644
index 0000000..4f76b46
--- /dev/null
+++ b/inst/gabor/phaseplot.m
@@ -0,0 +1,191 @@
+function []=phaseplot(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} phaseplot
+%@verbatim
+%PHASEPLOT  Phase plot
+%   Usage: phaseplot(f,op1,op2, ... );
+%          phaseplot(f,fs,op1,op2, ... );
+%
+%   PHASEPLOT(f) plots the phase of f using a DGT.
+%
+%   PHASEPLOT(f,fs) does the same for a signal with sampling rate fs Hz.
+%
+%   PHASEPLOT should only be used for short signals (shorter than the
+%   resolution of the screen), as there will otherwise be some visual
+%   aliasing, such that very fast changing areas will look very smooth.
+%   PHASEPLOT always calculates the phase of the full time/frequency plane
+%   (as opposed to SGRAM), and you therefore risk running out of memory
+%   for long signals.
+%
+%   PHASEPLOT takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'tfr',v     Set the ratio of frequency resolution to time resolution.
+%                 A value v=1 is the default. Setting v>1 will give better
+%                 frequency resolution at the expense of a worse time
+%                 resolution. A value of 0<v<1 will do the opposite.
+%  
+%     'wlen',s    Window length. Specifies the length of the window
+%                 measured in samples. See help of PGAUSS on the exact
+%                 details of the window length.
+%  
+%     'nf'        Display negative frequencies, with the zero-frequency
+%                 centered in the middle. For real signals, this will just
+%                 mirror the upper half plane. This is standard for complex
+%                 signals.
+%  
+%     'tc'        Time centering. Move the beginning of the signal to the
+%                 middle of the plot. This is usefull for visualizing the
+%                 window functions of the toolbox.
+%  
+%     'thr',r     Keep the coefficients with a magnitude larger than r times the
+%                 largest magnitude. Set the phase of the rest of the
+%                 coefficients to zero. This is useful, because for small
+%                 amplitude the phase values can be meaningless.
+%  
+%     'timeinv'   Display the phase as computed by a time-invariant
+%                 DGT. This is the default.
+%  
+%     'freqinv'   Display the phase as computed by a frequency-invariant
+%                 DGT.
+%  
+%     'fmax',y    Display y as the highest frequency.
+%
+%     'colorbar'   Display the colorbar. This is the default.
+%    
+%     'nocolorbar'  Do not display the colorbar.
+%
+%   For the best result when using PHASEPLOT, use a circulant color
+%   map, for instance hsv.
+%
+%   Examples:
+%   ---------
+%
+%   The following code shows the phaseplot of a
+%   periodic, hyperbolic secant visualized using the hsv colormap:
+%
+%     phaseplot(psech(200),'tc','nf');
+%     colormap(hsv);
+%
+%   The following phaseplot shows the phase of white, Gaussian noise:
+%
+%     phaseplot(randn(200,1));
+%     colormap(hsv);
+% 
+%
+%
+%   References:
+%     R. Carmona, W. Hwang, and B. Torresani. Practical Time-Frequency
+%     Analysis: continuous wavelet and Gabor transforms, with an
+%     implementation in S, volume 9 of Wavelet Analysis and its Applications.
+%     Academic Press, San Diego, 1998.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/phaseplot.php}
+%@seealso{phaselock, demo_phaseplot}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: NA
+
+if nargin<1
+  error('Too few input arguments.');
+end;
+
+if sum(size(f)>1)>1
+  error('Input must be a vector.');
+end;
+
+definput.import={'ltfattranslate','normalize','tfplot'};
+% Override the setting from tfplot, because phaseplot only uses the 'lin'
+% plotting.
+definput.flags.log={'lin'};
+definput.importdefaults={'lin'};
+
+% Define initial value for flags and key/value pairs.
+definput.flags.wlen={'nowlen','wlen'};
+definput.flags.tc={'notc','tc'};
+
+definput.flags.fmax={'nofmax','fmax'};
+definput.flags.phase={'timeinv','freqinv'};
+
+if isreal(f)
+  definput.flags.posfreq={'posfreq','nf'};
+else
+  definput.flags.posfreq={'nf','posfreq'};
+end;
+
+definput.keyvals.tfr=1;
+definput.keyvals.wlen=0;
+definput.keyvals.fmax=[];
+definput.keyvals.thr=[];
+
+[flags,kv,fs]=ltfatarghelper({'fs'},definput,varargin);
+
+% Downsample
+if ~isempty(kv.fmax)
+  if ~isempty(fs)
+    resamp=kv.fmax*2/fs;
+  else
+    resamp=kv.fmax*2/length(f);
+  end;
+
+  f=fftresample(f,round(length(f)*resamp));
+  kv.fs=2*kv.fmax;
+end;
+
+% Always do the full STFT
+L=length(f);
+a=1;
+b=1;
+M=L;
+N=L;
+
+% Set an explicit window length, if this was specified.
+if flags.do_wlen
+  kv.tfr=kv.wlen^2/L;
+end;
+
+g={'gauss',kv.tfr,flags.norm};
+
+if flags.do_nf
+  coef=dgt(f,g,a,M,flags.phase);
+else
+  coef=dgtreal(f,g,a,M,flags.phase);
+end;
+
+if ~isempty(kv.thr)
+  % keep only the largest coefficients.
+  maxc=max(abs(coef(:)));
+  mask=abs(coef)<maxc*kv.thr;
+  coef(mask)=0;
+end
+
+coef = angle(coef);
+
+if flags.do_nf
+  plotdgt(coef,a,'argimport',flags,kv);
+else
+  plotdgtreal(coef,a,M,'argimport',flags,kv);
+end;
+
+if nargout>0
+  varargout={coef};
+end;
+
diff --git a/inst/gabor/phaseunlock.m b/inst/gabor/phaseunlock.m
new file mode 100644
index 0000000..91ff6e6
--- /dev/null
+++ b/inst/gabor/phaseunlock.m
@@ -0,0 +1,88 @@
+function c = phaseunlock(c,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} phaseunlock
+%@verbatim
+%PHASEUNLOCK  Undo phase lock of Gabor coefficients
+%   Usage:  c=phaseunlock(c,a);
+%
+%   PHASEUNLOCK(c,a) removes phase locking from the Gabor coefficients c.
+%   The coefficient must have been obtained from a DGT with parameter a.
+%
+%   Phaselocking the coefficients modifies them so as if they were obtained
+%   from a time-invariant Gabor system. A filter bank produces phase locked
+%   coeffiecients. 
+%
+%
+%   References:
+%     M. Puckette. Phase-locked vocoder. Applications of Signal Processing to
+%     Audio and Acoustics, 1995., IEEE ASSP Workshop on, pages 222 -225,
+%     1995.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/phaseunlock.php}
+%@seealso{dgt, phaselock, symphase}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR:    Peter Balazs, Peter L. Soendergaard.
+%   TESTING:   OK
+%   REFERENCE: OK
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.lt=[0 1];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if  (prod(size(a))~=1 || ~isnumeric(a))
+  error('a must be a scalar');
+end;
+
+if rem(a,1)~=0
+  error('a must be an integer');
+end;
+
+M=size(c,1);
+N=size(c,2);
+L=N*a;
+b=L/M;
+
+if rem(b,1)~=0
+  error('Lattice error. The a parameter is probably incorrect.');
+end;
+
+TimeInd = (0:(N-1))*a;
+FreqInd = (0:(M-1));
+
+phase = FreqInd'*TimeInd;
+phase = mod(phase,M);
+phase = exp(-2*1i*pi*phase/M);
+
+if kv.lt(1)>0 
+    % truly non-separable case
+    
+    for n=0:(N-1)
+        w = mod(n*kv.lt(1)/kv.lt(2),1);
+        phase(:,n+1) = phase(:,n+1)*exp(-2*pi*1i*a*w*n/M);
+    end
+end
+
+% Handle multisignals
+c=bsxfun(@times,c,phase);
+
diff --git a/inst/gabor/plotdgt.m b/inst/gabor/plotdgt.m
new file mode 100644
index 0000000..4a3ddff
--- /dev/null
+++ b/inst/gabor/plotdgt.m
@@ -0,0 +1,76 @@
+function coef=plotdgt(coef,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotdgt
+%@verbatim
+%PLOTDGT  Plot DGT coefficients
+%   Usage: plotdgt(coef,a);
+%          plotdgt(coef,a,fs);
+%          plotdgt(coef,a,fs,dynrange);
+%
+%   PLOTDGT(coef,a) plots the Gabor coefficients coef. The coefficients
+%   must have been produced with a time shift of a.
+%
+%   PLOTDGT(coef,a,fs) does the same assuming a sampling rate of
+%   fs Hz of the original signal.
+%
+%   PLOTDGT(coef,a,fs,dynrange) additionally limits the dynamic range.
+%
+%   The figure generated by this function places the zero-frequency in
+%   the center of the y-axis, with positive frequencies above and
+%   negative frequencies below.
+%   
+%   C=PLOTDGT(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar
+%   functions will create the plot. This is useful for custom
+%   post-processing of the image data.
+%
+%   PLOTDGT supports all the optional parameters of TFPLOT. Please see
+%   the help of TFPLOT for an exhaustive list.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/plotdgt.php}
+%@seealso{dgt, tfplot, sgram, plotdgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+M=size(coef,1);
+
+% Move zero frequency to the center and Nyquist frequency to the top.
+if rem(M,2)==0
+  coef=circshift(coef,M/2-1);
+  yr=[-1+2/M, 1];
+else
+  coef=circshift(coef,(M-1)/2);
+  yr=[-1+2/M, 1-2/M];
+end;
+
+coef=tfplot(coef,a,yr,'argimport',flags,kv);
+
+
diff --git a/inst/gabor/plotdgtreal.m b/inst/gabor/plotdgtreal.m
new file mode 100644
index 0000000..f12f1c4
--- /dev/null
+++ b/inst/gabor/plotdgtreal.m
@@ -0,0 +1,67 @@
+function coef=plotdgtreal(coef,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotdgtreal
+%@verbatim
+%PLOTDGTREAL  Plot DGTREAL coefficients
+%   Usage: plotdgtreal(coef,a,M);
+%          plotdgtreal(coef,a,M,fs);
+%          plotdgtreal(coef,a,M,fs,dynrange);
+%
+%   PLOTDGTREAL(coef,a,M) plots Gabor coefficient from DGTREAL. The
+%   parameters a and M must match those from the call to DGTREAL.
+%
+%   PLOTDGTREAL(coef,a,M,fs) does the same assuming a sampling rate of fs*
+%   Hz of the original signal.
+%
+%   PLOTDGTREAL(coef,a,M,fs,dynrange) additionally limits the dynamic
+%   range.
+%
+%   C=PLOTDGTREAL(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar
+%   functions will create the plot. This is usefull for custom
+%   post-processing of the image data.
+%
+%   PLOTDGTREAL supports all the optional parameters of TFPLOT. Please
+%   see the help of TFPLOT for an exhaustive list.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/plotdgtreal.php}
+%@seealso{dgtreal, tfplot, sgram, plotdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+if rem(M,2)==0
+  yr=[0,1];
+else
+  yr=[0,1-2/M];
+end;
+
+coef=tfplot(coef,a,yr,'argimport',flags,kv);
+
diff --git a/inst/gabor/plotdwilt.m b/inst/gabor/plotdwilt.m
new file mode 100644
index 0000000..cb501fd
--- /dev/null
+++ b/inst/gabor/plotdwilt.m
@@ -0,0 +1,79 @@
+function plotdwilt(coef,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotdwilt
+%@verbatim
+%PLOTDWILT  Plot DWILT coefficients
+%   Usage: plotdwilt(coef,);
+%          plotdwilt(coef,fs);
+%          plotdwilt(coef,fs,dynrange);
+%
+%   PLOTDWILT(coef) will plot coefficients from DWILT.
+%
+%   PLOTDWILT(coef,fs) will do the same assuming a sampling rate of fs*
+%   Hz of the original signal. Since a Wilson representation does not
+%   contain coefficients for all positions on a rectangular TF-grid, there
+%   will be visible 'holes' among the lowest (DC) and highest (Nyquist rate)
+%   coefficients. See the help on WIL2RECT.
+%
+%   PLOTDWILT(coef,fs,dynrange) will additionally limit the dynamic
+%   range.
+%   
+%   PLOTDWILT supports all the optional parameters of TFPLOT. Please
+%   see the help of TFPLOT for an exhaustive list.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/plotdwilt.php}
+%@seealso{dwilt, tfplot, sgram, wil2rect}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+M=size(coef,1)/2;
+
+% Find smallest value in the coefficients, because we will be inserting
+% zeros, which messes up the dynamic range. Set a minimum value of the
+% dynamic range based on this
+maxc=max(abs(coef(:)));
+minc=min(abs(coef(:)));
+if isempty(kv.dynrange)
+  if flags.do_db
+    kv.dynrange=20*log10(maxc/minc);
+  end;
+  if flags.do_dbsq
+    kv.dynrange=10*log10(maxc/minc);
+  end;
+end;
+
+coef=wil2rect(coef);
+
+yr=[0,1];
+
+tfplot(coef,M,yr,'argimport',flags,kv);
+
+
diff --git a/inst/gabor/plotwmdct.m b/inst/gabor/plotwmdct.m
new file mode 100644
index 0000000..6f68398
--- /dev/null
+++ b/inst/gabor/plotwmdct.m
@@ -0,0 +1,60 @@
+function plotwmdct(coef,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotwmdct
+%@verbatim
+%PLOTWMDCT  Plot WMDCT coefficients
+%   Usage: plotwmdct(coef);
+%          plotwmdct(coef,fs);
+%          plotwmdct(coef,fs,dynrange);
+%
+%   PLOTWMDCT(coef) plots coefficients from WMDCT.
+%
+%   PLOTWMDCT(coef,fs) does the same assuming a sampling rate of
+%   fs Hz of the original signal.
+%
+%   PLOTWMDCT(coef,fs,dynrange) additionally limits the dynamic
+%   range.
+%   
+%   PLOTWMDCT supports all the optional parameters of TFPLOT. Please
+%   see the help of TFPLOT for an exhaustive list.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/plotwmdct.php}
+%@seealso{wmdct, tfplot, sgram, plotdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+M=size(coef,1);
+
+yr=[.5/M, 1-.5/M];
+
+tfplot(coef,M,yr,'argimport',flags,kv);
+
+
diff --git a/inst/gabor/proj_dual.m b/inst/gabor/proj_dual.m
new file mode 100644
index 0000000..e736ba4
--- /dev/null
+++ b/inst/gabor/proj_dual.m
@@ -0,0 +1,117 @@
+function [ sol ] = proj_dual( x,~, param )
+%-*- texinfo -*-
+%@deftypefn {Function} proj_dual
+%@verbatim
+%PROJ_DUAL projection onto the dual windows space
+%   Usage:  sol=proj_proj(x, ~, param)
+%           [sol, infos]=proj_b2(x, ~, param)
+%
+%   Input parameters:
+%         x     : Input signal.
+%         param : Structure of optional parameters.
+%   Output parameters:
+%         sol   : Solution.
+%         infos : Structure summarizing informations at convergence
+%
+%   PROJ_DUAL(x,~,param) solves:
+%
+%      sol = argmin_{z} ||x - z||_2^2   s.t.  A z=y
+%
+%   param is a Matlab structure containing the following fields:
+%
+%    param.y : measurements (default: 0).
+%
+%    param.A : Matrix (default: Id).
+%
+%    param.AAtinv : (A A^*)^(-1) Define this parameter to speed up computation.
+%
+%    param.verbose : 0 no log, 1 a summary at convergence, 2 print main
+%     steps (default: 1)
+%
+%
+%   infos is a Matlab structure containing the following fields:
+%
+%    infos.algo : Algorithm used
+%
+%    infos.iter : Number of iteration
+%
+%    infos.time : Time of execution of the function in sec.
+%
+%    infos.final_eval : Final evaluation of the function
+%
+%    infos.crit : Stopping critterion used 
+%
+%    infos.residue : Final residue  
+%
+%
+%   Rem: The input "~" is useless but needed for compatibility issue.
+%
+%
+%   References:
+%     M.-J. Fadili and J.-L. Starck. Monotone operator splitting for
+%     optimization problems in sparse recovery. In Image Processing (ICIP),
+%     2009 16th IEEE International Conference on, pages 1461-1464. IEEE,
+%     2009.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/proj_dual.php}
+%@seealso{prox_l2, proj_b1}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%
+% Author: Nathanael Perraudin
+% Date: Feb 20, 2013
+%
+
+% Start the time counter
+t1 = tic;
+
+% Optional input arguments
+if ~isfield(param, 'y'), param.y = 0; end
+if ~isfield(param, 'A'), param.A = eye(length(x)); end
+if ~isfield(param, 'AAtinv'), param.AAtinv=pinv(A*At); end
+if ~isfield(param, 'verbose'), param.verbose = 1; end
+
+
+% Projection  
+   
+sol = x - param.A'*param.AAtinv*(param.A*x-param.y);
+crit = 'TOL_EPS'; iter = 0; u = NaN;
+    
+
+
+% Log after the projection onto the L2-ball
+error=norm(param.y-param.A *sol );
+if param.verbose >= 1
+    fprintf(['  Proj. dual windows: ||y-Ax||_2 = %e,', ...
+        ' %s, iter = %i\n'],error , crit, iter);
+end
+
+% Infos about algorithm
+infos.algo=mfilename;
+infos.iter=iter;
+infos.final_eval=error;
+infos.crit=crit;
+infos.residue=u;
+infos.time=toc(t1);
+
+end
+
+
+
diff --git a/inst/gabor/projkern.m b/inst/gabor/projkern.m
new file mode 100644
index 0000000..e543e92
--- /dev/null
+++ b/inst/gabor/projkern.m
@@ -0,0 +1,89 @@
+function c=projkern(c,p2,p3,p4,p5);
+%-*- texinfo -*-
+%@deftypefn {Function} projkern
+%@verbatim
+%PROJKERN  Projection onto generating kernel space
+%   Usage:  cout=projkern(cin,a);
+%           cout=projkern(cin,g,a);
+%           cout=projkern(cin,ga,gs,a);
+%
+%   Input parameters:
+%         cin   : Input coefficients
+%         g     : analysis/synthesis window
+%         ga    : analysis window
+%         gs    : synthesis window
+%         a     : Length of time shift.
+%   Output parameters:
+%         cout  : Output coefficients
+%
+%   cout=PROJKERN(cin,a) projects a set of Gabor coefficients c onto the
+%   space of possible Gabor coefficients. This means that cin and cout*
+%   synthesize to the same signal. A tight window generated from a Gaussian
+%   will be used for both analysis and synthesis.
+%
+%   The rationale for this function is a follows: Because the coefficient
+%   space of a Gabor frame is larger than the signal space (since the frame
+%   is redundant) then there are many coefficients that correspond to the
+%   same signal.
+%
+%   Therefore, you might desire to work with the coefficients cin, but you
+%   are in reality working with cout.
+%
+%   cout=PROJKERN(cin,g,a) does the same, using the window g for analysis
+%   and synthesis.
+%
+%   cout=PROJKERN(cin,ga,gs,a) does the same, but for different analysis
+%   ga and synthesis gs windows.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/projkern.php}
+%@seealso{dgt, idgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(2,4,nargin));
+
+M=size(c,1);
+N=size(c,2);
+
+if nargin==2
+  a=p2;
+  L=a*N;
+  ga=gabtight(a,M,L);
+  gs=ga;
+end;
+
+if nargin==3;
+  ga=p2;
+  gs=p2;
+  a=p3;
+  L=a*N;
+end;
+
+if nargin==4;  
+  ga=p2;
+  gs=p3;
+  a=p4;
+  L=a*N;
+end;
+
+assert_squarelat(a,M,1,'PROJKERN');
+
+c=dgt(idgt(c,gs,a),ga,a,M);
+
+
diff --git a/inst/gabor/rect2wil.m b/inst/gabor/rect2wil.m
new file mode 100644
index 0000000..198601b
--- /dev/null
+++ b/inst/gabor/rect2wil.m
@@ -0,0 +1,58 @@
+function cout=rect2wil(cin);
+%-*- texinfo -*-
+%@deftypefn {Function} rect2wil
+%@verbatim
+%RECT2WIL  Inverse of WIL2RECT
+%   Usage:  c=rect2wil(c);
+%   
+%   RECT2WIL(c) takes Wilson coefficients processed by WIL2RECT and
+%   puts them back in the compact form used by DWILT and IDWILT. The
+%   coefficients can then be processed by IDWILT.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/rect2wil.php}
+%@seealso{wil2rect, dwilt, idwilt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+error(nargchk(1,1,nargin));
+  
+M=size(cin,1)-1;
+N=size(cin,2);
+W=size(cin,3);
+
+cout=zeros(2*M,N/2,W,assert_classname(cin));
+
+if rem(M,2)==0
+  for ii=0:N/2-1
+    cout(1:M+1  ,ii+1,:)=cin(1:M+1,2*ii+1,:);
+    cout(M+2:2*M,ii+1,:)=cin(2:M,2*ii+2,:);
+  end;
+else
+  for ii=0:N/2-1
+    cout(1:M    ,ii+1,:)=cin(1:M,2*ii+1,:);
+    cout(M+2:2*M,ii+1,:)=cin(2:M,2*ii+2,:);
+    cout(M+1    ,ii+1,:)=cin(M+1,2*ii+2,:);
+  end;  
+end;
+
+
diff --git a/inst/gabor/resgram.m b/inst/gabor/resgram.m
new file mode 100644
index 0000000..d73f44a
--- /dev/null
+++ b/inst/gabor/resgram.m
@@ -0,0 +1,236 @@
+function varargout=resgram(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} resgram
+%@verbatim
+%RESGRAM  Reassigned spectrogram plot
+%   Usage: resgram(f,op1,op2, ... );
+%          resgram(f,fs,op1,op2, ... );
+%
+%   RESGRAM(f) plots a reassigned spectrogram of f.
+%
+%   RESGRAM(f,fs) does the same for a signal with sampling rate fs*
+%   (sampled with fs samples per second).
+%
+%   Because reassigned spectrograms can have an extreme dynamical range,
+%   consider always using the 'dynrange' or 'clim' options (see below)
+%   in conjunction with the 'db' option (on by default). An example:
+%
+%     resgram(greasy,16000,'dynrange',70);
+%
+%   This will produce a reassigned spectrogram of the GREASY signal
+%   without drowning the interesting features in noise.
+%
+%   C=sgram(f, ... ) returns the image to be displayed as a matrix. Use this
+%   in conjunction with imwrite etc. These coefficients are *only* intended to
+%   be used by post-processing image tools. Reassignment should be done
+%   using the GABREASSIGN function instead.
+%
+%   RESGRAM accepts the following additional arguments:
+%
+%
+%     'dynrange',r  Limit the dynamical range to r by using a colormap in
+%                   the interval [chigh-r,chigh], where chigh is the highest
+%                   value in the plot. The default value of [] means to not
+%                   limit the dynamical range.
+%    
+%     'db'         Apply 20*log10 to the coefficients. This makes it possible to
+%                  see very weak phenomena, but it might show too much noise. A
+%                  logarithmic scale is more adapted to perception of sound.
+%                  This is the default.
+%
+%     'sharp',alpha
+%                  Set the sharpness of the plot. If alpha=0 the regular
+%                  spectrogram is obtained. alpha=1 means full
+%                  reassignment. Anything in between will produce a partially
+%                  sharpened picture. Default is alpha=1.
+%    
+%     'lin'        Show the energy of the coefficients on a linear scale.
+%    
+%     'tfr',v      Set the ratio of frequency resolution to time resolution.
+%                  A value v=1 is the default. Setting v>1 will give better
+%                  frequency resolution at the expense of a worse time
+%                  resolution. A value of 0<v<1 will do the opposite.
+%    
+%     'wlen',s     Window length. Specifies the length of the window
+%                  measured in samples. See help of PGAUSS on the exact
+%                  details of the window length.
+%
+%     'posfreq'    Display only the positive frequencies. This is the
+%                  default for real-valued signals.
+%    
+%     'nf'         Display negative frequencies, with the zero-frequency
+%                  centered in the middle. For real signals, this will just
+%                  mirror the upper half plane. This is standard for complex
+%                  signals.
+%    
+%     'tc'         Time centering. Move the beginning of the signal to the
+%                  middle of the plot. This is useful for visualizing the
+%                  window functions of the toolbox.
+%    
+%     'image'      Use imagesc to display the spectrogram. This is the
+%                  default.
+%    
+%     'clim',clim  Use a colormap ranging from clim(1) to clim(2). These
+%                  values are passed to imagesc. See the help on imagesc.
+%    
+%     'thr',r      Keep only the largest fraction r of the coefficients, and
+%                  set the rest to zero.
+%    
+%     'fmax',y     Display y as the highest frequency. Default value of []
+%                  means to use the Nyquist frequency.
+%    
+%     'xres',xres  Approximate number of pixels along x-axis / time.
+%                  The default value is 800
+%    
+%     'yres',yres  Approximate number of pixels along y-axis / frequency
+%                  The default value is 600
+%    
+%     'contour'    Do a contour plot to display the spectrogram.
+%           
+%     'surf'       Do a surf plot to display the spectrogram.
+%    
+%     'mesh'       Do a mesh plot to display the spectrogram.
+%    
+%     'colorbar'   Display the colorbar. This is the default.
+%    
+%     'nocolorbar'  Do not display the colorbar.
+%
+%   In addition to these parameters, sgram accepts any of the flags from
+%   NORMALIZE. The window used to calculate the spectrogram will be
+%   normalized as specified.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/resgram.php}
+%@seealso{sgram}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+% BUG: Setting the sharpness different from 1 produces a black line in the
+% middle of the plot.
+  
+if nargin<1
+  error('Too few input arguments.');
+end;
+
+if sum(size(f)>1)>1
+  error('Input must be a vector.');
+end;
+
+definput.import={'ltfattranslate','normalize','tfplot'};
+
+% Define initial value for flags and key/value pairs.
+definput.flags.wlen={'nowlen','wlen'};
+definput.flags.thr={'nothr','thr'};
+definput.flags.tc={'notc','tc'};
+definput.flags.plottype={'image','contour','mesh','pcolor'};
+
+% Override the setting from tfplot, because SGRAM does not support the
+% 'dbsq' setting (it does not make sense).
+definput.flags.log={'db','lin'};
+
+
+if isreal(f)
+  definput.flags.posfreq={'posfreq','nf'};
+else
+  definput.flags.posfreq={'nf','posfreq'};
+end;
+
+definput.keyvals.sharp=1;
+definput.keyvals.tfr=1;
+definput.keyvals.wlen=0;
+definput.keyvals.thr=0;
+definput.keyvals.fmax=[];
+definput.keyvals.xres=800;
+definput.keyvals.yres=600;
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+if (kv.sharp<0 || kv.sharp >1)
+  error(['RESGRAM: Sharpness parameter must be between (including) ' ...
+	 '0 and 1']);
+end;
+
+% Downsample
+if ~isempty(kv.fmax)
+  if ~isempty(kv.fs)
+    resamp=kv.fmax*2/fs;
+  else
+    resamp=kv.fmax*2/length(f);
+  end;
+
+  f=fftresample(f,round(length(f)*resamp));
+  kv.fs=2*kv.fmax;
+end;
+
+Ls=length(f);
+
+if flags.do_posfreq
+   kv.yres=2*kv.yres;
+end;
+
+try
+  [a,M,L,N,Ndisp]=gabimagepars(Ls,kv.xres,kv.yres);
+catch
+  err=lasterror;
+  if strcmp(err.identifier,'LTFAT:noframe')
+    error(sprintf(['The signal is too long. RESGRAM cannot visualize all the details.\n' ...
+                   'Try a shorter signal or increase the image resolution by calling:\n\n' ...
+                   '  sgram(...,''xres'',xres,''yres'',yres);\n\n' ...
+                   'for larger values of xres and yres.\n'...
+                   'The current values are:\n  xres=%i\n  yres=%i'],kv.xres,kv.yres));
+  else
+    rethrow(err);
+  end;
+end;
+
+
+
+% Set an explicit window length, if this was specified.
+if flags.do_wlen
+  kv.tfr=kv.wlen^2/L;
+end;
+
+g={'gauss',kv.tfr,flags.norm};
+
+[tgrad,fgrad,c]=gabphasegrad('dgt',f,g,a,M);          
+coef=gabreassign(abs(c).^2,kv.sharp*tgrad,kv.sharp*fgrad,a);
+
+% Cut away zero-extension.
+coef=coef(:,1:Ndisp);
+
+if flags.do_thr
+  % keep only the largest coefficients.
+  coef=largestr(coef,kv.thr);
+end
+
+if flags.do_posfreq
+  coef=coef(1:floor(M/2)+1,:);
+  plotdgtreal(coef,a,M,'argimport',flags,kv);
+else
+  plotdgt(coef,a,'argimport',flags,kv);
+end;
+
+
+if nargout>0
+  varargout={coef};
+end;
+
diff --git a/inst/gabor/s0norm.m b/inst/gabor/s0norm.m
new file mode 100644
index 0000000..d28a45e
--- /dev/null
+++ b/inst/gabor/s0norm.m
@@ -0,0 +1,87 @@
+function y = s0norm(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} s0norm
+%@verbatim
+%S0NORM S0-norm of signal
+%   Usage: y = s0norm(f);
+%          y = s0norm(f,...);
+%
+%   S0NORM(f) computes the S_0-norm of a vector.
+%
+%   If the input is a matrix or ND-array, the S_0-norm is computed along
+%   the first (non-singleton) dimension, and a vector of values is returned.
+%
+%   *WARNING**: The S_0-norm is computed by computing a full Short-time
+%   Fourier transform of a signal, which can be quite time-consuming. Use
+%   this function with care for long signals.
+%
+%   S0NORM takes the following flags at the end of the line of input
+%   parameters:
+%
+%     'dim',d   Work along specified dimension. The default value of []
+%               means to work along the first non-singleton one.
+%
+%     'rel'     Return the result relative to the l^2 norm (the energy) of the
+%               signal.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/s0norm.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+  
+%% ------ Checking of input parameters ---------
+
+if ~isnumeric(f) 
+  error('%s: Input must be numerical.',upper(mfilename));
+end;
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.flags.rel={'norel','rel'};
+definput.keyvals.dim=[];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+%% ------ Computation --------------------------
+ 
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim, ...
+                                                  upper(mfilename));
+permutedsize(1)=1;
+y=zeros(permutedsize,assert_classname(f));
+
+g=pgauss(L);
+
+for ii=1:W  
+  % Compute the STFT by the simple algorithm and sum each column of the
+  % STFT as they are computed, to avoid L^2 memory usage.
+  for jj=0:L-1
+    y(1,ii)=y(1,ii)+sum(abs(fft(f(:,ii).*circshift(g,jj))));
+  end;
+  
+  if flags.do_rel
+    y(1,ii)=y(1,ii)/norm(f(:,ii));
+  end;
+end;
+  
+y=y/L;
+
+y=assert_sigreshape_post(y,dim,permutedsize,order);
+
+
diff --git a/inst/gabor/sgram.m b/inst/gabor/sgram.m
new file mode 100644
index 0000000..c476208
--- /dev/null
+++ b/inst/gabor/sgram.m
@@ -0,0 +1,230 @@
+function varargout=sgram(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} sgram
+%@verbatim
+%SGRAM  Spectrogram
+%   Usage: sgram(f,op1,op2, ... );
+%          sgram(f,fs,op1,op2, ... );
+%          C=sgram(f, ... );
+%
+%   SGRAM(f) plots a spectrogram of f using a Discrete Gabor Transform (DGT).
+%
+%   SGRAM(f,fs) does the same for a signal with sampling rate fs (sampled
+%   with fs samples per second);
+%
+%   SGRAM(f,fs,dynrange) additionally limits the dynamic range of the
+%   plot. See the description of the 'dynrange' parameter below.
+%
+%   C=SGRAM(f, ... ) returns the image to be displayed as a matrix. Use this
+%   in conjunction with imwrite etc. These coefficients are *only* intended to
+%   be used by post-processing image tools. Numerical Gabor signal analysis
+%   and synthesis should *always* be done using the DGT, IDGT, DGTREAL and
+%   IDGTREAL functions.
+%
+%   Additional arguments can be supplied like this:
+%
+%       sgram(f,fs,'dynrange',50)
+%
+%   The arguments must be character strings possibly followed by an
+%   argument:
+%
+%     'dynrange',r  Limit the dynamical range to r by using a colormap in
+%                   the interval [chigh-r,chigh], where chigh is the highest
+%                   value in the plot. The default value of [] means to not
+%                   limit the dynamical range.
+%    
+%     'db'         Apply 20*log10 to the coefficients. This makes it possible to
+%                  see very weak phenomena, but it might show too much noise. A
+%                  logarithmic scale is more adapted to perception of sound.
+%                  This is the default.
+%    
+%     'lin'        Show the energy of the coefficients on a linear scale.
+%    
+%     'tfr',v      Set the ratio of frequency resolution to time resolution.
+%                  A value v=1 is the default. Setting v>1 will give better
+%                  frequency resolution at the expense of a worse time
+%                  resolution. A value of 0<v<1 will do the opposite.
+%    
+%     'wlen',s     Window length. Specifies the length of the window
+%                  measured in samples. See help of PGAUSS on the exact
+%                  details of the window length.
+%
+%     'posfreq'    Display only the positive frequencies. This is the
+%                  default for real-valued signals.
+%    
+%     'nf'         Display negative frequencies, with the zero-frequency
+%                  centered in the middle. For real signals, this will just
+%                  mirror the upper half plane. This is standard for complex
+%                  signals.
+%    
+%     'tc'         Time centering. Move the beginning of the signal to the
+%                  middle of the plot. This is useful for visualizing the
+%                  window functions of the toolbox.
+%    
+%     'image'      Use imagesc to display the spectrogram. This is the
+%                  default.
+%    
+%     'clim',clim  Use a colormap ranging from clim(1) to clim(2). These
+%                  values are passed to imagesc. See the help on imagesc.
+%    
+%     'thr',r      Keep only the largest fraction r of the coefficients, and
+%                  set the rest to zero.
+%    
+%     'fmax',y     Display y as the highest frequency. Default value of []
+%                  means to use the Nyquist frequency.
+%    
+%     'xres',xres  Approximate number of pixels along x-axis / time.
+%                  The default value is 800
+%    
+%     'yres',yres  Approximate number of pixels along y-axis / frequency
+%                  The Default value is 600
+%    
+%     'contour'    Do a contour plot to display the spectrogram.
+%           
+%     'surf'       Do a surf plot to display the spectrogram.
+%    
+%     'mesh'       Do a mesh plot to display the spectrogram.
+%    
+%     'colorbar'   Display the colorbar. This is the default.
+%    
+%     'nocolorbar'  Do not display the colorbar.
+%
+%   In addition to these parameters, SGRAM accepts any of the flags from
+%   NORMALIZE. The window used to calculate the spectrogram will be
+%   normalized as specified.
+%
+%   Examples:
+%   ---------
+%
+%   The GREASY signal is sampled using a sampling rate of 16 kHz. To
+%   display a spectrogram of GREASY with a dynamic range of 90 dB, use:
+%
+%     sgram(greasy,16000,90);
+%
+%   To create a spectrogram with a window length of 20ms (which is
+%   typically used in speech analysis) use :
+%
+%     fs=16000;
+%     sgram(greasy,fs,90,'wlen',round(20/1000*fs));
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/sgram.php}
+%@seealso{dgt, dgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+  
+if nargin<1
+  error('Too few input arguments.');
+end;
+
+if sum(size(f)>1)>1
+  error('Input must be a vector.');
+end;
+
+definput.import={'ltfattranslate','normalize','tfplot'};
+% Override the setting from tfplot, because SGRAM does not support the
+% 'dbsq' setting (it does not make sense).
+definput.flags.log={'db','lin'};
+
+% Define initial value for flags and key/value pairs.
+definput.flags.wlen={'nowlen','wlen'};
+definput.flags.thr={'nothr','thr'};
+
+if isreal(f)
+  definput.flags.posfreq={'posfreq','nf'};
+else
+  definput.flags.posfreq={'nf','posfreq'};
+end;
+
+definput.keyvals.tfr=1;
+definput.keyvals.wlen=0;
+definput.keyvals.thr=0;
+definput.keyvals.fmax=[];
+definput.keyvals.xres=800;
+definput.keyvals.yres=600;
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+% Downsample
+if ~isempty(kv.fmax)
+  if ~isempty(fs)
+    resamp=kv.fmax*2/fs;
+  else
+    resamp=kv.fmax*2/length(f);
+  end;
+
+  f=fftresample(f,round(length(f)*resamp));
+  kv.fs=2*kv.fmax;
+end;
+
+Ls=length(f);
+
+if flags.do_posfreq
+   kv.yres=2*kv.yres;
+end;
+
+try
+  [a,M,L,N,Ndisp]=gabimagepars(Ls,kv.xres,kv.yres);
+catch
+  err=lasterror;
+  if strcmp(err.identifier,'LTFAT:noframe')
+    error(sprintf(['The signal is too long. SGRAM cannot visualize all the details.\n' ...
+                   'Try a shorter signal or increase the image resolution by calling:\n\n' ...
+                   '  sgram(...,''xres'',xres,''yres'',yres);\n\n' ...
+                   'for larger values of xres and yres.\n'...
+                   'The current values are:\n  xres=%i\n  yres=%i'],kv.xres,kv.yres));
+  else
+    rethrow(err);
+  end;
+end;
+
+% Set an explicit window length, if this was specified.
+if flags.do_wlen
+  kv.tfr=kv.wlen^2/L;
+end;
+
+g={'gauss',kv.tfr,flags.norm};
+
+if flags.do_nf
+  coef=abs(dgt(f,g,a,M));
+else
+  coef=abs(dgtreal(f,g,a,M));
+end;
+
+% Cut away zero-extension.
+coef=coef(:,1:Ndisp);
+
+if flags.do_thr
+  % keep only the largest coefficients.
+  coef=largestr(coef,kv.thr);
+end
+
+if flags.do_nf
+  coef=plotdgt(coef,a,'argimport',flags,kv);
+else
+  coef=plotdgtreal(coef,a,M,'argimport',flags,kv);
+end;
+
+if nargout>0
+  varargout={coef};
+end;
+
diff --git a/inst/gabor/shearfind.m b/inst/gabor/shearfind.m
new file mode 100644
index 0000000..9475712
--- /dev/null
+++ b/inst/gabor/shearfind.m
@@ -0,0 +1,184 @@
+function [s0,s1,X] = shearfind(L,a,M,lt)
+%-*- texinfo -*-
+%@deftypefn {Function} shearfind
+%@verbatim
+%SHEARFIND  Shears for transformation of a general lattice to separable
+%   Usage:  [s0,s1,br] = shearfind(L,a,M,lt);
+%
+%   [s0,s1,br]=SHEARFIND(L,a,M,lt) computes three numbers, the first two
+%   represent a frequency and time shear respectively. With the returned
+%   choices of s_0 and s_1 one can transform an initial lattice given by
+%   a, M and lt into a separable (rectangular) lattice given by 
+%
+%       ar = a*L/(br*M)  and  Mr = L/br.
+%
+%   If s_0 is non-zero, the transformation from general to separable
+%   lattice requires a frequency-side shear. Similarly, if s_1 is
+%   non-zero, a time-side shear is required.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/shearfind.php}
+%@seealso{pchirp, matrix2latticetype}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+    
+    if nargin < 4 
+        error('Too few input arguments');
+    end
+    
+    Ltest=dgtlength(L,a,M,lt);
+    if Ltest~=L
+        error(['%s: Incorrect transform length L=%i specified. '...
+               'See the help of DGTLENGTH for the requirements.'],...
+              upper(mfilename),L);
+    end;
+
+    b=L/M;
+    s=b*lt(1)/lt(2);
+        
+    [Labfac,sfac,lenLabfac] = lattfac(a,b,s,L);
+
+    %lenLabfac = size(Labfac,2);
+
+    if s/a == round(s/a)
+        if s/a <= b/2
+            s1 = -s/a;
+        else 
+            s1 = b-s/a;
+        end
+        s0 = 0;
+        X = b;
+    elseif ones(1,lenLabfac) == (min(Labfac(3,:),Labfac(4,:)) <= sfac(2,1:end-1))
+        s0 = 0;
+        [Y,alpha,temp] = gcd(a,b);
+        s1 = -alpha*s/Y;
+         
+        B = prod(Labfac(1,:).^max(Labfac(4,:)-Labfac(3,:),0));
+        if abs(s1) > B/2
+            s1 = s1+sign(alpha)*B;            
+        end
+        X = b;
+        s1 = mod(s1,b);
+    elseif ones(1,lenLabfac) == (Labfac(3,:) < sfac(2,1:end-1))
+        s1 = 0;
+        [X,alpha,temp] = gcd(s,b);
+        if alpha < 0
+            alpha = b/X + alpha;
+        end
+        s0 = mod(alpha*a/X,a*lt(2));
+        
+    else
+        s1fac = (Labfac(3,:) == sfac(2,1:end-1)).*(Labfac(3,:) < Labfac(4,:));
+        s1 = prod(Labfac(1,:).^s1fac);
+
+        if s1*a/b == round(s1*a/b) 
+            s1 = 0; 
+        else 
+           B = prod(Labfac(1,:).^max(Labfac(4,:)-Labfac(3,:),0));
+           if s1 > B/2
+                s1 = s1-B;
+           end   
+        end
+
+        [X,alpha,temp] = gcd(s1*a+s,b);
+        if alpha < 0
+            alpha = b/X + alpha;
+        end
+        tempX = factor(X);
+        tempalph = factor(alpha);
+
+        Xfac = zeros(1,length(lenLabfac));
+        alphfac = zeros(1,length(lenLabfac)+1);
+
+        for kk = 1:lenLabfac
+            Xfac(kk) = sum(tempX == Labfac(1,kk));
+            tempX = tempX(tempX ~= Labfac(1,kk));
+            alphfac(kk) = sum(tempalph == Labfac(1,kk));
+            tempalph = tempalph(tempalph ~= Labfac(1,kk));
+        end
+
+        alphfac(lenLabfac+1) = prod(tempalph);
+
+        s0fac = [Labfac(3,:)+min(alphfac(1:end-1),Labfac(4,:)-Xfac)-Xfac,0];
+        pwrs = max(Labfac(4,:)-Xfac-alphfac(1:end-1),0);
+        pwrs2 = max(-Labfac(4,:)+Xfac+alphfac(1:end-1),0);
+
+        K = ceil(alphfac(end).*prod(Labfac(1,:).^(pwrs2-pwrs))-.5);
+
+        s0fac(end) = K*prod(Labfac(1,:).^pwrs) - alphfac(end).*prod(Labfac(1,:).^pwrs2);
+
+        s0 = prod(Labfac(1,:).^s0fac(1:end-1))*s0fac(end);
+
+        if s0*X^2/(a*b) == round(s0*X^2/(a*b)) 
+            s0 = 0; 
+        end
+    end
+    
+    s0=rem(s0,L);
+    s1=rem(s1,L);
+    
+end
+
+function [Labfac,sfac,lenLabfac] = lattfac(a,b,s,L)    
+
+    tempL = factor(L);
+    tempa = factor(a);
+    
+    if tempa == 1
+        tempa = [];
+    end
+    tempb = factor(b);
+    if tempb == 1
+        tempb = [];
+    end
+
+    Labfac = unique(tempL);
+    lenLabfac = length(Labfac);
+    Labfac = [Labfac;zeros(3,lenLabfac)];
+
+    for kk = 1:lenLabfac
+       Labfac(2,kk) = sum(tempL == Labfac(1,kk));
+       tempL = tempL(tempL ~= Labfac(1,kk));
+       Labfac(3,kk) = sum(tempa == Labfac(1,kk));
+       tempa = tempa(tempa ~= Labfac(1,kk));
+       Labfac(4,kk) = sum(tempb == Labfac(1,kk));
+       tempb = tempb(tempb ~= Labfac(1,kk));
+    end
+
+    if isempty(tempa) == 0 || isempty(tempb) == 0
+        error('a and b must be divisors of L');
+    end
+
+    if s*L/(a*b) ~= round(s*L/(a*b));
+        error('s must be a multiple of a*b/L');
+    end
+
+    temps = factor(s);
+
+    sfac = [Labfac(1,:),0;zeros(1,lenLabfac+1)];
+
+    for kk = 1:lenLabfac
+       sfac(2,kk) = sum(temps == sfac(1,kk));
+       temps = temps(temps ~= sfac(1,kk));
+    end
+
+    sfac(:,lenLabfac+1) = [prod(temps);1];
+
+end
+
diff --git a/inst/gabor/symphase.m b/inst/gabor/symphase.m
new file mode 100644
index 0000000..0886ecb
--- /dev/null
+++ b/inst/gabor/symphase.m
@@ -0,0 +1,79 @@
+function c = symphase(c,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} symphase
+%@verbatim
+%SYMPHASE  Change Gabor coefficients to symmetric phase
+%   Usage:  c=symphase(c,a);
+%
+%   SYMPHASE(c,a) alters the phase of the Gabor coefficients c so as if
+%   they were obtained from a Gabor transform based on symmetric
+%   time/frequency shifts. The coefficient must have been obtained from a
+%   DGT with parameter a.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/symphase.php}
+%@seealso{dgt, phaselock}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHORS : Peter Balazs, Peter L. Soendergaard.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.lt=[0 1];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if  (prod(size(a))~=1 || ~isnumeric(a))
+  error('a must be a scalar');
+end;
+
+if rem(a,1)~=0
+  error('a must be an integer');
+end;
+
+M=size(c,1);
+N=size(c,2);
+L=N*a;
+b=L/M;
+
+if rem(b,1)~=0
+  error('Lattice error. The a parameter is probably incorrect.');
+end;
+
+TimeInd = (0:(N-1))*a;
+FreqInd = (0:(M-1));
+
+phase = FreqInd'*TimeInd;
+phase = mod(phase,M);
+phase = exp(1i*pi*phase/M);
+
+if kv.lt(1)>0 
+    % truly non-separable case
+    
+    for n=0:(N-1)
+        w = mod(n*kv.lt(1)/kv.lt(2),1);
+        phase(:,n+1) = phase(:,n+1)*exp(pi*1i*a*w*n/M);
+    end
+end
+
+% Handle multisignals
+c=bsxfun(@times,c,phase);
+
+
diff --git a/inst/gabor/tconv.m b/inst/gabor/tconv.m
new file mode 100644
index 0000000..3038298
--- /dev/null
+++ b/inst/gabor/tconv.m
@@ -0,0 +1,108 @@
+function h=tconv(f,g)
+%-*- texinfo -*-
+%@deftypefn {Function} tconv
+%@verbatim
+%TCONV  Twisted convolution
+%   Usage:  h=tconv(f,g);
+%
+%   TCONV(f,g) computes the twisted convolution of the square matrices
+%   f and g.
+%
+%   Let h=TCONV(f,g) for f,g being L xL matrices. Then h is given by
+%
+%                   L-1 L-1
+%      h(m+1,n+1) = sum sum f(k+1,l+1)*g(m-k+1,n-l+1)*exp(-2*pi*i*(m-k)*l/L);
+%                   l=0 k=0
+%
+%   where m-k and n-l are computed modulo L.
+%
+%   If both f and g are of class sparse then h will also be a sparse
+%   matrix. The number of non-zero elements of h is usually much larger than
+%   the numbers for f and g. Unless f and g are very sparse, it can be
+%   faster to convert them to full matrices before calling TCONV. 
+%
+%   The routine SPREADINV can be used to calculate an inverse convolution.
+%   Define h and r by:
+%
+%     h=tconv(f,g);
+%     r=tconv(spreadinv(f),h);
+%
+%   then r is equal to g.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/tconv.php}
+%@seealso{spreadop, spreadfun, spreadinv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_SPREAD
+%   REFERENCE: REF_TCONV
+
+error(nargchk(2,2,nargin));
+
+
+if any(size(f)~=size(g))
+  error('Input matrices must be same size.');
+end;
+
+if size(f,1)~=size(f,2)
+  error('Input matrices must be square.');
+end;
+
+L=size(f,1);
+
+if issparse(f) && issparse(g)
+  
+  % Version for sparse matrices.
+  
+  % precompute the Lth roots of unity
+  % Optimization note : the special properties and symmetries of the 
+  % roots of unity could be exploited to reduce this computation.
+  % Furthermore here we precompute every possible root if some are 
+  % unneeded. 
+  temp=exp((-i*2*pi/L)*(0:L-1)');
+  [rowf,colf,valf]=find(f);
+  [rowg,colg,valg]=find(g);
+  
+  h=sparse(L,L);  
+  for indf=1:length(valf)
+    for indg=1:length(valg)
+      m=mod(rowf(indf)+rowg(indg)-2, L);
+      n=mod(colf(indf)+colg(indg)-2, L);
+      h(m+1,n+1)=h(m+1,n+1)+valf(indf)*valg(indg)*temp(mod((m-(rowf(indf)-1))*(colf(indf)-1),L)+1);
+    end
+  end
+
+  
+else
+
+  % The conversion to 'full' is in order for Matlab to work.
+  f=ifft(full(f))*L;
+  g=ifft(full(g))*L;
+  
+  Tf=comp_col2diag(f);
+  Tg=comp_col2diag(g);
+  
+  Th=Tf*Tg;
+  
+  h=spreadfun(Th);
+
+end;
+
diff --git a/inst/gabor/tfplot.m b/inst/gabor/tfplot.m
new file mode 100644
index 0000000..0bbdc95
--- /dev/null
+++ b/inst/gabor/tfplot.m
@@ -0,0 +1,205 @@
+function coef=tfplot(coef,step,yr,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} tfplot
+%@verbatim
+%TFPLOT  Plot coefficient matrix on the TF plane
+%   Usage: tfplot(coef,step,yr);
+%          tfplot(coef,step,yr,...);
+%
+%   TFPLOT(coef,step,yr) will plot a rectangular coefficient array on the
+%   TF-plane. The shift in samples between each column of coefficients is
+%   given by the variable step. The vector yr is a 1 x2 vector
+%   containing the lowest and highest normalized frequency.
+%
+%   C=TFPLOT(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar
+%   functions will create the plot. This is usefull for custom
+%   post-processing of the image data.
+%
+%   TFPLOT is not meant to be called directly. Instead, it is called by
+%   other plotting routines to give a uniform display format. 
+%
+%   TFPLOT (and all functions that call it) takes the following arguments.
+%
+%     'dynrange',r
+%              Limit the dynamical range to r by using a colormap in
+%              the interval [chigh-r,chigh], where chigh is the highest
+%              value in the plot. The default value of [] means to not
+%              limit the dynamical range.
+%
+%     'db'     Apply 20*log_{10} to the coefficients. This makes 
+%              it possible to see very weak phenomena, but it might show 
+%              too much noise. A logarithmic scale is more adapted to 
+%              perception of sound. This is the default.
+%
+%     'dbsq'   Apply 10*log_{10} to the coefficients. Same as the
+%              'db' option, but assume that the input is already squared.  
+%
+%     'lin'    Show the coefficients on a linear scale. This will
+%              display the raw input without any modifications. Only works for
+%              real-valued input.
+%
+%     'linsq'  Show the square of the coefficients on a linear scale.
+%
+%     'linabs'  Show the absolute value of the coefficients on a linear scale.
+%
+%     'tc'     Time centering. Move the beginning of the signal to the
+%              middle of the plot. 
+%
+%     'clim',clim   Use a colormap ranging from clim(1) to clim(2). These
+%                   values are passed to imagesc. See the help on imagesc.
+%
+%     'image'       Use imagesc to display the plot. This is the default.
+%
+%     'contour'     Do a contour plot.
+%          
+%     'surf'        Do a surf plot.
+%
+%     'colorbar'    Display the colorbar. This is the default.
+%
+%     'nocolorbar'  Do not display the colorbar.
+%
+%     'display'     Display the figure. This is the default.
+%
+%     'nodisplay'   Do not display figure. This is usefull if you only
+%                   want to obtain the output for further processing.
+%
+%   If both 'clim' and 'dynrange' are specified, then 'clim' takes
+%   precedence.
+%
+%   It is possible to customize the text by setting the following values:
+%
+%     'time', t       The word denoting time. Default is 'Time'
+%
+%     'frequency',f   The word denoting frequency. Default is 'Frequency'
+%  
+%     'samples',s     The word denoting samples. Default is 'samples'
+%  
+%     'normalized',n  Defult value is 'normalized'.
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/tfplot.php}
+%@seealso{sgram, plotdgt, plotdgtreal, plotwmdct, plotdwilt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+M=size(coef,1);
+N=size(coef,2);
+
+if size(coef,3)>1
+  error('Input is multidimensional.');
+end;
+
+% Apply transformation to coefficients.
+if flags.do_db
+  coef=20*log10(abs(coef)+realmin);
+end;
+
+if flags.do_dbsq
+  coef=10*log10(abs(coef)+realmin);
+end;
+
+if flags.do_linsq
+  coef=abs(coef).^2;
+end;
+
+if flags.do_linabs
+  coef=abs(coef);
+end;
+
+if flags.do_lin
+  if ~isreal(coef)
+    error(['Complex valued input cannot be plotted using the "lin" flag.',...
+           'Please use the "linsq" or "linabs" flag.']);
+  end;
+end;
+  
+% 'dynrange' parameter is handled by converting it into clim
+% clim overrides dynrange, so do nothing if clim is already specified
+if  ~isempty(kv.dynrange) && isempty(kv.clim)
+  maxclim=max(coef(:));
+  kv.clim=[maxclim-kv.dynrange,maxclim];
+end;
+
+% Handle clim by thresholding and cutting
+if ~isempty(kv.clim)
+  coef(coef<kv.clim(1))=kv.clim(1);
+  coef(coef>kv.clim(2))=kv.clim(2);
+end;
+  
+if flags.do_tc
+  xr=(-floor(N/2):floor((N-1)/2))*step;
+  coef=fftshift(coef,2);
+else
+  xr=(0:N-1)*step;
+end;
+
+
+if flags.do_display
+    if ~isempty(kv.fs)
+        xr=xr/kv.fs;
+        yr=yr*fs/2;
+    end;
+    
+    % Convert yr to range of values
+    yr=linspace(yr(1),yr(2),M);
+        
+    switch(flags.plottype)
+      case 'image'
+        % Call imagesc explicitly with clim. This is necessary for the
+        % situations where the data (is by itself limited (from above or
+        % below) to within the specified range. Setting clim explicitly
+        % avoids the colormap moves in the top or bottom.
+	if isempty(kv.clim)
+          imagesc(xr,yr,coef);
+        else
+	  imagesc(xr,yr,coef,kv.clim);
+        end;
+      case 'contour'
+        contour(xr,yr,coef);
+      case 'surf'
+        surf(xr,yr,coef,'EdgeColor','none');
+      case 'pcolor'
+        pcolor(xr,yr,coef);
+    end;
+    
+    if flags.do_colorbar
+        colorbar;
+    end;
+    
+    axis('xy');
+    if ~isempty(kv.fs)
+        xlabel(sprintf('%s (s)',kv.time));
+        ylabel(sprintf('%s (Hz)',kv.frequency));
+    else
+        xlabel(sprintf('%s (%s)',kv.time,kv.samples));
+        ylabel(sprintf('%s (%s)',kv.frequency,kv.normalized));
+    end;
+    
+end;
diff --git a/inst/gabor/wil2rect.m b/inst/gabor/wil2rect.m
new file mode 100644
index 0000000..078f1ad
--- /dev/null
+++ b/inst/gabor/wil2rect.m
@@ -0,0 +1,58 @@
+function cout=wil2rect(cin);
+%-*- texinfo -*-
+%@deftypefn {Function} wil2rect
+%@verbatim
+%WIL2RECT  Arrange Wilson coefficients in a rectangular layout
+%   Usage:  c=wil2rect(c);
+%
+%   WIL2RECT(c) rearranges the coefficients c in a rectangular shape. The
+%   coefficients must have been obtained from DWILT. After rearrangement
+%   the coefficients are placed correctly on the time/frequency-plane.
+%
+%   The rearranged array is larger than the input array: it contains
+%   zeros on the spots where the Wilson transform is missing a DC or
+%   Nyquest component.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wil2rect.php}
+%@seealso{rect2wil, dwilt, wmdct}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+error(nargchk(1,1,nargin));
+  
+M=size(cin,1)/2;
+N=size(cin,2)*2;
+W=size(cin,3);
+
+cout=zeros(M+1,N,W,assert_classname(cin));
+
+if rem(M,2)==0
+  for ii=0:N/2-1
+    cout(1:M+1,2*ii+1,:)=cin(1:M+1  ,ii+1,:);
+    cout(2:M,2*ii+2,:)  =cin(M+2:2*M,ii+1,:);
+  end;
+else
+  for ii=0:N/2-1
+    cout(1:M,2*ii+1,:)  =cin(1:M    ,ii+1,:);
+    cout(2:M,2*ii+2,:)  =cin(M+2:2*M,ii+1,:);
+    cout(M+1,2*ii+2,:)  =cin(M+1    ,ii+1,:);
+  end;  
+end;
+
+
diff --git a/inst/gabor/wilbounds.m b/inst/gabor/wilbounds.m
new file mode 100644
index 0000000..43268dd
--- /dev/null
+++ b/inst/gabor/wilbounds.m
@@ -0,0 +1,103 @@
+function [AF,BF]=wilbounds(g,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wilbounds
+%@verbatim
+%WILBOUNDS  Calculate frame bounds of Wilson basis
+%   Usage:  [AF,BF]=wilbounds(g,M)
+%           [AF,BF]=wilbounds(g,M,L)
+%
+%   Input parameters:
+%           g       : Window function.
+%           M       : Number of channels.
+%           L       : Length of transform to do (optional)
+%   Output parameters:
+%           AF,BF   : Frame bounds.
+%          
+%   WILBOUNDS(g,M) calculates the frame bounds of the Wilson frame operator
+%   of the Wilson basis with window g and M channels.
+%
+%   [A,B]=WILBOUNDS(g,a,M) returns the frame bounds A and B instead of
+%   just the ratio.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%
+%   If the length of g is equal to 2*M then the input window is
+%   assumed to be a FIR window. Otherwise the smallest possible transform
+%   length is chosen as the window length.
+%
+%   If the optional parameter L is specified, the window is cut or
+%   zero-extended to length L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wilbounds.php}
+%@seealso{wilwin, gabframebounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+   error('Too few input parameters.');    
+end;
+
+definput.keyvals.L=[];
+
+[flags,keyvals]=ltfatarghelper({'L'},definput,varargin);
+L=keyvals.L;
+
+if size(M,1)>1 || size(M,2)>1
+  error('M must be a scalar');
+end;
+
+if rem(M,1)~=0
+  error('M must be an integer.')
+end;
+
+[g,info]=wilwin(g,M,L,'WILBOUNDS');
+Lwindow=length(g);
+
+[b,N,L]=assert_L(Lwindow,Lwindow,L,M,2*M,'WILBOUNDS');
+
+g=fir2long(g,L);
+
+a=M;
+
+N=L/a;
+
+if rem(N,2)==1
+  error('L/M must be even.');
+end;
+
+
+% Get the factorization of the window.
+gf=comp_wfac(g,a,2*M);
+
+% Compute all eigenvalues.
+lambdas=comp_gfeigs(gf,L,a,2*M);
+
+% Min and max eigenvalue.
+AF=lambdas(1);
+BF=lambdas(size(lambdas,1));
+
+% Divide by 2 (only difference to gfeigs).
+AF=AF/2;
+BF=BF/2;
+
+if nargout<2
+  AF=BF/AF;
+end;
+
diff --git a/inst/gabor/wildual.m b/inst/gabor/wildual.m
new file mode 100644
index 0000000..74c7814
--- /dev/null
+++ b/inst/gabor/wildual.m
@@ -0,0 +1,111 @@
+function [gamma]=wildual(g,M,L)
+%-*- texinfo -*-
+%@deftypefn {Function} wildual
+%@verbatim
+%WILDUAL  Wilson dual window
+%   Usage:  gamma=wildual(g,M);
+%           gamma=wildual(g,M,L);
+%
+%   Input parameters:
+%         g     : Gabor window.
+%         M     : Number of modulations.
+%         L     : Length of window. (optional)
+%   Output parameters:
+%         gamma : Canonical dual window.
+%
+%   WILDUAL(g,M) returns the dual window of the Wilson or WMDCT basis with
+%   window g, parameter M and length equal to the length of the window g.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%
+%   If the length of g is equal to 2*M then the input window is
+%   assumed to be an FIR window. In this case, the dual window also has
+%   length of 2*M. Otherwise the smallest possible transform length is
+%   chosen as the window length.
+%
+%   WILDUAL(g,M,L) does the same, but now L is used as the length of the
+%   Wilson basis.
+%
+%   The input window g must be real and whole-point even. If g is not
+%   whole-point even, then reconstruction using the dual window will not be
+%   perfect. For a random window g, the window closest to g that satisfies
+%   these restrictions can be found by :
+%
+%     g_wpe = real(peven(g));
+%
+%   All windows in the toolbox satisfies these restrictions unless
+%   clearly stated otherwise.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wildual.php}
+%@seealso{dwilt, wilwin, wmdct, wilorth, isevenfunction}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: TEST_DWILT
+%   REFERENCE: OK
+
+error(nargchk(2,3,nargin));
+
+if nargin==2
+    L=[];
+end;
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+    if isnumeric(g)
+        % Use the window length
+        Ls=length(g);
+    else
+        % Use the smallest possible length
+        Ls=1;
+    end;
+
+    % ----- step 2b : Verify M and get L from the window length ----------
+    L=dwiltlength(Ls,M);
+
+else
+
+    % ----- step 2a : Verify M and get L
+
+    Luser=dwiltlength(L,M);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DWILTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=wilwin(g,M,L,upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+%% ----- call gabdual ----------------
+a=M;
+
+g=fir2long(g,L);
+gamma=2*comp_gabdual_long(g,a,2*M);
+
diff --git a/inst/gabor/wilframediag.m b/inst/gabor/wilframediag.m
new file mode 100644
index 0000000..184ba69
--- /dev/null
+++ b/inst/gabor/wilframediag.m
@@ -0,0 +1,50 @@
+function d=wilframediag(g,M,L,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wilframediag
+%@verbatim
+%WILFRAMEDIAG  Diagonal of Wilson and WMDCT frame operator
+%   Usage:  d=wilframediag(g,M,L);
+%
+%   Input parameters:
+%         g     : Window function.
+%         M     : Number of channels.
+%         L     : Length of transform to do.
+%   Output parameters:
+%         d     : Diagonal stored as a column vector
+%
+%   WILFRAMEDIAG(g,M,L) computes the diagonal of the Wilson or WMDCT frame
+%   operator with respect to the window g and number of channels M. The
+%   diagonal is stored a as column vector of length L.
+%
+%   The diagonal of the frame operator can for instance be used as a
+%   preconditioner.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wilframediag.php}
+%@seealso{dwilt, wmdct, gabframediag}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+d=gabframediag(g,M,2*M,L)/2;
+
+
+
diff --git a/inst/gabor/wilorth.m b/inst/gabor/wilorth.m
new file mode 100644
index 0000000..d459712
--- /dev/null
+++ b/inst/gabor/wilorth.m
@@ -0,0 +1,146 @@
+function [gt]=wilorth(p1,p2,p3)
+%-*- texinfo -*-
+%@deftypefn {Function} wilorth
+%@verbatim
+%WILORTH  Wilson orthonormal window
+%   Usage:   gt=wilorth(M,L);
+%            gt=wilorth(g,M);
+%            gt=wilorth(g,M,L);
+%
+%   Input parameters:
+%         g   : Auxiliary window window function (optional).
+%         M   : Number of modulations.
+%         L   : Length of window (optional).
+%   Output parameters:
+%         gt  : Window generating an orthonormal Wilson basis.
+%
+%   WILORTH(M,L) computes a nice window of length L generating an
+%   orthonormal Wilson or WMDCT basis with M frequency bands for signals
+%   of length L.
+%
+%   WILORTH(g,M) computes a window generating an orthonomal basis from the
+%   window g and number of channels M.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%
+%   If the length of g is equal to 2xM, then the input window is
+%   assumed to be a FIR window. In this case, the orthonormal window also
+%   has length of 2xM. Otherwise the smallest possible transform
+%   length is chosen as the window length.
+%
+%   WILORTH(g,M,L) pads or truncates g to length L before calculating
+%   the orthonormal window. The output will also be of length L.
+%
+%   The input window g must be real whole-point even. If g is not
+%   whole-point even, the computed window will not generate an orthonormal
+%   system (i.e. reconstruction will not be perfect). For a random window
+%   g, the window closest to g that satisfies these restrictions can be
+%   found by :
+%
+%     g_wpe = real(peven(g));
+%
+%   All Gabor windows in the toolbox satisfies these restrictions unless
+%   clearly stated otherwise.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wilorth.php}
+%@seealso{dwilt, wmdct, wildual, isevenfunction}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_DWILT TEST_WMDCT
+%   REFERENCE: OK
+
+error(nargchk(2,3,nargin));
+
+wasrow=0;
+
+% Detect which parameters was entered, and do simple transformations.
+if nargin == 3
+  g=p1;
+  M=p2;
+  L=p3;
+
+  if size(g,2)>1
+    if size(g,1)>1
+      error('g must be a vector');
+    else
+      % g was a row vector.
+      wasrow=1;
+      g=g(:);
+    end;
+  end;
+
+  assert_squarelat(M,M,1,'WILORTH',0);
+  [b,N,L]=assert_L(L,length(g),L,M,2*M,'WILORTH');
+
+
+  % fir2long is now safe.
+  g=fir2long(g,L);
+else
+
+  if numel(p1)>1
+    % First parameter is a vector.
+    g=p1;
+    M=p2;
+    
+    if size(g,2)>1
+      if size(g,1)>1
+        error('g must be a vector');
+      else
+        % g was a row vector.
+        wasrow=1;
+        g=g(:);
+      end;
+    end;
+
+    assert_squarelat(M,2*M,1,'WILORTH',0);
+    [b,N,L]=assert_L(length(g),length(g),[],M,2*M,'WILORTH');
+  else
+    
+    M=p1;
+    L=p2;
+    
+    assert_squarelat(M,M,1,'WILORTH',0);
+    [b,N,L]=assert_L(L,L,L,M,2*M,'WILORTH');
+
+    a=M;
+    b=L/(2*M);
+        
+    % Create default window, a Gaussian.
+    g=comp_pgauss(L,a/b,0,0);    
+  end;
+
+end;
+
+a=M;
+b=L/(2*M);
+
+% Multiply by sqrt(2), because comp_gabtight will return a normalized
+% tight frame, i.e. the framebounds are A=B=1 instead of A=B=2. This means
+% that the returned gt only has norm=.701 and not norm=1.
+
+gt=sqrt(2)*comp_gabtight_long(g,a,2*M);
+
+if wasrow
+  gt=gt.';
+end;
+
+
diff --git a/inst/gabor/wilwin.m b/inst/gabor/wilwin.m
new file mode 100644
index 0000000..8a2d751
--- /dev/null
+++ b/inst/gabor/wilwin.m
@@ -0,0 +1,263 @@
+function [g,info] = wilwin(g,M,L,callfun);
+%-*- texinfo -*-
+%@deftypefn {Function} wilwin
+%@verbatim
+%WILWIN  Compute a Wilson/WMDCT window from text or cell array
+%   Usage: [g,info] = wilwin(g,M,L);
+%
+%   [g,info]=WILWIN(g,M,L) computes a window that fits well with the
+%   specified number of channels M and transform length L. The window itself
+%   is specified by a text description or a cell array containing additional
+%   parameters.
+%
+%   The window can be specified directly as a vector of numerical
+%   values. In this case, WILWIN only checks assumptions about transform
+%   sizes etc.
+%
+%   [g,info]=WILWIN(g,M) does the same, but the window must be a FIR
+%   window, as the transform length is unspecified.
+%
+%   The window can be specified as one of the following text strings:
+%  
+%     'gauss'      Gaussian window with optimal concentration
+%
+%     'dualgauss'  Riesz dual of Gaussian window with optimal concentration.
+%
+%     'tight'      Window generating an orthonormal basis
+%
+%   In these cases, a long window is generated with a length of L.
+%
+%   It is also possible to specify one of the window names from FIRWIN. In
+%   such a case, WILWIN generates the specified FIR window with a length
+%   of M.
+%
+%   The window can also be specified as cell array. The possibilities are:
+%
+%     {'gauss',...}
+%       Additional parameters are passed to PGAUSS
+%
+%     {'dual',...}
+%       Dual window of whatever follows. See the examples below.
+%
+%     {'tight',...}
+%       Orthonormal window of whatever follows.
+%
+%   It is also possible to specify one of the window names from FIRWIN as
+%   the first field in the cell array. In this case, the remaining
+%   entries of the cell array are passed directly to FIRWIN.
+%
+%   Some examples:
+%
+%     g=wilwin('gauss',M,L);
+%
+%   This computes a Gaussian window of length L fitted for a system with
+%   M channels. :
+%
+%     g=wilwin({'gauss',1},M,L);
+%
+%   This computes a Gaussian window with equal time and frequency support
+%   irrespective of M. :
+%
+%     gd=wilwin('gaussdual',M,L);
+%
+%   This computes the dual of a Gaussian window fitted for a system with M*
+%   channels. :
+%
+%     gd=wilwin({'tight','gauss'},M,L);
+%
+%   This computes the orthonormal window of the Gaussian window fitted for
+%   the system. :
+%
+%     g=wilwin({'dual',{'hann',20}},M,L);
+%
+%   This computes the dual of a Hann window of length 20.  
+%
+%   The structure info provides some information about the computed
+%   window:
+%
+%     info.gauss
+%        True if the window is a Gaussian.
+%
+%     info.tfr
+%        Time/frequency support ratio of the window. Set whenever it makes sense.
+%
+%     info.wasrow
+%        Input was a row window
+%
+%     info.isfir
+%        Input is an FIR window
+%
+%     info.isdual
+%        Output is the dual window of the auxiliary window.
+%
+%     info.istight
+%        Output is known to be a tight window.
+%
+%     info.auxinfo
+%        Info about auxiliary window.
+%   
+%     info.gl
+%        Length of window.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wilwin.php}
+%@seealso{pgauss, firwin, gabwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Assert correct input.
+error(nargchk(2,4,nargin));
+
+if nargin==2
+  L=[];
+end;
+  
+% Basic discovery: Some windows depend on L, and some windows help define
+% L, so the calculation of L is window dependant.
+  
+% Default values.
+info.gauss=0;
+info.wasrow=0;
+info.isfir=0;
+info.istight=0;
+info.isdual=0;
+
+% Manually get the list of window names
+definput=arg_firwin(struct);
+firwinnames =  definput.flags.wintype;
+
+% Create window if string was given as input.
+if ischar(g)
+  winname=lower(g);
+  switch(winname)
+   case {'pgauss','gauss'}
+    complain_L(L,callfun);
+    g=comp_pgauss(L,2*M*M/L,0,0);
+    info.gauss=1;
+    info.tfr=2*M*M/L;
+   case {'psech','sech'}
+    complain_L(L,callfun);
+    g=psech(L,2*M*M/L);
+    info.tfr=a*M/L;
+   case {'dualgauss','gaussdual'}
+    complain_L(L,callfun);
+    g=comp_pgauss(L,2*M*M/L,0,0);
+    g=wildual(g,M);
+    info.isdual=1;
+    info.tfr=a*M/L;
+   case {'tight'}
+    complain_L(L,callfun);
+    g=wilorth(M,L);
+    info.tfr=2*M*M/L;
+    info.istight=1;
+   case firwinnames
+    [g,firinfo]=firwin(winname,2*M,'2');
+    info.isfir=1;
+    if firinfo.issqpu
+      info.istight=1;
+    end;
+   otherwise
+    error('%s: Unknown window type: %s',callfun,winname);
+  end;
+end;
+
+if iscell(g)
+  if isempty(g) || ~ischar(g{1})
+    error('First element of window cell array must be a character string.');
+  end;
+  
+  winname=lower(g{1});
+  
+  switch(winname)
+   case {'pgauss','gauss'}
+    complain_L(L,callfun);
+    [g,info.tfr]=pgauss(L,g{2:end});
+    info.gauss=1;
+   case {'psech','sech'}
+    complain_L(L,callfun);
+    [g,info.tfr]=psech(L,g{2:end});    
+   case {'dual'}
+    gorig = g{2};  
+    [g,info.auxinfo] = wilwin(gorig,M,L,callfun);    
+    g = wildual(g,M,L);
+    
+    % gorig can be string or cell array
+    if info.auxinfo.isfir && test_isfir(gorig,M)
+        info.isfir = 1; 
+    end
+    
+    info.isdual=1;
+   case {'tight'}
+    gorig = g{2};
+    [g,info.auxinfo] = wilwin(g{2},M,L,callfun);    
+    g = wilorth(g,M,L);  
+    % gorig can be string or cell array
+    if info.auxinfo.isfir && test_isfir(gorig,M)
+        info.isfir = 1; 
+    end
+    info.istight=1;
+   case firwinnames
+    g=firwin(winname,g{2},'energy',g{3:end});
+    info.isfir=1;
+   otherwise
+    error('Unsupported window type.');
+  end;
+end;
+
+if isnumeric(g)
+  if size(g,2)>1
+    if size(g,1)==1
+      % g was a row vector.
+      g=g(:);
+      info.wasrow=1;
+    end;
+  end;
+end;
+
+if rem(length(g),2*M)~=0
+  % Zero-extend the window to a multiple of 2*M
+  g=fir2long(g,ceil(length(g)/(2*M))*2*M);
+end;
+
+% Information to be determined post creation.
+info.wasreal = isreal(g);
+info.gl      = length(g);
+
+if (~isempty(L) && (info.gl<L))
+  info.isfir=1;
+end;
+
+function complain_L(L,callfun)
+  
+  if isempty(L)
+    error(['%s: You must specify a length L if a window is represented as a ' ...
+           'text string or cell array.'],callfun);
+  end;
+  
+  function isfir=test_isfir(gorig,M)
+    % Original window is FIR, dual window is FIR if length of the original
+    % window is <= M. This is true if the length was not explicitly
+    % defined (gorig{2}).
+    if iscell(gorig) && numel(gorig)>1 && isnumeric(gorig{2}) && gorig{2}<=2*M...
+         || ischar(gorig)   
+        isfir = 1; 
+    else
+       isfir = 0;
+    end
+
+
diff --git a/inst/gabor/wmdct.m b/inst/gabor/wmdct.m
new file mode 100644
index 0000000..7299d6e
--- /dev/null
+++ b/inst/gabor/wmdct.m
@@ -0,0 +1,186 @@
+function [c,Ls,g]=wmdct(f,g,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wmdct
+%@verbatim
+%WMDCT  Windowed MDCT transform
+%   Usage:  c=wmdct(f,g,M);
+%           c=wmdct(f,g,M,L);
+%           [c,Ls]=wmdct(...);
+%
+%   Input parameters:
+%         f     : Input data
+%         g     : Window function.
+%         M     : Number of bands.
+%         L     : Length of transform to do.
+%   Output parameters:
+%         c     : M xN array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   WMDCT(f,g,M) computes a Windowed Modified Discrete Cosine Transform with
+%   M bands and window g.
+%
+%   The length of the transform will be the smallest possible that is
+%   larger than the signal. f will be zero-extended to the length of the 
+%   transform. If f is a matrix, the transformation is applied to each column.
+%   g must be whole-point even.
+%
+%   The window g may be a vector of numerical values, a text string or a
+%   cell array. See the help of WILWIN for more details.
+%
+%   WMDCT(f,g,M,L) computes the MDCT transform as above, but does
+%   a transform of length L. f will be cut or zero-extended to length L*
+%   before the transform is done.
+%
+%   [c,Ls]=WMDCT(f,g,M) or [c,Ls]=wmdct(f,g,M,L)` additionally returns the
+%   length of the input signal f. This is handy for reconstruction:
+%
+%     [c,Ls]=wmdct(f,g,M);
+%     fr=iwmdct(c,gd,M,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, provided
+%   that gd is a dual Wilson window of g.
+%
+%   [c,Ls,g]=WMDCT(...) additionally outputs the window used in the
+%   transform. This is useful if the window was generated from a description
+%   in a string or cell array.
+%
+%   The WMDCT is sometimes known as an odd-stacked cosine modulated filter
+%   bank. The WMDCT defined by this routine is slightly different from the
+%   most common definition of the WMDCT, in order to be able to use the
+%   same window functions as the Wilson transform.
+%
+%   Assume that the following code has been executed for a column vector f
+%   of length L:
+%
+%     c=wmdct(f,g,M);  % Compute the WMDCT of f.
+%     N=size(c,2);     % Number of translation coefficients.
+%
+%   The following holds for m=0,...,M-1 and n=0,...,N-1:
+%
+%   If m+n is even:
+%
+%                    L-1
+%       c(m+1,n+1) = sum f(l+1)*cos(pi*(m+.5)*l/M+pi/4)*g(l-n*M+1)
+%                    l=0
+%
+%   If m+n is odd:
+%
+%                   L-1
+%      c(m+1,n+1) = sum f(l+1)*sin(pi*(m+.5)*l/M+pi/4)*g(l-n*M+1)
+%                   l=0
+%
+%   Examples:
+%   ---------
+%
+%   The following example shows the WMDCT coefficients (128 channels) of the
+%   GREASY test signal:
+%
+%     fs=16000; % Sampling rate
+%     c=wmdct(greasy,{'hann',0.02*fs},128);
+%     plotwmdct(c,fs,90);
+%
+%   Compare the visual difference with the redundant expansion of the
+%   same signal given in the example of the DGTREAL function.
+%
+%
+%   References:
+%     H. Boelcskei and F. Hlawatsch. Oversampled Wilson-type cosine modulated
+%     filter banks with linear phase. In Asilomar Conf. on Signals, Systems,
+%     and Computers, pages 998-1002, nov 1996.
+%     
+%     H. S. Malvar. Signal Processing with Lapped Transforms. Artech House
+%     Publishers, 1992.
+%     
+%     J. P. Princen and A. B. Bradley. Analysis/synthesis filter bank design
+%     based on time domain aliasing cancellation. IEEE Transactions on
+%     Acoustics, Speech, and Signal Processing, ASSP-34(5):1153-1161, 1986.
+%     
+%     J. P. Princen, A. W. Johnson, and A. B. Bradley. Subband/transform
+%     coding using filter bank designs based on time domain aliasing
+%     cancellation. Proceedings - ICASSP, IEEE International Conference on
+%     Acoustics, Speech and Signal Processing, pages 2161-2164, 1987.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wmdct.php}
+%@seealso{iwmdct, wilwin, dwilt, wildual, wilorth}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR:    Peter L. Soendergaard
+%   TESTING:   TEST_WMDCT
+%   REFERENCE: REF_WMDCT
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.L=[];
+definput.keyvals.dim=[];
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,dummy,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim,upper(mfilename));
+
+%% ------ step 2: Verify a, M and L
+if isempty(L)
+
+    % ----- step 2b : Verify a, M and get L from the signal length f----------
+    L=dwiltlength(Ls,M);
+
+else
+
+    % ----- step 2a : Verify a, M and get L
+    Luser=dwiltlength(L,M);
+    if Luser~=L
+        error(['%s: Incorrect transform length L=%i specified. Next valid length ' ...
+               'is L=%i. See the help of DWILTLENGTH for the requirements.'],...
+              upper(mfilename),L,Luser);
+    end;
+
+end;
+
+%% ----- step 3 : Determine the window 
+
+[g,info]=wilwin(g,M,L,upper(mfilename));
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+%% ----- step 4: final cleanup ---------------
+
+f=postpad(f,L);
+
+% If the signal is single precision, make the window single precision as
+% well to avoid mismatches.
+if isa(f,'single')
+  g=single(g);
+end;
+
+%% ----- Call the computational subroutines.
+c  = comp_dwiltiii(f,g,M);
+
+%% ----- reorder coefficients to correct final layout
+order=assert_groworder(order);
+permutedsize=[M,L/M,permutedsize(2:end)];
+
+c=assert_sigreshape_post(c,dim,permutedsize,order);
+
+
diff --git a/inst/gabor/wmdct2.m b/inst/gabor/wmdct2.m
new file mode 100644
index 0000000..efa5840
--- /dev/null
+++ b/inst/gabor/wmdct2.m
@@ -0,0 +1,115 @@
+function [c,Ls]=wmdct2(f,g1,p3,p4,p5)
+%-*- texinfo -*-
+%@deftypefn {Function} wmdct2
+%@verbatim
+%WMDCT2  2D Discrete windowed MDCT transform
+%   Usage: c=wmdct2(f,g,M); 
+%          c=wmdct2(f,g1,g2,[M1,M2]);
+%          c=wmdct2(f,g1,g2,[M1,M2],[L1,L2]);
+%          [c,L]=wmdct2(f,g1,g2,[M1,M2],[L1,L2]);
+%
+%   Input parameters:
+%         f        : Input data, matrix.
+%         g,g1,g2  : Window functions.
+%         M,M1,M2  : Number of bands.
+%         L1,L2    : Length of transform to do.
+%   Output parameters:
+%         c        : array of coefficients.
+%         Ls       : Original size of input matrix.
+%
+%   WMDCT2(f,g,M) calculates a two dimensional Modified Discrete Cosine
+%   transform of the input signal f using the window g and parameter 
+%   M along each dimension.
+%
+%   For each dimension, the length of the transform will be the smallest
+%   possible that is larger than the length of the signal along that
+%   dimension. f will be appropriately zero-extended.
+%
+%   All windows must be whole-point even.
+% 
+%   WMDCT2(f,g,M,L) computes a 2D windowed MDCT as above, but does a
+%   transform of length L along each dimension. f will be cut or
+%   zero-extended to length L before the transform is done.
+%
+%   [c,Ls]=wmdct(f,g,M) or [c,Ls]=wmdct(f,g,M,L) additionally return the
+%   length of the input signal f. This is handy for reconstruction.
+%
+%   c=WMDCT2(f,g1,g2,M) makes it possible to use different windows along
+%   the two dimensions.
+%
+%   The parameters L, M and Ls can also be vectors of length 2. In this case
+%   the first element will be used for the first dimension and the second
+%   element will be used for the second dimension. 
+%
+%   The output c has 4 or 5 dimensions. The dimensions index the following
+%   properties:
+%
+%      1. Number of translation along 1st dimension of input.
+%
+%      2. Number of channel along 1st dimension  of input
+%
+%      3. Number of translation along 2nd dimension of input.
+%
+%      4. Number of channel along 2nd dimension  of input
+%
+%      5. Plane number, corresponds to 3rd dimension of input. 
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/wmdct2.php}
+%@seealso{wmdct, iwmdct2, dgt2, wildual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.
+
+error(nargchk(3,5,nargin));
+
+L=[];
+
+if prod(size(p3))>2
+  % Two windows was specified.
+  g2=p3;
+  M=p4;
+  if nargin==5
+    L=p5;
+  end;
+else
+  g2=g1;
+  M=p3;
+  if nargin==4
+    L=p4;
+  end;
+end;
+  
+if isempty(L)
+  L1=[];
+  L2=[];
+else
+  L1=L(1);
+  L2=L(2);
+end;
+
+% Expand M if necessary to two elements
+M=bsxfun(@times,M,[1 1]);
+
+Ls=size(f);
+Ls=Ls(1:2);
+
+c=wmdct(f,g1,M(1),L1);
+c=wmdct(c,g2,M(2),L2,'dim',3);
+
diff --git a/inst/gabor/zak.m b/inst/gabor/zak.m
new file mode 100644
index 0000000..12dfefa
--- /dev/null
+++ b/inst/gabor/zak.m
@@ -0,0 +1,116 @@
+function c=zak(f,a);
+%-*- texinfo -*-
+%@deftypefn {Function} zak
+%@verbatim
+%ZAK  Zak transform
+%   Usage:  c=zak(f,a);
+%
+%   ZAK(f,a) computes the Zak transform of f with parameter a.  The
+%   coefficients are arranged in an a xL/a matrix, where L is the
+%   length of f.
+%
+%   If f is a matrix then the transformation is applied to each column.
+%   This is then indexed by the third dimension of the output.
+%
+%   Assume that c=zak(f,a), where f is a column vector of length L and
+%   N=L/a. Then the following holds for m=0,...,a-1 and n=0,...,N-1
+%
+%                          N-1  
+%     c(m+1,n+1)=1/sqrt(N)*sum f(m-k*a+1)*exp(2*pi*i*n*k/N)
+%                          k=0
+%
+%   Examples:
+%   ---------
+%
+%   This figure shows the absolute value of the Zak-transform of a Gaussian.
+%   Notice that the Zak-transform is 0 in only a single point right in the
+%   middle of the plot :
+%
+%     a=64;
+%     L=a^2; 
+%     g=pgauss(L);
+%     zg=zak(g,a);
+%
+%     surf(abs(zg));
+%   
+%   This figure shows the absolute value of the Zak-transform of a 4th order
+%   Hermite function.  Notice how the Zak transform of the Hermite functions
+%   is zero on a circle centered on the corner :
+%
+%     a=64;
+%     L=a^2; 
+%     g=pherm(L,4);
+%     zg=zak(g,a);
+%
+%     surf(abs(zg));
+%
+%
+%   References:
+%     A. J. E. M. Janssen. Duality and biorthogonality for discrete-time
+%     Weyl-Heisenberg frames. Unclassified report, Philips Electronics,
+%     002/94.
+%     
+%     H. Boelcskei and F. Hlawatsch. Discrete Zak transforms, polyphase
+%     transforms, and applications. IEEE Trans. Signal Process.,
+%     45(4):851-866, april 1997.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/gabor/zak.php}
+%@seealso{izak}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_ZAK
+%   REFERENCE: REF_ZAK
+
+error(nargchk(2,2,nargin));
+
+if (prod(size(a))~=1 || ~isnumeric(a))
+  error([callfun,': a must be a scalar']);
+end;
+
+if rem(a,1)~=0
+  error([callfun,': a must be an integer']);
+end;
+
+
+if size(f,2)>1 && size(f,1)==1
+  % f was a row vector.
+  f=f(:);
+end;
+
+L=size(f,1);
+W=size(f,2);
+N=L/a;
+
+if rem(N,1)~=0
+  error('The parameter for ZAK must divide the length of the signal.');
+end;
+
+c=zeros(a,N,W,assert_classname(f));
+
+for ii=1:W
+  % Compute it, it can be done in one line!
+  % We use a normalized DFT, as this gives the correct normalization
+  % of the Zak transform.
+  c(:,:,ii)=dft(reshape(f(:,ii),a,N),[],2);
+end;
+
+
+
diff --git a/inst/isoctave.m b/inst/isoctave.m
new file mode 100644
index 0000000..5dab3ac
--- /dev/null
+++ b/inst/isoctave.m
@@ -0,0 +1,39 @@
+function t=isoctave()
+%-*- texinfo -*-
+%@deftypefn {Function} isoctave
+%@verbatim
+%ISOCTAVE  True if the operating environment is octave
+%   Usage: t=isoctave();
+%
+%   ISOCTAVE returns 1 if the operating environment is Octave, otherwise
+%   it returns 0 (Matlab)
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/isoctave.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.  
+%   TESTING: NA
+%   REFERENCE: NA
+persistent inout;
+
+if isempty(inout),
+  inout = exist('OCTAVE_VERSION','builtin') ~= 0;
+end;
+t = inout;
+
diff --git a/inst/ltfat/DESCRIPTION b/inst/ltfat/DESCRIPTION
new file mode 100644
index 0000000..a8f59d9
--- /dev/null
+++ b/inst/ltfat/DESCRIPTION
@@ -0,0 +1,16 @@
+Name: LTFAT
+Version: 1.4.4
+Date: 2014-3-20
+Author: Peter L. Soendergaard <soender at users.sourceforge.net>
+Maintainer: Zdenek Prusa
+Title: The Large Time-Frequency Analysis Toolbox
+Description: The Large Time/Frequency Analysis Toolbox (LTFAT) is a
+ Matlab/Octave toolbox for working with time-frequency analysis,
+ wavelets and signal processing. It is intended both as an educational
+ and a computational tool. The toolbox provides a large number of
+ linear transforms including Gabor and wavelet transforms along with
+ routines for constructing windows (filter prototypes) and routines
+ for manipulating coefficients.
+License: GPLv3+
+BuildRequires: fftw3, lapack, blas, portaudio 
+Url: http://ltfat.sourceforge.net/
diff --git a/inst/ltfat/INDEX b/inst/ltfat/INDEX
new file mode 100644
index 0000000..cab4e85
--- /dev/null
+++ b/inst/ltfat/INDEX
@@ -0,0 +1,365 @@
+ltfat >> Time-frequency analysis and Wavelets
+signals
+ ctestfun
+ noise
+ pinknoise
+ expchirp
+ bat
+ batmask
+ greasy
+ cocktailparty
+ gspi
+ linus
+ ltfatlogo
+ otoclick
+ traindoppler
+ cameraman
+ lichtenstein
+ ltfattext
+operators
+ operatornew
+ operator
+ ioperator
+ operatoradj
+ operatorappr
+ operatoreigs
+ operatormatrix
+ framemul
+ iframemul
+ framemuladj
+ framemulappr
+ framemuleigs
+ gabmulappr
+ spreadop
+ spreadinv
+ spreadadj
+ spreadfun
+ spreadeigs
+deprecated
+ gabelitistlasso
+ gabgrouplasso
+ gablasso
+ gabmuleigs
+ gabmul
+ framematrix
+ iufilterbank
+ iunsdgt
+ iunsdgtreal
+ tfmat
+sigproc
+ rms
+ normalize
+ gaindb
+ crestfactor
+ uquant
+ rampup
+ rampdown
+ rampsignal
+ thresh
+ largestr
+ largestn
+ dynlimit
+ groupthresh
+ rgb2jpeg
+ jpeg2rgb
+ qam4
+ iqam4
+gabor
+ tconv
+ dsft
+ zak
+ izak
+ col2diag
+ s0norm
+ dgt
+ idgt
+ isgram
+ isgramreal
+ dgt2
+ idgt2
+ dgtreal
+ idgtreal
+ gabwin
+ dgtlength
+ dwilt
+ idwilt
+ dwilt2
+ idwilt2
+ wmdct
+ iwmdct
+ wmdct2
+ iwmdct2
+ wil2rect
+ rect2wil
+ wilwin
+ dwiltlength
+ gabdual
+ gabtight
+ gabfirdual
+ gaboptdual
+ gabfirtight
+ gabopttight
+ gabconvexopt
+ gabprojdual
+ gabmixdual
+ wilorth
+ wildual
+ gabframebounds
+ gabrieszbounds
+ wilbounds
+ gabdualnorm
+ gabframediag
+ wilframediag
+ gabphasegrad
+ gabreassign
+ phaselock
+ phaseunlock
+ symphase
+ matrix2latticetype
+ latticetype2matrix
+ shearfind
+ noshearlength
+ tfplot
+ plotdgt
+ plotdgtreal
+ plotdwilt
+ plotwmdct
+ sgram
+ gabimagepars
+ resgram
+ instfreqplot
+ phaseplot
+blockproc
+ block
+ blockdevices
+ blockread
+ blockplay
+ blockpanel
+ blockpanelget
+ blockdone
+ blockframeaccel
+ blockframepairaccel
+ blockana
+ blocksyn
+ blockfigure
+ blockplot
+ block_fwt
+ block_ifwt
+demos
+ demo_dgt
+ demo_gabfir
+ demo_imagecompression
+ demo_audiocompression
+ demo_audiodenoise
+ demo_ofdm
+ demo_audioshrink
+ demo_gabmulappr
+ demo_nsdgt
+ demo_pgauss
+ demo_pbspline
+ demo_gabmixdual
+ demo_framemul
+ demo_phaseplot
+ demo_frsynabs
+ demo_nextfastfft
+ demo_audscales
+ demo_auditoryfilterbank
+ demo_blockproc_basicloop
+ demo_blockproc_paramequalizer
+ demo_blockproc_denoising
+ demo_blockproc_slidingsgram
+ demo_blockproc_slidingcqt
+ demo_blockproc_slidingerblets
+ demo_blockproc_pitchshift
+ demo_blockproc_dgtequalizer
+auditory
+ semiaudplot
+ audtofreq
+ freqtoaud
+ audspace
+ audspacebw
+ erbtofreq
+ freqtoerb
+ erbspace
+ erbspacebw
+ audfiltbw
+ rangecompress
+ rangeexpand
+ gammatonefir
+nonstatgab
+ nsdgt
+ unsdgt
+ insdgt
+ nsdgtreal
+ unsdgtreal
+ insdgtreal
+ nsgabdual
+ nsgabtight
+ nsgabframebounds
+ nsgabframediag
+ plotnsdgt
+ plotnsdgtreal
+wavelets
+ fwt
+ ifwt
+ fwt2
+ ifwt2
+ ufwt
+ iufwt
+ fwtlength
+ fwtclength
+ wfbt
+ iwfbt
+ uwfbt
+ iuwfbt
+ wpfbt
+ iwpfbt
+ uwpfbt
+ iuwpfbt
+ wpbest
+ wfbtlength
+ wfbtinit
+ wfbtput
+ wfbtremove
+ wfbt2filterbank
+ fwt2filterbank
+ fwtinit
+ plotwavelets
+ wfiltinfo
+ wavfun
+ wavcell2pack
+ wavpack2cell
+ wfilt_algmband
+ wfilt_apr
+ wfilt_db
+ wfilt_dden
+ wfilt_dgrid
+ wfilt_dtree
+ wfilt_hden
+ wfilt_lemarie
+ wfilt_matlabwtwrapper
+ wfilt_maxflat
+ wfilt_mband
+ wfilt_optfs
+ wfilt_remez
+ wfilt_symds
+ wfilt_spline
+ wfilt_sym
+ wfreq_lemarie
+filterbank
+ filterbank
+ ufilterbank
+ ifilterbank
+ filterbankwin
+ filterbanklength
+ filterbanklengthcoef
+ cqt
+ icqt
+ erblett
+ ierblett
+ insdgfb
+ cqtfilters
+ erbfilters
+ filterbankdual
+ filterbanktight
+ filterbankrealdual
+ filterbankrealtight
+ filterbankbounds
+ filterbankrealbounds
+ filterbankresponse
+ plotfilterbank
+fourier
+ fftindex
+ modcent
+ floor23
+ floor235
+ ceil23
+ ceil235
+ nextfastfft
+ dft
+ idft
+ fftreal
+ ifftreal
+ gga
+ chirpzt
+ plotfft
+ plotfftreal
+ involute
+ peven
+ podd
+ pconv
+ convolve
+ pxcorr
+ isevenfunction
+ middlepad
+ expwave
+ pchirp
+ shah
+ pheaviside
+ prect
+ psinc
+ pgauss
+ psech
+ pbspline
+ firwin
+ firkaiser
+ fir2long
+ long2fir
+ firfilter
+ blfilter
+ warpedblfilter
+ pfilt
+ magresp
+ transferfunction
+ pherm
+ hermbasis
+ dfracft
+ ffracft
+ fftresample
+ dctresample
+ pderiv
+ dcti
+ dctii
+ dctiii
+ dctiv
+ dsti
+ dstii
+ dstiii
+ dstiv
+frames
+ frame
+ framepair
+ framedual
+ frametight
+ frameaccel
+ frana
+ frsyn
+ frsynmatrix
+ framediag
+ franaiter
+ frsyniter
+ plotframe
+ framegram
+ framebounds
+ framered
+ framelength
+ framelengthcoef
+ framecoef2native
+ framenative2coef
+ framecoef2tf
+ frametf2coef
+ franalasso
+ franagrouplasso
+ frsynabs
+base
+ ltfatstart
+ ltfatstop
+ ltfathelp
+ ltfatmex
+ ltfatbasepath
+ isoctave
+ ltfatarghelper
+ ltfatgetdefaults
+ ltfatsetdefaults
+ scalardistribute
+ mulaclab
diff --git a/inst/ltfat/PKG_ADD b/inst/ltfat/PKG_ADD
new file mode 100644
index 0000000..f11ce42
--- /dev/null
+++ b/inst/ltfat/PKG_ADD
@@ -0,0 +1,6 @@
+# Only execute it if it exists on the path. PKG_ADD also gets called from the directory
+# where the binaries are installed, and here ltfatstart should not be called.
+if exist("ltfatstart","file")   
+  # Start ltfat quietly 
+  ltfatstart(0);
+end;
diff --git a/inst/ltfat/inst/CITATION b/inst/ltfat/inst/CITATION
new file mode 100644
index 0000000..04a3f56
--- /dev/null
+++ b/inst/ltfat/inst/CITATION
@@ -0,0 +1,17 @@
+To cite LTFAT in publications please use:
+
+    Peter L. Søndergaard, Bruno Torrésani, Peter Balazs. The Linear Time-Frequency Analysis Toolbox.
+    International Journal of Wavelets, Multiresolution Analysis and Information Processing, 10(4), 2012.
+
+A BibTex entry for LaTex users:
+
+  @article{ltfatnote015,
+    author = "Peter L. S{\o}ndergaard and Bruno Torr\'esani and Peter Balazs",
+    title = {{The Linear Time Frequency Analysis Toolbox}},
+    journal = "International Journal of Wavelets, Multiresolution Analysis and Information Processing",
+    year = 2012,
+    volume = 10,
+    number = 4,
+    doi = "10.1142/S0219691312500324"
+  }
+ 
\ No newline at end of file
diff --git a/inst/ltfat_version b/inst/ltfat_version
new file mode 100644
index 0000000..1c99cf0
--- /dev/null
+++ b/inst/ltfat_version
@@ -0,0 +1 @@
+1.4.4
diff --git a/inst/ltfatarghelper.m b/inst/ltfatarghelper.m
new file mode 100755
index 0000000..e2cd2bc
--- /dev/null
+++ b/inst/ltfatarghelper.m
@@ -0,0 +1,290 @@
+function [flags,keyvals,varargout]  = ltfatarghelper(posdepnames,definput,arglist,callfun)
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatarghelper
+%@verbatim
+%LTFATARGHELPER  Parse arguments for LTFAT
+%   Usage: [flags,varargout]  = ltfatarghelper(posdepnames,definput,arglist,callfun);
+%
+%   Input parameters:
+%      posdepnames : Names of the position dependant parameters.
+%      definput    : Struct to define the allowed input
+%      arglist     : Commandline of the calling function (varargin)
+%      callfun     : Name of calling function (optional)
+%
+%   Output parameters:
+%      flags       : Struct with information about flags.
+%      keyvals     : Struct with key / values.
+%      varargout   : The position dependant pars. properly initialized
+%
+%   [flags,keyvals]=LTFATARGHELPER(posdepnames,definput,arglist) assists in
+%   parsing input parameters for a function in LTFAT. Parameters come in
+%   four categories:
+%  
+%    Position dependant parameters. These must not be strings. These are
+%     the first parameters passed to a function, and they are really just a
+%     short way of specifying key/value pairs. See below.
+%
+%    Flags. These are single string appearing after the position dependant
+%     parameters.
+%
+%    Key/value pairs. The key is always a string followed by the value,
+%     which can be anything.
+%
+%    Expansions. These appear as flags, that expand into a pre-defined list
+%     of parameters.  This is a short-hand way of specifying standard sets of
+%     flags and key/value pairs.
+%
+%   The parameters are parsed in order, so parameters appearing later in
+%   varargin will override previously set values.
+%
+%   The following example for calling LTFATARGHELPER is taken from DGT:
+%  
+%     definput.keyvals.L=[];
+%     definput.flags.phase={'freqinv','timeinv'};
+%     [flags,kv]=ltfatarghelper({'L'},definput,varargin);
+%
+%   The first line defines a key/value pair with the key 'L' having an
+%   initial value of [] (the empty matrix).
+%
+%   The second line defines a group of flags by the name of phase.  The
+%   group phase contains the flags 'freqinv' and 'timeinv', which can
+%   both be specified on the command line by the user. The group-name
+%   phase is just for internal use, and does not appear to the user. The
+%   flag mentioned first in the list will be selected by default, and only
+%   one flag in a group can be selected at any time. A group can contain as
+%   many flags as desired.
+%  
+%   The third line is the actual call to LTFATARGHELPER which defines the
+%   output flags and kv.  The input {'L'} indicates that the value of
+%   the parameter 'L' can also be given as the very first value in
+%   varargin.
+%
+%   The output struct kv contains the key/value pairs, so the value
+%   associated to 'L' is stored in kv.L.
+%
+%   The output struct flags contains information about the flags choosen
+%   by the user. The value of flags.phase will be set to the selected flag
+%   in the group phase and additionally, the value of flags.do_timeinv
+%   will be 1 if 'timeinv' was selected and 0 otherwise, and similarly for
+%   'freqinv'. This allows for easy checking of selected flags.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatarghelper.php}
+%@seealso{ltfatgetdefaults, ltfatsetdefaults}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+persistent TF_CONF;
+
+if isempty(TF_CONF)
+
+%  basepath=which('ltfatarghelper');
+%  % Kill the function name and comp from the path.
+%  basepath=basepath(1:end-22);
+%  % add the base path
+%  addpath(basepath);
+%  ltfatstart;
+
+  TF_CONF.fundefs = struct;
+end;
+
+if ischar(posdepnames)
+  % Special interface needed for ltfatsetdefaults and ltfatgetdefaults,
+  % activated when first argument is a string.
+
+  % First input  argument, posdepnames, is a string, one of the options
+  % in the "switch" section below
+  % Second input argument, definput,    is a function name to get or set
+  % Third  input argument, arglist ,    is a cell-array with options to set.
+  
+  switch(lower(posdepnames))
+   case 'get'
+    if isfield(TF_CONF.fundefs,definput)
+      flags=TF_CONF.fundefs.(definput);
+    else
+      flags={};
+    end;
+   case 'set'
+    TF_CONF.fundefs.(definput)=arglist;
+   case 'all'
+    flags=TF_CONF.fundefs;
+   case 'clearall'
+    TF_CONF.fundefs=struct; 
+  end;
+  return
+end;
+
+if nargin<4
+  f=dbstack;  
+  callfun=f(2).name;
+end;
+
+nposdep=numel(posdepnames);
+
+% Resolve import specifications BEFORE adding our own specifications.
+if isfield(definput,'import')
+  for imp = definput.import;
+    definput=feval(['arg_',imp{1}],definput);
+  end;
+end;
+
+if isfield(definput,'flags')
+  defflags=definput.flags;
+else
+  defflags=struct;
+end;
+
+if isfield(definput,'keyvals')
+  defkeyvals=definput.keyvals;
+else
+  defkeyvals=struct;
+end;
+
+if isfield(definput,'groups')
+  groups=definput.groups;
+else
+  groups=struct;
+end;
+
+total_args = numel(arglist);
+
+% Determine the position of the first optional argument.
+% If no optional argument is given, return nposdep+1
+first_str_pos = 1;
+while first_str_pos<=total_args && ~ischar(arglist{first_str_pos}) 
+  first_str_pos = first_str_pos +1;    
+end;
+
+% If more than nposdep arguments are given, the first additional one must
+% be a string
+if (first_str_pos>nposdep+1)
+  error('%s: Too many input arguments',upper(callfun));
+end;
+
+n_first_args=min(nposdep,first_str_pos-1);
+
+keyvals=defkeyvals;      
+
+% Copy the given first arguments
+for ii=1:n_first_args
+  keyvals.(posdepnames{ii})=arglist{ii};
+end;
+
+% Initialize the position independent parameters.
+% and create reverse mapping of flag -> group
+flagnames=fieldnames(defflags);
+flags=struct;
+% In order for flags to start with a number, it is necessary to add
+% 'x_' before the flag when the flags are used a field names in
+% flagreverse. Externally, flags are never used a field names in
+% structs, so this is an internal problem in ltfatarghelper that is
+% fixed this way.
+flagsreverse=struct;
+for ii=1:numel(flagnames)
+  name=flagnames{ii};
+  flaggroup=defflags.(name);
+  flags.(name)=flaggroup{1};
+  for jj=1:numel(flaggroup)
+    flagsreverse.(['x_', flaggroup{jj}])=name;
+    flags.(['do_',flaggroup{jj}])=0;
+  end;
+  flags.(['do_',flaggroup{1}])=1;
+end;
+
+%Get the rest of the arguments
+restlist = arglist(first_str_pos:end);
+
+%Check for default arguments
+if isfield(TF_CONF.fundefs,callfun)
+  s=TF_CONF.fundefs.(callfun);
+  restlist=[s,restlist];
+end;
+
+% Check for import defaults
+if isfield(definput,'importdefaults')
+  % Add the importdefaults before the user specified arguments.
+  restlist=[definput.importdefaults,restlist];
+end;
+
+while ~isempty(restlist)
+  argname=restlist{1};
+  restlist=restlist(2:end);  % pop
+  found=0;
+  
+  % Is this name a flag? If so, set it
+  if isfield(flagsreverse,['x_',argname])
+    % Unset all other flags in this group
+    flaggroup=defflags.(flagsreverse.(['x_',argname]));
+    for jj=1:numel(flaggroup)
+      flags.(['do_',flaggroup{jj}])=0;
+    end;
+    
+    flags.(flagsreverse.(['x_',argname]))=argname;
+    flags.(['do_',argname])=1;
+    found=1;
+  end;
+  
+  % Is this name the key of a key/value pair? If so, set the value.
+  if isfield(defkeyvals,argname)      
+    keyvals.(argname)=restlist{1};
+    restlist=restlist(2:end);
+    found=1;
+  end;
+  
+  % Is this name a group definition? If so, put the group in front of the parameters
+  if isfield(groups,argname)
+    s=groups.(argname);
+    restlist=[s,restlist];
+    found=1;
+  end;
+  
+  % Is the name == 'argimport'
+  if strcmp('argimport',argname)   
+    fieldnames_flags= fieldnames(restlist{1});  
+    fieldnames_kvs  = fieldnames(restlist{2});        
+    for ii=1:numel(fieldnames_flags)
+      importname=fieldnames_flags{ii};
+      flags.(importname)=restlist{1}.(importname);
+    end;
+    for ii=1:numel(fieldnames_kvs)
+      importname=fieldnames_kvs{ii};
+      keyvals.(importname)=restlist{2}.(importname);
+    end;      
+    restlist=restlist(3:end);
+    found=1;
+  end;
+  
+  if found==0
+    if ischar(argname)
+      error('%s: Unknown parameter: %s',upper(callfun),argname);
+    else
+      error('%s: Parameter is not a string, it is of class %s',upper(callfun),class(argname));          
+    end;      
+  end;
+  
+  %ii=ii+1;
+end;
+
+% Fill varargout
+
+varargout=cell(1,nposdep);
+for ii=1:nposdep
+    varargout(ii)={keyvals.(posdepnames{ii})};
+end;
+
+
diff --git a/inst/ltfatbasepath.m b/inst/ltfatbasepath.m
new file mode 100644
index 0000000..986e1ec
--- /dev/null
+++ b/inst/ltfatbasepath.m
@@ -0,0 +1,36 @@
+function bp = ltfatbasepath;
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatbasepath
+%@verbatim
+%LTFATBASEPATH  The base path of the LTFAT installation
+%   Usage: bp = ltfatbasepath;
+%
+%   LTFATBASEPATH returns the top level directory in which the LTFAT
+%   files are installed.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatbasepath.php}
+%@seealso{ltfatstart}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+f=mfilename('fullpath');
+
+bp = f(1:end-13);
+
+
diff --git a/inst/ltfatgetdefaults.m b/inst/ltfatgetdefaults.m
new file mode 100644
index 0000000..6c4eaa3
--- /dev/null
+++ b/inst/ltfatgetdefaults.m
@@ -0,0 +1,43 @@
+function d=ltfatgetdefaults(fname)
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatgetdefaults
+%@verbatim
+%LTFATGETDEFAULTS  Get default parameters of function
+%
+%   LTFATGETDEFAULTS(fname) returns the default parameters
+%   of the function fname as a cell array.
+%
+%   LTFATGETDEFAULTS('all') returns all the set defaults.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatgetdefaults.php}
+%@seealso{ltfatsetdefaults, ltfatstart}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<1
+    error('%s: Too few input arguments',upper(mfilename));
+end;
+
+if strcmpi(fname,'all')
+  d=ltfatarghelper('all');
+else
+  d=ltfatarghelper('get',fname);
+end;
+
+
diff --git a/inst/ltfathelp.m b/inst/ltfathelp.m
new file mode 100644
index 0000000..41c9cc1
--- /dev/null
+++ b/inst/ltfathelp.m
@@ -0,0 +1,115 @@
+function op1=ltfathelp(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ltfathelp
+%@verbatim
+%LTFATHELP Help on the LTFAT toolbox
+%   Usage:  ltfathelp;
+%           v=ltfathelp('version');
+%           mlist=ltfathelp('modules');
+%
+%   LTFATHELP displays some general help on the LTFAT toolbox.
+%
+%   LTFATHELP('version') returns the version number.
+%
+%   LTFATHELP('modules') returns a cell array of installed modules and
+%   corresponding version numbers.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfathelp.php}
+%@seealso{ltfatstart}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.  
+%   TESTING: NA
+%   REFERENCE: NA
+
+
+  
+% Verify that comp_pgauss is in path
+if ~exist('comp_pgauss','file')
+  disp(' ');
+  disp('--- LTFAT - The Linear Time Frequency Analysis toolbox. ---');
+  disp(' ')
+  disp('To start the toolbox, call LTFATSTART as the first command.');
+  disp(' ');
+  return;
+end;
+
+bp=ltfatbasepath;
+
+definput.keyvals.versiondata=[];
+definput.keyvals.modulesdata=[];
+definput.flags.mode={'general','version','modules'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_general
+  disp(' ');
+  disp('--- LTFAT - The Linear Time Frequency Analysis toolbox. ---');
+  disp(' ')
+
+  disp(['Version ',kv.versiondata]);
+  disp(' ');
+  disp('Installed modules:');
+  disp(' ');
+  disp('Name:            Version:  Description');
+  modinfo=ltfathelp('modules');
+  for ii=1:length(modinfo);
+    s=sprintf(' %-15s %7s  %s',modinfo{ii}.name,modinfo{ii}.version, ...
+	      modinfo{ii}.description);
+    disp(s);
+  end;
+
+  disp('Type "help modulename" where "modulename" is the name of one')
+  disp('of the modules to see help on that module.') 
+
+  disp(' ');
+  disp('For other questions, please don''t hesitate to send an email to ltfat-help at lists.sourceforge.net.'); 
+    
+end;
+  
+if flags.do_version
+  op1=kv.versiondata;
+end;
+
+if flags.do_modules
+  op1={};
+  for ii=1:numel(kv.modulesdata)
+    
+    p=kv.modulesdata{ii};
+    
+    % Get the first line of the help file
+    [FID, MSG] = fopen ([bp,p.name,filesep,'Contents.m'],'r');
+    if FID==-1
+      error('Module %s does not contain a Contents.m file.',p.name);
+    end;
+    firstline = fgetl (FID);
+    fclose(FID);
+    
+    
+    % Load the information into the cell array.	
+    op1{ii}.name=p.name;
+    op1{ii}.version=p.version;
+    op1{ii}.description=firstline(2:end);
+  end;
+end;
+
+
+
+
diff --git a/inst/ltfatmex.m b/inst/ltfatmex.m
new file mode 100644
index 0000000..6f733f3
--- /dev/null
+++ b/inst/ltfatmex.m
@@ -0,0 +1,526 @@
+function ltfatmex(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatmex
+%@verbatim
+%LTFATMEX   Compile Mex/Oct interfaces
+%   Usage:  ltfatmex;
+%           ltfatmex(...);
+%
+%   LTFATMEX compiles the C backend in order to speed up the execution of
+%   the toolbox. The C backend is linked to Matlab and Octave through Mex
+%   and Octave C++ interfaces.
+%
+%   The action of LTFATMEX is determined by one of the following flags:
+%
+%     'compile'  Compile stuff. This is the default.
+%
+%     'clean'    Removes the compiled functions.
+%
+%     'test'     Run some small tests that verify that the compiled
+%                functions work.
+%
+%   The target to work on is determined by on of the following flags.
+%
+%   General LTFAT:
+%
+%     'lib'      Perform action on the LTFAT C library.
+%
+%     'mex'      Perform action on the mex / oct interfaces.
+%
+%     'gpc'      Perform action on the GPC code for use with MULACLAB
+%
+%     'auto'     Choose automatically which targets to work on from the 
+%                previous ones based on the operation system etc. This is 
+%                the default.
+%
+%   Block-processing framework related:
+%
+%     'playrec'  Perform action on the playrec code for use with real-time
+%                block streaming framework.
+%
+%     'java'     Perform compilation of JAVA classes into the bytecode.
+%                The classes makes the GUI for the blockproc. framework.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatmex.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard.
+%   TESTING: NA
+%   REFERENCE: NA
+
+% Verify that comp_pgauss is in path
+if ~exist('comp_pgauss','file')
+  disp(' ');
+  disp('--- LTFAT - The Linear Time Frequency Analysis toolbox. ---');
+  disp(' ')
+  disp('To start the toolbox, call LTFATSTART as the first command.');
+  disp(' ');
+  return;
+end;
+
+bp=mfilename('fullpath');
+bp=bp(1:end-length(mfilename));
+
+definput.flags.target={'auto','lib','mex','gpc','playrec','java','blockproc'};
+definput.flags.command={'compile','clean','test'};
+definput.flags.libs={'matlablibs','systemlibs'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_systemlibs && (isoctave)
+    error('%s: Library preference is relevant only for Matlab.',...
+         upper(mfilename));
+end
+
+% Remember the current directory.
+curdir=pwd;
+
+% Compile backend lib?
+do_lib  = flags.do_lib || flags.do_auto;
+% Compile MEX/OCT interfaces?
+do_mex  = flags.do_mex || flags.do_auto;
+% Compile MEX PolygonClip.mex... using Generic Polygon Clipper
+% (relevant only for the mulaclab, which does not work in Octave)
+do_gpc  = flags.do_gpc || (flags.do_auto && ~isoctave);
+% Compile MEX playrec.mex... using Portaudio library.
+% (relevant only for the bloc processing framework)
+do_playrec  = flags.do_playrec || flags.do_blockproc;
+% Compile Java classes containing GUI for the bloc proc. framework.
+do_java  = flags.do_java || flags.do_blockproc;
+
+
+if isoctave && flags.do_gpc
+    error('%s: Compiling GPC is not relevant for Octave.',upper(mfilename));
+end
+
+if isoctave
+	extname='oct';
+    ext='oct';
+else
+    extname='mex';
+    ext=mexext;
+end;
+
+fftw_lib_names = {'fftw3', 'fftw3f' };
+
+% Check if we are on Windows
+if ispc
+    makefilename='Makefile_mingw';
+    make_exe = 'mingw32-make';
+    sharedExt = 'dll';
+    %fftw_lib_names = {'fftw3', 'fftw3f' };
+    % The pre-compiled Octave for Windows comes only in 32bit version (3.6.4)
+    % We use different Makefiles
+    if isoctave
+      makefilename='Makefile_mingwoct';      
+    end
+end;
+
+% Check if we are on Unix-type system
+if isunix
+   makefilename='Makefile_unix';
+   make_exe = 'make';
+   sharedExt = 'so';
+end;
+
+% Check if we are on Mac
+if ismac
+   makefilename='Makefile_mac';
+   make_exe = 'make';
+   sharedExt = 'dylib';
+end;
+
+
+clear mex;
+% -------------- Handle cleaning --------------------------------
+if flags.do_clean
+
+  if do_lib
+    disp('========= Cleaning libltfat ===============');
+    cd([bp,'src']);
+    callmake(make_exe,makefilename,'target','clean');
+    %[status,result]=system([make_exe, ' -f ',makefilename,' clean']);
+    %disp('Done.');    
+  end;
+  
+  if do_mex
+    fprintf('========= Cleaning %s interfaces =========\n', upper(extname));
+     cd([bp,extname]);
+     callmake(make_exe,makefilename,'target','clean','ext',ext);
+     %[status,result]=system([make_exe, ' -f ',makefilename,' clean',...
+     %                ' EXT=',ext]); 
+  end;
+  
+  if do_gpc
+    disp('========= Cleaning GPC ====================');
+    cd([bp,'thirdparty',filesep,'PolygonClip']);
+    clear mex; 
+    callmake(make_exe,makefilename,'target','clean','ext',mexext);
+    %[status,result]=system([make_exe, ' -f ',makefilename,' clean',' EXT=',mexext]);
+  end;
+  
+  if do_playrec
+     % Use the correct makefile 
+     if isoctave
+       if ~strcmpi(makefilename(end-2:end),ext)
+          makefilename = [makefilename,ext];
+       end
+    end 
+      
+    disp('========= Cleaning PLAYREC ================');
+    cd([bp,'thirdparty',filesep,'Playrec']);
+    clear mex; 
+    %[status,result]=system([make_exe, ' -f ',makefilename,' clean',' EXT=',mexext]);
+    callmake(make_exe,makefilename,'target','clean','ext',mexext); 
+  end;
+  
+  if do_java
+    disp('========= Cleaning JAVA ================');
+    cd([bp,'blockproc',filesep,'java']);
+    %[status,result]=system([make_exe,' clean']);
+    callmake(make_exe,[],'target','clean');
+  end;
+
+  cd(curdir);
+end;
+
+% -------------- Handle compiling  --------------------------------
+
+if flags.do_compile
+  if do_lib
+    disp('========= Compiling libltfat ==============');
+    cd([bp,'src']);
+    clear mex; 
+    
+    dfftw = ['-l',fftw_lib_names{1}];
+    sfftw = ['-l',fftw_lib_names{2}];
+    if ispc && ~isoctave
+        fftw_lib_found_names = searchfor(bp,fftw_lib_names,sharedExt);
+        if ~isempty(fftw_lib_found_names)
+           dfftw = ['-l:',fftw_lib_found_names{1}];
+           sfftw = ['-l:',fftw_lib_found_names{2}];
+       end
+    end
+      % DFFTW and SFFTW are not used in the unix_makefile
+      [status,result] = callmake(make_exe,makefilename,'matlabroot','arch',...
+                       'dfftw',dfftw,'sfftw',sfftw);
+      if(~status)
+        disp('Done.');
+      else
+        error('Failed to build LTFAT libs:\n %s',result);
+      end
+    %end;
+  end;
+  
+  if do_mex
+    fprintf('========= Compiling %s interfaces ========\n', upper(extname));
+    clear mex; 
+    cd([bp,extname]);
+    
+    dfftw = ['-l',fftw_lib_names{1}];
+    sfftw = ['-l',fftw_lib_names{2}];
+    if ~isoctave
+        fftw_lib_found_names = searchfor(bp,fftw_lib_names,sharedExt);
+        if ~isempty(fftw_lib_found_names)
+            if ~ismac
+               dfftw = ['-l:',fftw_lib_found_names{1}];
+               sfftw = ['-l:',fftw_lib_found_names{2}];
+            else
+                % We need a full path here.
+               dfftw = [binDirPath(),filesep,fftw_lib_found_names{1}];
+               sfftw = [binDirPath(),filesep,fftw_lib_found_names{2}];               
+            end
+       end
+    end
+    
+    [status,result] = callmake(make_exe,makefilename,'matlabroot','arch',...
+                      'ext',ext,'dfftw',dfftw,'sfftw',sfftw);
+
+    if(~status)
+      disp('Done.');
+    else
+      error('Failed to build %s interfaces: %s \n',upper(extname),result);
+    end
+  end;
+  
+  if do_gpc
+    disp('========= Compiling GPC ===================');
+    % Compile the PolygonClip interface to GPC for use with mulaclab
+    cd([bp,'thirdparty',filesep,'PolygonClip']);
+    clear mex; 
+    [status,result] = callmake(make_exe,makefilename,'matlabroot','arch',...
+                      'ext',ext);
+
+    if(~status)
+      disp('Done.');
+    else
+      error('Failed to build GPC:\n %s',result);
+    end
+  end;
+  if do_playrec
+    disp('========= Compiling PLAYREC ===============');
+    cd([bp,'thirdparty',filesep,'Playrec']);
+    clear mex; 
+    % Compile the Playrec (interface to portaudio) for the real-time block-
+    % stream processing
+
+     portaudioLib = '-lportaudio';
+
+     binArchPath = binDirPath();
+       playrecRelPath = ['thirdparty',filesep,'Playrec'];
+
+       foundPAuser = [];
+       if ispc
+          foundPAuser = dir([bp,playrecRelPath,filesep,'*portaudio*',sharedExt,'*']);
+       end
+       
+       foundPAmatlab = [];
+       if ~isoctave
+          % Check if portaudio library is present in the Matlab instalation
+          foundPAmatlab = dir([binArchPath,filesep,'*portaudio*',sharedExt,'*']);
+       end
+       
+       if ~isempty(foundPAuser)
+          if numel(foundPAuser)>1
+             error('Ambiguous portaudio libraries in %s. Please leave just one.',playrecRelPath);
+          end
+          foundPAuser = foundPAuser(1).name;
+
+       elseif ~isempty(foundPAmatlab)
+          if numel(foundPAmatlab)>1
+             if ispc 
+                %This should not happen on Windows
+                %Use the first one on Linux
+                error('Ambiguous portaudio libraries in %s.',binArchPath);
+             end
+          end
+             foundPAmatlab = foundPAmatlab(1).name;
+       else
+          if ispc && isoctave || ispc
+          error(['Portaudio not found. Please download Portaudio http://www.portaudio.com\n',...
+                 'and build it as a shared library and copy it to the\n',...
+                 '%s directory. \n'],playrecPath);
+          end
+       end
+
+    if isoctave
+       if ~strcmpi(makefilename(end-2:end),ext)
+          makefilename = [makefilename,ext];
+       end
+    end
+    
+    doPAuser = ~isempty(foundPAuser);
+    doPAmatlab = ~isempty(foundPAmatlab) && ~doPAuser;
+
+    if doPAmatlab 
+       if ismac
+          % Full path is needed on MAC since 
+          % clang does not understand -l: prefix.
+          portaudioLib = [binArchPath,filesep,foundPAmatlab];    
+       else
+          portaudioLib = ['-l:',foundPAmatlab]; 
+       end
+       fprintf('    ...using %s from Matlab instalation.\n',foundPAmatlab);          
+    elseif doPAuser
+        portaudioLib = ['-l:',foundPAuser]; 
+        fprintf('   ...using %s from ltfat%s%s.\n',...
+                  foundPAuser,filesep,playrecRelPath);
+    end
+
+    [status,result] = callmake(make_exe,makefilename,'matlabroot','arch',...
+                      'ext',mexext,'portaudio',portaudioLib);
+    if(~status)
+      disp('Done.');
+    else
+      error('Failed to build PLAYREC:\n %s',result);
+    end
+  end;
+  
+  if do_java
+    disp('========= Compiling JAVA classes ===================');
+    % Compile the JAVA classes
+    cd([bp,'blockproc',filesep,'java']);
+    clear mex; 
+    [status,result] = callmake(make_exe);
+    if(~status)
+      disp('Done.');
+    else
+      error('Failed to build JAVA classes:\n %s',result);
+    end
+  end;
+end;
+
+% -------------- Handle testing ---------------------------------------
+
+if flags.do_test
+  
+  if do_mex
+    
+    fprintf('========= Testing %s interfaces ==========\n', extname);
+    fprintf('1.: Test if comp_pgauss.%s was compiled: ',ext);
+    fname=['comp_pgauss.',ext];
+    if exist(fname,'file')
+      disp('SUCCESS.');
+    else
+      disp('FAILED.');
+    end;
+    
+    fprintf('2.: Test if pgauss executes:              ');
+    pgauss(100);
+    % If the execution of the script makes it here, we know that pgauss
+    % did not crash the system, so we can just print success. Same story
+    % with the following entries.
+    disp('SUCCESS.');
+
+    fprintf('3.: Test if fftreal executes:             ');
+    fftreal(randn(10,1),10);
+    disp('SUCCESS.');
+
+    fprintf('4.: Test if dgt executes:                 ');
+    dgt(randn(12,1),randn(12,1),3,4);
+    disp('SUCCESS.');
+
+    
+  end;
+  
+end;
+
+% Jump back to the original directory.
+cd(curdir);
+
+
+function status = filesExist(filenames)
+   if(~iscell(filenames))
+      filenames={filenames};
+   end
+   for ii=1:length(filenames)
+      filename = filenames{ii};
+      if(~exist(filename,'file'))
+         error('%s: File %s not found.',mfilename,filename);
+      end
+   end
+ 
+function found_files=searchfor(bp,files,sharedExt)
+
+found_names = {};
+      if ispc 
+         for ii=1:numel(files) 
+            % Search the ltfat/mex lib
+            L = dir([bp,'mex',filesep,'*',files{ii},'*.',sharedExt]);
+            if isempty(L)
+                error(['%s: %s could not be found in ltfat/mex subdir.',...
+                       ' Please download the FFTW dlls and istall them.'],...
+                      upper(mfilename),files{ii});
+            end
+            found_files{ii} = L(1).name;
+            fprintf('   ...using %s from ltfat/mex.\n',L(1).name);
+         end
+      elseif isunix
+          for ii=1:numel(files)
+             L = dir([binDirPath(),filesep,'*',files{ii},'*.',sharedExt,'*']); 
+             
+             if isempty(L)
+                 error('%s: Matlab FFTW libs were not found. Strange.',...
+                      upper(mfilename));
+             end
+
+             found_files{ii} = L(1).name;
+
+             fprintf('   ...using %s from Matlab instalation.\n',...
+                     found_files{ii});
+          end
+          
+      end;
+
+function path=binDirPath()
+path = [matlabroot,filesep,'bin',filesep,computer('arch')];
+   
+function [status,result]=callmake(make_exe,makefilename,varargin)
+%CALLMAKE   
+%   Usage:  callmake(make_exe,makefilename);
+%           callmake(make_exe,makefilename,'matlabroot',matlabroot,...);
+%
+%   `callmake(make_exe,makefilename)` is a platform independent wrapper for
+%   calling the make command `make_exe` on `makefilename` file. When 
+%   `makefilename` is missing or is empty, the default `Makefile` file is
+%   used.
+%   
+%   `callmake(...,'target',target)` used `target` from the makefile.
+%
+%   Flags:
+%
+%       matlabroot:   Pass MATLABROOT=matlabroot variable to the makefile.
+%
+%       arch:         Pass ARCH=computer('arch') variable to the makefile.
+%
+%   Key-value parameters:
+%
+%       ext:          Pass EXT variable to the makefile.
+%
+%       portaudio:    Pass PORTAUDIO variable to the makefile.
+%
+%       dfftw:        Pass DFFTW variable to the makefile.
+%
+%       sfftw:        Pass SFFTW variable to the makefile.
+  
+
+  if nargin < 2 || isempty(makefilename)
+     systemCommand = make_exe; 
+  else
+     systemCommand = [make_exe, ' -f ',makefilename];
+  end
+  definput.flags.matlabroot={'none','matlabroot'};
+  definput.flags.arch={'none','arch'};
+  definput.keyvals.ext=[];
+  definput.keyvals.dfftw=[];
+  definput.keyvals.sfftw=[];
+  definput.keyvals.target=[];
+  definput.keyvals.portaudio=[];
+  [flags,kv]=ltfatarghelper({},definput,varargin);
+  
+  if flags.do_matlabroot
+     systemCommand = [systemCommand, ' MATLABROOT=','"',matlabroot,'"']; 
+  end
+  
+  if flags.do_arch
+     systemCommand = [systemCommand, ' ARCH=',computer('arch')]; 
+  end
+  
+  if ~isempty(kv.ext)
+     systemCommand = [systemCommand, ' EXT=',kv.ext]; 
+  end
+  
+  if ~isempty(kv.dfftw)
+     systemCommand = [systemCommand, ' DFFTW=',kv.dfftw]; 
+  end
+  
+  if ~isempty(kv.sfftw)
+     systemCommand = [systemCommand, ' SFFTW=',kv.sfftw]; 
+  end
+  
+  if ~isempty(kv.portaudio)
+     systemCommand = [systemCommand, ' PORTAUDIO=',kv.portaudio]; 
+  end
+  
+  if ~isempty(kv.target)
+     systemCommand = [systemCommand,' ',kv.target];  
+  end
+
+  [status,result]=system(systemCommand);
+
+
diff --git a/inst/ltfatsetdefaults.m b/inst/ltfatsetdefaults.m
new file mode 100644
index 0000000..a4d16c8
--- /dev/null
+++ b/inst/ltfatsetdefaults.m
@@ -0,0 +1,42 @@
+function ltfatsetdefaults(fname,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatsetdefaults
+%@verbatim
+%LTFATSETDEFAULTS  Set default parameters of function
+%
+%   LTFATSETDEFAULTS(fname,...) sets the default parameters to be the
+%   parameters specified at the end of the list of input arguments.
+%
+%   LTFATSETDEFAULTS(fname) clears any default parameters for the function
+%   fname.
+%
+%   LTFATSETDEFAULTS('clearall') clears all defaults from all functions.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatsetdefaults.php}
+%@seealso{ltfatgetdefaults, ltfatstart}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if strcmpi(fname,'clearall')
+  ltfatarghelper('clearall');
+else
+  ltfatarghelper('set',fname,varargin);
+end;
+
+
diff --git a/inst/ltfatstart.m b/inst/ltfatstart.m
new file mode 100644
index 0000000..0642d8f
--- /dev/null
+++ b/inst/ltfatstart.m
@@ -0,0 +1,212 @@
+function ltfatstart(ltfatstartprint)
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatstart
+%@verbatim
+%LTFATSTART   Start the LTFAT toolbox
+%   Usage:  ltfatstart;
+%
+%   LTFATSTART starts the LTFAT toolbox. This command must be run
+%   before using any of the functions in the toolbox.
+%
+%   To configure default options for functions, you can use the
+%   LTFATSETDEFAULTS function in your startup script. A typical startup
+%   file could look like:
+%
+%     addpath('/path/to/my/work/ltfat');
+%     ltfatstart;
+%     ltfatsetdefaults('sgram','nocolorbar');
+%
+%   This will add the main LTFAT directory to you path, start the
+%   toolbox, and configure SGRAM to not display the colorbar.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatstart.php}
+%@seealso{ltfatsetdefaults, ltfatmex, ltfathelp, ltfatstop}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.  
+%   TESTING: NA
+
+if nargin==0
+    ltfatstartprint=1;
+end;
+
+% Get the basepath as the directory this function resides in.
+% The 'which' solution below is more portable than 'mfilename'
+% becase old versions of Matlab does not have "mfilename('fullpath')"
+basepath=which('ltfatstart');
+% Kill the function name from the path.
+basepath=basepath(1:end-13);
+
+% add the base path
+addpath(basepath);
+
+bp=[basepath,filesep];
+
+% Load the version number
+[FID, MSG] = fopen ([bp,'ltfat_version'],'r');
+if FID == -1
+    error(MSG);
+else
+    ltfat_version = fgetl (FID);
+    fclose(FID);
+end
+
+%% --- Check for old versions of Octave and Matlab
+if isoctave
+   major_rq=3;
+   minor_rq=6;
+   intp='Octave';
+   req_versionname='3.6.0';
+else
+   major_rq=7;
+   minor_rq=9;
+   intp='Matlab';
+   req_versionname='2009b';
+end;
+
+% Split into major and minor version
+s=version;
+stops=find(s=='.');
+major_no  = str2num(s(1:stops(1)));
+if numel(stops)==1
+  minor_no  = str2num(s(stops(1)+1:end));
+  bugfix_no = 0;
+else
+  minor_no  = str2num(s(stops(1)+1:stops(2)));
+  bugfix_no = str2num(s(stops(2)+1:end));
+end;
+
+% Do the check, multiply by some big number to make the check easy
+if major_rq*1000+minor_rq>major_no*1000+minor_no
+  warning(['Your version of %s is too old for this version of LTFAT ' ...
+         'to function proberly. Your need at least version %s of %s.'],...
+	  intp,req_versionname,intp);
+end;
+
+
+%% -----------  install the modules -----------------
+
+modules={};
+nplug=0;
+
+% List all files in base directory
+d=dir(basepath);
+
+for ii=1:length(d)
+  
+  % We only look for directories
+  if ~d(ii).isdir
+    continue;
+  end;
+  
+  % Skip the default directories . and ..
+  if (d(ii).name(1)=='.')
+    continue;
+  end;
+  
+  % Skip directories without an init file
+  name=d(ii).name;
+  % CThe file is a directory and it does not start with '.' This could
+  % be a module
+  if ~exist([bp,name,filesep,name,'init.m'],'file')
+    continue
+  end;
+    
+  % Now we know that we have found a module
+  
+  % Set 'status' to zero if the module forgets to define it.
+  status=0;
+  
+  module_version=ltfat_version;
+     
+  % Add the module dir to the path
+  addpath([bp,name])  
+  
+  % Execute the init file to see if the status is set.
+  eval([name,'init']);
+  if status>0
+    if status==1
+      nplug=nplug+1;
+      modules{nplug}.name=name;
+      modules{nplug}.version=module_version;
+    end;
+  else
+    % Something failed, restore the path
+    rmpath([bp,name]);
+  end;
+end;
+
+
+% Check if Octave was called using 'silent'
+%if isoctave
+%  args=argv;
+%  for ii=1:numel(args)
+%    s=lower(args{ii});
+%    if strcmp(s,'--silent') || strcmp(s,'-q')
+%      printbanner=0;
+%    end;
+%  end;
+%end;
+
+if ltfatstartprint
+  try
+    s=which('comp_pgauss');
+    if isempty(s)
+      error('comp_pgauss not found, something is wrong.')
+    end;
+  
+    if strcmp(s(end-1:end),'.m')
+      backend = 'LTFAT is using the script language backend.';
+    else
+      if isoctave
+        backend = 'LTFAT is using the C++ Octave backend.';
+      else
+        backend = 'LTFAT is using the MEX backend.';
+      end;
+    end;
+  catch
+    backend = 'Error with backend, consider running "ltfatmex clean" immidiatly.';
+  end; 
+  
+  banner = sprintf(['LTFAT version %s. Copyright 2005-2014 Peter L. Soendergaard. ' ...
+                    'For help, please type "ltfathelp". %s'], ...
+                   ltfat_version,backend);
+  
+  disp(banner);
+  
+  if exist('ltfat_binary_notes.m','file')
+    ltfat_binary_notes;    
+  end;
+
+end;
+
+%% ---------- load information into ltfathelp ------------
+
+% As comp is now in the path, we can call ltfatarghelper
+ltfatsetdefaults('ltfathelp','versiondata',ltfat_version,...
+                 'modulesdata',modules);
+
+%% ---------- other initializations ---------------------
+
+% Force the loading of FFTW, necessary for Matlab 64 bit on Linux. Thanks
+% to NFFT for this trick.
+fft([1,2,3,4]);
+
+
diff --git a/inst/ltfatstop.m b/inst/ltfatstop.m
new file mode 100644
index 0000000..cd5eeb7
--- /dev/null
+++ b/inst/ltfatstop.m
@@ -0,0 +1,50 @@
+function ltfatstop()
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatstop
+%@verbatim
+%LTFATSTOP   Stops the LTFAT toolbox
+%   Usage:  ltfatstop;
+%
+%   LTFATSTOP removes all LTFAT subdirectories from the path.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/ltfatstop.php}
+%@seealso{ltfatstart}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard.  
+
+fullpath=strsplit(path,pathsep);
+
+bp=ltfatbasepath;
+% Remove the file separator at the end
+bp=bp(1:end-1);
+bplen=numel(bp);
+
+for line=fullpath
+    % Strip the cell array container away
+    thispath=line{1};
+    if numel(thispath)>=bplen && strcmp(thispath(1:bplen),bp)
+        rmpath(thispath);
+        disp(thispath)
+    end;    
+end;
+    
+  
+
diff --git a/inst/nonstatgab/Contents.m b/inst/nonstatgab/Contents.m
new file mode 100644
index 0000000..f6aa595
--- /dev/null
+++ b/inst/nonstatgab/Contents.m
@@ -0,0 +1,43 @@
+% LTFAT - Non-stationary Gabor systems
+%
+%  Florent Jaillet and Peter L. Soendergaard, 2011 - 2014
+%
+%  Transforms
+%    NSDGT                - Non-stationary DGT
+%    UNSDGT               - Uniform non-stationary DGT
+%    INSDGT               - Inverse NSDGT and UNSDGT
+%    NSDGTREAL            - Non-stationary DGT for real-valued signals
+%    UNSDGTREAL           - Uniform non-stationary DGT for real-valued signals
+%    INSDGTREAL           - Inverse NSDGTREAL and UNSDGTREAL
+%
+%  Window construction and bounds
+%    NSGABDUAL            - Non-stationary dual windows
+%    NSGABTIGHT           - Non-stationary tight windows
+%    NSGABFRAMEBOUNDS     - Frame bounds of an NSDGT system
+%    NSGABFRAMEDIAG       - Diagoal of non-stationary Gabor frame operator
+%
+%  Plots
+%    PLOTNSDGT            - Plot output coefficients from NSDGT
+%    PLOTNSDGTREAL        - Plot output coefficients from NSDGTREAL
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/nonstatgab/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/nonstatgab/insdgt.m b/inst/nonstatgab/insdgt.m
new file mode 100644
index 0000000..2b1fd9a
--- /dev/null
+++ b/inst/nonstatgab/insdgt.m
@@ -0,0 +1,113 @@
+function f=insdgt(c,g,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} insdgt
+%@verbatim
+%INSDGT  Inverse nonstationary discrete Gabor transform
+%   Usage:  f=insdgt(c,g,a,Ls);
+%
+%   Input parameters:
+%         c     : Cell array of coefficients.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         Ls    : Length of input signal.
+%   Output parameters:
+%         f     : Signal.
+%
+%   INSDGT(c,g,a,Ls) computes the inverse non-stationary Gabor transform
+%   of the input coefficients c.
+%
+%   INSDGT is used to invert the functions NSDGT and UNSDGT. Please
+%   read the help of these functions for details of variables format and
+%   usage.
+%
+%   For perfect reconstruction, the windows used must be dual windows of the
+%   ones used to generate the coefficients. The windows can be generated
+%   using NSGABDUAL or NSGABTIGHT.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/insdgt.php}
+%@seealso{nsdgt, nsgabdual, nsgabtight, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet and Nicki Holighaus
+%   TESTING: TEST_NSDGT
+%   REFERENCE: REF_INSDGT
+%   Last changed 2009-05
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+definput.keyvals.Ls=[];
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+timepos=cumsum(a)-a(1);
+L=sum(a);
+
+if iscell(c)
+    % ---- invert the non-uniform case ---------
+    M=cellfun(@(x) size(x,1),c);
+    N=length(c);
+    W=size(c{1},2);   
+    f=zeros(L,W,assert_classname(c{1}));
+else
+    % ---- invert the uniform case ----------------
+    [M, N, W]=size(c);   
+    f=zeros(L,W,assert_classname(c));
+end
+
+[g,info]=nsgabwin(g,a,M);
+
+
+
+for ii = 1:N
+    Lg = length(g{ii});
+    gt = g{ii};
+    
+    % This is an explicit fftshift
+    gt = gt([Lg-floor(Lg/2)+1:Lg,1:ceil(Lg/2)]);
+    
+    win_range = mod(timepos(ii)+(-floor(Lg/2):ceil(Lg/2)-1),L)+1;
+    
+    if iscell(c)
+        M = size(c{ii},1);
+        temp = ifft(c{ii},[],1)*M;
+    else
+        temp = ifft(c(:,ii,:),[],1)*M;
+    end
+    idx = mod([M-floor(Lg/2)+1:M,1:ceil(Lg/2)]-1,M)+1;
+    temp = temp(idx,:);
+    f(win_range,:) = f(win_range,:) + bsxfun(@times,temp,gt);
+end
+
+if ~isempty(Ls)
+  f = f(1:Ls,:);
+end;
+
diff --git a/inst/nonstatgab/insdgtreal.m b/inst/nonstatgab/insdgtreal.m
new file mode 100644
index 0000000..c07cfd1
--- /dev/null
+++ b/inst/nonstatgab/insdgtreal.m
@@ -0,0 +1,119 @@
+function f=insdgtreal(c,g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} insdgtreal
+%@verbatim
+%INSDGTREAL  Inverse NSDGT for real-valued signals
+%   Usage:  f=insdgt(c,g,a,M,Ls);
+%
+%   Input parameters:
+%         c     : Cell array of coefficients.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         M     : Vector of numbers of frequency channels.
+%         Ls    : Length of input signal.
+%   Output parameters:
+%         f     : Signal.
+%
+%   insdgt(c,g,a,Ls) computes the inverse non-stationary Gabor transform
+%   of the input coefficients c.
+%
+%   insdgt is used to invert the functions NSDGT and UNSDGT. Please
+%   read the help of these functions for details of variables format and
+%   usage.
+%
+%   For perfect reconstruction, the windows used must be dual windows of the
+%   ones used to generate the coefficients. The windows can be generated
+%   using NSGABDUAL or NSGABTIGHT.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/insdgtreal.php}
+%@seealso{nsdgt, nsgabdual, nsgabtight, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet and Nicki Holighaus
+%   TESTING: TEST_NSDGT
+%   REFERENCE: 
+%   Last changed 2009-05
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+definput.keyvals.Ls=[];
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+timepos=cumsum(a)-a(1);
+L=sum(a);
+
+[g,info]=nsgabwin(g,a,M);
+
+if iscell(c)
+    % ---- invert the non-uniform case ---------
+    
+    N=length(c); % Number of time positions
+    W=size(c{1},2); % Number of signal channels
+    f=zeros(L,W,assert_classname(c{1})); % Initialisation of the result
+else
+    % ---- invert the uniform case ----------------
+    [M2, N, W]=size(c);
+    f=zeros(L,W,assert_classname(c)); % Initialisation of the result
+    
+    if ~info.isuniform
+        error('%s: M must be a scalar or a constant vector.',upper(mfilename));    
+    end;
+    M=M(1);       
+end
+
+for ii = 1:N
+    Lg = length(g{ii});
+    gt = g{ii};
+    
+    % This is an explicit fftshift
+    idx=[Lg-floor(Lg/2)+1:Lg,1:ceil(Lg/2)];
+    gt = gt(idx);
+    
+    win_range = mod(timepos(ii)+(-floor(Lg/2):ceil(Lg/2)-1),L)+1;
+    
+    if iscell(c)
+        temp = ifftreal(c{ii},M(ii),1)*M(ii);
+        idx = mod([M(ii)-floor(Lg/2)+1:M(ii),1:ceil(Lg/2)]-1,M(ii))+1;
+    else
+        temp = ifftreal(c(:,ii,:),M,1)*M;
+        idx = mod([M-floor(Lg/2)+1:M,1:ceil(Lg/2)]-1,M)+1; 
+    end
+    temp = temp(idx,:);
+    f(win_range,:) = f(win_range,:) + bsxfun(@times,temp,gt);
+end
+
+if ~isempty(Ls)
+  f = f(1:sum(a),:);
+end;
+
+
diff --git a/inst/nonstatgab/nonstatgabinit.m b/inst/nonstatgab/nonstatgabinit.m
new file mode 100644
index 0000000..2148490
--- /dev/null
+++ b/inst/nonstatgab/nonstatgabinit.m
@@ -0,0 +1,26 @@
+status=1;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} nonstatgabinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nonstatgabinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/nonstatgab/nsdgt.m b/inst/nonstatgab/nsdgt.m
new file mode 100644
index 0000000..757241b
--- /dev/null
+++ b/inst/nonstatgab/nsdgt.m
@@ -0,0 +1,169 @@
+function [c,Ls] = nsdgt(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} nsdgt
+%@verbatim
+%NSDGT  Non-stationary Discrete Gabor transform
+%   Usage:  c=nsdgt(f,g,a,M);
+%           [c,Ls]=nsdgt(f,g,a,M);
+%
+%   Input parameters:
+%         f     : Input signal.
+%         g     : Cell array of window functions.
+%         a     : Vector of time shifts.
+%         M     : Vector of numbers of frequency channels.
+%   Output parameters:
+%         c     : Cell array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   NSDGT(f,g,a,M) computes the nonstationary Gabor coefficients of the
+%   input signal f. The signal f can be a multichannel signal, given in
+%   the form of a 2D matrix of size Ls xW, with Ls the signal
+%   length and W the number of signal channels.
+%
+%   The nonstationnary Gabor theory extends standard Gabor theory by
+%   enabling the evolution of the window over time. It is therefor necessary
+%   to specify a set of windows instead of a single window.  This is done by
+%   using a cell array for g. In this cell array, the n'th element g{n}
+%   is a row vector specifying the n'th window.
+%
+%   The resulting coefficients also require a storage in a cell array, as
+%   the number of frequency channels is not constant over time. More
+%   precisely, the n'th cell of c, c{n}, is a 2D matrix of size 
+%   M(n) xW and containing the complex local spectra of the signal channels
+%   windowed by the n'th window g{n} shifted in time at position a(n).
+%   c{n}(m,w) is thus the value of the coefficient for time index n,
+%   frequency index m and signal channel w.
+%
+%   The variable a contains the distance in samples between two
+%   consequtive blocks of coefficients. The variable M contains the
+%   number of channels for each block of coefficients. Both a and M are
+%   vectors of integers.
+%
+%   The variables g, a and M must have the same length, and the result c*
+%   will also have the same length.
+%   
+%   The time positions of the coefficients blocks can be obtained by the
+%   following code. A value of 0 correspond to the first sample of the
+%   signal:
+%
+%     timepos = cumsum(a)-a(1);
+%
+%   [c,Ls]=NSDGT(f,g,a,M) additionally returns the length Ls of the input 
+%   signal f. This is handy for reconstruction:
+%
+%     [c,Ls]=nsdgt(f,g,a,M);
+%     fr=insdgt(c,gd,a,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, 
+%   provided that gd are dual windows of g.
+%
+%   Notes:
+%   ------
+%
+%   NSDGT uses circular border conditions, that is to say that the signal is
+%   considered as periodic for windows overlapping the beginning or the 
+%   end of the signal.
+%
+%   The phaselocking convention used in NSDGT is different from the
+%   convention used in the DGT function. NSDGT results are phaselocked (a
+%   phase reference moving with the window is used), whereas DGT results are
+%   not phaselocked (a fixed phase reference corresponding to time 0 of the
+%   signal is used). See the help on PHASELOCK for more details on
+%   phaselocking conventions.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsdgt.php}
+%@seealso{insdgt, nsgabdual, nsgabtight, phaselock, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Florent Jaillet and Nicki Holighaus
+%   TESTING: TEST_NSDGT
+%   REFERENCE: REF_NSDGT
+
+% Notes:
+% - The choice of a different phaselocking convention than the one used in
+%   dgt is motivated by the will to keep a diagonal frame operator in the
+%   painless case and to keep the circular border condition. With the other
+%   convention, there is in general a problem for windows overlapping the
+%   beginning and the end of the signal (except if time positions and
+%   signal length have some special ratio properties).
+
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(M)
+  error('%s: M must be numeric.',upper(mfilename));
+end;
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,upper(mfilename),0);
+
+L=nsdgtlength(Ls,a);
+f=postpad(f,L);
+
+[g,info]=nsgabwin(g,a,M);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a); % Number of time positions
+
+c=cell(N,1); % Initialisation of the result
+    
+% The actual transform
+   
+for ii = 1:N
+    Lg = length(g{ii});
+    
+    % This is an explicit fftshift
+    idx=[Lg-floor(Lg/2)+1:Lg,1:ceil(Lg/2)];
+
+    win_range = mod(timepos(ii)+(-floor(Lg/2):ceil(Lg/2)-1),L)+1;
+    if M(ii) < Lg 
+        % if the number of frequency channels is too small, aliasing is introduced
+        col = ceil(Lg/M(ii));
+        
+        temp = zeros(col*M(ii),W,assert_classname(f,g{1}));
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = bsxfun(@ ...
+                                                          times,f(win_range,:),g{ii}(idx));
+        
+        temp = reshape(temp,M(ii),col,W);
+        X = squeeze(fft(sum(temp,2)));
+        
+        c{ii}=X;
+    else
+        
+        temp = zeros(M(ii),W,assert_classname(f,g{1}));
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = bsxfun(@times, ...
+                                                          f(win_range,:),g{ii}(idx));
+        
+        
+        c{ii} = fft(temp);
+    end       
+end
+
diff --git a/inst/nonstatgab/nsdgtlength.m b/inst/nonstatgab/nsdgtlength.m
new file mode 100644
index 0000000..e0a80e7
--- /dev/null
+++ b/inst/nonstatgab/nsdgtlength.m
@@ -0,0 +1,58 @@
+function L=nsdgtlength(Ls,a);
+%-*- texinfo -*-
+%@deftypefn {Function} nsdgtlength
+%@verbatim
+%NSDGTLENGTH  Nsdgt length from signal
+%   Usage: L=nsdgtlength(Ls,a);
+%
+%   NSDGTLENGTH(Ls,a) returns the length of an NSDGT with time shifts
+%   a, such that it is long enough to expand a
+%   signal of length Ls.
+%
+%   If the returned length is longer than the signal length, the signal
+%   will be zero-padded by NSDGT or UNSDGT.
+%
+%   If instead a set of coefficients are given, call NSDGTLENGTHCOEF.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsdgtlength.php}
+%@seealso{nsdgt, nsdgtlengthcoef}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if ~isnumeric(Ls)
+  error('%s: Ls must be numeric.',upper(mfilename));
+end;
+
+if ~isscalar(Ls)
+  error('%s: Ls must a scalar.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isvector(a) || any(a<0)
+  error('%s: "a" must be a vector of non-negative numbers.',upper(mfilename));
+end;
+
+L=sum(a);
+
+if Ls>L
+    error('%s: The signal must have at most %i samples.',upper(mfilename),L);
+end;
diff --git a/inst/nonstatgab/nsdgtreal.m b/inst/nonstatgab/nsdgtreal.m
new file mode 100644
index 0000000..974493d
--- /dev/null
+++ b/inst/nonstatgab/nsdgtreal.m
@@ -0,0 +1,187 @@
+function [c,Ls] = nsdgtreal(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} nsdgtreal
+%@verbatim
+%NSDGTREAL  Non-stationary Discrete Gabor transform for real valued signals
+%   Usage:  c=nsdgtreal(f,g,a,M);
+%           [c,Ls]=nsdgtreal(f,g,a,M);
+%
+%   Input parameters:
+%         f     : Input signal.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         M     : Vector of numbers of frequency channels.
+%   Output parameters:
+%         c     : Cell array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   NSDGTREAL(f,g,a,M) computes the nonstationary Gabor coefficients of the
+%   input signal f. The signal f can be a multichannel signal, given in
+%   the form of a 2D matrix of size Ls xW, with Ls the signal
+%   length and W the number of signal channels.
+%
+%   As opposed to NSDGT only the coefficients of the positive frequencies
+%   of the output are returned. NSDGTREAL will refuse to work for complex
+%   valued input signals.
+%
+%   The nonstationnary Gabor theory extends standard Gabor theory by
+%   enabling the evolution of the window over time. It is therefor necessary
+%   to specify a set of windows instead of a single window.  This is done by
+%   using a cell array for g. In this cell array, the n'th element g{n}
+%   is a row vector specifying the n'th window.
+%
+%   The resulting coefficients also require a storage in a cell array, as
+%   the number of frequency channels is not constant over time. More
+%   precisely, the n'th cell of c, c{n}, is a 2D matrix of size
+%   M(n)/2+1 xW and containing the complex local spectra of the
+%   signal channels windowed by the n'th window g{n} shifted in time at
+%   position a(n).  c{n}(m,l) is thus the value of the coefficient for
+%   time index n, frequency index m and signal channel l.
+%
+%   The variable a contains the distance in samples between two
+%   consequtive blocks of coefficients. The variable M contains the
+%   number of channels for each block of coefficients. Both a and M are
+%   vectors of integers.
+%
+%   The variables g, a and M must have the same length, and the result c*
+%   will also have the same length.
+%   
+%   The time positions of the coefficients blocks can be obtained by the
+%   following code. A value of 0 correspond to the first sample of the
+%   signal:
+%
+%     timepos = cumsum(a)-a(1);
+%
+%   [c,Ls]=NSDGTREAL(f,g,a,M) additionally returns the length Ls of the input 
+%   signal f. This is handy for reconstruction:
+%
+%     [c,Ls]=nsdgtreal(f,g,a,M);
+%     fr=insdgtreal(c,gd,a,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, 
+%   provided that gd are dual windows of g.
+%
+%   Notes:
+%   ------
+%
+%   NSDGTREAL uses circular border conditions, that is to say that the signal is
+%   considered as periodic for windows overlapping the beginning or the 
+%   end of the signal.
+%
+%   The phaselocking convention used in NSDGTREAL is different from the
+%   convention used in the DGT function. NSDGTREAL results are phaselocked (a
+%   phase reference moving with the window is used), whereas DGT results are
+%   not phaselocked (a fixed phase reference corresponding to time 0 of the
+%   signal is used). See the help on PHASELOCK for more details on
+%   phaselocking conventions.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsdgtreal.php}
+%@seealso{nsdgt, insdgtreal, nsgabdual, nsgabtight, phaselock, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGTREAL
+%   REFERENCE: 
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(M)
+  error('%s: M must be numeric.',upper(mfilename));
+end;
+
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,upper(mfilename),0);
+
+L=nsdgtlength(Ls,a);
+f=postpad(f,L);
+
+[g,info]=nsgabwin(g,a,M);
+
+if L<info.gl
+  error('%s: Window is too long.',upper(mfilename));
+end;
+
+timepos=cumsum(a)-a(1);
+
+N=length(a); % Number of time positions
+
+c=cell(N,1); % Initialisation of the result
+   
+for ii = 1:N
+    Lg = length(g{ii});
+    gt = g{ii}; gt = gt([end-floor(Lg/2)+1:end,1:ceil(Lg/2)]);
+    win_range = mod(timepos(ii)+(-floor(Lg/2):ceil(Lg/2)-1),L)+1;
+    if M(ii) < Lg 
+        % if the number of frequency channels is too small, aliasing is introduced
+        col = ceil(Lg/M(ii));
+        temp = zeros(col*M(ii),W,assert_classname(f,g{1}));
+        temp([col*M(ii)-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = bsxfun(@times,f(win_range,:),gt);
+        temp = reshape(temp,M(ii),col,W);
+        
+        c{ii}=squeeze(fftreal(sum(temp,2)));
+    else
+        temp = zeros(M(ii),W,assert_classname(f,g{1}));
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = bsxfun(@times,f(win_range,:),gt);
+        c{ii} = fftreal(temp);
+    end       
+end
+
+if 0
+for ii=1:N
+  shift=floor(length(g{ii})/2);
+  temp=zeros(M(ii),W,assert_classname(f,g{1}));
+  
+  % Windowing of the signal.
+  % Possible improvements: The following could be computed faster by 
+  % explicitely computing the indexes instead of using modulo and the 
+  % repmat is not needed if the number of signal channels W=1 (but the time 
+  % difference when removing it whould be really small)
+  temp(1:length(g{ii}))=f(mod((1:length(g{ii}))+timepos(ii)-shift-1,L)+1,:).*...
+    repmat(conj(circshift(g{ii},shift)),1,W);
+  
+  temp=circshift(temp,-shift);
+  if M(ii)<length(g{ii}) 
+    % Fft size is smaller than window length, some aliasing is needed
+    x=floor(length(g{ii})/M(ii));
+    y=length(g{ii})-x*M(ii);
+    % Possible improvements: the following could probably be computed 
+    % faster using matrix manipulation (reshape, sum...)
+    temp1=temp;
+    temp=zeros(M(ii),size(temp,2),assert_classname(f,g{1}));
+    for jj=0:x-1
+      temp=temp+temp1(jj*M(ii)+(1:M(ii)),:);
+    end
+    temp(1:y,:)=temp(1:y,:)+temp1(x*M(ii)+(1:y),:);
+  end
+  
+  c{ii}=fftreal(temp); % FFT of the windowed signal
+end
+end;
diff --git a/inst/nonstatgab/nsgabdual.m b/inst/nonstatgab/nsgabdual.m
new file mode 100644
index 0000000..c72c38d
--- /dev/null
+++ b/inst/nonstatgab/nsgabdual.m
@@ -0,0 +1,128 @@
+function gd=nsgabdual(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} nsgabdual
+%@verbatim
+%NSGABDUAL  Canonical dual window for non-stationary Gabor frames
+%   Usage:  gd=nsgabdual(g,a,M);
+%           gd=nsgabdual(g,a,M,L);
+%
+%   Input parameters:
+%         g     : Cell array of windows.
+%         a     : Vector of time shift.
+%         M     : Vector of numbers of channels.
+%         L     : Transform length.
+%   Output parameters:
+%         gd : Cell array of canonical dual windows
+%
+%   NSGABDUAL(g,a,M,L) computes the canonical dual windows of the 
+%   non-stationary discrete Gabor frame defined by windows given in g an
+%   time-shifts given by a.
+%   
+%   NSGABDUAL is designed to be used with the functions NSDGT and
+%   INSDGT.  See the help on NSDGT for more details about the variables
+%   structure.
+%
+%   The computed dual windows are only valid for the 'painless case', that
+%   is to say that they ensure perfect reconstruction only if for each 
+%   window the number of frequency channels used for computation of NSDGT is
+%   greater than or equal to the window length. This correspond to cases
+%   for which the frame operator is diagonal.
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsgabdual.php}
+%@seealso{nsgabtight, nsdgt, insdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGT
+%   REFERENCE:
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(M)
+  error('%s: M must be numeric.',upper(mfilename));
+end;
+
+definput.keyvals.L=sum(a);
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a);
+
+[g,info]=nsgabwin(g,a,M);
+a=info.a;
+M=info.M;
+
+if info.isfac
+    if info.ispainless
+        f=zeros(L,1); % Diagonal of the frame operator
+        
+        % Compute the diagonal of the frame operator:
+        f=nsgabframediag(g,a,M);
+        
+        % Initialize the result with g
+        gd=g;
+        
+        % Correct each window to ensure perfect reconstrution
+        for ii=1:N
+            shift=floor(length(g{ii})/2);
+            tempind=mod((1:length(g{ii}))+timepos(ii)-shift-1,L)+1;
+            gd{ii}(:)=circshift(circshift(g{ii},shift)./f(tempind),-shift);
+        end
+        
+    else
+
+        if 0
+            % Convert to freq. domain and run filterbankdual
+            % The code does not work
+            gf=cell(1,N);
+            gd=cell(1,N);
+            for ii=1:N
+                gf{ii}=circshift(fft(fir2long(g{ii},L)),timepos(ii));
+            end;
+            
+            gfd=filterbankdual(gf,M);
+            for ii=1:N
+                gd{ii}=ifft(circshift(gfd{ii},-timepos(ii)));
+            end;
+        else
+            error('Not implemented yet.');
+        end;
+    end;
+else
+    
+    error(['%s: The canonical dual frame of this system is not a ' ...
+           'non-stationary Gabor frame. You must call an iterative ' ...
+           'method to perform the desired inverstion. Please see ' ...
+           'FRANAITER or FRSYNITER.'],upper(mfilename));        
+end;
+
diff --git a/inst/nonstatgab/nsgabframebounds.m b/inst/nonstatgab/nsgabframebounds.m
new file mode 100644
index 0000000..cc4ea86
--- /dev/null
+++ b/inst/nonstatgab/nsgabframebounds.m
@@ -0,0 +1,75 @@
+function [AF,BF]=nsgabframebounds(g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} nsgabframebounds
+%@verbatim
+%NSGABFRAMEBOUNDS  Frame bounds of nonstationnary Gabor frame
+%   Usage:  fcond=nsgabframebounds(g,a,M);
+%           [A,B]=nsgabframebounds(g,a,M);
+%
+%   Input parameters:
+%         g     : Cell array of windows
+%         a     : Vector of time positions of windows.
+%         M     : Vector of numbers of frequency channels.
+%   Output parameters:
+%         fcond : Frame condition number (B/A)
+%         A,B   : Frame bounds.
+%
+%   NSGABFRAMEBOUNDS(g,a,Ls) calculates the ratio B/A of the frame
+%   bounds of the nonstationary discrete Gabor frame defined by windows
+%   given in g at positions given by a. Please see the help on NSDGT
+%   for a more thourough description of g and a.
+%
+%   [A,B]=NSGABFRAMEBOUNDS(g,a,Ls) returns the actual frame bounds A*
+%   and B instead of just the their ratio.
+%
+%   The computed frame bounds are only valid for the 'painless case' when
+%   the number of frequency channels used for computation of NSDGT is greater
+%   than or equal to the window length. This correspond to cases for which
+%   the frame operator is diagonal.
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsgabframebounds.php}
+%@seealso{nsgabtight, nsdgt, insdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGT
+
+% Compute the diagonal of the frame operator.
+f=nsgabframediag(g,a,M);
+
+AF=min(f);
+BF=max(f);
+
+if nargout<2
+  % Avoid the potential warning about division by zero.
+  if AF==0
+    AF=Inf;
+  else
+    AF=BF/AF;
+  end;
+end;
+
+
diff --git a/inst/nonstatgab/nsgabframediag.m b/inst/nonstatgab/nsgabframediag.m
new file mode 100644
index 0000000..a545166
--- /dev/null
+++ b/inst/nonstatgab/nsgabframediag.m
@@ -0,0 +1,67 @@
+function d=nsgabframediag(g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} nsgabframediag
+%@verbatim
+%NSGABFRAMEDIAG  Diagonal of Gabor frame operator
+%   Usage:  d=nsgabframediag(g,a,M);
+%
+%   Input parameters:
+%         g     : Window function.
+%         a     : Length of time shift.
+%         M     : Number of channels.
+%   Output parameters:
+%         d     : Diagonal stored as a column vector
+%
+%   NSGABFRAMEDIAG(g,a,M) computes the diagonal of the non-stationary
+%   Gabor frame operator with respect to the window g and parameters a*
+%   and M. The diagonal is stored as a column vector of length L=sum(a).
+%
+%   The diagonal of the frame operator can for instance be used as a
+%   preconditioner.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsgabframediag.php}
+%@seealso{nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+L=sum(a);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a);
+
+[g,info]=nsgabwin(g,a,M);
+
+a=info.a;
+M=info.M;
+
+d=zeros(L,1,assert_classname(g{1}));
+for ii=1:N
+    shift=floor(length(g{ii})/2);
+    temp=abs(circshift(g{ii},shift)).^2*M(ii);
+    tempind=mod((1:length(g{ii}))+timepos(ii)-shift-1,L)+1;
+    d(tempind)=d(tempind)+temp;
+end
+
+
+
diff --git a/inst/nonstatgab/nsgabtight.m b/inst/nonstatgab/nsgabtight.m
new file mode 100644
index 0000000..65a3360
--- /dev/null
+++ b/inst/nonstatgab/nsgabtight.m
@@ -0,0 +1,129 @@
+function gt=nsgabtight(g,a,M,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} nsgabtight
+%@verbatim
+%NSGABTIGHT  Canonical tight window for non-stationary Gabor frames
+%   Usage:  gt=nsgabtight(g,a,M);
+%           gt=nsgabtight(g,a,M,L);
+%
+%   Input parameters:
+%         g     : Cell array of windows
+%         a     : Vector of time shifts of windows.
+%         M     : Vector of numbers of channels.
+%         L     : Transform length.
+%   Output parameters:
+%         gt : Cell array of canonical tight windows
+%
+%   NSGABTIGHT(g,a,M) computes the canonical tight windows of the 
+%   non-stationary discrete Gabor frame defined by windows given in g and  
+%   time-shifts given by a.
+%   
+%   NSGABTIGHT is designed to be used with functions NSDGT and
+%   INSDGT.  Read the help on NSDGT for more details about the variables
+%   structure.
+%
+%   The computed tight windows are only valid for the 'painless case', that
+%   is to say that they ensure perfect reconstruction only if for each 
+%   window the number of frequency channels used for computation of NSDGT is
+%   greater than or equal to the window length. This correspond to cases
+%   for which the frame operator is diagonal.
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsgabtight.php}
+%@seealso{nsgabtight, nsdgt, insdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGT
+%   REFERENCE:
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(M)
+  error('%s: M must be numeric.',upper(mfilename));
+end;
+
+definput.keyvals.L=sum(a);
+[flags,kv,L]=ltfatarghelper({'L'},definput,varargin);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a);
+
+[g,info]=nsgabwin(g,a,M);
+
+a=info.a;
+M=info.M;
+
+if info.isfac
+    if info.ispainless
+        f=zeros(L,1); % Diagonal of the frame operator
+
+        % Compute the diagonal of the frame operator:
+        f=nsgabframediag(g,a,M);
+        
+        % As we want tight frame, we will use the sqrt of the operator
+        f=sqrt(f);
+        
+        % Initialize the result with g
+        gt=g;
+        
+        % Correct each window to ensure perfect reconstrution
+        for ii=1:N
+            shift=floor(length(g{ii})/2);
+            tempind=mod((1:length(g{ii}))+timepos(ii)-shift-1,L)+1;
+            gt{ii}(:)=circshift(circshift(g{ii},shift)./f(tempind),-shift);
+        end
+    
+    else
+        if 0
+            % Convert to freq. domain and run filterbanktight
+            gf=cell(1,N);
+            gt=cell(1,N);
+            for ii=1:N
+                gf{ii}=circshift(fft(fir2long(g{ii},L)),timepos(ii));
+            end;
+            
+            gft=filterbanktight(gf,M);
+            for ii=1:N
+                gt{ii}=ifft(circshift(gft{ii},-timepos(ii)));
+            end;
+                
+        else
+            error(['%s: Not implemented yet.'],upper(mfilename));
+        end;
+    end;
+else
+            
+    error(['%s: The canonical tight frame of this system is not a ' ...
+               'non-stationary Gabor frame.'],upper(mfilename));
+end;
+
diff --git a/inst/nonstatgab/nsgabwin.m b/inst/nonstatgab/nsgabwin.m
new file mode 100644
index 0000000..585cf64
--- /dev/null
+++ b/inst/nonstatgab/nsgabwin.m
@@ -0,0 +1,138 @@
+function [g,info] = nsgabwin(g,a,M);
+%-*- texinfo -*-
+%@deftypefn {Function} nsgabwin
+%@verbatim
+%NSGABWIN  Compute a set of non-stationary Gabor windows from text or cell array
+%   Usage: [g,info] = nsgabwin(g,a,M);
+%
+%   [g,info]=NSGABWIN(g,a,M,L) computes a window that fits well with
+%   time shift a, number of channels M and and transform length L.
+%   The window itself is as a cell array containing additional parameters.
+%
+%   The window can be specified directly as a cell array of vectors of
+%   numerical values. In this case, NSGABWIN only checks assumptions
+%   about transform sizes etc.
+%
+%   [g,info]=NSGABWIN(g,a,M) does the same, but the windows must be FIR
+%   windows, as the transform length is unspecified.
+%
+%   The window can also be specified as cell array. The possibilities are:
+%
+%     {'dual',...}
+%         Canonical dual window of whatever follows. See the examples below.
+%
+%     {'tight',...}
+%         Canonical tight window of whatever follows. See the examples below.
+%
+%   The structure info provides some information about the computed
+%   window:
+%
+%     info.gauss    True if the windows are Gaussian.
+%
+%     info.tfr      Time/frequency support ratios of the window. 
+%                   Set whenever it makes sense.
+%
+%     info.isfir    Input is an FIR window
+%
+%     info.isdual   Output is the dual window of the auxiliary window.
+%
+%     info.istight  Output is known to be a tight window.
+%
+%     info.auxinfo  Info about auxiliary window.
+%   
+%     info.gl       Length of windows.
+%
+%     info.isfac    True if the frame generated by the window has a fast
+%                   factorization.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/nsgabwin.php}
+%@seealso{filterbank, filterbankdual, filterbankrealdual}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Assert correct input.
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~iscell(g)
+  error('%s: Window g must be a cell array.',upper(mfilename));
+end;
+
+if isempty(g)
+  error('%s: Window g must not be empty.',upper(mfilename));
+end;
+
+info.isdual=0;
+info.istight=0;
+
+% To stop the madness, all index/lengths vectors are converted to columns
+a=a(:);
+M=M(:);
+
+if ischar(g{1})
+    winname=lower(g{1});
+    switch(winname)
+      case {'dual'}
+        [g,info.auxinfo] = nsgabwin(g{2},a,M);
+        g = nsgabdual(g,a,M);
+        info.isdual=1;
+        
+      case {'tight'}
+        [g,info.auxinfo] = nsgabwin(g{2},a,M);    
+        g = nsgabtight(g,a,M);
+        info.istight=1;
+        
+      otherwise
+        error('%s: Unsupported window type %s.',winname,upper(mfilename));
+    end;
+end;
+
+info.gl=cellfun(@length,g);
+info.gl=info.gl(:);
+
+info.L=sum(a);
+info.a=a;
+N=length(a);
+
+if N~=numel(g)
+  error(['%s: The number of time-shifts %i must match the number of windows ' ...
+         '%i.'],upper(mfilename),N,numel(g));
+end;
+
+if numel(M)~=1 && numel(M)~=N
+    error(['%s: The arrays "a" and "M" must be equally long. ' ...
+           'numel(a)=%i, numel(M)=%i.'],upper(mfilename),N,numel(M));
+end;
+
+if any(info.L<info.gl)
+    error('%s: Window is too long.',upper(mfilename));
+end;
+
+info.ispainless=all(info.gl<=M);
+info.isuniform=std(M)==0;
+
+info.isfac=info.ispainless || (info.isuniform && rem(info.L,M(1))==0);
+
+if info.isuniform
+    info.M=repmat(M(1),N,1);
+else
+    info.M=M;
+end;
+
diff --git a/inst/nonstatgab/plotnsdgt.m b/inst/nonstatgab/plotnsdgt.m
new file mode 100644
index 0000000..e10e6c4
--- /dev/null
+++ b/inst/nonstatgab/plotnsdgt.m
@@ -0,0 +1,112 @@
+function coef = plotnsdgt(coef,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotnsdgt
+%@verbatim
+%PLOTNSDGT Plot spectrogram from non-stationary Gabor coefficients
+%   Usage:  plotnsdgt(c,a,fs,dynrange);
+%
+%   Input parameters:
+%         coef     : Cell array of coefficients.
+%         a        : Vector of time positions of windows.
+%         fs       : signal sample rate in Hz (optional)
+%         dynrange : Color scale dynamic range in dB (optional).
+%
+%   PLOTNSDGT(coef,a) plots coefficients computed using NSDGT or
+%   UNSDGT. For more details on the format of the variables coef and a,
+%   please read the function help for these functions.
+%
+%   PLOTNSDGT(coef,a,fs) does the same assuming a sampling rate of
+%   fs Hz of the original signal.
+%
+%   PLOTNSDGT(coef,a,fs,dynrange) additionally limits the dynamic range.
+%
+%   C=PLOTNSDGT(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar
+%   functions will create the plot. This is useful for custom
+%   post-processing of the image data.
+%
+%   PLOTNSDGT supports all the optional parameters of TFPLOT. Please
+%   see the help of TFPLOT for an exhaustive list. In addition, the
+%   following parameters may be specified:
+%
+%     'xres',xres  Approximate number of pixels along x-axis / time.
+%                  The default value is 800
+%
+%     'yres',yres  Approximate number of pixels along y-axis / frequency
+%                  The default value is 600
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/plotnsdgt.php}
+%@seealso{tfplot, nsdgt, unsdgt, nsdgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet and Peter L. Soendergaard
+%   TESTING: OK 
+%   REFERENCE: NA
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+
+definput.keyvals.xres=800;
+definput.keyvals.yres=600;
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a);
+cwork=zeros(kv.yres,N);
+
+%% -------- Interpolate in frequency ---------------------
+
+for ii=1:N
+  column=coef{ii};
+  M=length(column);
+  cwork(:,ii)=interp1(linspace(0,1,M),column,linspace(0,1,kv.yres),'nearest');
+end;
+
+%% --------  Interpolate in time -------------------------
+
+% Time step in next equidistant spacing on the x-axis (in samples)
+aplot=timepos(end)/kv.xres;
+
+% Time positions where we want our pixels plotted (in samples)
+xr=(0:kv.xres-1)*aplot;
+
+% Move zero frequency to the center and Nyquist frequency to the top.
+if rem(kv.yres,2)==0
+  coef=circshift(coef,kv.yres/2-1);
+else
+  coef=circshift(coef,(kv.yres-1)/2);
+end;
+
+coef=zeros(kv.yres,kv.xres);
+for ii=1:kv.yres
+  data=interp1(timepos,cwork(ii,:).',xr,'nearest').';
+  coef(ii,:)=data;
+end;
+
+yr=[-1+2/kv.yres,1];
+
+coef=tfplot(coef,aplot,yr,'argimport',flags,kv);
+
+
diff --git a/inst/nonstatgab/plotnsdgtreal.m b/inst/nonstatgab/plotnsdgtreal.m
new file mode 100644
index 0000000..0c1493a
--- /dev/null
+++ b/inst/nonstatgab/plotnsdgtreal.m
@@ -0,0 +1,104 @@
+function coef = plotnsdgtreal(coef,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotnsdgtreal
+%@verbatim
+%PLOTNSDGTREAL Plot spectrogram from NSDGTREAL coefficients
+%   Usage:  plotnsdgtreal(c,a,fs,dynrange);
+%
+%   Input parameters:
+%         coef     : Cell array of coefficients.
+%         a        : Vector of time positions of windows.
+%         fs       : signal sample rate in Hz (optional).
+%         dynrange : Colorscale dynamic range in dB (optional).
+%
+%   PLOTNSDGTREAL(coef,a) plots coefficients computed using NSDGTREAL or
+%   UNSDGTREAL. For more details on the format of the variables coef and a,
+%   please read the function help for these functions.
+%
+%   PLOTNSDGTREAL(coef,a,fs) does the same assuming a sampling rate of
+%   fs Hz of the original signal.
+%
+%   PLOTNSDGTREAL(coef,a,fs,dynrange) additionally limits the dynamic range.
+%
+%   C=PLOTNSDGTREAL(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar
+%   functions will create the plot. This is usefull for custom
+%   post-processing of the image data.
+%
+%   PLOTNSDGTREAL supports all the optional parameters of TFPLOT. Please
+%   see the help of TFPLOT for an exhaustive list. In addition, the
+%   following parameters may be specified:
+%
+%     'xres',xres  Approximate number of pixels along x-axis /time.
+%                  Default value is 800
+%
+%     'yres',yres  Approximate number of pixels along y-axis / frequency
+%                  Default value is 600
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/plotnsdgtreal.php}
+%@seealso{tfplot, nsdgt, nsdgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Florent Jaillet & Peter L. Soendergaard
+%   TESTING: OK 
+%   REFERENCE: NA
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'ltfattranslate','tfplot'};
+
+definput.keyvals.xres=800;
+definput.keyvals.yres=600;
+
+[flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a);
+cwork=zeros(kv.yres,N);
+
+%% -------- Interpolate in frequency ---------------------
+
+for ii=1:N
+  column=coef{ii};
+  M=length(column);
+  cwork(:,ii)=interp1(linspace(0,1,M),column,linspace(0,1,kv.yres),'nearest');
+end;
+
+%% --------  Interpolate in time -------------------------
+
+% Time step in next equidistant spacing on the x-axis (in samples)
+aplot=timepos(end)/kv.xres;
+
+% Time positions where we want our pixels plotted (in samples)
+xr=(0:kv.xres-1)*aplot;
+
+coef=zeros(kv.yres,kv.xres);
+for ii=1:kv.yres
+  data=interp1(timepos,cwork(ii,:).',xr,'nearest').';
+  coef(ii,:)=data;
+end;
+
+yr=[0,1];
+
+coef=tfplot(coef,aplot,yr,'argimport',flags,kv);
+
diff --git a/inst/nonstatgab/unsdgt.m b/inst/nonstatgab/unsdgt.m
new file mode 100644
index 0000000..08d1394
--- /dev/null
+++ b/inst/nonstatgab/unsdgt.m
@@ -0,0 +1,146 @@
+function [c,Ls] = unsdgt(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} unsdgt
+%@verbatim
+%UNSDGT  Uniform Nonstationary Discrete Gabor transform
+%   Usage:  c=unsdgt(f,g,a,M);
+%           [c,Ls]=unsdgt(f,g,a,M);
+%
+%   Input parameters:
+%         f     : Input signal.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         M     : Numbers of frequency channels.
+%   Output parameters:
+%         c     : Cell array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   UNSDGT(f,g,a,M) computes the uniform nonstationary Gabor coefficients
+%   of the input signal f. The signal f can be a multichannel signal,
+%   given in the form of a 2D matrix of size Ls xW, with Ls being
+%   the signal length and W the number of signal channels.
+%
+%   The non-stationary Gabor theory extends standard Gabor theory by
+%   enabling the evolution of the window over time. It is therefor necessary
+%   to specify a set of windows instead of a single window.  This is done by
+%   using a cell array for g. In this cell array, the n'th element g{n}
+%   is a row vector specifying the n'th window. However, the uniformity
+%   means that the number of channels is fixed.
+%
+%   The resulting coefficients is stored as a M xN xW
+%   array. c(m,n,w) is thus the value of the coefficient for time index n,
+%   frequency index m and signal channel w.
+%
+%   The variable a contains the distance in samples between two consequtive
+%   blocks of coefficients. a is a vectors of integers. The variables g and
+%   a must have the same length.
+%   
+%   The time positions of the coefficients blocks can be obtained by the
+%   following code. A value of 0 correspond to the first sample of the
+%   signal:
+%
+%     timepos = cumsum(a)-a(1);
+%
+%   [c,Ls]=nsdgt(f,g,a,M) additionally returns the length Ls of the input 
+%   signal f. This is handy for reconstruction:
+%
+%     [c,Ls]=unsdgt(f,g,a,M);
+%     fr=iunsdgt(c,gd,a,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, 
+%   provided that gd are dual windows of g.
+%
+%   Notes:
+%   ------
+%
+%   UNSDGT uses circular border conditions, that is to say that the signal is
+%   considered as periodic for windows overlapping the beginning or the 
+%   end of the signal.
+%
+%   The phaselocking convention used in UNSDGT is different from the
+%   convention used in the DGT function. UNSDGT results are phaselocked
+%   (a phase reference moving with the window is used), whereas DGT results
+%   are not phaselocked (a fixed phase reference corresponding to time 0 of
+%   the signal is used). See the help on PHASELOCK for more details on
+%   phaselocking conventions.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/unsdgt.php}
+%@seealso{insdgt, nsgabdual, nsgabtight, phaselock, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGT
+%   REFERENCE: 
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(M)
+  error('%s: M must be numeric.',upper(mfilename));
+end;
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,upper(mfilename),0);
+
+L=nsdgtlength(Ls,a);
+f=postpad(f,L);
+
+[g,info]=nsgabwin(g,a,M);
+
+if ~info.isuniform
+    error('%s: M must be a scalar or a constant vector.',upper(mfilename));    
+end;
+M=M(1);
+
+timepos=cumsum(a)-a(1);
+
+N=length(a); % Number of time positions
+c=zeros(M,N,W,assert_classname(f,g{1})); % Initialisation of the result
+
+   
+for ii = 1:N
+    Lg = length(g{ii});
+    gt = g{ii}; gt = gt([end-floor(Lg/2)+1:end,1:ceil(Lg/2)]);
+    win_range = mod(timepos(ii)+(-floor(Lg/2):ceil(Lg/2)-1),L)+1;
+    if M < Lg 
+        % if the number of frequency channels is too small, aliasing is introduced
+        col = ceil(Lg/M);
+        temp = zeros(col*M,W,assert_classname(f,g{1}));
+        temp([col*M-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = bsxfun(@times,f(win_range,:),gt);
+        temp = reshape(temp,M,col,W);
+        
+        c(:,ii,:)=fft(sum(temp,2));
+    else
+        temp = zeros(M,W,assert_classname(f,g{1}));
+        temp([end-floor(Lg/2)+1:end,1:ceil(Lg/2)],:) = bsxfun(@times, ...
+                                                          f(win_range,:),gt);
+        c(:,ii,:)=fft(temp);
+    end       
+end
+
diff --git a/inst/nonstatgab/unsdgtreal.m b/inst/nonstatgab/unsdgtreal.m
new file mode 100644
index 0000000..c3e796d
--- /dev/null
+++ b/inst/nonstatgab/unsdgtreal.m
@@ -0,0 +1,166 @@
+function [c,Ls] = unsdgtreal(f,g,a,M)
+%-*- texinfo -*-
+%@deftypefn {Function} unsdgtreal
+%@verbatim
+%UNSDGTREAL  Uniform non-stationary Discrete Gabor transform
+%   Usage:  c=unsdgtreal(f,g,a,M);
+%           [c,Ls]=unsdgtreal(f,g,a,M);
+%
+%   Input parameters:
+%         f     : Input signal.
+%         g     : Cell array of window functions.
+%         a     : Vector of time positions of windows.
+%         M     : Vector of numbers of frequency channels.
+%   Output parameters:
+%         c     : Cell array of coefficients.
+%         Ls    : Length of input signal.
+%
+%   UNSDGTREAL(f,g,a,M) computes the nonstationary Gabor coefficients of the
+%   input signal f. The signal f can be a multichannel signal, given in
+%   the form of a 2D matrix of size Ls xW, with Ls the signal
+%   length and W the number of signal channels.
+%
+%   As opposed to NSDGT only the coefficients of the positive frequencies
+%   of the output are returned. UNSDGTREAL will refuse to work for complex
+%   valued input signals.
+%
+%   The non-stationary Gabor theory extends standard Gabor theory by
+%   enabling the evolution of the window over time. It is therefore
+%   necessary to specify a set of windows instead of a single window.  This
+%   is done by using a cell array for g. In this cell array, the n'th
+%   element g{n} is a row vector specifying the n'th window. The
+%   uniformity means that the number of channels is not allowed to vary over
+%   time.
+%
+%   The resulting coefficients is stored as a M/2+1 xN xW
+%   array. c(m,n,l) is thus the value of the coefficient for time index n,
+%   frequency index m and signal channel l.
+%
+%   The variable a contains the distance in samples between two
+%   consequtive blocks of coefficients. The variable M contains the
+%   number of channels for each block of coefficients. Both a and M are
+%   vectors of integers.
+%
+%   The variables g, a and M must have the same length, and the result c*
+%   will also have the same length.
+%   
+%   The time positions of the coefficients blocks can be obtained by the
+%   following code. A value of 0 correspond to the first sample of the
+%   signal:
+%
+%     timepos = cumsum(a)-a(1);
+%
+%   [c,Ls]=UNSDGTREAL(f,g,a,M) additionally returns the length Ls of the input 
+%   signal f. This is handy for reconstruction:
+%
+%     [c,Ls]=unsdgtreal(f,g,a,M);
+%     fr=insdgtreal(c,gd,a,Ls);
+%
+%   will reconstruct the signal f no matter what the length of f is, 
+%   provided that gd are dual windows of g.
+%
+%   Notes:
+%   ------
+%
+%   UNSDGTREAL uses circular border conditions, that is to say that the signal is
+%   considered as periodic for windows overlapping the beginning or the 
+%   end of the signal.
+%
+%   The phaselocking convention used in UNSDGTREAL is different from the
+%   convention used in the DGT function. UNSDGTREAL results are phaselocked (a
+%   phase reference moving with the window is used), whereas DGT results are
+%   not phaselocked (a fixed phase reference corresponding to time 0 of the
+%   signal is used). See the help on PHASELOCK for more details on
+%   phaselocking conventions.
+%
+%
+%
+%   References:
+%     P. Balazs, M. Doerfler, F. Jaillet, N. Holighaus, and G. A. Velasco.
+%     Theory, implementation and applications of nonstationary Gabor frames.
+%     J. Comput. Appl. Math., 236(6):1481-1496, 2011.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/nonstatgab/unsdgtreal.php}
+%@seealso{nsdgt, insdgtreal, nsgabdual, nsgabtight, phaselock, demo_nsdgt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Florent Jaillet
+%   TESTING: TEST_NSDGTREAL
+%   REFERENCE: 
+
+if ~isnumeric(a)
+  error('%s: a must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(M)
+  error('%s: M must be numeric.',upper(mfilename));
+end;
+
+L=sum(a);
+
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,'UNSDGTREAL',0);
+f=postpad(f,L);
+
+[g,info]=nsgabwin(g,a,M);
+
+if ~info.isuniform
+    error('%s: M must be a scalar or a constant vector.',upper(mfilename));    
+end;
+M=M(1);
+
+timepos=cumsum(a)-a(1);
+  
+N=length(a); % Number of time positions
+
+M2=floor(M/2)+1;
+c=zeros(M2,N,W,assert_classname(f,g{1})); % Initialisation of the result
+
+for ii=1:N
+  shift=floor(length(g{ii})/2);
+  temp=zeros(M,W,assert_classname(f,g{1}));
+  
+  % Windowing of the signal.
+  % Possible improvements: The following could be computed faster by 
+  % explicitely computing the indexes instead of using modulo and the 
+  % repmat is not needed if the number of signal channels W=1 (but the time 
+  % difference when removing it whould be really small)
+  temp(1:length(g{ii}))=f(mod((1:length(g{ii}))+timepos(ii)-shift-1,L)+1,:).*...
+    repmat(conj(circshift(g{ii},shift)),1,W);
+  
+  temp=circshift(temp,-shift);
+  if M<length(g{ii}) 
+    % Fft size is smaller than window length, some aliasing is needed
+    x=floor(length(g{ii})/M);
+    y=length(g{ii})-x*M;
+    % Possible improvements: the following could probably be computed 
+    % faster using matrix manipulation (reshape, sum...)
+    temp1=temp;
+    temp=zeros(M,size(temp,2),assert_classname(f,g{1}));
+    for jj=0:x-1
+      temp=temp+temp1(jj*M+(1:M),:);
+    end
+    temp(1:y,:)=temp(1:y,:)+temp1(x*M+(1:y),:);
+  end
+  
+  % FFT of the windowed signal
+  c(:,ii,:) = reshape(fftreal(temp),M2,1,W); 
+end
+
+
diff --git a/inst/operators/Contents.m b/inst/operators/Contents.m
new file mode 100644
index 0000000..c9f3921
--- /dev/null
+++ b/inst/operators/Contents.m
@@ -0,0 +1,49 @@
+% LTFAT - Operators
+%
+%  Peter L. Soendergaard, 2013 - 2014.
+%
+%  General operator framework
+%    OPERATORNEW       - Construct a new operator
+%    OPERATOR          - Apply an operator
+%    IOPERATOR         - Apply the inverse of an operator
+%    OPERATORADJ       - Apply the adjoint of an operator
+%    OPERATORAPPR      - Best approx. by operator
+%    OPERATOREIGS      - Eigenpairs of an operator
+%    OPERATORMATRIX    - Matrix representation of an operator
+%
+%  Frame multipliers
+%    FRAMEMUL          - Apply frame multiplier
+%    IFRAMEMUL         - Apply the inverse of a frame multipllier
+%    FRAMEMULADJ       - Apply the adjoint of a frame multiplier
+%    FRAMEMULAPPR      - Best approx. by frame multiplier
+%    FRAMEMULEIGS      - Eigenpairs of a frame multiplier
+%    GABMULAPPR        - Best approximation by a Gabor mult.
+%
+%  Spreading operators
+%    SPREADOP          - Spreading operator
+%    SPREADINV         - Apply inverse spreading operator
+%    SPREADADJ         - Symbol of adjoint spreading operator
+%    SPREADFUN         - Symbol of operator expressed as a matrix
+%    SPREADEIGS        - Eigenpairs of spreading operator
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/operators/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/operators/framemul.m b/inst/operators/framemul.m
new file mode 100644
index 0000000..1440f70
--- /dev/null
+++ b/inst/operators/framemul.m
@@ -0,0 +1,92 @@
+function h=framemul(f,Fa,Fs,s,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} framemul
+%@verbatim
+%FRAMEMUL  Frame multiplier
+%   Usage:  h=framemul(f,Fa,Fs,s);
+%
+%   Input parameters:
+%          Fa   : Analysis frame
+%          Fs   : Synthesis frame
+%          s    : Symbol
+%          f    : Input signal
+%
+%   Output parameters: 
+%          h    : Output signal
+%
+%   FRAMEMUL(f,Fa,Fs,s) applies the frame multiplier with symbol s*
+%   to the signal f. The frame Fa is used for analysis and the frame
+%   Fs for synthesis.
+%
+%   Examples:
+%   ---------
+%
+%   In the following example Gabor coefficients obtained through the DGT 
+%   of pink noise are multiplied by the symbol batmask before resynthesis. 
+%   The result of this operation is an output signal h that is constructed 
+%   through a Gabor expansion of the modified coefficients.:
+%
+%      f = pinknoise(400);
+%      a = 10;
+%      M = 40;
+%      [Fa, Fs] = framepair('dgt', 'gauss', 'dual', a, M); 
+%      s = framenative2coef(Fa, batmask);
+%      fhat = framemul(f, Fa, Fs, s);
+%      figure(1);
+%      plotframe(Fa,frana(Fa,f),'clim',[-100,-20]);
+%      figure(2);
+%      plotframe(Fa,s,'lin');
+%      figure(3);
+%      plotframe(Fa,frana(Fa,fhat),'clim',[-100,-20]);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/framemul.php}
+%@seealso{iframemul, framemuladj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% Author: Peter L. Soendergaard
+
+if nargin < 4
+    error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if size(s,2)>1
+    error(['%s: Symbol should be a column vecor i.e. ',... 
+           'in the common Frames framework coefficient format. ',...
+           'See FRAMENATIVE2COEF and FRAMECOEF2NATIVE.' ],upper(mfilename));
+end
+
+% Check for compatibility
+L1=framelength(Fa,size(f,1));
+L2=framelengthcoef(Fs,size(s,1));
+if L1~=L2
+    error(['%s: The symbol and signal lengths are incompatible.'],upper(mfilename));
+end;
+
+% This is not *strictly* necessary, but we cannot check that the symbol
+% is complex-valued in just the right way.
+if Fa.realinput && ~isreal(s)
+    error(['%s: For real-valued-input-only frames, the symbol must also ' ...
+           'be real.'],upper(mfilename));
+end;
+
+h=frsyn(Fs,s.*frana(Fa,f));
+
+
+
diff --git a/inst/operators/framemuladj.m b/inst/operators/framemuladj.m
new file mode 100644
index 0000000..71cf75e
--- /dev/null
+++ b/inst/operators/framemuladj.m
@@ -0,0 +1,59 @@
+function h=framemuladj(f,Fa,Fs,s,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} framemuladj
+%@verbatim
+%FRAMEMULADJ  Adjoint operator of frame multiplier
+%   Usage: h=framemuladj(f,Fa,Fs,s);
+%
+%   Input parameters:
+%          Fa   : Analysis frame
+%          Fs   : Synthesis frame
+%          s    : Symbol
+%          f    : Input signal
+%
+%   Output parameters: 
+%          h    : Output signal
+%
+%   FRAMEMULADJ(f,Fa,Fs,s) applies the adjoint of the frame multiplier
+%   with symbol s to the signal f. The frame Fa is used for analysis
+%   and the frame Fs for synthesis.
+%
+%   FRAMEMULADJ(f,Fa,Fs,s) does the same using the frames Fa for
+%   analysis and Fs for synthesis.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/framemuladj.php}
+%@seealso{framemul, iframemul}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+% Author: Peter L. Soendergaard
+
+if nargin < 4
+    error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% Swap the analysis and synthesis frames and conjugate the symbol.
+h=frsyn(Fa,conj(s).*frana(Fs,f));
+
+
+
+
+
+
+
diff --git a/inst/operators/framemulappr.m b/inst/operators/framemulappr.m
new file mode 100644
index 0000000..49ecaf0
--- /dev/null
+++ b/inst/operators/framemulappr.m
@@ -0,0 +1,122 @@
+function [s,TA]=framemulappr(Fa,Fs,T)
+%-*- texinfo -*-
+%@deftypefn {Function} framemulappr
+%@verbatim
+%FRAMEMULAPPR  Best Approximation of a matrix by a frame multiplier
+%   Usage: s=framemulappr(Fa,Fs,T);
+%         [s,TA]=framemulappr(Fa,Fs,T);
+%
+%   Input parameters:
+%          Fa   : Analysis frame
+%          Fs   : Synthesis frame
+%          T    : The operator represented as a matrix
+%
+%   Output parameters: 
+%          s    : Symbol of best approximation
+%          TA   : The best approximation of the matrix T
+%
+%   s=FRAMEMULAPPR(Fa,Fs,T) computes the symbol s of the frame
+%   multiplier that best approximates the matrix T in the Frobenious norm
+%   of the matrix (the Hilbert-Schmidt norm of the operator). The frame
+%   multiplier uses Fa for analysis and Fs for synthesis.
+%
+%   Examples:
+%   
+%     T = eye(2,2);
+%     D = [0 1/sqrt(2) -1/sqrt(2); 1 -1/sqrt(2) -1/sqrt(2)];
+%     F = frame('gen',D);
+%     [coeff,TA] = framemulappr(F,F,T)
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/framemulappr.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   Literature : [1] P. Balazs; Irregular And Regular Gabor frame multipliers 
+%                  with application to psychoacoustical masking 
+%                  (Ph.D. thesis 2005)
+%              [2] P. Balazs; Hilbert- Schmidt Operators and Frames -
+%                  Classification, Best Approximation by Multipliers and 
+%                  Algorithms; 
+%                  International Journal of Wavelets, Multiresolution and
+%                  Information Processing}, to appear, 
+%                  http://arxiv.org/abs/math.FA/0611634
+
+% Author: Peter Balazs and Peter L. Soendergaard
+
+if nargin < 3
+    error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+[N M] = size(T);
+
+Mfix=M;
+
+% Bootstrap the code
+D=frsynmatrix(Fa,Mfix);
+Ds=frsynmatrix(Fs,Mfix);
+
+[Nd Kd] = size(D);
+
+% TODO: Check for for correct framelengths
+
+% TODO: Check this error('The frames must have the same number of
+% elements.');
+
+% TODO: Possible optimization for Fa=Fs
+
+% TODO: Express the pinv as an iterative algorithm
+
+% Compute the lower symbol.
+% The more elegant code
+% 
+% is slower, O(k(n^2+n^2)))
+% see [Xxl]
+
+if 1
+  % Original expression
+  %lowsym = diag(D'*T*D);
+  
+  % New expression
+  lowsym = conj(diag(frana(Fa,frana(Fa,T)')));
+else
+    lowsym = zeros(Kd,1); %lower symbol
+    for ii=1:Kd
+        lowsym(ii) = D(:,ii)'*(T*D(:,ii));
+    end;
+end;
+
+Gram = (Ds'*Ds).*((D'*D).');
+
+% upper symbol:
+s = Gram\lowsym;
+  
+% synthesis
+if nargout>1
+    TA = zeros(N,M);
+    for ii = 1:Kd
+        P = Ds(:,ii)*D(:,ii)';
+        TA = TA + s(ii)*P;
+    end;
+end;
+
+
+
+
+
diff --git a/inst/operators/framemuleigs.m b/inst/operators/framemuleigs.m
new file mode 100644
index 0000000..3814fd9
--- /dev/null
+++ b/inst/operators/framemuleigs.m
@@ -0,0 +1,166 @@
+function varargout=framemuleigs(Fa,Fs,s,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} framemuleigs
+%@verbatim
+%FRAMEMULEIGS  Eigenpairs of frame multiplier
+%   Usage:  [V,D]=framemuleigs(Fa,Fs,s,K);
+%           D=framemuleigs(Fa,Fs,s,K,...);
+%
+%   Input parameters:
+%         Fa    : Analysis frame
+%         Fs    : Synthesis frame
+%         s     : Symbol of Gabor multiplier
+%         K     : Number of eigenvectors to compute.
+%   Output parameters:
+%         V     : Matrix containing eigenvectors.
+%         D     : Eigenvalues.
+%
+%   [V,D]=FRAMEMULEIGS(Fa,Fs,s,K) computes the K largest eigenvalues and eigen-
+%   vectors of the frame multiplier with symbol s, analysis frame Fa*
+%   and synthesis frame Fs. The eigenvectors are stored as column
+%   vectors in the matrix V and the corresponding eigenvalues in the
+%   vector D.
+%
+%   If K is empty, then all eigenvalues/pairs will be returned.
+%
+%   D=FRAMEMULEIGS(...) computes only the eigenvalues.
+%
+%   FRAMEMULEIGS takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'iter'       Call eigs to use an iterative algorithm.
+%
+%     'full'       Call eig to solve the full problem.
+%
+%     'auto'       Use the full method for small problems and the
+%                  iterative method for larger problems. This is the
+%                  default. 
+%
+%     'crossover',c
+%                  Set the problem size for which the 'auto' method
+%                  switches. Default is 200.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%   Examples:
+%   ---------
+%
+%   The following example calculates and plots the first eigenvector of the
+%   Gabor multiplier given by the BATMASK function. Note that the mask
+%   must be converted to a column vector to work with in this framework:
+%
+%     mask=batmask;
+%     [Fa,Fs]=framepair('dgt','gauss','dual',10,40);
+%     [V,D]=framemuleigs(Fa,Fs,mask(:));
+%     sgram(V(:,1),'dynrange',90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/framemuleigs.php}
+%@seealso{framemul, framemulappr}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Change this to 1 or 2 to see the iterative method in action.
+printopts=0;
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if nargout==2
+  doV=1;
+else
+  doV=0;
+end;
+
+tolchooser.double=1e-9;
+tolchooser.single=1e-5;
+
+definput.keyvals.K=6;
+definput.keyvals.maxit=100;
+definput.keyvals.tol=tolchooser.(class(s));
+definput.keyvals.crossover=200;
+definput.flags.print={'quiet','print'};
+definput.flags.method={'auto','iter','full'};
+
+
+[flags,kv,K]=ltfatarghelper({'K'},definput,varargin);
+
+% Do the computation. For small problems a direct calculation is just as
+% fast.
+
+L=framelengthcoef(Fa,size(s,1));
+
+if (flags.do_iter) || (flags.do_auto && L>kv.crossover)
+    
+  if flags.do_print
+    opts.disp=1;
+  else
+    opts.disp=0;
+  end;
+  opts.isreal = Fa.realinput;
+  opts.maxit  = kv.maxit;
+  opts.tol    = kv.tol;
+    
+  if doV
+      [V,D] = eigs(@(x) framemul(x,Fa,Fs,s),L,K,'LM',opts);
+  else
+      D     = eigs(@(x) framemul(x,Fa,Fs,s),L,K,'LM',opts);
+  end;
+
+else
+  % Compute the transform matrix.
+  bigM=frsynmatrix(Fs,L)*diag(s)*frsynmatrix(Fa,L)'; 
+
+  if doV
+    [V,D]=eig(bigM);
+  else
+    D=eig(bigM);
+  end;
+
+end;
+
+% The output from eig and eigs is sometimes a diagonal matrix, so we must
+% extract the diagonal.
+if doV
+  D=diag(D);
+end;
+
+% Sort them in descending order
+[~,idx]=sort(abs(D),1,'descend');
+D=D(idx(1:K));
+
+if doV
+  V=V(:,idx(1:K));
+  varargout={V,D};
+else
+  varargout={D};
+end;
+
+% Clean the eigenvalues, if we know that they are real-valued
+%if isreal(ga) && isreal(gs) && isreal(c)
+%  D=real(D);
+%end;
+
diff --git a/inst/operators/gabmulappr.m b/inst/operators/gabmulappr.m
new file mode 100644
index 0000000..b06dbb6
--- /dev/null
+++ b/inst/operators/gabmulappr.m
@@ -0,0 +1,162 @@
+function [sym,lowb,upb]=gabmulappr(T,p2,p3,p4,p5);
+%-*- texinfo -*-
+%@deftypefn {Function} gabmulappr
+%@verbatim
+%GABMULAPPR  Best Approximation by a Gabor multiplier
+%   Usage:  sym=gabmulappr(T,a,M);
+%           sym=gabmulappr(T,g,a,M);
+%           sym=gabmulappr(T,ga,gs,a,M);
+%           [sym,lowb,upb]=gabmulappr( ... );
+%
+%   Input parameters:
+%         T     : matrix to be approximated
+%         g     : analysis/synthesis window
+%         ga    : analysis window
+%         gs    : synthesis window
+%         a     : Length of time shift.
+%         M     : Number of channels.
+%
+%   Output parameters:
+%         sym   : symbol
+%
+%   sym=GABMULAPPR(T,g,a,M) calculates the best approximation of the given
+%   matrix T in the Frobenius norm by a Gabor multiplier determined by the
+%   symbol sym over the rectangular time-frequency lattice determined by
+%   a and M.  The window g will be used for both analysis and
+%   synthesis.
+%
+%   GABMULAPPR(T,a,M) does the same using an optimally concentrated, tight
+%   Gaussian as window function.
+%
+%   GABMULAPPR(T,gs,ga,a) does the same using the window ga for analysis
+%   and gs for synthesis.
+%
+%   [sym,lowb,upb]=GABMULAPPR(...) additionally returns the lower and
+%   upper Riesz bounds of the rank one operators, the projections resulting
+%   from the tensor products of the analysis and synthesis frames.
+%
+%
+%
+%   References:
+%     M. Doerfler and B. Torresani. Representation of operators in the
+%     time-frequency domain and generalized Gabor multipliers. J. Fourier
+%     Anal. Appl., 16(2):261-293, April 2010.
+%     
+%     P. Balazs. Hilbert-Schmidt operators and frames - classification, best
+%     approximation by multipliers and algorithms. International Journal of
+%     Wavelets, Multiresolution and Information Processing, 6:315 - 330,
+%     2008.
+%     
+%     P. Balazs. Basic definition and properties of Bessel multipliers.
+%     Journal of Mathematical Analysis and Applications, 325(1):571-585,
+%     January 2007.
+%     
+%     H. G. Feichtinger, M. Hampejs, and G. Kracher. Approximation of
+%     matrices by Gabor multipliers. IEEE Signal Procesing Letters,
+%     11(11):883-886, 2004.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/gabmulappr.php}
+%@seealso{framemulappr, demo_gabmulappr}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR    : Monika Doeerfler
+% REFERENCE : REF_GABMULAPPR
+% TESTING   : TEST_GABMULAPPR
+  
+error(nargchk(3,5,nargin));
+
+L=size(T,1);
+
+if size(T,2)~=L
+  error('T must be square.');
+end;
+
+if nargin==3
+  % Usage: sym=gabmulappr(T,a,M);
+  a=p2;
+  M=p3;
+  ga=gabtight(a,M,L);
+  gs=ga;
+end;
+
+if nargin==4
+  % Usage: sym=gabmulappr(T,g,a,M);
+  ga=p2;
+  gs=p2;
+  a=p3;
+  M=p4;
+end;
+  
+if nargin==5
+  % Usage: sym=gabmulappr(T,ga,gm,a,M);
+  ga=p2;
+  gs=p3;
+  a=p4;
+  M=p5;
+end;
+
+if size(ga,2)>1
+  if size(ga,1)>1
+    error('Input g/ga must be a vector');
+  else
+    % ga was a row vector.
+    ga=ga(:);
+  end;
+end;
+
+if size(gs,2)>1
+  if size(gs,1)>1
+    error('Input g/gs must be a vector');
+  else
+    % gs was a row vector.
+    gs=gs(:);
+  end;
+end;
+
+N=L/a;
+b=L/M;
+
+Vg=dgt(gs,ga,1,L);
+
+s=spreadfun(T);
+
+A=zeros(N,M);
+V=zeros(N,M);
+for k=0:b-1 
+  for l=0:a-1
+    A = A+ s(l*N+1:(l+1)*N,k*M+1:k*M+M).*conj(Vg(l*N+1:(l+1)*N,k*M+1:k*M+M));
+    V = V+abs(Vg(l*N+1:(l+1)*N,k*M+1:k*M+M)).^2;
+  end;
+end;
+
+if nargout>1
+  lowb = min(V(:));
+  upb  = max(V(:));
+end;
+
+SF1=A./V;
+
+SF=zeros(N,M);
+jjmod=mod(-M:-1,M)+1;
+iimod=mod(-N:-1,N)+1;
+SF=SF1(iimod,jjmod);
+
+sym=b*dsft(SF)*sqrt(M)/sqrt(N);
+
diff --git a/inst/operators/iframemul.m b/inst/operators/iframemul.m
new file mode 100644
index 0000000..806fb43
--- /dev/null
+++ b/inst/operators/iframemul.m
@@ -0,0 +1,101 @@
+function [h,relres,iter]=iframemul(f,Fa,Fs,s,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iframemul
+%@verbatim
+%IFRAMEMUL  Inverse of frame multiplier
+%   Usage: h=iframemul(f,Fa,Fs,s);
+%         [h,relres,iter]=iframemul(...);
+%
+%   Input parameters:
+%          Fa   : Analysis frame
+%          Fs   : Synthesis frame
+%          s    : Symbol
+%          f    : Input signal
+%
+%   Output parameters: 
+%          h    : Output signal
+%
+%   IFRAMEMUL(f,F,s) applies the inverse of the frame multiplier with
+%   symbol s to the signal f. The frame Fa is used for analysis
+%   and the frame Fs for synthesis.
+%
+%   Because the inverse of a frame multiplier is not necessarily again a
+%   frame multiplier for the same frames, the problem is solved using an 
+%   iterative algorithm.
+%
+%   [h,relres,iter]=IFRAMEMUL(...) additionally returns the relative
+%   residuals in a vector relres and the number of iteration steps iter.
+%
+%   IFRAMEMUL takes the following parameters at the end of the line of
+%   input arguments:
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/iframemul.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   See also: iframemul
+  
+% Author: Peter L. Soendergaard
+
+if nargin < 4
+    error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+tolchooser.double=1e-9;
+tolchooser.single=1e-5;
+
+definput.keyvals.tol=tolchooser.(class(f));
+definput.keyvals.maxit=100;
+definput.keyvals.printstep=10;
+definput.flags.print={'quiet','print'};
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Check for compatibility
+L1=framelength(Fa,size(f,1));
+L2=framelengthcoef(Fs,size(s,1));
+if L1~=L2
+    error(['%s: The symbol and signal lengths are incompatible.'],upper(mfilename));
+end;
+
+% This is not *strictly* necessary, but we cannot check that the symbol
+% is complex-valued in just the right way.
+if Fa.realinput && ~isreal(s)
+    error(['%s: For real-valued-input-only frames, the symbol must also ' ...
+           'be real.'],upper(mfilename));
+end;
+
+% The frame multiplier is not positive definite, so we cannot solve it
+% directly using pcg.
+% Apply the multiplier followed by its adjoint. 
+A=@(x) framemuladj(framemul(x,Fa,Fs,s),Fa,Fs,s);
+
+[h,flag,dummytilde,iter1,relres]=pcg(A,framemuladj(f,Fa,Fs,s),kv.tol,kv.maxit);
+
+
+
+
diff --git a/inst/operators/ioperator.m b/inst/operators/ioperator.m
new file mode 100644
index 0000000..35e8473
--- /dev/null
+++ b/inst/operators/ioperator.m
@@ -0,0 +1,53 @@
+function outsig=ioperator(Op,insig);
+%-*- texinfo -*-
+%@deftypefn {Function} ioperator
+%@verbatim
+%IOPERATOR  Apply inverse of operator
+%   Usage: c=ioperator(Op,f);
+%
+%   c=IOPERATOR(Op,f) applies the inverse op the operator Op to the
+%   input signal f.  The operator object Op must have been created using
+%   OPERATORNEW.
+%
+%   If f is a matrix, the transform will be applied along the columns
+%   of f. If f is an N-D array, the transform will be applied along
+%   the first non-singleton dimension.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/ioperator.php}
+%@seealso{operatornew, operator, operatoradj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(Op)
+  error('%s: First agument must be a operator definition structure.',upper(mfilename));
+end;
+
+switch(Op.type)
+  case 'framemul'
+    outsig=iframemul(insig,Op.Fa,Op.Fs,Op.s);
+  case 'spread'
+    outsig=spreadinv(insig,Op.s);
+end;
+
+  
+
diff --git a/inst/operators/operator.m b/inst/operators/operator.m
new file mode 100644
index 0000000..004f1c2
--- /dev/null
+++ b/inst/operators/operator.m
@@ -0,0 +1,52 @@
+function outsig=operator(Op,insig);
+%-*- texinfo -*-
+%@deftypefn {Function} operator
+%@verbatim
+%OPERATOR  Apply operator
+%   Usage: c=operator(Op,f);
+%
+%   c=OPERATOR(Op,f) applies the operator Op to the input signal f.
+%   The operator object Op must have been created using OPERATORNEW.
+%
+%   If f is a matrix, the transform will be applied along the columns
+%   of f. If f is an N-D array, the transform will be applied along
+%   the first non-singleton dimension.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operator.php}
+%@seealso{operatornew, ioperator, operatoradj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(Op)
+  error('%s: First agument must be a operator definition structure.',upper(mfilename));
+end;
+
+switch(Op.type)
+  case 'framemul'
+    outsig=framemul(insig,Op.Fa,Op.Fs,Op.s);
+  case 'spread'
+    outsig=spreadop(insig,Op.s);
+end;
+
+  
+
diff --git a/inst/operators/operatoradj.m b/inst/operators/operatoradj.m
new file mode 100644
index 0000000..c9e2684
--- /dev/null
+++ b/inst/operators/operatoradj.m
@@ -0,0 +1,53 @@
+function outsig=operatoradj(Op,insig);
+%-*- texinfo -*-
+%@deftypefn {Function} operatoradj
+%@verbatim
+%OPERATORADJ  Apply the adjoint of an operator
+%   Usage: c=operatoradj(Op,f);
+%
+%   c=OPERATORADJ(Op,f) applies the adjoint operator of the operator Op*
+%   to the input signal f.  The operator object Op must have been
+%   created using OPERATORNEW.
+%
+%   If f is a matrix, the transform will be applied along the columns
+%   of f. If f is an N-D array, the transform will be applied along
+%   the first non-singleton dimension.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operatoradj.php}
+%@seealso{operatornew, operator, ioperator}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(Op)
+  error('%s: First argument must be a operator definition structure.',upper(mfilename));
+end;
+
+switch(Op.type)
+  case 'framemul'
+    outsig=framemuladj(insig,Op.Fa,Op.Fs,Op.s);
+  case 'spread'
+    outsig=spreadadj(insig,Op.s);
+end;
+
+  
+
diff --git a/inst/operators/operatorappr.m b/inst/operators/operatorappr.m
new file mode 100644
index 0000000..0eb9e2f
--- /dev/null
+++ b/inst/operators/operatorappr.m
@@ -0,0 +1,55 @@
+function Opout=operatorappr(Opin,T);
+%-*- texinfo -*-
+%@deftypefn {Function} operatorappr
+%@verbatim
+%OPERATORAPPR  Best approximation by operator
+%   Usage: c=operatorappr(Op,K);
+%
+%   Opout=OPERATORAPPR(Opin,T) computes the an operator Opout of the
+%   same type as Opin that best approximates the matrix T in the
+%   Frobenious norm of the matrix (the Hilbert-Schmidt norm of the
+%   operator).
+%
+%   For some operator classes, the approximation is always exact, so that
+%   operator(Opout,f) computes the exact same result as T'*f.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operatorappr.php}
+%@seealso{operatornew, operator, operatoreigs}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(Op)
+  error('%s: First argument must be a operator definition structure.',upper(mfilename));
+end;
+
+switch(Op.type)
+  case 'framemul'
+    s=framemulappr(Op.Fa,Op.Fs,T);
+    Opout=operatornew('framemul',Op.Fa,Op.Fs,s);
+  case 'spread'
+    s=spreadfun(T);
+    Opout=operatornew('spread',s);
+end;
+
+  
+
diff --git a/inst/operators/operatoreigs.m b/inst/operators/operatoreigs.m
new file mode 100644
index 0000000..455146d
--- /dev/null
+++ b/inst/operators/operatoreigs.m
@@ -0,0 +1,77 @@
+function outsig=operatoreigs(Op,K,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} operatoreigs
+%@verbatim
+%OPERATOREIGS  Apply the adjoint of an operator
+%   Usage: c=operatoreigs(Op,K);
+%
+%   [V,D]=OPERATOREIGS(Op,K) computes the K largest eigenvalues and
+%   eigenvectors of the operator Op to the input signal f.  The operator
+%   object Op must have been created using OPERATORNEW.
+%
+%   If K is empty, then all eigenvalues/pairs will be returned.
+%
+%   D=OPERATOREIGS(...) computes only the eigenvalues.
+%
+%   OPERATOREIGS takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'tol',t      Stop if relative residual error is less than the
+%                  specified tolerance. Default is 1e-9 
+%
+%     'maxit',n    Do at most n iterations.
+%
+%     'iter'       Call eigs to use an iterative algorithm.
+%
+%     'full'       Call eig to solve the full problem.
+%
+%     'auto'       Use the full method for small problems and the
+%                  iterative method for larger problems. This is the
+%                  default. 
+%
+%     'crossover',c
+%                  Set the problem size for which the 'auto' method
+%                  switches. Default is 200.
+%
+%     'print'      Display the progress.
+%
+%     'quiet'      Don't print anything, this is the default.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operatoreigs.php}
+%@seealso{operatornew, operator, ioperator}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(Op)
+  error('%s: First argument must be a operator definition structure.',upper(mfilename));
+end;
+
+switch(Op.type)
+  case 'framemul'
+    outsig=framemuleigs(Op.Fa,Op.Fs,Op.s,K,varargin{:});
+  case 'spread'
+    outsig=spreadeigs(K,Op.s);
+end;
+
+  
+
diff --git a/inst/operators/operatormatrix.m b/inst/operators/operatormatrix.m
new file mode 100644
index 0000000..f2c3dd6
--- /dev/null
+++ b/inst/operators/operatormatrix.m
@@ -0,0 +1,42 @@
+function T=operatormatrix(F);
+%-*- texinfo -*-
+%@deftypefn {Function} operatormatrix
+%@verbatim
+%OPERATORMATRIX  Matrix representation of an operator
+%   Usage: T=operatormatrix(Op);
+%
+%   T=OPERATORMATRIX(Op) returns the matrix representation T of the
+%   operator Op. The operator object Op must have been created using
+%   OPERATORNEW.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operatormatrix.php}
+%@seealso{operatornew, operator, operatoreigs}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isstruct(Op)
+  error('%s: First argument must be a operator definition structure.',upper(mfilename));
+end;
+
+T=operator(Op,eye(Op.L));
+
diff --git a/inst/operators/operatornew.m b/inst/operators/operatornew.m
new file mode 100644
index 0000000..1c810ed
--- /dev/null
+++ b/inst/operators/operatornew.m
@@ -0,0 +1,82 @@
+function Op=operatornew(otype,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} operatornew
+%@verbatim
+%OPERATORNEW  Construct a new operator
+%   Usage: F=operatornew(otype,...);
+%
+%   Op=OPERATORNEW(otype,...) constructs a new operator object Op of type
+%   otype. Arguments following otype are specific to the type of operator
+%   chosen.
+%
+%   Frame multipliers
+%   -----------------
+%
+%   OPERATORNEW('framemul',Fa,Fs,s) constructs a frame multiplier with
+%   analysis frame Fa, synthesis frame Fs and symbol s. See the help on
+%   FRAMEMUL.
+%
+%   Spreading operators
+%   -------------------
+%
+%   OPERATORNEW('spread',s) constructs a spreading operator with symbol
+%   s. See the help on SPREADOP.
+%  
+%   Examples
+%   --------
+%
+%   The following example creates a Gabor frame for real-valued signals,
+%   analyses an input signal and plots the frame coefficients:
+%
+%      F=frame('wmdct','gauss',40);
+%      c=frana(F,greasy);
+%      plotframe(F,c);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operatornew.php}
+%@seealso{operator, ioperator}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~ischar(otype)
+  error(['%s: First agument must be a string denoting the type of ' ...
+         'frame.'],upper(mfilename));
+end;
+
+otype=lower(otype);
+
+switch(otype)
+  case 'framemul'
+    Op.Fa=varargin{1};
+    Op.Fs=varargin{2};
+    Op.s =varargin{3};
+    Op.L =framelengthcoef(Op.Fs,size(Op.s,1));
+  case 'spread'
+    Op.s =varargin{1};
+    Op.L =length(Op.s);
+  otherwise
+    error('%s: Unknows operator type: %s',upper(mfilename),otype);  
+end;
+
+Op.type=otype;
+
diff --git a/inst/operators/operatorsinit.m b/inst/operators/operatorsinit.m
new file mode 100644
index 0000000..505d3eb
--- /dev/null
+++ b/inst/operators/operatorsinit.m
@@ -0,0 +1,25 @@
+status=1;
+
+%-*- texinfo -*-
+%@deftypefn {Function} operatorsinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/operatorsinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/operators/spreadadj.m b/inst/operators/spreadadj.m
new file mode 100644
index 0000000..2b57af1
--- /dev/null
+++ b/inst/operators/spreadadj.m
@@ -0,0 +1,113 @@
+function cadj=spreadadj(coef);
+%-*- texinfo -*-
+%@deftypefn {Function} spreadadj
+%@verbatim
+%SPREADADJ  Symbol of adjoint spreading function
+%   Usage: cadj=spreadadj(c);
+%
+%   cadj=SPREADADJ(c) computes the symbol cadj of the spreading
+%   operator that is the adjoint of the spreading operator with symbol c.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/spreadadj.php}
+%@seealso{spreadop, tconv, spreadfun, spreadinv}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Florent Jaillet
+%   TESTING: TEST_SPREAD
+%   REFERENCE: REF_SPREADADJ REF_SPREADADJ_1
+  
+error(nargchk(1,1,nargin));
+
+if ~isnumeric(coef) || ndims(coef)~=2 || size(coef,1)~=size(coef,2)
+    error('Input symbol coef must be a square matrix.');
+end;
+
+L=size(coef,1);
+
+% The algorithm used to compute the adjoint symbol can be expressed by
+% the following code. See ref_spreadadj_1
+%
+% cadj=zeros(L);
+% for ii=0:L-1
+%   for jj=0:L-1
+%     cadj(ii+1,jj+1)=conj(coef(mod(L-ii,L)+1,mod(L-jj,L)+1))...
+%         *exp(-i*2*pi*ii*jj/L);
+%   end;
+% end;
+%
+% The two algorithms below for full and sparse matrices are adaptations
+% of this algorithm.
+
+if issparse(coef)
+  % implementation for sparse matrix without loop
+  
+  [row,col,val]=find(coef);
+  
+  % This array keeps all possible values of the exponential that we could
+  % possible need. Indexing this array is faster than computing the
+  % exponential directly.
+  temp=exp((-i*2*pi/L)*(0:L-1)');
+  
+  ii=mod(L-row+1, L);
+  jj=mod(L-col+1, L);
+  cadj=sparse(ii+1,jj+1,conj(val).*temp(mod(ii.*jj,L)+1),L,L);        
+  
+else
+  
+  % implementation for full matrix.
+  %
+  % This implementation uses the direct formula with 
+  % the following Optimizations :
+  % - Avoiding mod : In the loop of for the explicit case, we see that 
+  %   mod(L-ii,L)~=L-ii only for ii==0 (idem for jj), so we can
+  %   remove the mod by processing separetly the cases ii==0 or
+  %   jj==0.
+  % - Precomputation of exp : In the loop of the explicit case, we see that we
+  %   compute many time complex exponential terms with the same 
+  %   values. Using precomputation and modulo, we can reduce the
+  %   computation time
+  %    
+  
+  cadj=zeros(L,assert_classname(coef));
+  
+  % Proceesing for ii==0 or jj==0
+  cadj(1,1)=conj(coef(1,1));
+  cadj(2:end,1)=conj(coef(end:-1:2,1));
+  cadj(1,2:end,1)=conj(coef(1,end:-1:2));
+  
+  % Proceesing for ii~=0 and jj~=0
+  
+  % Precomputation for exponential term  
+  temp2=exp((-i*2*pi/L)*(0:L-1));
+  
+  % Optimization note : Here we are computing indexes for all the
+  % exponential terms, which leads to a highly structured matrix
+  % which strcture can be formalized (notably it is symetric) and
+  % used to reduce the computation cost
+  temp=mod((1:L-1)'*(1:L-1),L)+1;
+    
+  % Finaly we construct the matrix containing all the needed exponential
+  % terms. This is (part of) the DFT matrix.
+  temp=temp2(temp);
+  
+  cadj(2:L,2:L)=conj(coef(L:-1:2,L:-1:2)).*temp;    
+end;
+
+
diff --git a/inst/operators/spreadeigs.m b/inst/operators/spreadeigs.m
new file mode 100644
index 0000000..65343dc
--- /dev/null
+++ b/inst/operators/spreadeigs.m
@@ -0,0 +1,62 @@
+function [V,D]=spreadeigs(K,coef);
+%-*- texinfo -*-
+%@deftypefn {Function} spreadeigs
+%@verbatim
+%SPREADEIGS  Eigenpairs of Spreading operator
+%   Usage: h=spreadeigs(K,c);
+%
+%   SPREADEIGS(K,c) computes the K largest eigenvalues and eigen-
+%   vectors of the spreading operator with symbol c.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/spreadeigs.php}
+%@seealso{tconv, spreadfun, spreadinv, spreadadj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(2,2,nargin));
+
+if ndims(coef)>2 || size(coef,1)~=size(coef,2)
+    error('Input symbol coef must be a square matrix.');
+end;
+
+L=size(coef,1);
+
+% This version explicitly constucts the matrix representation T
+% and then applies this matrix as the final step.
+coef=fft(coef);
+  
+T=zeros(L);
+for ii=0:L-1
+  for jj=0:L-1
+    T(ii+1,jj+1)=coef(ii+1,mod(ii-jj,L)+1);
+  end;
+end;
+
+if nargout==2
+  doV=1;
+else
+  doV=0;
+end;
+
+if doV
+  [V,D]=eig(T);
+else
+  D=eig(T);
+end;
+
diff --git a/inst/operators/spreadfun.m b/inst/operators/spreadfun.m
new file mode 100644
index 0000000..a658338
--- /dev/null
+++ b/inst/operators/spreadfun.m
@@ -0,0 +1,48 @@
+function coef=spreadfun(T)
+%-*- texinfo -*-
+%@deftypefn {Function} spreadfun
+%@verbatim
+%SPREADFUN  Spreading function of a matrix
+%   Usage:  c=spreadfun(T);
+%
+%   SPREADFUN(T) computes the spreading function of the operator T,
+%   represented as a matrix. The spreading function represent the operator T*
+%   as a weighted sum of time-frequency shifts. See the help text for
+%   SPREADOP for the exact definition.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/spreadfun.php}
+%@seealso{spreadop, tconv, spreadinv, spreadadj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+error(nargchk(1,1,nargin));
+
+if ndims(T)>2 || size(T,1)~=size(T,2)
+    error('Input symbol T must be a square matrix.');
+end;
+
+L=size(T,1);
+
+% The 'full' appearing on the next line is to guard the mex file.
+coef=comp_col2diag(full(T));
+
+coef=fft(coef)/L;
+
+
diff --git a/inst/operators/spreadinv.m b/inst/operators/spreadinv.m
new file mode 100644
index 0000000..ce63407
--- /dev/null
+++ b/inst/operators/spreadinv.m
@@ -0,0 +1,68 @@
+function out=spreadinv(p1,p2);
+%-*- texinfo -*-
+%@deftypefn {Function} spreadinv
+%@verbatim
+%SPREADINV  Apply inverse spreading operator
+%   Usage: h=spreadinv(f,c);
+%
+%   SPREADINV(c) computes the symbol of the inverse of the spreading
+%   operator with symbol c.
+%
+%   SPREADINV(f,c) applies the inverse of the spreading operator with
+%   symbol c to the input signal f.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/spreadinv.php}
+%@seealso{spreadfun, tconv, spreadfun, spreadadj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(1,2,nargin));
+
+% FIXME This function should handle sparse symbols, and use a iterative
+% method instead of creating the full symbol.
+
+% FIXME This function should handle f though comp_reshape_pre and post.
+if nargin==1
+  coef=p1;
+else
+  f=p1;
+  coef=p2;
+end;
+
+if ndims(coef)>2 || size(coef,1)~=size(coef,2)
+    error('Input symbol T must be a square matrix.');
+end;
+
+L=size(coef,1);
+
+% Create a matrix representation of the operator.
+coef=ifft(full(coef))*L;
+T=comp_col2diag(coef);
+
+if nargin==1
+  
+  % Calculate the inverse symbol.
+  out=spreadfun(inv(T));
+    
+else
+  
+  out=T\f;
+  
+end;
+
diff --git a/inst/operators/spreadop.m b/inst/operators/spreadop.m
new file mode 100644
index 0000000..49dfd76
--- /dev/null
+++ b/inst/operators/spreadop.m
@@ -0,0 +1,122 @@
+function h=spreadop(f,coef)
+%-*- texinfo -*-
+%@deftypefn {Function} spreadop
+%@verbatim
+%SPREADOP  Spreading operator
+%   Usage: h=spreadop(f,c);
+%
+%   SPREADOP(f,c) applies the operator with spreading function c to the
+%   input f. c must be square.
+%
+%   SPREADOP(f,c) computes the following for c of size L xL:
+% 
+%              L-1 L-1 
+%     h(l+1) = sum sum c(m+1,n+1)*exp(2*pi*i*l*m/L)*f(l-n+1)
+%              n=0 m=0
+%
+%   where l=0,...,L-1 and l-n is computed modulo L.
+%
+%   The combined symbol of two spreading operators can be found by using
+%   tconv. Consider two symbols c1 and c2 and define f1 and f2 by:
+%
+%     h  = tconv(c1,c2)
+%     f1 = spreadop(spreadop(f,c2),c1);
+%     f2 = spreadop(f,h);
+%
+%   then f1 and f2 are equal.
+%
+%
+%   References:
+%     H. G. Feichtinger and W. Kozek. Operator quantization on LCA groups. In
+%     H. G. Feichtinger and T. Strohmer, editors, Gabor Analysis and
+%     Algorithms, chapter 7, pages 233-266. Birkhauser, Boston, 1998.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/operators/spreadop.php}
+%@seealso{tconv, spreadfun, spreadinv, spreadadj}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard
+%   TESTING: TEST_SPREAD
+%   REFERENCE: REF_SPREADOP
+
+error(nargchk(2,2,nargin));
+
+if ndims(coef)>2 || size(coef,1)~=size(coef,2)
+    error('Input symbol coef must be a square matrix.');
+end;
+
+L=size(coef,1);
+
+% Change f to correct shape.
+[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,'DGT',0);
+
+f=postpad(f,L);
+
+h=zeros(L,W);
+
+if issparse(coef) && nnz(coef)<L
+
+    % The symbol is so sparse that the straighforward definition is
+    % the fastest way to apply it.
+
+    [mr,nr,cv]=find(coef);
+    h=zeros(L,W);
+
+    % We need mr and nr to be zero-indexed
+    mr=mr-1;
+    nr=nr-1;
+
+    % This is the basic idea of the routine below
+    %for ii=1:length(mr)
+    %  for l=0:L-1
+    %	h(l+1,:)=h(l+1,:)+cv(ii)*exp(-2*pi*i*l*mr(ii)/L)*f(mod(l-nr(ii),L)+1,:);
+    %  end;
+    %end;
+
+    l=(-2*pi*i*(0:L-1)/L).';
+    for ii=1:length(mr)
+        bigmod=repmat(exp(l*mr(ii)),1,W);
+        h=h+cv(ii)*(bigmod.*circshift(f,nr(ii)));
+    end;
+
+else
+
+  % This version only touches coef one column at a time, and it suited
+  % if coef is sparse.
+  
+  if issparse(coef)
+    for n=0:L-1
+      % The 'full' below is required for Matlab compatibility, as
+      % Matlab refuses to do an ifft of a sparse matrix.
+      cf=ifft(full(coef(:,n+1)))*L;
+      modind=mod((0:L-1).'-n,L)+1;
+      h=h+repmat(cf,1,W).*f(modind,:);
+    end;            
+  else
+    for n=0:L-1
+      cf=ifft(coef(:,n+1))*L;
+      modind=mod((0:L-1).'-n,L)+1;
+      h=h+repmat(cf,1,W).*f(modind,:);
+    end;                            
+  end;
+  
+end;
+
+
diff --git a/inst/scalardistribute.m b/inst/scalardistribute.m
new file mode 100644
index 0000000..3b94090
--- /dev/null
+++ b/inst/scalardistribute.m
@@ -0,0 +1,98 @@
+function varargout=scalardistribute(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} scalardistribute
+%@verbatim
+%SCALARDISTRIBUTE  Copy scalar to array shape for parameter handling
+%   Usage:  [...] = scalardistribute(...);
+%
+%   [...]=SCALARDISTRIBUTE(...) copies the input parameters to the
+%   output parameters.
+%
+%    If one of the input parameters is an array, all the output parameters
+%     will be column vectors containing the same number of elements. If one
+%     of the other input parameters is a scalar, it will be replicated to
+%     the correct length. This allows a scalar value to be repeated for
+%     all conditions.
+%
+%    If two or more input parameters are arrays, the must have the exact
+%     same size. They will be converted to vectors and returned in the
+%     output parameters. This allows two arrays to co-vary at the same time.
+%
+%   This operator is usefull for sanitizing input parameters: The user is
+%   allowed to enter scalars or arrays as input paremeters. These input
+%   are in turn passed to SCALARDISTRIBUTE, which makes sure that the
+%   arrays have the same shape, and that scalars are replicated. The user
+%   of scalardistibute can now generate conditions based on all the
+%   parameters, and be sure the have the right sizes.
+%
+%   As an example, consider:
+%
+%     [a,b,c]=scalardistribute(1,[2,3],[4,5])
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/scalardistribute.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+  npars=length(varargin);
+  
+  scalartest=zeros(npars,1);
+  for ii=1:npars
+    if ~isnumeric(varargin{ii})
+      error('%s: Input no. %i must be numerical.',upper(mfilename),ii);
+    end;
+    if isempty(varargin{ii})
+      error('%s: Input no. %i is empty.',upper(mfilename),ii);
+    end;
+
+    scalartest(ii)=isscalar(varargin{ii});
+  end;
+
+  idx=find(scalartest==0);
+  
+  % Tjeck that all non-scalars have the same shape
+  for jj=1:numel(idx)
+    ref_size  = size(varargin{idx(1)});
+    this_size = size(varargin{idx(jj)});
+    if any((ref_size-this_size)~=0)
+      error('%s: Input no. %i and no. %i must have the same shape.',upper(mfilename),idx(1),idx(jj));
+    end;
+  end;  
+
+  if numel(idx)==0
+    % All arguments are scalar, so this is just a dummy, but it must
+    % still be defined for the code not to fail.
+    shape=1;
+  else
+    shape=ones(numel(varargin{idx(1)}),1);
+  end;
+  
+  varargout=cell(1,npars);
+  for ii=1:npars
+    if scalartest(ii)
+      % Replicate scalar
+      varargout{ii}=shape*varargin{ii};
+    else
+      % Copy input and turn it into a vector. This would be a one-liner
+      % in Octave.
+      tmp=varargin{ii};
+      varargout{ii}=tmp(:);
+    end;
+  end;
+  
+  
diff --git a/inst/signals/Clar.wav b/inst/signals/Clar.wav
new file mode 100644
index 0000000..195231a
Binary files /dev/null and b/inst/signals/Clar.wav differ
diff --git a/inst/signals/Contents.m b/inst/signals/Contents.m
new file mode 100644
index 0000000..fdd6b1a
--- /dev/null
+++ b/inst/signals/Contents.m
@@ -0,0 +1,53 @@
+% LTFAT - Signals
+%
+%  Signal generators
+%    CTESTFUN       -  Complex valued test function.
+%    NOISE          -  Stochastic noise generator.
+%    PINKNOISE      -  Pink noise.
+%    EXPCHIRP       -  Exponential chirp.
+%
+%  Sound signals.
+%    BAT            -  Bat chirp.
+%    BATMASK        -  Mask for bat signal.
+%    GREASY         -  Woman speaking the word 'greasy'
+%    COCKTAILPARTY  -  Sentence by male, native English speaker.
+%    GSPI           -  Glockenspiel test signal.
+%    LINUS          -  Linus pronouncing Linux.
+%    LTFATLOGO      -  Synthetic sound from spectrogram reconstruction.
+%    OTOCLICK       -  Click-evoked otoacoustic emmision. 
+%    TRAINDOPPLER   -  Sound of passing train.
+%
+%  Images.
+%    CAMERAMAN      -  Greyscale image of the cameraman.
+%    LICHTENSTEIN   -  Color image of the Lichtenstein castle.
+%    LTFATTEXT      -  Black and white word: 'LTFAT'.
+%
+%  Other test signals are available from:
+%
+%    http://sound.media.mit.edu/mpeg4/audio/sqam/
+%    http://www.dogstar.dantimax.dk/testwavs/
+%    (currently not available)
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%
+%   Url: http://ltfat.sourceforge.net/doc/signals/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
diff --git a/inst/signals/Piano2.wav b/inst/signals/Piano2.wav
new file mode 100644
index 0000000..59eeba2
Binary files /dev/null and b/inst/signals/Piano2.wav differ
diff --git a/inst/signals/bat.asc b/inst/signals/bat.asc
new file mode 100644
index 0000000..cd7f9eb
--- /dev/null
+++ b/inst/signals/bat.asc
@@ -0,0 +1,400 @@
+0.0029
+0.0024
+0.002
+0.0024
+0.0015
+0.0015
+0.002
+0.002
+0.0005
+0.0015
+0.0005
+0.0015
+0
+-0.0015
+0.001
+0.0015
+-0.0049
+-0.001
+0.0063
+-0.0049
+-0.0083
+0.0127
+0.0068
+-0.0259
+0.0059
+0.0386
+-0.0405
+-0.0269
+0.0474
+0.0151
+-0.063
+-0.0093
+0.0659
+-0.0073
+-0.0684
+0
+0.0728
+-0.0146
+-0.0752
+0.0029
+0.0771
+-0.0024
+-0.085
+-0.0063
+0.0698
+0.0264
+-0.0908
+-0.0254
+0.0605
+0.0669
+-0.083
+-0.0542
+0.0347
+0.0845
+-0.0391
+-0.0903
+0.0078
+0.0737
+0.0474
+-0.1108
+-0.0449
+0.0513
+0.0903
+-0.04
+-0.106
+0.0049
+0.0684
+0.0776
+-0.0923
+-0.0801
+0.0366
+0.0742
+0.0537
+-0.1113
+-0.0591
+0.0508
+0.0718
+0.0376
+-0.1196
+-0.0503
+0.0527
+0.0679
+0.0449
+-0.1128
+-0.0566
+0.0508
+0.0654
+0.0659
+-0.1084
+-0.0732
+0.043
+0.064
+0.083
+-0.0771
+-0.104
+0.0205
+0.0737
+0.0762
+-0.0068
+-0.1357
+-0.0234
+0.0762
+0.0557
+0.0771
+-0.1216
+-0.0918
+0.0532
+0.0728
+0.0723
+-0.0156
+-0.1436
+-0.02
+0.0835
+0.0498
+0.0947
+-0.103
+-0.1279
+0.0405
+0.0908
+0.0415
+0.0732
+-0.145
+-0.0898
+0.0757
+0.0786
+0.0439
+0.0459
+-0.1646
+-0.0591
+0.0903
+0.064
+0.0415
+0.0425
+-0.167
+-0.0522
+0.0869
+0.0581
+0.0322
+0.064
+-0.1626
+-0.0718
+0.0903
+0.0679
+0.0156
+0.0972
+-0.1479
+-0.1138
+0.0786
+0.0884
+0.0088
+0.1069
+-0.0942
+-0.1675
+0.0396
+0.1069
+0.021
+0.0464
+0.0327
+-0.2012
+-0.0376
+0.1138
+0.063
+-0.0083
+0.1172
+-0.1265
+-0.1587
+0.0684
+0.1138
+0.0083
+0.0244
+0.0742
+-0.1958
+-0.0674
+0.1152
+0.084
+-0.0205
+0.0547
+0.0088
+-0.2139
+-0.0059
+0.1362
+0.0513
+-0.0327
+0.0747
+-0.0322
+-0.208
+0.0405
+0.145
+0.0278
+-0.0435
+0.0728
+-0.0215
+-0.2021
+0.0444
+0.1426
+0.022
+-0.0557
+0.0513
+0.04
+-0.2031
+0.0146
+0.1455
+0.0317
+-0.062
+0.0098
+0.1226
+-0.1719
+-0.0596
+0.1387
+0.0723
+-0.0532
+-0.0342
+0.1206
+-0.0396
+-0.1738
+0.0718
+0.1255
+-0.0137
+-0.0625
+0.02
+0.147
+-0.1489
+-0.084
+0.1284
+0.0742
+-0.0542
+-0.0449
+0.0811
+0.0894
+-0.1924
+-0.0083
+0.1348
+0.0259
+-0.0684
+-0.0215
+0.105
+0.0483
+-0.1895
+0.0283
+0.1279
+0.0083
+-0.0693
+-0.0176
+0.1128
+0.0566
+-0.1865
+0.0176
+0.126
+0.0103
+-0.0728
+-0.0132
+0.0918
+0.1035
+-0.166
+-0.0229
+0.1279
+0.0278
+-0.063
+-0.0205
+0.0532
+0.1431
+-0.0923
+-0.1108
+0.106
+0.0684
+-0.0449
+-0.041
+0.0254
+0.1025
+0.0586
+-0.1646
+0.0146
+0.1128
+0.0059
+-0.061
+-0.0073
+0.0454
+0.1138
+-0.0093
+-0.146
+0.0703
+0.084
+-0.0239
+-0.0527
+0.0122
+0.0469
+0.0908
+-0.0029
+-0.123
+0.0679
+0.0732
+-0.0293
+-0.0469
+0.0181
+0.0347
+0.0542
+0.062
+-0.1182
+0.0254
+0.0811
+-0.0068
+-0.0444
+0.001
+0.0347
+0.0234
+0.0688
+-0.0088
+-0.0767
+0.0703
+0.0352
+-0.0322
+-0.02
+0.021
+0.0205
+0.0088
+0.063
+0.0186
+-0.0596
+0.0444
+0.0181
+-0.0142
+-0.0103
+0.0083
+0.0137
+0.0098
+0.0303
+0.0635
+-0.0312
+-0.0166
+0.0322
+0.0024
+-0.0083
+0
+0.0098
+0.0137
+0.0176
+0.0264
+0.042
+0.0015
+-0.0239
+0.0142
+0.0039
+-0.0039
+0.001
+0.0093
+0.0103
+0.0166
+0.0229
+0.0239
+0.022
+-0.0083
+-0.0151
+0.0039
+0.0059
+0.002
+0.0039
+0.0146
+0.0181
+0.0156
+0.0142
+0.0137
+0.0088
+0.001
+-0.0054
+-0.0005
+0.0029
+0.0083
+0.0103
+0.0132
+0.0166
+0.0122
+0.0078
+0.0103
+0.0098
+0.0049
+0.002
+0
+0.0044
+0.0103
+0.0107
+0.0093
+0.0088
+0.0083
+0.0078
+0.0063
+0.0049
+0.0073
+0.002
+0.0034
+0.0068
+0.0073
+0.0093
+0.0083
+0.0083
+0.0073
+0.0078
+0.0063
+0.0054
+0.0029
+0.0024
diff --git a/inst/signals/bat.m b/inst/signals/bat.m
new file mode 100644
index 0000000..d6fa57d
--- /dev/null
+++ b/inst/signals/bat.m
@@ -0,0 +1,73 @@
+function [s,fs]=bat()
+%-*- texinfo -*-
+%@deftypefn {Function} bat
+%@verbatim
+%BAT  Load the 'bat' test signal
+%   Usage:  s=bat;
+%
+%   BAT loads the 'bat' signal. It is a 400 samples long recording
+%   of a bat chirp sampled with a sampling period of 7 microseconds.
+%   This gives a sampling rate of 143 kHz.
+%
+%   [sig,fs]=BAT additionally returns the sampling frequency fs.
+%
+%   The signal can be obtained from
+%   http://dsp.rice.edu/software/bat-echolocation-chirp
+%
+%   Please acknowledge use of this data in publications as follows:
+%
+%     The author wishes to thank Curtis Condon, Ken White, and Al Feng of
+%     the Beckman Institute of the University of Illinois for the bat data
+%     and for permission to use it in this paper.
+%
+%   Examples:
+%   ---------
+%
+%   Plot of 'bat' in the time-domain:
+%
+%     plot((1:400)/143000,bat);
+%     xlabel('Time (seconds)');
+%     ylabel('Amplitude');
+%
+%   Plot of 'bat' in the frequency-domain:
+%
+%     plotfftreal(fftreal(bat),143000,90);
+%
+%   Plot of 'bat' in the time-frequency-domain:
+%
+%     sgram(bat,143000,90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/bat.php}
+%@seealso{batmask}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=load('-ascii',[f,'.asc']);
+fs=143000;
+
diff --git a/inst/signals/batmask.asc b/inst/signals/batmask.asc
new file mode 100644
index 0000000..d7427ea
--- /dev/null
+++ b/inst/signals/batmask.asc
@@ -0,0 +1,40 @@
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/inst/signals/batmask.m b/inst/signals/batmask.m
new file mode 100644
index 0000000..a24d240
--- /dev/null
+++ b/inst/signals/batmask.m
@@ -0,0 +1,50 @@
+function c=batmask()
+%-*- texinfo -*-
+%@deftypefn {Function} batmask
+%@verbatim
+%BATMASK  Load a Gabor multiplier symbol for the 'bat' test signal
+%   Usage:  c=batmask;
+%
+%   BATMASK loads a Gabor multiplier with a 0/1 symbol that masks out
+%   the main contents of the 'bat' signal. The symbol fits a Gabor
+%   multiplier with lattice given by a=10 and M=40.
+%
+%   The mask was created manually using a image processing program. The
+%   mask is symmetric, such that the result will be real valued if the
+%   multiplier is applied to a real valued signal using a real valued
+%   window.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/batmask.php}
+%@seealso{bat}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_BATMASK
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+c=load('-ascii',[f,'.asc']);
+
+
diff --git a/inst/signals/cameraman.m b/inst/signals/cameraman.m
new file mode 100644
index 0000000..c041f1e
--- /dev/null
+++ b/inst/signals/cameraman.m
@@ -0,0 +1,50 @@
+function s=cameraman();
+%-*- texinfo -*-
+%@deftypefn {Function} cameraman
+%@verbatim
+%CAMERAMAN  Load the 'cameraman' test image
+%   Usage: s=cameraman;
+% 
+%   CAMERAMAN loads a 256 x256 greyscale image of a cameraman.
+% 
+%   The returned matrix s consists of integers between 0 and 255,
+%   which have been converted to double precision.
+% 
+%   To display the image, use imagesc with a gray colormap:
+% 
+%     imagesc(cameraman); colormap(gray); axis('image');
+% 
+%   See ftp://nic.funet.fi/pub/graphics/misc/test-images/ or
+%   http://sipi.usc.edu/database/database.cgi?volume=misc.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/cameraman.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=double(imread([f,'.png']));
+
diff --git a/inst/signals/cameraman.png b/inst/signals/cameraman.png
new file mode 100644
index 0000000..ffc94b1
Binary files /dev/null and b/inst/signals/cameraman.png differ
diff --git a/inst/signals/cocktailparty.m b/inst/signals/cocktailparty.m
new file mode 100644
index 0000000..a85ff47
--- /dev/null
+++ b/inst/signals/cocktailparty.m
@@ -0,0 +1,49 @@
+function [s,fs]=cocktailparty()
+%-*- texinfo -*-
+%@deftypefn {Function} cocktailparty
+%@verbatim
+%COCKTAILPARTY  Load the 'cocktailparty' test signal
+%   Usage:  s=cocktailparty;
+%
+%   COCKTAILPARTY loads the 'cocktailparty' signal. It is a recording of a
+%   male native English speaker pronouncing the sentence "The cocktail party
+%   effect refers to the ability to focus on a single talker among a mixture
+%   of conversations in background noises".
+%
+%   [sig,fs]=COCKTAILPARTY additionally returns the sampling frequency fs.
+%
+%   The signal is 363200 samples long and recorded at 44.1 kHz in an
+%   anechoic environment.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/cocktailparty.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : James harte and Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=wavread([f,'.wav']);
+fs=44100;
+
diff --git a/inst/signals/cocktailparty.wav b/inst/signals/cocktailparty.wav
new file mode 100644
index 0000000..7e0390d
Binary files /dev/null and b/inst/signals/cocktailparty.wav differ
diff --git a/inst/signals/ctestfun.m b/inst/signals/ctestfun.m
new file mode 100644
index 0000000..af9ae4c
--- /dev/null
+++ b/inst/signals/ctestfun.m
@@ -0,0 +1,40 @@
+function [ftest]=ctestfun(L)
+%-*- texinfo -*-
+%@deftypefn {Function} ctestfun
+%@verbatim
+%CTESTFUN  Complex 1-D test function
+%   Usage:  ftest=ctestfun(L);
+%
+%   CTESTFUN(L) returns a test signal consisting of a superposition of a
+%   chirp and an indicator function.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/ctestfun.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+ftest=zeros(L,1);
+
+sp=round(L/4);
+lchirp=round(L/2);
+ftest(sp+1:sp+lchirp)=exp(2*i*linspace(0,2*pi*sqrt(lchirp)/10,lchirp).^2)';
+
+s=round(L*7/16);
+l=round(L/16);
+ftest(s:s+l)=ftest(s:s+l)+ones(l+1,1);
+
+
diff --git a/inst/signals/expchirp.m b/inst/signals/expchirp.m
new file mode 100644
index 0000000..1b40784
--- /dev/null
+++ b/inst/signals/expchirp.m
@@ -0,0 +1,65 @@
+function outsig=expchirp(L,fstart,fend,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} expchirp
+%@verbatim
+%EXPCHIRP  Exponential chirp
+%   Usage: outsig=expchirp(L,fstart,fend)
+% 
+%   EXPCHIRP(L,fstart,fend) computes an exponential chirp of length L*
+%   starting at normalized frequency fstart and ending at frequency fend.
+%
+%   EXPCHIRP takes the following parameters at the end of the line of input
+%   arguments:
+%
+%     'fs',fs    Use a sampling frequency of fs Hz. If this option is
+%                specified, fstart and fend will be measured in Hz.
+%
+%     'phi',phi  Starting phase of the chirp. Default value is 0.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/expchirp.php}
+%@seealso{pchirp}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+    
+% AUTHORS:  Piotr Majdak, Peter L. Soendergaard.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.phi=0;
+definput.keyvals.fs=[];
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if ~isempty(kv.fs)
+  fstart=fstart/kv.fs*2;
+  fend  =  fend/kv.fs*2;
+end;
+
+w1=pi*fstart*L;
+w2=pi*fend*L;
+
+A=w1/log(w2/w1);
+tau=1/log(w2/w1);
+
+t=((0:L-1)/L).';
+outsig=exp(i*A*(exp(t/tau)-1)+kv.phi);
+
+
diff --git a/inst/signals/greasy.m b/inst/signals/greasy.m
new file mode 100644
index 0000000..7260fc1
--- /dev/null
+++ b/inst/signals/greasy.m
@@ -0,0 +1,79 @@
+function [s,fs]=greasy()
+%-*- texinfo -*-
+%@deftypefn {Function} greasy
+%@verbatim
+%GREASY  Load the 'greasy' test signal
+%   Usage:  s=greasy;
+%
+%   GREASY loads the 'greasy' signal. It is a recording of a woman
+%   pronouncing the word "greasy".
+%
+%   The signal is 5880 samples long and recorded at 16 kHz with around 11
+%   bits of effective quantization.
+%
+%   [sig,fs]=GREASY additionally returns the sampling frequency fs.
+%
+%   The signal has been scaled to not produce any clipping when
+%   played. To get integer values use round(GREASY*2048).
+%
+%   The signal was obtained from Wavelab:
+%   http://www-stat.stanford.edu/~wavelab/, it is a part of the first
+%   sentence of the TIMIT speech corpus "She had your dark suit in greasy
+%   wash water all year":
+%   http://www.ldc.upenn.edu/Catalog/CatalogEntry.jsp?catalogId=LDC93S1.
+%
+%   Examples:
+%   ---------
+%
+%   Plot of 'greasy' in the time-domain:
+%
+%     plot((1:5880)/16000,greasy);
+%     xlabel('Time (seconds)');
+%     ylabel('Amplitude');
+%
+%   Plot of 'greasy' in the frequency-domain:
+%
+%     plotfftreal(fftreal(greasy),16000,90);
+%
+%   Plot of 'greasy' in the time-frequency-domain:
+%
+%     sgram(greasy,16000,90);
+%
+%   References:
+%     S. Mallat and Z. Zhang. Matching pursuits with time-frequency
+%     dictionaries. IEEE Trans. Signal Process., 41(12):3397-3415, 1993.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/greasy.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s = wavread([f,'.wav']);
+fs = 16000;
+
+
diff --git a/inst/signals/greasy.wav b/inst/signals/greasy.wav
new file mode 100644
index 0000000..b31cb8c
Binary files /dev/null and b/inst/signals/greasy.wav differ
diff --git a/inst/signals/gspi.m b/inst/signals/gspi.m
new file mode 100644
index 0000000..750e0a8
--- /dev/null
+++ b/inst/signals/gspi.m
@@ -0,0 +1,50 @@
+function [s,fs]=gspi()
+%-*- texinfo -*-
+%@deftypefn {Function} gspi
+%@verbatim
+%GSPI  Load the 'glockenspiel' test signal
+%
+%   GSPI loads the 'glockenspiel' signal. This is a recording of a simple
+%   tune played on a glockenspiel. It is 262144 samples long, mono, recorded
+%   at 44100 Hz using 16 bit quantization.
+%   
+%   [sig,fs]=GSPI additionally returns the sampling frequency fs.
+%
+%   This signal, and other similar audio tests signals, can be found on
+%   the EBU SQAM test signal CD http://tech.ebu.ch/publications/sqamcd.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/gspi.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+% Load audio signal
+s = wavread([f,'.wav']);
+fs = 44100;
+
+
diff --git a/inst/signals/gspi.wav b/inst/signals/gspi.wav
new file mode 100644
index 0000000..f2a54a9
Binary files /dev/null and b/inst/signals/gspi.wav differ
diff --git a/inst/signals/lichtenstein.m b/inst/signals/lichtenstein.m
new file mode 100644
index 0000000..c7d1997
--- /dev/null
+++ b/inst/signals/lichtenstein.m
@@ -0,0 +1,55 @@
+function s=lichtenstein();
+%-*- texinfo -*-
+%@deftypefn {Function} lichtenstein
+%@verbatim
+%LICHTENSTEIN  Load the 'lichtenstein' test image
+%   Usage: s=lichtenstein;
+% 
+%   LICHTENSTEIN loads a 512 x512 color image of a castle
+%   Lichtenstein, http://en.wikipedia.org/wiki/Lichtenstein_Castle.
+% 
+%   The returned matrix s consists of integers between 0 and 255.
+% 
+%   To display the image, simply use image:
+% 
+%     image(lichtenstein); axis('image');
+% 
+%   See
+%   http://commons.wikimedia.org/wiki/File:Lichtenstein_img_processing_test.png.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/lichtenstein.php}
+%@seealso{cameraman}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=imread([f,'.png']);
+
+
+
+
+
diff --git a/inst/signals/lichtenstein.png b/inst/signals/lichtenstein.png
new file mode 100644
index 0000000..3e30a69
Binary files /dev/null and b/inst/signals/lichtenstein.png differ
diff --git a/inst/signals/linus.m b/inst/signals/linus.m
new file mode 100644
index 0000000..8a9ef15
--- /dev/null
+++ b/inst/signals/linus.m
@@ -0,0 +1,49 @@
+function [s,fs]=linus()
+%-*- texinfo -*-
+%@deftypefn {Function} linus
+%@verbatim
+%LINUS  Load the 'linus' test signal
+%   Usage:  s=linus;
+%
+%   LINUS loads the 'linus' signal. It is a recording of Linus Thorvalds
+%   pronouncing the words "Hello. My name is Linus Thorvalds, and I
+%   pronounce Linux as Linux".
+%
+%   The signal is 41461 samples long and is sampled at 8 kHz.
+%
+%   [sig,fs]=LINUS additionally returns the sampling frequency fs.
+%
+%   See http://www.paul.sladen.org/pronunciation/.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/linus.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=wavread([f,'.wav']);
+fs=8000;
+
diff --git a/inst/signals/linus.wav b/inst/signals/linus.wav
new file mode 100644
index 0000000..68f7479
Binary files /dev/null and b/inst/signals/linus.wav differ
diff --git a/inst/signals/ltfatlogo.m b/inst/signals/ltfatlogo.m
new file mode 100644
index 0000000..d5531cb
--- /dev/null
+++ b/inst/signals/ltfatlogo.m
@@ -0,0 +1,57 @@
+function [s,fs]=ltfatlogo()
+%-*- texinfo -*-
+%@deftypefn {Function} ltfatlogo
+%@verbatim
+%LTFATLOGO  Load the 'ltfatlogo' test signal
+%   Usage:  s=ltfatlogo;
+%
+%   LTFATLOGO loads the 'ltfatlogo' signal. This is a sound synthezised
+%   from an artificial spectrogram of the word 'LTFAT'. See the help of
+%   LTFATTEXT.
+%
+%   [sig,fs]=LTFATLOGO additionally returns the sampling frequency fs.
+%
+%   The signal is 7200 samples long and recorded at 8 kHz. It has been
+%   scaled to not produce any clipping.
+%
+%   Examples:
+%   ---------
+%
+%   To produce a spectrogram of the logo, use:
+%
+%     sgram(ltfatlogo,8000,90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/ltfatlogo.php}
+%@seealso{ltfattext}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s = wavread([f,'.wav']);
+fs=8000;
+
diff --git a/inst/signals/ltfatlogo.wav b/inst/signals/ltfatlogo.wav
new file mode 100644
index 0000000..daa00b9
Binary files /dev/null and b/inst/signals/ltfatlogo.wav differ
diff --git a/inst/signals/ltfattext.m b/inst/signals/ltfattext.m
new file mode 100644
index 0000000..ae2e546
--- /dev/null
+++ b/inst/signals/ltfattext.m
@@ -0,0 +1,56 @@
+function s=ltfattext();
+%-*- texinfo -*-
+%@deftypefn {Function} ltfattext
+%@verbatim
+%LTFATTEXT  Load the 'ltfattext' test image
+%   Usage: s=ltfattext;
+% 
+%   LTFATTEXT loads a 401 x600 black and white image of the word
+%   'LTFAT'.
+% 
+%   The image is assumed to be used as a spectrogram with 800 channels
+%   as produced by DGTREAL.
+% 
+%   The returned matrix s consists of the integers 0 and 1, which have
+%   been converted to double precision.
+% 
+%   To display the image, use imagesc with a gray colormap:
+% 
+%     imagesc(ltfattext);
+%     colormap(gray);
+%     axis('xy');
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/ltfattext.php}
+%@seealso{ltfatlogo, dgtreal}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=flipud(double(imread([f,'.png'])))/255;
+
diff --git a/inst/signals/ltfattext.png b/inst/signals/ltfattext.png
new file mode 100644
index 0000000..9a6eb40
Binary files /dev/null and b/inst/signals/ltfattext.png differ
diff --git a/inst/signals/noise.m b/inst/signals/noise.m
new file mode 100644
index 0000000..e43fc1a
--- /dev/null
+++ b/inst/signals/noise.m
@@ -0,0 +1,121 @@
+function outsig = noise(siglen,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} noise
+%@verbatim
+% NOISE  Stochastic noise generator
+%   Usage: outsig = noise(siglen,nsigs,type);
+%
+%   Input parameters:
+%       siglen    : Length of the noise (samples)
+%       nsigs     : Number of signals (default is 1)
+%       type      : type of noise. See below.
+%
+%   Output parameters:
+%       outsig    : siglen xnsigs signal vector
+%
+%   NOISE(siglen,nsigs) generates nsigs channels containing white noise
+%   of the given type with the length of siglen. The signals are arranged as
+%   columns in the output. If only siglen is given, a column vector is
+%   returned.
+%
+%   NOISE takes the following optional parameters:
+%
+%     'white'  Generate white (gaussian) noise. This is the default.
+%
+%     'pink'   Generate pink noise.
+%
+%     'brown'  Generate brown noise.
+%
+%     'red'    This is the same as brown noise.     
+%
+%   By default, the noise is normalized to have a unit energy, but this can
+%   be changed by passing a flag to NORMALIZE.
+%
+%   Examples:
+%   ---------
+%    
+%   White noise in the time-frequency domain:
+%
+%     sgram(noise(5000,'white'),'dynrange',70);
+%
+%   Pink noise in the time-frequency domain:
+%
+%     sgram(noise(5000,'pink'),'dynrange',70);
+%
+%   Brown/red noise in the time-frequency domain:
+%
+%     sgram(noise(5000,'brown'),'dynrange',70);
+% 
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/noise.php}
+%@seealso{normalize}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Hagen Wierstorf and Peter L. Soendergaard.
+
+
+
+% ------ Checking of input parameter -------------------------------------
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(siglen) || ~isscalar(siglen) || siglen<=0
+    error('%s: siglen has to be a positive scalar.',upper(mfilename));
+end
+
+definput.import={'normalize'};
+definput.importdefaults={'2'};
+definput.flags.noisetype={'white','pink','brown','red'};
+definput.keyvals.nsigs=1;
+[flags,kv,nsigs]  = ltfatarghelper({'nsigs'},definput,varargin);
+
+if flags.do_white
+  outsig=randn(siglen,nsigs);
+end;
+
+if flags.do_brown || flags.do_red
+  outsig=cumsum(randn(siglen,nsigs));
+end;
+
+if flags.do_pink
+  % --- Handle trivial condition
+
+  if siglen==1
+    outsig=ones(1,nsigs);
+    return;
+  end;
+
+  % ------ Computation -----------------------------------------------------
+  fmax = floor(siglen/2)-1;
+  f = (2:(fmax+1)).';
+  % 1/f amplitude factor
+  a = 1./sqrt(f);
+  % Random phase
+  p = randn(fmax,nsigs) + i*randn(fmax,nsigs);
+  sig = bsxfun(@times,a,p);
+
+  outsig = ifftreal([ones(1,nsigs); sig; 1/(fmax+2)*ones(1,nsigs)],siglen);
+
+end;
+
+outsig=normalize(outsig,flags.norm);
+
+
diff --git a/inst/signals/otoclick.asc b/inst/signals/otoclick.asc
new file mode 100644
index 0000000..932d6db
--- /dev/null
+++ b/inst/signals/otoclick.asc
@@ -0,0 +1,2210 @@
+ -2.61530908e-05
+ -2.42245964e-05
+ -1.51572894e-05
+ -1.23660475e-05
+ -9.25338982e-06
+ -1.08943017e-05
+ -1.30427122e-05
+ -7.56172806e-06
+ -1.14694667e-05
+ -9.50713908e-06
+ -9.79472158e-06
+ -8.18764291e-06
+ -5.49790072e-06
+ -2.02999411e-06
+ -6.76664703e-07
+ -2.40215970e-06
+ -3.21415734e-06
+ -7.96772688e-06
+ -9.84547144e-06
+ -1.22476311e-05
+ -9.82855482e-06
+ -1.11311344e-05
+ -1.48697069e-05
+ -1.41253757e-05
+ -1.15202166e-05
+ -1.34825442e-05
+ -1.64429523e-05
+ -2.54087596e-05
+ -2.39370139e-05
+ -2.28881836e-05
+ -2.45290955e-05
+ -2.13318548e-05
+ -1.94033604e-05
+ -1.67982013e-05
+ -1.73226164e-05
+ -1.74071995e-05
+ -1.72211167e-05
+ -1.71534502e-05
+ -1.76101989e-05
+ -1.67643680e-05
+ -1.66290351e-05
+ -1.07928020e-05
+ -7.40947850e-06
+ -5.17648498e-06
+ -2.53749264e-06
+ -1.75763657e-05
+ 1.54093470e-04
+ 1.38005766e-03
+ 3.55298027e-03
+ 4.94374616e-03
+ 4.82066085e-03
+ 3.47895316e-03
+ 1.80217802e-03
+ 1.16854919e-03
+ 1.04201289e-03
+ 4.63176990e-05
+ -1.59953386e-03
+ -3.08317197e-03
+ -3.44735291e-03
+ -2.83118204e-03
+ -2.54275371e-03
+ -2.63356211e-03
+ -2.65861562e-03
+ -2.39146839e-03
+ -1.71948959e-03
+ -1.45284987e-03
+ -1.61892030e-03
+ -1.57559685e-03
+ -1.49104759e-03
+ -1.35128250e-03
+ -1.28427577e-03
+ -1.35135016e-03
+ -1.10147480e-03
+ -7.92661950e-04
+ -5.69802430e-04
+ -2.79445606e-04
+ -1.32440199e-04
+ 6.94088820e-05
+ 2.60346745e-04
+ 2.17040204e-04
+ 2.32248243e-04
+ 2.39471639e-04
+ 2.07566898e-04
+ 2.55846924e-04
+ 1.87351540e-04
+ 1.92155859e-04
+ 2.67857723e-04
+ 2.34565819e-04
+ 2.71190297e-04
+ 2.93181899e-04
+ 3.14801337e-04
+ 3.97709679e-04
+ 3.82095641e-04
+ 3.83364388e-04
+ 4.40745555e-04
+ 4.47190786e-04
+ 4.82935599e-04
+ 4.67964392e-04
+ 4.22407941e-04
+ 4.57949755e-04
+ 4.58085088e-04
+ 4.45600624e-04
+ 4.38546394e-04
+ 3.97236014e-04
+ 4.10430976e-04
+ 4.11801222e-04
+ 3.92973027e-04
+ 4.09618978e-04
+ 3.90959949e-04
+ 4.00551671e-04
+ 4.24996184e-04
+ 4.13543634e-04
+ 4.26383346e-04
+ 4.06641654e-04
+ 3.69475845e-04
+ 3.44997499e-04
+ 3.05700196e-04
+ 2.75199535e-04
+ 2.52514351e-04
+ 2.16245123e-04
+ 2.02813328e-04
+ 1.87554539e-04
+ 1.63837441e-04
+ 1.60420285e-04
+ 1.36381771e-04
+ 1.22357895e-04
+ 1.01195206e-04
+ 8.69514144e-05
+ 1.22442478e-04
+ 1.50879312e-04
+ 1.52943140e-04
+ 1.24404806e-04
+ 5.35749279e-05
+ 2.70665881e-06
+ -3.10758265e-05
+ -7.06268784e-05
+ -1.17553576e-04
+ -1.56664795e-04
+ -1.87351540e-04
+ -1.98431924e-05
+ 1.17699059e-03
+ 3.31044673e-03
+ 4.67348627e-03
+ 4.54759281e-03
+ 3.21814966e-03
+ 1.52733374e-03
+ 8.89272753e-04
+ 7.90225957e-04
+ -1.57239960e-04
+ -1.75065000e-03
+ -3.19566748e-03
+ -3.53897332e-03
+ -2.90436332e-03
+ -2.59375731e-03
+ -2.66544993e-03
+ -2.66709085e-03
+ -2.38028651e-03
+ -1.70365564e-03
+ -1.43145035e-03
+ -1.59464496e-03
+ -1.54078245e-03
+ -1.43968874e-03
+ -1.29148225e-03
+ -1.23361050e-03
+ -1.32551849e-03
+ -1.08325561e-03
+ -7.65527696e-04
+ -5.34954198e-04
+ -2.53563181e-04
+ -1.19211404e-04
+ 6.48752284e-05
+ 2.46508951e-04
+ 2.00969417e-04
+ 2.10713389e-04
+ 1.96909429e-04
+ 1.62957777e-04
+ 2.11288554e-04
+ 1.48697069e-04
+ 1.50439480e-04
+ 2.14959460e-04
+ 1.66459517e-04
+ 1.95454600e-04
+ 2.23637684e-04
+ 2.45747704e-04
+ 3.28334631e-04
+ 3.13887839e-04
+ 3.24105476e-04
+ 3.94123357e-04
+ 4.12833136e-04
+ 4.54075849e-04
+ 4.36178068e-04
+ 3.89420537e-04
+ 4.31644414e-04
+ 4.31796664e-04
+ 4.21765110e-04
+ 4.09060730e-04
+ 3.70135593e-04
+ 3.94867688e-04
+ 4.02716998e-04
+ 3.80014897e-04
+ 3.80234813e-04
+ 3.55739551e-04
+ 3.71911838e-04
+ 4.07876567e-04
+ 4.11293723e-04
+ 4.36262651e-04
+ 4.24539435e-04
+ 3.78779984e-04
+ 3.45927913e-04
+ 2.97309554e-04
+ 2.67434807e-04
+ 2.52176018e-04
+ 2.21590774e-04
+ 2.02745662e-04
+ 1.67880513e-04
+ 1.36229521e-04
+ 1.31729701e-04
+ 1.11598926e-04
+ 1.02650036e-04
+ 8.45323381e-05
+ 5.80916648e-05
+ 6.34880658e-05
+ 7.87130216e-05
+ 7.94066029e-05
+ 6.59071421e-05
+ 1.94371936e-05
+ -1.38377932e-05
+ -3.47636491e-05
+ -7.64461949e-05
+ -1.30444038e-04
+ -1.81566057e-04
+ -2.06924066e-04
+ -2.07600731e-04
+ -2.22961020e-04
+ -2.40655802e-04
+ -2.47726948e-04
+ -2.38659641e-04
+ -2.17902951e-04
+ -2.32298993e-04
+ -2.59737746e-04
+ -2.54645845e-04
+ -2.13758380e-04
+ -1.48037320e-04
+ -9.53420567e-05
+ -6.42662302e-05
+ -4.65883648e-05
+ -3.17186580e-05
+ -2.86229170e-05
+ -2.54256762e-05
+ -1.65952019e-05
+ 2.87582499e-06
+ 3.13464924e-05
+ 4.92781070e-05
+ 6.31835667e-05
+ 7.71566928e-05
+ 7.77826077e-05
+ 6.25914851e-05
+ 3.28520714e-05
+ 6.71589718e-06
+ 3.73857249e-06
+ 6.41139807e-06
+ 7.96772688e-06
+ -8.50905865e-06
+ -2.85890837e-05
+ -4.31542915e-05
+ -5.32535122e-05
+ -5.77702491e-05
+ -6.93581321e-05
+ -7.98802682e-05
+ -7.90175207e-05
+ -7.75796082e-05
+ -7.55157809e-05
+ -8.22824279e-05
+ -8.57841678e-05
+ -7.37733693e-05
+ -5.37948439e-05
+ -3.75718077e-05
+ -3.10927431e-05
+ -3.38501518e-05
+ -4.32727078e-05
+ -4.78571112e-05
+ -4.22577107e-05
+ -3.69289762e-05
+ -2.96209974e-05
+ -1.56309546e-05
+ -8.84739100e-06
+ -1.37532101e-05
+ -3.08051606e-05
+ -5.08175192e-05
+ -7.21155408e-05
+ -7.79686905e-05
+ -7.47545331e-05
+ -6.68375561e-05
+ -6.00539924e-05
+ -5.25937641e-05
+ -4.63346156e-05
+ -4.49305363e-05
+ -4.41862051e-05
+ -3.78763068e-05
+ -3.32073203e-05
+ -3.49158987e-05
+ -3.29874043e-05
+ -3.16848247e-05
+ -1.77455318e-05
+ -3.14649087e-06
+ 6.41139807e-06
+ -9.96388776e-06
+ -3.16509915e-05
+ -4.86521922e-05
+ -5.04284370e-05
+ -4.09212979e-05
+ -3.10589099e-05
+ -3.43069005e-05
+ -4.80262773e-05
+ -6.17625708e-05
+ -7.79686905e-05
+ -8.14535137e-05
+ -7.22170405e-05
+ -5.81593313e-05
+ -4.52012022e-05
+ -3.93988024e-05
+ -4.47952034e-05
+ -4.57087007e-05
+ -4.49305363e-05
+ -4.09043813e-05
+ -2.61361742e-05
+ -7.74781085e-06
+ 9.01655717e-06
+ 2.60346745e-05
+ 4.15133796e-05
+ 4.68590307e-05
+ 4.12765469e-05
+ 3.34272363e-05
+ 2.83691677e-05
+ 2.93164983e-05
+ 3.71319756e-05
+ 4.30527918e-05
+ 4.70958634e-05
+ 4.62669491e-05
+ 3.79608899e-05
+ 1.63583692e-05
+ -6.07306571e-06
+ -1.74748660e-05
+ -1.86928624e-05
+ -1.25521302e-05
+ -7.42639512e-06
+ -1.54787051e-05
+ -2.49012611e-05
+ -3.02807455e-05
+ -4.02108000e-05
+ -5.39301769e-05
+ -6.17964040e-05
+ -6.16103212e-05
+ -4.73665292e-05
+ -2.93164983e-05
+ -2.63222570e-05
+ -3.17186580e-05
+ -3.81638893e-05
+ -3.50850649e-05
+ -2.60346745e-05
+ -1.09112183e-05
+ 8.11997644e-07
+ 3.72165587e-06
+ 5.88698292e-06
+ 5.29490130e-06
+ 4.26298763e-06
+ 1.01499706e-07
+ 6.81739689e-06
+ 2.13487714e-05
+ 4.14287965e-05
+ 4.68082809e-05
+ 3.53557308e-05
+ 1.51572894e-05
+ -7.78164409e-07
+ -6.74973042e-06
+ -1.07589688e-05
+ -7.22339571e-06
+ 1.06574691e-06
+ 4.48290366e-06
+ 8.96580732e-07
+ -5.27798469e-06
+ -2.08074396e-05
+ -3.67090602e-05
+ -4.71296966e-05
+ -5.24584311e-05
+ -4.37632897e-05
+ -3.04837449e-05
+ -1.88620286e-05
+ -1.96401930e-05
+ -2.88089997e-05
+ -5.15956836e-05
+ -6.69390558e-05
+ -6.39955643e-05
+ -5.22554317e-05
+ -4.67575310e-05
+ -4.04983825e-05
+ -3.85529715e-05
+ -2.87920831e-05
+ -1.67643680e-05
+ -1.37362935e-05
+ -7.37564527e-06
+ -1.53941220e-06
+ 8.89814085e-06
+ 1.77793651e-05
+ 2.48335946e-05
+ 2.36155981e-05
+ 2.00292752e-05
+ 2.13656880e-05
+ 2.12811049e-05
+ 1.45144579e-05
+ 1.00315542e-05
+ -3.36640690e-06
+ -2.03337743e-05
+ -4.24776268e-05
+ -6.59578920e-05
+ -8.92689910e-05
+ -9.65600532e-05
+ -9.44285594e-05
+ -8.61055835e-05
+ -7.58202800e-05
+ -7.68521937e-05
+ -7.62262788e-05
+ -7.18110417e-05
+ -6.03754082e-05
+ -4.22577107e-05
+ -1.64598689e-05
+ 1.60877033e-05
+ 4.40001223e-05
+ 5.99524927e-05
+ 6.89183000e-05
+ 7.84254391e-05
+ 7.75965249e-05
+ 8.22147615e-05
+ 8.32297585e-05
+ 7.57864468e-05
+ 6.71758884e-05
+ 5.21370154e-05
+ 3.34103197e-05
+ 1.20953816e-05
+ -1.75932823e-05
+ -4.25283766e-05
+ -6.03923248e-05
+ -6.98487140e-05
+ -7.93558531e-05
+ -8.65792488e-05
+ -9.29568136e-05
+ -9.34304789e-05
+ -8.99456557e-05
+ -7.62262788e-05
+ -6.72773881e-05
+ -5.26614305e-05
+ -3.51865646e-05
+ -2.05367737e-05
+ -2.84199175e-06
+ 4.95656895e-06
+ 8.84739100e-06
+ 1.57324544e-05
+ 2.29220168e-05
+ 2.83691677e-05
+ 2.97901636e-05
+ 2.43599293e-05
+ 1.44806247e-05
+ 2.65590896e-06
+ -1.25690469e-05
+ -2.32772658e-05
+ -2.71004214e-05
+ -2.45798454e-05
+ -2.73541706e-05
+ -2.93503315e-05
+ -3.50850649e-05
+ -4.05491324e-05
+ -4.62500325e-05
+ -4.50151194e-05
+ -3.80793062e-05
+ -2.09089393e-05
+ -3.62015616e-06
+ 1.58677873e-05
+ 2.24145183e-05
+ 1.64937021e-05
+ 1.36009605e-05
+ 1.38039600e-05
+ 1.27551297e-05
+ 1.02683869e-05
+ 8.22147615e-06
+ 3.46790661e-06
+ 1.30257955e-06
+ 9.47330585e-07
+ -1.10127180e-05
+ -3.42561506e-05
+ -5.33719285e-05
+ -6.32173999e-05
+ -6.27099014e-05
+ -6.34203993e-05
+ -6.29974839e-05
+ -6.02231586e-05
+ -6.17794874e-05
+ -6.04938245e-05
+ -4.99716883e-05
+ -4.36956232e-05
+ -3.47298159e-05
+ -2.88935828e-05
+ -2.37001812e-05
+ -1.89466117e-05
+ -1.53264555e-05
+ -9.06730703e-06
+ -8.77972453e-06
+ -7.08806277e-06
+ -1.23491308e-06
+ -1.40407926e-06
+ 3.82315557e-06
+ 5.09190189e-06
+ 3.07882440e-06
+ 2.97732470e-06
+ 1.89466117e-06
+ 3.29874043e-06
+ 6.64823071e-06
+ 1.48020404e-05
+ 2.28374337e-05
+ 2.82507514e-05
+ 3.61846450e-05
+ 3.62861447e-05
+ 3.24629891e-05
+ 2.53072599e-05
+ 1.97924426e-05
+ 2.28205171e-05
+ 2.16363539e-05
+ 1.83037802e-05
+ 6.39448145e-06
+ -5.56556719e-06
+ -1.81684473e-05
+ -2.34633486e-05
+ -3.25983221e-05
+ -3.90604700e-05
+ -4.60808663e-05
+ -4.84491928e-05
+ -4.85676091e-05
+ -4.94811064e-05
+ -5.40316766e-05
+ -5.63323366e-05
+ -5.52158398e-05
+ -5.08682691e-05
+ -3.78086403e-05
+ -2.90289158e-05
+ -2.12811049e-05
+ -1.53772054e-05
+ -1.61215366e-05
+ -1.59016205e-05
+ -1.82868636e-05
+ -1.53433722e-05
+ -9.93005452e-06
+ -8.44139218e-06
+ -1.47174573e-06
+ -2.72357543e-06
+ -5.29490130e-06
+ -1.56309546e-05
+ -2.62715071e-05
+ -3.53895640e-05
+ -3.38670684e-05
+ -3.36133191e-05
+ -2.40046804e-05
+ -2.10273557e-05
+ -2.00800251e-05
+ -2.20254361e-05
+ -2.81154184e-05
+ -2.49012611e-05
+ -2.84875840e-05
+ -2.70496715e-05
+ -2.29051002e-05
+ -1.92003610e-05
+ -7.83239394e-06
+ -8.62747497e-07
+ -8.83047438e-06
+ -7.24031233e-06
+ -9.99772099e-06
+ -6.44523130e-06
+ -3.58632293e-06
+ -1.82699470e-06
+ -3.01115793e-06
+ -5.14265175e-06
+ -4.97348557e-06
+ -6.34373159e-06
+ -2.99424131e-06
+ -6.47906454e-06
+ -8.03539335e-06
+ -5.90389954e-06
+ -7.27414556e-06
+ -1.21122982e-05
+ -1.75763657e-05
+ -1.72042001e-05
+ -1.71534502e-05
+ -1.41422923e-05
+ -9.55788894e-06
+ -5.81931645e-06
+ -9.76088835e-06
+ -7.30797880e-06
+ -1.50050398e-05
+ -2.18055201e-05
+ -2.57809252e-05
+ -2.35648483e-05
+ -1.83714467e-05
+ -1.13341338e-05
+ -4.16148793e-06
+ -1.67474514e-06
+ -8.79664114e-06
+ -1.60031202e-05
+ -2.26006011e-05
+ -2.21438524e-05
+ -1.80500310e-05
+ -1.29412125e-05
+ -6.12381557e-06
+ -2.70665881e-06
+ -1.87774455e-06
+ -7.27414556e-06
+ -8.20455953e-06
+ -1.39731261e-05
+ -1.92003610e-05
+ -1.64598689e-05
+ -1.56140380e-05
+ -8.49214203e-06
+ -3.51865646e-06
+ -4.24607101e-06
+ -8.61055835e-06
+ -7.03731292e-06
+ -1.21968813e-05
+ -1.14018003e-05
+ -7.24031233e-06
+ -9.20263997e-06
+ -6.03923248e-06
+ -6.58056424e-06
+ -7.95081027e-06
+ -1.11818842e-05
+ -1.51911226e-05
+ -1.65275354e-05
+ -1.59354538e-05
+ -2.16363539e-05
+ -2.92319152e-05
+ -3.57617296e-05
+ -4.46937037e-05
+ -4.42369550e-05
+ -4.66729479e-05
+ -4.54718681e-05
+ -3.94664688e-05
+ -3.91958029e-05
+ -4.12257971e-05
+ -4.35602903e-05
+ -4.37971229e-05
+ -3.75210578e-05
+ -3.00269962e-05
+ -2.01646082e-05
+ -1.15709664e-05
+ 5.07498528e-08
+ 8.40755894e-06
+ 1.22645477e-05
+ 1.66967016e-05
+ 1.27043798e-05
+ 1.54448719e-05
+ 2.07736064e-05
+ 2.73203374e-05
+ 3.17863244e-05
+ 3.10081600e-05
+ 2.43937626e-05
+ 1.44467914e-05
+ 6.51289777e-06
+ -5.85314968e-06
+ -1.15540498e-05
+ -1.91665277e-05
+ -2.13318548e-05
+ -2.29896833e-05
+ -3.10927431e-05
+ -3.65737272e-05
+ -4.71127800e-05
+ -5.45391751e-05
+ -6.37587317e-05
+ -6.56026430e-05
+ -6.28452343e-05
+ -5.94788274e-05
+ -5.48775074e-05
+ -5.49620905e-05
+ -5.23569314e-05
+ -4.41692885e-05
+ -3.60493121e-05
+ -2.78447525e-05
+ -2.08412729e-05
+ -1.03529700e-05
+ 2.46982617e-06
+ 1.33810445e-05
+ 2.42415130e-05
+ 3.22261565e-05
+ 4.36787066e-05
+ 4.66221981e-05
+ 5.02085210e-05
+ 5.31350958e-05
+ 4.93965234e-05
+ 4.08028816e-05
+ 3.53557308e-05
+ 3.09066603e-05
+ 1.84560298e-05
+ 8.96580732e-06
+ 6.76664703e-08
+ -8.79664114e-06
+ -1.89804449e-05
+ -3.29197378e-05
+ -4.56579509e-05
+ -6.08998233e-05
+ -6.88168003e-05
+ -6.94257986e-05
+ -6.52135608e-05
+ -5.92250782e-05
+ -5.49790072e-05
+ -5.10881851e-05
+ -5.20862655e-05
+ -4.89059414e-05
+ -4.29682087e-05
+ -3.43407337e-05
+ -2.45460121e-05
+ -1.57324544e-05
+ -3.84007219e-06
+ 8.81355776e-06
+ 1.38547098e-05
+ 1.16555495e-05
+ 5.02423542e-06
+ 6.08998233e-07
+ 1.09958014e-06
+ -2.02999411e-07
+ -1.18416323e-06
+ -3.56940631e-06
+ -1.10973011e-05
+ -2.06382735e-05
+ -2.74049205e-05
+ -3.50173984e-05
+ -3.89251371e-05
+ -3.91112199e-05
+ -4.23084606e-05
+ -3.84514718e-05
+ -3.57448130e-05
+ -3.32073203e-05
+ -2.67959223e-05
+ -2.25667679e-05
+ -1.79485313e-05
+ -5.34565116e-06
+ 1.81007808e-06
+ 1.13510504e-05
+ 2.11626886e-05
+ 1.97924426e-05
+ 2.80985018e-05
+ 3.18878241e-05
+ 3.34103197e-05
+ 3.31396539e-05
+ 2.85552505e-05
+ 2.54764261e-05
+ 1.84898630e-05
+ 1.20784650e-05
+ 6.93581321e-07
+ -7.35872865e-06
+ -1.81515307e-05
+ -2.86060003e-05
+ -3.45944830e-05
+ -4.06167988e-05
+ -4.80262773e-05
+ -6.39786477e-05
+ -6.82416353e-05
+ -7.24538731e-05
+ -7.57356969e-05
+ -7.20647909e-05
+ -6.82416353e-05
+ -6.42662302e-05
+ -5.95803271e-05
+ -5.62985033e-05
+ -5.62985033e-05
+ -5.24753478e-05
+ -4.66391147e-05
+ -4.15810460e-05
+ -3.52542310e-05
+ -2.39708471e-05
+ -2.07736064e-05
+ -1.35840439e-05
+ -8.45830879e-06
+ -1.18923822e-05
+ -1.28904626e-05
+ -1.34825442e-05
+ -9.10114026e-06
+ 9.81163820e-07
+ 8.25530938e-06
+ 1.00315542e-05
+ 1.48697069e-05
+ 1.72718666e-05
+ 1.50388730e-05
+ 1.09788848e-05
+ 8.76280791e-06
+ 7.56172806e-06
+ 1.48020404e-05
+ 2.35479317e-05
+ 2.11288554e-05
+ 1.83545301e-05
+ 1.48866235e-05
+ 1.00992207e-05
+ 2.40215970e-06
+ -2.63899234e-06
+ -1.05052195e-05
+ -1.51911226e-05
+ -1.74071995e-05
+ -2.13995212e-05
+ -2.57301753e-05
+ -2.54933427e-05
+ -3.21923233e-05
+ -3.45775663e-05
+ -3.32749868e-05
+ -2.99762464e-05
+ -2.68466721e-05
+ -2.43937626e-05
+ -1.89973615e-05
+ -8.64439159e-06
+ -1.42099588e-06
+ 5.34565116e-06
+ 1.45652077e-05
+ 1.94371936e-05
+ 2.08243562e-05
+ 1.63076194e-05
+ 1.87436123e-05
+ 1.08773851e-05
+ 4.85506925e-06
+ -1.35332941e-06
+ -2.40215970e-06
+ -7.56172806e-06
+ -2.38862640e-05
+ -3.56771465e-05
+ -4.74511123e-05
+ -6.13058221e-05
+ -6.49936448e-05
+ -7.15403758e-05
+ -7.54819477e-05
+ -6.68037228e-05
+ -6.17794874e-05
+ -5.46406748e-05
+ -4.76371951e-05
+ -3.94157190e-05
+ -3.77917237e-05
+ -3.04499117e-05
+ -1.55463716e-05
+ -1.30257955e-06
+ 4.87198586e-06
+ 1.80500310e-05
+ 2.59670080e-05
+ 2.86567502e-05
+ 2.66605893e-05
+ 1.82191971e-05
+ 1.23829641e-05
+ 5.49790072e-06
+ -2.35140984e-06
+ -6.07306571e-06
+ -1.89466117e-05
+ -2.86905834e-05
+ -3.97878846e-05
+ -4.74172791e-05
+ -5.79732485e-05
+ -6.42493136e-05
+ -6.44692296e-05
+ -6.46722290e-05
+ -6.56195596e-05
+ -6.00878257e-05
+ -4.86691088e-05
+ -4.17840454e-05
+ -3.01792458e-05
+ -2.42415130e-05
+ -1.64937021e-05
+ -1.06405525e-05
+ -5.24415145e-07
+ 8.47522541e-06
+ 1.40915424e-05
+ 1.76271155e-05
+ 1.76101989e-05
+ 2.29220168e-05
+ 2.85045006e-05
+ 2.35648483e-05
+ 1.81007808e-05
+ 1.14187169e-05
+ -1.35332941e-06
+ -2.68974220e-06
+ -7.27414556e-06
+ -8.89814085e-06
+ -1.06913023e-05
+ -1.20784650e-05
+ -1.14356335e-05
+ -1.75256158e-05
+ -2.12980215e-05
+ -2.64575899e-05
+ -2.71004214e-05
+ -2.87582499e-05
+ -2.53918430e-05
+ -1.69504508e-05
+ -1.72549499e-05
+ -1.33302947e-05
+ -1.38377932e-05
+ -1.73056998e-05
+ -2.13149382e-05
+ -1.82868636e-05
+ -1.43622083e-05
+ -1.03868032e-05
+ 1.82699470e-06
+ 6.64823071e-06
+ 1.00823041e-05
+ 7.79856071e-06
+ 7.25722894e-06
+ 9.25338982e-06
+ 8.05230997e-06
+ 8.52597526e-06
+ 1.19092988e-05
+ 1.35671273e-05
+ 1.33641279e-05
+ 1.17062994e-05
+ 1.72549499e-06
+ -2.58824249e-06
+ -8.57672512e-06
+ -1.30257955e-05
+ -1.76778654e-05
+ -2.45290955e-05
+ -3.01454125e-05
+ -3.50004818e-05
+ -4.04137994e-05
+ -4.32388745e-05
+ -4.28836256e-05
+ -4.98532720e-05
+ -4.69605304e-05
+ -4.71635298e-05
+ -4.81616103e-05
+ -4.92611904e-05
+ -4.58102004e-05
+ -4.26975428e-05
+ -3.48313156e-05
+ -2.87075000e-05
+ -2.72357543e-05
+ -2.47828448e-05
+ -2.62715071e-05
+ -2.75233368e-05
+ -3.16002417e-05
+ -2.91134989e-05
+ -2.74387537e-05
+ -2.71850045e-05
+ -2.61700074e-05
+ -2.32095993e-05
+ -2.49689276e-05
+ -2.93334149e-05
+ -2.90627490e-05
+ -3.12449927e-05
+ -2.91811653e-05
+ -2.62715071e-05
+ -1.86928624e-05
+ -1.23491308e-05
+ -7.18956247e-06
+ -4.38140395e-06
+ -4.73665292e-07
+ 8.11997644e-07
+ -7.95081027e-07
+ 1.55632882e-06
+ 2.70665881e-07
+ 6.61439748e-06
+ 1.25352136e-05
+ 1.23491308e-05
+ 9.27030644e-06
+ 7.47714497e-06
+ 4.90581910e-07
+ -5.85314968e-06
+ -9.01655717e-06
+ -9.32105629e-06
+ -1.17232160e-05
+ -1.48358736e-05
+ -1.47851238e-05
+ -2.00969417e-05
+ -1.89804449e-05
+ -2.30235165e-05
+ -2.29220168e-05
+ -2.56963421e-05
+ -2.41400133e-05
+ -2.48505112e-05
+ -2.13318548e-05
+ -1.29412125e-05
+ -1.14525501e-05
+ -4.04307160e-06
+ -2.62207573e-06
+ -2.89274161e-06
+ -3.77240572e-06
+ -2.53749264e-06
+ -5.32873454e-06
+ -1.82699470e-06
+ 3.04499117e-06
+ 1.18416323e-06
+ 5.43023425e-06
+ 3.26490719e-06
+ 2.57132587e-06
+ -3.21415734e-07
+ -6.73281380e-06
+ -1.16047997e-05
+ -1.47682072e-05
+ -2.21100192e-05
+ -2.22791854e-05
+ -2.19070198e-05
+ -2.35986815e-05
+ -2.37509311e-05
+ -2.91811653e-05
+ -3.54572305e-05
+ -4.02953831e-05
+ -4.00078006e-05
+ -4.27482926e-05
+ -3.98724677e-05
+ -3.46790661e-05
+ -2.75402534e-05
+ -2.12472717e-05
+ -1.90142782e-05
+ -2.41569299e-05
+ -2.43260961e-05
+ -2.49520109e-05
+ -2.09766058e-05
+ -1.60707867e-05
+ -1.79485313e-05
+ -1.19431320e-05
+ -8.01847674e-06
+ -7.22339571e-06
+ -1.37193769e-05
+ -1.84221966e-05
+ -2.43091795e-05
+ -2.53241765e-05
+ -2.76755864e-05
+ -3.06698277e-05
+ -2.53918430e-05
+ -2.35648483e-05
+ -2.42584296e-05
+ -2.63053403e-05
+ -2.61700074e-05
+ -2.93164983e-05
+ -2.46136786e-05
+ -2.13487714e-05
+ -1.75763657e-05
+ -1.80161977e-05
+ -1.17062994e-05
+ -6.80048027e-06
+ -9.13497350e-07
+ 1.31949617e-06
+ 3.84007219e-06
+ 5.80239983e-06
+ 2.63899234e-06
+ 4.70281969e-06
+ 2.97732470e-06
+ 1.18416323e-06
+ 3.95848852e-06
+ 7.98464350e-06
+ 4.14457131e-06
+ 3.95848852e-06
+ 3.09574102e-06
+ -2.53749264e-07
+ -6.08998233e-06
+ -1.24337139e-05
+ -1.32964614e-05
+ -1.30934620e-05
+ -8.98272394e-06
+ -1.09450516e-05
+ -8.57672512e-06
+ -1.25182970e-05
+ -2.14164379e-05
+ -2.57132587e-05
+ -3.06359944e-05
+ -3.16509915e-05
+ -2.87075000e-05
+ -2.50873439e-05
+ -2.67113392e-05
+ -2.27359340e-05
+ -2.34295154e-05
+ -2.26851842e-05
+ -2.29896833e-05
+ -2.37847643e-05
+ -2.45121789e-05
+ -1.93018607e-05
+ -7.62939453e-06
+ -2.16532705e-06
+ -5.24415145e-07
+ 2.13149382e-06
+ 3.46790661e-06
+ 3.84007219e-06
+ 2.11457720e-06
+ -2.58824249e-06
+ -4.29682087e-06
+ -6.14073218e-06
+ -9.64247202e-06
+ -1.01668872e-05
+ -1.42268754e-05
+ -2.26175177e-05
+ -3.38332352e-05
+ -3.92127196e-05
+ -4.59455334e-05
+ -5.30505127e-05
+ -5.52665897e-05
+ -5.54526724e-05
+ -5.45391751e-05
+ -4.94641898e-05
+ -4.58778669e-05
+ -4.47782867e-05
+ -4.33234576e-05
+ -3.86544712e-05
+ -2.82000015e-05
+ -2.68974220e-05
+ -1.64429523e-05
+ -1.08773851e-05
+ -3.97540513e-06
+ 4.87198586e-06
+ 6.95272983e-06
+ 1.10465513e-05
+ 9.52405570e-06
+ 5.59940042e-06
+ 3.21415734e-07
+ -5.49790072e-06
+ -7.20647909e-06
+ -1.29750457e-05
+ -1.49881232e-05
+ -1.85744461e-05
+ -2.45121789e-05
+ -2.81830849e-05
+ -3.67090602e-05
+ -4.03968828e-05
+ -4.50997025e-05
+ -4.32727078e-05
+ -4.02784665e-05
+ -3.30889040e-05
+ -2.39708471e-05
+ -1.94033604e-05
+ -1.13510504e-05
+ -8.50905865e-06
+ -7.05422953e-06
+ -2.23299352e-06
+ 6.14073218e-06
+ 1.77793651e-05
+ 2.43430127e-05
+ 2.58993415e-05
+ 3.57955628e-05
+ 3.47128993e-05
+ 3.14310755e-05
+ 2.89104995e-05
+ 2.13995212e-05
+ 1.44467914e-05
+ 1.03698866e-05
+ 6.93581321e-06
+ 9.64247202e-07
+ -1.01499706e-06
+ -1.36178772e-05
+ -2.27866839e-05
+ -2.82507514e-05
+ -3.42730672e-05
+ -4.05998822e-05
+ -4.14287965e-05
+ -4.76202785e-05
+ -4.42538716e-05
+ -3.84007219e-05
+ -3.71319756e-05
+ -3.65229774e-05
+ -3.14818253e-05
+ -2.49520109e-05
+ -2.34802652e-05
+ -2.02661079e-05
+ -1.92003610e-05
+ -1.45821244e-05
+ -1.12157175e-05
+ -7.51097821e-06
+ -2.30065999e-06
+ 1.01499706e-06
+ 2.36832646e-07
+ -4.21223778e-06
+ -9.94697114e-06
+ -1.27720463e-05
+ -1.79316146e-05
+ -2.00800251e-05
+ -2.06213568e-05
+ -2.14164379e-05
+ -2.00123586e-05
+ -1.81853639e-05
+ -2.46982617e-05
+ -3.05175781e-05
+ -3.33595699e-05
+ -3.20739069e-05
+ -3.22599897e-05
+ -2.44783456e-05
+ -1.94202770e-05
+ -1.62061196e-05
+ -1.15033000e-05
+ -1.08773851e-05
+ -1.55802048e-05
+ -1.55463716e-05
+ -1.66459517e-05
+ -1.66459517e-05
+ -1.16386329e-05
+ -9.21955658e-06
+ -1.11988008e-05
+ -1.56140380e-05
+ -1.45652077e-05
+ -1.51742060e-05
+ -2.03676076e-05
+ -2.28036005e-05
+ -2.30742664e-05
+ -2.10273557e-05
+ -1.64429523e-05
+ -1.22137979e-05
+ -1.02683869e-05
+ -5.39640101e-06
+ -1.42099588e-06
+ -1.81007808e-06
+ -5.24415145e-07
+ 5.29490130e-06
+ 2.50365940e-06
+ 5.90389954e-06
+ 8.45830879e-06
+ 6.49598115e-06
+ 7.76472747e-06
+ 3.29874043e-06
+ -1.03191367e-06
+ -7.62939453e-06
+ -1.77624485e-05
+ -2.23806851e-05
+ -2.78278359e-05
+ -3.33934031e-05
+ -3.16340749e-05
+ -3.22938230e-05
+ -3.20400737e-05
+ -3.12619093e-05
+ -3.30043209e-05
+ -2.94010814e-05
+ -2.48166780e-05
+ -2.43599293e-05
+ -2.10950221e-05
+ -1.39731261e-05
+ -4.92273572e-06
+ 1.28566294e-06
+ 5.98848263e-06
+ 8.67822482e-06
+ 7.62939453e-06
+ 5.83623307e-06
+ 2.89274161e-06
+ -6.39448145e-06
+ -9.57480555e-06
+ -9.91313791e-06
+ -1.20615483e-05
+ -1.35840439e-05
+ -2.21269358e-05
+ -2.32772658e-05
+ -3.03822452e-05
+ -4.19532116e-05
+ -4.71127800e-05
+ -4.61146995e-05
+ -4.14795463e-05
+ -3.52711477e-05
+ -3.65568106e-05
+ -3.10081600e-05
+ -2.57301753e-05
+ -2.48674279e-05
+ -1.99616088e-05
+ -1.77116986e-05
+ -1.58847039e-05
+ -1.35671273e-05
+ -7.84931056e-06
+ 3.04499117e-07
+ 4.73665292e-07
+ 3.18032411e-06
+ 2.08074396e-06
+ -1.53941220e-06
+ -6.44523130e-06
+ -6.54673101e-06
+ -8.11997644e-06
+ -1.16724661e-05
+ -1.07758854e-05
+ -9.03347379e-06
+ -7.54481144e-06
+ -7.69706100e-06
+ -1.15202166e-05
+ -1.30257955e-05
+ -1.38377932e-05
+ -9.20263997e-06
+ -1.12664673e-05
+ -1.49035401e-05
+ -9.52405570e-06
+ -6.74973042e-06
+ -5.83623307e-06
+ -3.11265764e-06
+ -3.62015616e-06
+ -8.49214203e-06
+ -1.56647879e-05
+ -1.31272952e-05
+ -1.34656276e-05
+ -1.34317944e-05
+ -8.44139218e-06
+ -1.08097186e-05
+ -7.07114615e-06
+ -6.03923248e-06
+ -7.91697703e-06
+ -1.00146376e-05
+ -1.21799647e-05
+ -1.12157175e-05
+ -1.02683869e-05
+ -7.76472747e-06
+ -3.36640690e-06
+ -4.87198586e-06
+ -2.26682676e-06
+ -3.43407337e-06
+ -8.62747497e-06
+ -1.23998807e-05
+ -2.19916029e-05
+ -2.06890233e-05
+ -1.80500310e-05
+ -1.59185371e-05
+ -1.64767855e-05
+ -1.96909429e-05
+ -2.30573498e-05
+ -2.37509311e-05
+ -2.45460121e-05
+ -2.50196774e-05
+ -2.40385136e-05
+ -2.28881836e-05
+ -2.35648483e-05
+ -1.89466117e-05
+ -1.54279552e-05
+ -1.90988613e-05
+ -2.00292752e-05
+ -1.72549499e-05
+ -2.20931026e-05
+ -2.43599293e-05
+ -2.38693474e-05
+ -2.54087596e-05
+ -2.55610092e-05
+ -2.63391736e-05
+ -2.62715071e-05
+ -2.97224971e-05
+ -2.84368342e-05
+ -3.27336550e-05
+ -3.23953227e-05
+ -2.82507514e-05
+ -3.07036609e-05
+ -3.33257366e-05
+ -2.58147584e-05
+ -1.75763657e-05
+ -1.47343739e-05
+ -1.03698866e-05
+ -9.06730703e-06
+ -1.12833839e-05
+ -8.98272394e-06
+ -9.13497350e-06
+ -1.04375531e-05
+ -6.52981439e-06
+ -3.62015616e-06
+ -4.77048616e-06
+ -5.26106807e-06
+ -7.34181203e-06
+ -1.14356335e-05
+ -1.71872835e-05
+ -2.09427726e-05
+ -2.34971818e-05
+ -2.47659281e-05
+ -2.28036005e-05
+ -2.25160180e-05
+ -1.76271155e-05
+ -1.63076194e-05
+ -1.95386933e-05
+ -1.70857838e-05
+ -1.65782852e-05
+ -1.63583692e-05
+ -9.96388776e-06
+ -7.08806277e-06
+ -1.31949617e-06
+ 4.14457131e-06
+ 7.68014438e-06
+ 9.59172217e-06
+ 6.32681498e-06
+ 7.78164409e-06
+ 2.36832646e-06
+ -1.33641279e-06
+ -3.55248969e-07
+ -1.69166176e-06
+ -2.55440926e-06
+ -3.78932234e-06
+ -1.13341338e-05
+ -1.67474514e-05
+ -2.14502711e-05
+ -2.69143386e-05
+ -3.28013215e-05
+ -3.39854847e-05
+ -4.00585504e-05
+ -4.38817060e-05
+ -3.67090602e-05
+ -4.04307160e-05
+ -3.88743872e-05
+ -3.91112199e-05
+ -4.09043813e-05
+ -3.44253168e-05
+ -3.02130790e-05
+ -2.20085195e-05
+ -1.86082793e-05
+ -1.13172172e-05
+ 4.05998822e-07
+ 7.00347968e-06
+ 1.00146376e-05
+ 1.42776252e-05
+ 1.99616088e-05
+ 1.71365336e-05
+ 1.46159576e-05
+ 1.51911226e-05
+ 1.21461314e-05
+ 1.39562095e-05
+ 1.08604685e-05
+ 4.70281969e-06
+ -4.90581910e-07
+ -1.45482911e-05
+ -2.78447525e-05
+ -3.11096597e-05
+ -4.05322157e-05
+ -4.56241176e-05
+ -4.26467929e-05
+ -4.40677888e-05
+ -4.61146995e-05
+ -4.31712081e-05
+ -4.38478728e-05
+ -4.56410342e-05
+ -3.75379744e-05
+ -3.22769064e-05
+ -3.20231571e-05
+ -2.07228565e-05
+ -1.09788848e-05
+ -5.92081616e-07
+ 6.41139807e-06
+ 1.08773851e-05
+ 9.49022247e-06
+ 5.59940042e-06
+ 7.93389365e-06
+ 5.87006630e-06
+ 9.23647320e-06
+ 6.47906454e-06
+ 5.93773277e-06
+ 1.91157779e-06
+ -3.28182381e-06
+ -8.30605923e-06
+ -1.70857838e-05
+ -2.30065999e-05
+ -2.66436727e-05
+ -3.05344947e-05
+ -3.34949028e-05
+ -2.78278359e-05
+ -2.68466721e-05
+ -2.95871642e-05
+ -2.88428330e-05
+ -3.17524912e-05
+ -3.40362346e-05
+ -3.11434930e-05
+ -2.73034208e-05
+ -2.71173380e-05
+ -2.31926827e-05
+ -2.06890233e-05
+ -1.81346141e-05
+ -9.55788894e-06
+ -9.81163820e-06
+ -1.36009605e-05
+ -1.22307145e-05
+ -9.01655717e-06
+ -7.03731292e-06
+ -6.68206395e-06
+ -1.62399529e-06
+ -1.84391132e-06
+ 4.41523719e-06
+ 5.83623307e-06
+ 2.63899234e-06
+ -4.51673690e-06
+ -6.12381557e-06
+ -7.96772688e-06
+ -1.18416323e-05
+ -1.36178772e-05
+ -1.49881232e-05
+ -1.65275354e-05
+ -2.04521907e-05
+ -2.35479317e-05
+ -3.15494918e-05
+ -3.66583103e-05
+ -4.17502122e-05
+ -4.57594506e-05
+ -4.53534517e-05
+ -4.06675487e-05
+ -3.66413937e-05
+ -3.35456527e-05
+ -3.12619093e-05
+ -2.49858442e-05
+ -2.25329346e-05
+ -1.50050398e-05
+ -1.03529700e-05
+ -2.74049205e-06
+ 2.38524308e-06
+ 8.59364173e-06
+ 1.42099588e-05
+ 2.19408530e-05
+ 2.43430127e-05
+ 1.95894432e-05
+ 1.33979611e-05
+ 5.07498528e-06
+ 7.12189600e-06
+ 4.14457131e-06
+ -3.85698881e-06
+ -1.04037198e-05
+ -1.67643680e-05
+ -2.59331748e-05
+ -3.08389939e-05
+ -3.61677284e-05
+ -4.42707882e-05
+ -4.71466132e-05
+ -5.00562714e-05
+ -5.07836860e-05
+ -4.56917841e-05
+ -4.30358751e-05
+ -3.39009016e-05
+ -2.79124190e-05
+ -2.78278359e-05
+ -2.16025207e-05
+ -1.59862036e-05
+ -1.26028801e-05
+ -6.52981439e-06
+ 3.41715675e-06
+ 4.48290366e-06
+ 1.02176370e-05
+ 1.34148777e-05
+ 1.68320345e-05
+ 1.38377932e-05
+ 9.15189011e-06
+ 4.46598704e-06
+ -5.58248380e-07
+ -6.05614910e-06
+ -9.89622129e-06
+ -1.33641279e-05
+ -1.63922024e-05
+ -1.77116986e-05
+ -2.60515911e-05
+ -3.46790661e-05
+ -3.97709679e-05
+ -4.18855451e-05
+ -4.53365351e-05
+ -4.48290366e-05
+ -4.42538716e-05
+ -3.74703080e-05
+ -3.59478124e-05
+ -3.10419933e-05
+ -2.69143386e-05
+ -2.49350943e-05
+ -2.72526709e-05
+ -2.45121789e-05
+ -1.45821244e-05
+ -1.05221361e-05
+ -2.99424131e-06
+ 5.88698292e-06
+ 4.12765469e-06
+ 4.31373748e-06
+ 2.89274161e-06
+ 3.53557308e-06
+ -4.05998822e-06
+ -1.12157175e-05
+ -8.76280791e-06
+ -1.12157175e-05
+ -1.59862036e-05
+ -1.65275354e-05
+ -1.78977814e-05
+ -2.65083398e-05
+ -3.20231571e-05
+ -3.20231571e-05
+ -3.58293960e-05
+ -3.56263966e-05
+ -3.22769064e-05
+ -3.04329950e-05
+ -2.65760062e-05
+ -2.69143386e-05
+ -1.84052799e-05
+ -1.61046199e-05
+ -1.40746258e-05
+ -1.61384532e-05
+ -1.65444520e-05
+ -1.16386329e-05
+ -8.06922659e-06
+ -5.59940042e-06
+ -5.59940042e-06
+ -5.71781674e-06
+ -5.65015027e-06
+ -9.89622129e-06
+ -1.37701267e-05
+ -1.94541102e-05
+ -2.14671877e-05
+ -2.04014408e-05
+ -2.17378536e-05
+ -2.39370139e-05
+ -2.23468518e-05
+ -1.95556099e-05
+ -1.79146980e-05
+ -2.20085195e-05
+ -2.72865042e-05
+ -2.53580098e-05
+ -2.21607690e-05
+ -1.95386933e-05
+ -1.71534502e-05
+ -1.00823041e-05
+ -1.06067192e-05
+ -1.13172172e-05
+ -1.52926223e-05
+ -1.71365336e-05
+ -1.69842841e-05
+ -1.68489511e-05
+ -1.87943621e-05
+ -1.93018607e-05
+ -1.83037802e-05
+ -2.12980215e-05
+ -1.81515307e-05
+ -1.52249558e-05
+ -1.77624485e-05
+ -1.57493710e-05
+ -2.00292752e-05
+ -2.05706070e-05
+ -1.52249558e-05
+ -9.13497350e-06
+ -5.39640101e-06
+ -2.87582499e-06
+ 1.25182970e-06
+ 2.80815852e-06
+ -2.33449323e-06
+ -3.80623896e-06
+ -6.69898056e-06
+ -9.47330585e-06
+ -7.57864468e-06
+ -8.86430762e-06
+ -6.08998233e-06
+ -8.45830879e-06
+ -1.55971214e-05
+ -1.67305348e-05
+ -1.78639482e-05
+ -2.31419329e-05
+ -2.71173380e-05
+ -2.73034208e-05
+ -2.64406733e-05
+ -2.09596892e-05
+ -1.75086992e-05
+ -1.67136182e-05
+ -1.07928020e-05
+ -1.32964614e-05
+ -1.53941220e-05
+ -1.28397127e-05
+ -1.28735460e-05
+ -8.86430762e-06
+ -2.45290955e-06
+ -1.77624485e-06
+ 2.38524308e-06
+ 2.04691073e-06
+ -3.80623896e-06
+ -7.79856071e-06
+ -8.66130820e-06
+ -1.04883029e-05
+ -1.22137979e-05
+ -1.27043798e-05
+ -1.23491308e-05
+ -1.26197967e-05
+ -1.12157175e-05
+ -9.67630526e-06
+ -1.60200369e-05
+ -1.50557897e-05
+ -1.81515307e-05
+ -1.97586093e-05
+ -1.80838642e-05
+ -1.62230363e-05
+ -1.49204567e-05
+ -1.08097186e-05
+ -1.27212964e-05
+ -1.49712066e-05
+ -1.80500310e-05
+ -1.91326945e-05
+ -2.30573498e-05
+ -2.34633486e-05
+ -2.42922629e-05
+ -2.47997614e-05
+ -2.42245964e-05
+ -1.87097791e-05
+ -1.89127785e-05
+ -1.99277755e-05
+ -1.66797849e-05
+ -1.35163775e-05
+ -1.87943621e-05
+ -1.69504508e-05
+ -9.98080438e-06
+ -1.20784650e-05
+ -5.51481733e-06
+ -1.04883029e-06
+ -3.82315557e-06
+ -8.05230997e-06
+ -9.50713908e-06
+ -1.17232160e-05
+ -1.47851238e-05
+ -1.33810445e-05
+ -1.54787051e-05
+ -1.59354538e-05
+ -1.44806247e-05
+ -1.56478713e-05
+ -1.75594491e-05
+ -2.11965218e-05
+ -2.63899234e-05
+ -2.60854243e-05
+ -2.61023409e-05
+ -2.55440926e-05
+ -2.38016809e-05
+ -1.98939423e-05
+ -1.49712066e-05
+ -1.78808648e-05
+ -1.52249558e-05
+ -1.65106188e-05
+ -1.66290351e-05
+ -1.62061196e-05
+ -1.54448719e-05
+ -1.26705466e-05
+ -1.39562095e-05
+ -1.04206364e-05
+ -1.03022201e-05
+ -1.50727063e-05
+ -2.06551901e-05
+ -1.85406129e-05
+ -1.61722864e-05
+ -2.23130186e-05
+ -2.16701871e-05
+ -2.10273557e-05
+ -1.70350339e-05
+ -1.20784650e-05
+ -1.40238760e-05
+ -1.48020404e-05
+ -1.12664673e-05
+ -1.42268754e-05
+ -1.89973615e-05
+ -1.83206968e-05
+ -1.10465513e-05
+ -1.06913023e-05
+ -9.21955658e-06
+ -7.51097821e-06
+ -6.05614910e-06
+ -1.01161373e-05
+ -1.19092988e-05
+ -1.85406129e-05
+ -1.99785254e-05
+ -1.78639482e-05
+ -1.59523704e-05
+ -1.45821244e-05
+ -1.12326341e-05
+ -1.03191367e-05
+ -1.16555495e-05
+ -1.12833839e-05
+ -1.38208766e-05
+ -1.30088789e-05
+ -1.53095389e-05
+ -1.26536300e-05
+ -1.02514703e-05
+ -4.58440337e-06
+ -5.39640101e-06
+ -3.90773866e-06
+ -3.56940631e-06
+ -3.73857249e-06
+ -5.37948439e-06
+ -1.28227961e-05
+ -7.51097821e-06
+ -9.47330585e-06
+ -9.52405570e-06
+ -1.02007204e-05
+ -9.13497350e-06
+ -1.32457116e-05
+ -1.74241161e-05
+ -2.16363539e-05
+ -2.51380937e-05
+ -2.72357543e-05
+ -2.77601695e-05
+ -2.92149986e-05
+ -3.06529111e-05
+ -2.86905834e-05
+ -2.59331748e-05
+ -2.37340145e-05
+ -2.54425928e-05
+ -2.52057602e-05
+ -2.58824249e-05
+ -2.61700074e-05
+ -2.00461918e-05
+ -1.26536300e-05
+ -9.93005452e-06
+ -3.45098999e-06
+ 1.43791249e-06
+ 4.60131998e-06
+ 1.97924426e-06
+ 1.69166176e-07
+ 1.99616088e-06
+ 2.96040808e-06
+ 1.26874632e-06
+ 1.35332941e-07
+ -7.27414556e-07
+ -6.88506336e-06
+ -1.13510504e-05
+ -1.57493710e-05
+ -2.49012611e-05
+ -3.27167384e-05
+ -3.68443931e-05
+ -4.26298763e-05
+ -4.33234576e-05
+ -4.44399544e-05
+ -4.03292163e-05
+ -3.72503919e-05
+ -3.71996421e-05
+ -3.33088200e-05
+ -3.13972422e-05
+ -3.04160784e-05
+ -2.56455923e-05
+ -1.81007808e-05
+ -8.72897467e-06
+ -1.94541102e-06
+ 5.07498528e-06
+ 5.27798469e-06
+ 1.03022201e-05
+ 1.24337139e-05
+ 7.95081027e-06
+ 7.98464350e-06
+ 2.02999411e-06
+ 4.73665292e-07
+ -4.04307160e-06
+ -5.53173395e-06
+ -7.93389365e-06
+ -1.08773851e-05
+ -2.09258560e-05
+ -2.88766662e-05
+ -3.19893239e-05
+ -3.92127196e-05
+ -3.93649691e-05
+ -3.60323955e-05
+ -3.25306556e-05
+ -2.90796656e-05
+ -2.76755864e-05
+ -2.62545905e-05
+ -2.49858442e-05
+ -1.73395330e-05
+ -1.65782852e-05
+ -1.62907027e-05
+ -9.57480555e-06
+ -3.87390543e-06
+ 1.06574691e-06
+ 2.30065999e-06
+ 1.87774455e-06
+ 1.48866235e-06
+ 4.22915440e-07
+ -4.77048616e-06
+ -7.68014438e-06
+ -8.03539335e-06
+ -1.06067192e-05
+ -9.32105629e-06
+ -6.56364762e-06
+ -1.26536300e-05
+ -1.11649676e-05
+ -1.36517104e-05
+ -2.07228565e-05
+ -2.72357543e-05
+ -2.87920831e-05
+ -2.65421730e-05
+ -2.61530908e-05
+ -2.61361742e-05
+ -2.43768459e-05
+ -2.63391736e-05
+ -2.74218371e-05
+ -2.62545905e-05
+ -2.75740867e-05
+ -2.86736668e-05
+ -2.82338348e-05
+ -2.39708471e-05
+ -2.44614290e-05
+ -2.16025207e-05
+ -1.52418724e-05
+ -1.08435519e-05
+ -1.08266353e-05
+ -1.30765454e-05
+ -1.01330539e-05
+ -1.32795448e-05
+ -1.11649676e-05
+ -4.70281969e-06
+ -3.94157190e-06
+ -1.20107985e-06
+ -4.73665292e-07
+ -3.80623896e-06
+ -5.81931645e-06
+ -1.10296347e-05
+ -1.49712066e-05
+ -1.77116986e-05
+ -1.96740263e-05
+ -2.11119387e-05
+ -2.48335946e-05
+ -2.65760062e-05
+ -2.90289158e-05
+ -2.54425928e-05
+ -3.14649087e-05
+ -3.77917237e-05
+ -3.54403138e-05
+ -3.31734871e-05
+ -3.05006615e-05
+ -2.76248365e-05
+ -1.95725265e-05
+ -1.30596288e-05
+ -8.23839276e-06
+ -1.03191367e-05
+ -9.84547144e-06
+ -5.43023425e-06
+ -2.75740867e-06
+ 6.07306571e-06
+ 7.59556130e-06
+ 7.27414556e-06
+ 8.10305982e-06
+ 7.40947850e-06
+ 9.03347379e-06
+ 5.53173395e-06
+ 3.29874043e-06
+ -7.18956247e-06
+ -7.02039630e-06
+ -8.66130820e-06
+ -9.65938864e-06
+ -1.29412125e-05
+ -1.90650280e-05
+ -1.89973615e-05
+ -2.18901032e-05
+ -2.66944226e-05
+ -2.96209974e-05
+ -2.93334149e-05
+ -2.99254965e-05
+ -2.72865042e-05
+ -2.56794255e-05
+ -2.18055201e-05
+ -1.88958618e-05
+ -1.55971214e-05
+ -1.49881232e-05
+ -1.58001208e-05
+ -1.32457116e-05
+ -1.18077991e-05
+ -7.81547732e-06
+ -6.52981439e-06
+ -3.82315557e-06
+ 3.50173984e-06
+ 1.18416323e-07
+ -8.96580732e-07
+ -1.89466117e-06
+ -6.78356365e-06
+ -1.14694667e-05
+ -1.33133780e-05
+ -1.34656276e-05
+ -1.79823645e-05
+ -1.37193769e-05
+ -1.29073792e-05
+ -2.41738465e-05
+ -2.26175177e-05
+ -2.22453521e-05
+ -3.03484119e-05
+ -3.28351547e-05
+ -2.78278359e-05
+ -2.62207573e-05
+ -2.29389334e-05
+ -1.97924426e-05
+ -1.58170374e-05
+ -1.53602888e-05
+ -1.68658677e-05
+ -1.14187169e-05
+ -8.99964056e-06
+ -1.38885430e-05
+ -7.86622718e-06
+ -7.37564527e-06
+ -6.66514733e-06
+ -5.68398351e-06
+ -7.30797880e-06
+ -8.84739100e-06
+ -1.19431320e-05
+ -1.35671273e-05
+ -2.11119387e-05
+ -2.19239364e-05
+ -2.76925030e-05
+ -2.93503315e-05
+ -2.27697673e-05
+ -2.18055201e-05
+ -2.23637684e-05
+ -2.27697673e-05
+ -2.08074396e-05
+ -1.76101989e-05
+ -1.82699470e-05
+ -1.61722864e-05
+ -8.15380968e-06
+ -4.29682087e-06
+ -1.16724661e-06
+ 3.58632293e-06
+ 3.04499117e-06
+ 8.62747497e-07
+ 2.36832646e-07
+ -2.53749264e-06
+ -7.71397762e-06
+ -9.30413967e-06
+ -1.03868032e-05
+ -8.32297585e-06
+ -1.24506305e-05
+ -1.53941220e-05
+ -1.69166176e-05
+ -2.42922629e-05
+ -2.64575899e-05
+ -2.94856645e-05
+ -2.83184178e-05
+ -2.57809252e-05
+ -2.12303551e-05
+ -1.75594491e-05
+ -1.92680274e-05
+ -1.59523704e-05
+ -1.69673674e-05
+ -1.42776252e-05
+ -1.40069594e-05
+ -1.52757057e-05
+ -1.14356335e-05
+ -9.76088835e-06
+ -4.31373748e-06
+ -4.00923837e-06
+ -1.97924426e-06
+ -6.22531527e-06
+ -9.71013849e-06
+ -1.28397127e-05
+ -1.59185371e-05
+ -1.86082793e-05
+ -2.24652682e-05
+ -1.71703668e-05
+ -1.62399529e-05
+ -1.66797849e-05
+ -2.06721067e-05
+ -1.65782852e-05
+ -2.16532705e-05
+ -2.02491913e-05
+ -2.42245964e-05
+ -2.27359340e-05
+ -2.40892634e-05
+ -2.44783456e-05
+ -2.15010210e-05
+ -2.17209370e-05
+ -2.09427726e-05
+ -2.23468518e-05
+ -2.34971818e-05
+ -2.43430127e-05
+ -2.35817649e-05
+ -2.58485917e-05
+ -1.95048601e-05
+ -1.38547098e-05
+ -1.10973011e-05
+ -8.30605923e-06
+ -7.52789483e-06
+ -9.27030644e-06
+ -1.08943017e-05
+ -1.19262154e-05
+ -8.03539335e-06
+ -9.15189011e-06
+ -1.12664673e-05
+ -6.61439748e-06
+ -8.03539335e-06
+ -1.09450516e-05
+ -1.22137979e-05
+ -1.48527902e-05
+ -2.43260961e-05
+ -2.67790056e-05
+ -2.93841647e-05
+ -2.49858442e-05
+ -2.73034208e-05
+ -2.67620890e-05
+ -2.31419329e-05
+ -2.44445124e-05
+ -2.52565101e-05
+ -2.22622687e-05
+ -2.16701871e-05
+ -2.24483515e-05
+ -1.47851238e-05
+ -9.23647320e-06
+ -5.00731881e-06
+ -5.92081616e-07
+ 2.53749264e-06
+ 3.26490719e-06
+ 7.61247791e-06
+ 8.30605923e-06
+ 2.79124190e-06
+ -1.84391132e-06
+ -1.20107985e-06
+ -1.70857838e-06
+ -4.90581910e-06
+ -8.00156012e-06
+ -8.42447556e-06
+ -1.51742060e-05
+ -1.99954420e-05
+ -3.12280761e-05
+ -3.20062405e-05
+ -3.04160784e-05
+ -3.29535711e-05
+ -3.14987419e-05
+ -2.99931630e-05
+ -3.04837449e-05
+ -2.89104995e-05
+ -2.35479317e-05
+ -2.44445124e-05
+ -2.79970021e-05
+ -2.49520109e-05
+ -1.90650280e-05
+ -1.44975413e-05
+ -1.04206364e-05
+ -7.88314380e-06
+ -5.39640101e-06
+ -4.39832057e-06
+ -7.83239394e-06
+ -9.43947261e-06
+ -7.91697703e-06
+ -1.03868032e-05
+ -7.34181203e-06
+ -9.45638923e-06
+ -9.79472158e-06
+ -8.54289188e-06
+ -8.23839276e-06
+ -9.18572335e-06
+ -1.87266957e-05
+ -2.27021008e-05
+ -2.40215970e-05
+ -2.52226768e-05
+ -2.13826046e-05
+ -2.24314349e-05
+ -2.31419329e-05
+ -2.39370139e-05
+ -2.59162581e-05
+ -2.62884237e-05
+ -2.63899234e-05
+ -2.83860843e-05
+ -3.16848247e-05
+ -3.20569903e-05
+ -2.62715071e-05
+ -2.12641883e-05
+ -1.44975413e-05
+ -1.38208766e-05
+ -1.42607086e-05
+ -1.18416323e-05
+ -1.12833839e-05
+ -1.00315542e-05
+ -7.22339571e-06
+ -4.29682087e-06
+ -2.02999411e-06
+ 1.03191367e-06
+ 3.40024013e-06
+ 2.79124190e-06
+ -3.95848852e-06
+ -4.19532116e-06
+ -7.20647909e-06
+ -9.43947261e-06
+ -1.50388730e-05
+ -1.28735460e-05
+ -1.23322142e-05
+ -1.44467914e-05
+ -1.40069594e-05
+ -2.00800251e-05
+ -2.32941824e-05
+ -2.49350943e-05
+ -2.63560902e-05
+ -2.70327549e-05
+ -2.74049205e-05
+ -2.72526709e-05
+ -2.69143386e-05
+ -2.65760062e-05
+ -2.14333545e-05
+ -2.27359340e-05
+ -2.40723468e-05
+ -2.10781055e-05
+ -2.08074396e-05
+ -1.85575295e-05
+ -1.52926223e-05
+ -9.50713908e-06
+ -3.73857249e-06
+ -9.47330585e-07
+ 2.75740867e-06
+ 4.78740278e-06
+ 1.04883029e-06
+ -9.64247202e-07
+ -1.20107985e-06
+ -1.37024602e-06
+ -3.89082204e-06
+ -6.08998233e-06
+ -4.09382146e-06
+ -6.49598115e-06
+ -9.71013849e-06
+ -1.83883633e-05
+ -2.54595095e-05
+ -2.83184178e-05
+ -3.44760666e-05
+ -3.62184783e-05
+ -3.87390543e-05
+ -3.86206379e-05
+ -3.54403138e-05
+ -3.79608899e-05
+ -3.84345552e-05
+ -3.16509915e-05
+ -3.16509915e-05
+ -2.96717472e-05
+ -1.96909429e-05
+ -1.17401326e-05
+ -5.24415145e-06
+ 3.78932234e-06
+ 8.22147615e-06
+ 8.89814085e-06
+ 8.28914262e-06
+ 8.49214203e-06
+ 1.00484708e-05
+ 6.15764880e-06
+ 3.34949028e-06
+ 1.26874632e-06
+ 9.30413967e-07
+ -7.81547732e-06
+ -1.36178772e-05
+ -1.53095389e-05
+ -2.54425928e-05
+ -2.89781659e-05
+ -3.80623896e-05
+ -4.07690484e-05
+ -3.98724677e-05
+ -3.78932234e-05
diff --git a/inst/signals/otoclick.m b/inst/signals/otoclick.m
new file mode 100644
index 0000000..751a4e7
--- /dev/null
+++ b/inst/signals/otoclick.m
@@ -0,0 +1,52 @@
+function [s,fs]=otoclick()
+%-*- texinfo -*-
+%@deftypefn {Function} otoclick
+%@verbatim
+%OTOCLICK  Load the 'otoclick' test signal
+%   Usage:  s=otoclick;
+%
+%   OTOCLICK loads the 'otoclick' signal. The signal is a click-evoked
+%   otoacoustic emission. It consists of two clear clicks followed by a
+%   ringing. The ringing is the actual otoacoustic emission.
+%
+%   [sig,fs]=OTOCLICK additionally returns the sampling frequency fs.
+%
+%   It was measured by Sarah Verhulst at CAHR (Centre of Applied Hearing
+%   Research) at Department of Eletrical Engineering, Technical University
+%   of Denmark
+%
+%   The signal is 2210 samples long and sampled at 44.1 kHz.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/otoclick.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=load('-ascii',[f,'.asc']);
+fs=44100;
+
+
diff --git a/inst/signals/pinknoise.m b/inst/signals/pinknoise.m
new file mode 100644
index 0000000..c870739
--- /dev/null
+++ b/inst/signals/pinknoise.m
@@ -0,0 +1,44 @@
+function outsig = pinknoise(varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} pinknoise
+%@verbatim
+% PINKNOISE Generates a pink noise signal
+%   Usage: outsig = pinknoise(siglen,nsigs);
+%
+%   Input parameters:
+%       siglen    : Length of the noise (samples)
+%       nsigs     : Number of signals (default is 1)
+%
+%   Output parameters:
+%       outsig    : siglen xnsigs signal vector
+%
+%   PINKNOISE(siglen,nsigs) generates nsigs channels containing pink noise
+%   (1/f spectrum) with the length of siglen. The signals are arranged as
+%   columns in the output.
+%
+%   PINKNOISE is just a wrapper around noise(...,'pink');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/pinknoise.php}
+%@seealso{noise}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+outsig = noise(varargin{:},'pink');
+
+
diff --git a/inst/signals/signalsinit.m b/inst/signals/signalsinit.m
new file mode 100644
index 0000000..5c4df37
--- /dev/null
+++ b/inst/signals/signalsinit.m
@@ -0,0 +1,27 @@
+status=1;
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} signalsinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/signalsinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/signals/traindoppler.m b/inst/signals/traindoppler.m
new file mode 100644
index 0000000..b6f2c35
--- /dev/null
+++ b/inst/signals/traindoppler.m
@@ -0,0 +1,51 @@
+function [s,fs]=traindoppler()
+%-*- texinfo -*-
+%@deftypefn {Function} traindoppler
+%@verbatim
+%TRAINDOPPLER  Load the 'traindoppler' test signal
+%   Usage:  s=traindoppler;
+%
+%   TRAINDOPPLER loads the 'traindoppler' signal. It is a recording
+%   of a train passing close by with a clearly audible doppler shift of
+%   the train whistle sound.
+%
+%   [sig,fs]=TRAINDOPPLER additionally returns the sampling frequency
+%   fs.
+%
+%   The signal is 157058 samples long and sampled at 8 kHz.
+%
+%   The signal was obtained from
+%   http://www.fourmilab.ch/cship/doppler.html
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/signals/traindoppler.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: TEST_SIGNALS
+%   REFERENCE: OK
+  
+if nargin>0
+  error('This function does not take input arguments.')
+end;
+
+f=mfilename('fullpath');
+
+s=wavread([f,'.wav']);
+fs=8000;
+
diff --git a/inst/signals/traindoppler.wav b/inst/signals/traindoppler.wav
new file mode 100644
index 0000000..f6d8dea
Binary files /dev/null and b/inst/signals/traindoppler.wav differ
diff --git a/inst/sigproc/Contents.m b/inst/sigproc/Contents.m
new file mode 100644
index 0000000..62e7d70
--- /dev/null
+++ b/inst/sigproc/Contents.m
@@ -0,0 +1,53 @@
+% LTFAT - Signal processing tools
+%
+%  Peter L. Soendergaard, 2007 - 2014.
+%
+%  General
+%    RMS            -  Root Mean Square norm of signal.
+%    NORMALIZE      -  Normalize signal by specified norm.
+%    GAINDB         -  Scale input signal
+%    CRESTFACTOR    -  Compute the crest factor of a signal.
+%    UQUANT         -  Simulate uniform quantization.
+%
+%  Ramping
+%    RAMPUP         -  Rising ramp.
+%    RAMPDOWN       -  Falling ramp.
+%    RAMPSIGNAL     -  Ramp a signal.
+%
+%  Thresholding methods
+%    THRESH         -  Coefficient thresholding.
+%    LARGESTR       -  Keep largest ratio of coefficients.
+%    LARGESTN       -  Keep N largest coefficients.
+%    DYNLIMIT       -  Limit the dynamical range.
+%    GROUPTHRESH    -  Group thresholding.
+%
+%  Image processing
+%    RGB2JPEG       -  Convert RGB values to the JPEG color model
+%    JPEG2RGB       -  Convert values from the JPEG color model to RGB
+%
+%  Tools for OFDM
+%    QAM4           -  Quadrature amplitude modulation, order 4
+%    IQAM4          -  Inverse QAM of order 4
+%
+%  For help, bug reports, suggestions etc. please send email to
+%  ltfat-help at lists.sourceforge.net
+%
+%
+%   Url: http://ltfat.sourceforge.net/doc/sigproc/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/sigproc/crestfactor.m b/inst/sigproc/crestfactor.m
new file mode 100644
index 0000000..2cc3f12
--- /dev/null
+++ b/inst/sigproc/crestfactor.m
@@ -0,0 +1,34 @@
+function c=crestfactor(insig)
+%-*- texinfo -*-
+%@deftypefn {Function} crestfactor
+%@verbatim
+%CRESTFACTOR  Crest factor of input signal in dB
+%   Usage:  c=crestfactor(insig);
+%
+%   CRESTFACTOR(insig) computes the crest factor of the input signal
+%   insig. The output is measured in dB.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/crestfactor.php}
+%@seealso{rms, gaindb}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+c=20*log10(norm(insig,Inf)/rms(insig));
+
+
diff --git a/inst/sigproc/dynlimit.m b/inst/sigproc/dynlimit.m
new file mode 100644
index 0000000..086e2ae
--- /dev/null
+++ b/inst/sigproc/dynlimit.m
@@ -0,0 +1,36 @@
+function xo=dynlimit(xi,dynrange,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} dynlimit
+%@verbatim
+%DYNLIMIT  Limit the dynamical range of the input
+%   Usage: xo=dynlimit(xi,dynrange);
+%
+%   DYNLIMIT(xi,dynrange) will threshold the input such that the
+%   difference between the maximum and minumum value of xi is exactly
+%   dynrange.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/dynlimit.php}
+%@seealso{thresh, largestr, largestn}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+xmax=max(xi(:));
+xo=xi;
+xo(xo<xmax-dynrange)=xmax-dynrange;
+
diff --git a/inst/sigproc/elitistthresh.m b/inst/sigproc/elitistthresh.m
new file mode 100644
index 0000000..db5fd2a
--- /dev/null
+++ b/inst/sigproc/elitistthresh.m
@@ -0,0 +1,97 @@
+function [xo]=elitistthresh(xi,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} elitistthresh
+%@verbatim
+%ELITISTTHRESH   elitist (hard/soft) thresholding
+%   Usage:  xo=elitistthresh(xi,lambda);
+%
+%   ELITISTTHRESH(xi,lambda) performs hard elitist thresholding on xi,
+%   with threshold lambda. The input xi must be a two-dimensional array,
+%   the first dimension labelling groups, and the second one labelling
+%   members.  All coefficients within a given group are shrunk according to
+%   the value of the l^1 norm of the group in comparison to the threshold
+%   value lambda.
+%
+%   ELITISTTHRESH(x,lambda,'soft') will do the same using soft
+%   thresholding.
+%
+%   ELITISTTHRESH accepts the following flags at the end of the line of input
+%   arguments:
+%
+%     'hard'    Perform hard thresholding. This is the default.
+%
+%     'soft'    Perform soft thresholding.  
+%
+%     'full'    Return the output as a full matrix. This is the default.
+%
+%     'sparse'  Return the output as a sparse matrix.
+%  
+%
+%
+%   References:
+%     M. Kowalski. Sparse regression using mixed norms. Appl. Comput. Harmon.
+%     Anal., 27(3):303-324, 2009.
+%     
+%     M. Kowalski and B. Torresani. Sparsity and persistence: mixed norms
+%     provide simple signal models with dependent coefficients. Signal, Image
+%     and Video Processing, 3(3):251-264, 2009.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/elitistthresh.php}
+%@seealso{groupthresh, demo_audioshrink}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Bruno Torresani.  
+ 
+if nargin<2
+  error('Too few input parameters.');
+end;
+
+if (prod(size(lambda))~=1 || ~isnumeric(lambda))
+  error('lambda must be a scalar.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.flags.iofun={'hard','soft'};
+definput.flags.outclass={'full','sparse'};
+
+[flags,keyvals]=ltfatarghelper({},definput,varargin,mfilename);
+
+NbGroups = size(xi,1);
+NbMembers = size(xi,2);
+
+if flags.do_sparse
+  xo = sparse(size(xi));
+else
+  xo = zeros(size(xi));
+end;
+
+for g=1:NbGroups,
+    y = sort(abs(xi(g,:)),'descend');
+    rhs = cumsum(y);
+    rhs = rhs .* lambda ./ (1 + lambda * (1:NbMembers));
+    M_g = find(diff(sign(y-rhs)));
+    if (M_g~=0)
+        tau_g = lambda * norm(y(1:M_g),1)/(1+lambda*M_g);
+    else
+        tau_g = 0;
+    end
+    xo(g,:) = thresh(xi(g,:),tau_g,flags.iofun,flags.outclass);
+end
+
diff --git a/inst/sigproc/gaindb.m b/inst/sigproc/gaindb.m
new file mode 100644
index 0000000..9541343
--- /dev/null
+++ b/inst/sigproc/gaindb.m
@@ -0,0 +1,86 @@
+function inoutsig = gaindb(inoutsig,gn,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} gaindb
+%@verbatim
+%GAINDB  Increase/decrease level of signal
+%   Usage:  outsig = gaindb(insig,gn);
+%
+%   GAINDB(insig,gn) increases the energy level of the signal by gn*
+%   dB.
+%
+%   If gn is a scalar, the whole input signal is scaled.
+%
+%   If gn is a vector, each column is scaled by the entries in
+%   gn. The length of gn must match the number of columns.
+%
+%   GAINDB(insig,gn,dim) scales the signal along dimension dim.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/gaindb.php}
+%@seealso{rms}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR: Peter L. Soendergaard, 2009
+
+% ------ Checking of input parameters ---------
+  
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(inoutsig)
+  error('%s: insig must be numeric.',upper(mfilename));
+end;
+
+if ~isnumeric(gn) 
+  error('%s: gn must be numeric.',upper(mfilename));
+end;
+
+definput.keyvals.dim=[];
+[flags,kv]=ltfatarghelper({'dim'},definput,varargin);
+
+
+% ------ Computation --------------------------
+
+if isscalar(gn)
+  inoutsig = inoutsig*10^(gn/20);
+else
+  if isvector(gn)
+    M=length(gn);
+        
+    [inoutsig,L,Ls,W,dim,permutedsize,order]=...
+        assert_sigreshape_pre(inoutsig,[],kv.dim,upper(mfilename));
+      
+    if M~=W
+      error('%s: Length of gn and signal size must match.',upper(mfilename));
+    end;
+
+    for ii=1:W
+      inoutsig(:,ii)=inoutsig(:,ii)*10^(gn(ii)/20);
+    end;
+    
+    inoutsig=assert_sigreshape_post(inoutsig,kv.dim,permutedsize,order);     
+    
+  else
+    if ~isnumeric(gn) 
+      error('%s: gn must be a scalar or vector.',upper(mfilename));
+    end;
+  end;
+end;
+
diff --git a/inst/sigproc/groupthresh.m b/inst/sigproc/groupthresh.m
new file mode 100644
index 0000000..b344804
--- /dev/null
+++ b/inst/sigproc/groupthresh.m
@@ -0,0 +1,126 @@
+function [xo]=groupthresh(xi,lambda,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} groupthresh
+%@verbatim
+%GROUPTHRESH   Group thresholding
+%   Usage:  xo=groupthresh(xi,lambda);
+%
+%   GROUPTHRESH(x,lambda) performs group thresholding on x, with
+%   threshold lambda.  x must be a two-dimensional array, the first
+%   dimension labelling groups, and the second one labelling members. This
+%   means that the groups are the row vectors of the input (the vectors
+%   along the 2nd dimension).
+%
+%   Several types of grouping behaviour are available:
+%
+%    GROUPTHRESH(x,lambda,'group') shrinks all coefficients within a given
+%     group according to the value of the l^2 norm of the group in
+%     comparison to the threshold lambda. This is the default.
+%
+%    GROUPTHRESH(x,lambda,'elite') shrinks all coefficients within a
+%     given group according to the value of the l^1 norm of the
+%     group in comparison to the threshold value lambda.
+%
+%   GROUPTHRESH(x,lambda,dim) chooses groups along dimension
+%   dim. The default value is dim=2.
+%
+%   GROUPTHRESH accepts all the flags of THRESH to choose the
+%   thresholding type within each group and the output type (full / sparse
+%   matrix). Please see the help of THRESH for the available
+%   options. Default is to use soft thresholding and full matrix output.
+%  
+%
+%
+%   References:
+%     M. Kowalski. Sparse regression using mixed norms. Appl. Comput. Harmon.
+%     Anal., 27(3):303-324, 2009.
+%     
+%     M. Kowalski and B. Torresani. Sparsity and persistence: mixed norms
+%     provide simple signal models with dependent coefficients. Signal, Image
+%     and Video Processing, 3(3):251-264, 2009.
+%     
+%     G. Yu, S. Mallat, and E. Bacry. Audio Denoising by Time-Frequency Block
+%     Thresholding. IEEE Trans. Signal Process., 56(5):1830-1839, 2008.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/groupthresh.php}
+%@seealso{thresh, demo_audioshrink}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Kai Siedenburg, Bruno Torresani.
+%   REFERENCE: OK
+ 
+
+if nargin<2
+  error('Too few input parameters.');k
+end;
+
+if (prod(size(lambda))~=1 || ~isnumeric(lambda))
+  error('lambda must be a scalar.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.import={'thresh','groupthresh'};
+definput.importdefaults={'soft'};
+definput.keyvals.dim=2;
+
+[flags,keyvals,dim]=ltfatarghelper({'dim'},definput,varargin);
+
+% kv.dim (the time or frequency selector) is handled by assert_sigreshape_pre
+[xi,L,NbMembers,NbGroups,dim,permutedsize,order]=assert_sigreshape_pre(xi,[],dim,'GROUPTHRESH');
+
+if flags.do_sparse
+  xo = sparse(size(xi));
+else
+  xo = zeros(size(xi));
+end;
+
+if flags.do_group
+  
+  groupnorm = sqrt(sum(abs(xi).^2));
+  w = thresh(groupnorm, lambda, flags.iofun,flags.outclass)./groupnorm;
+  
+  % Clean w for NaN. NaN appears if the input has a group with norm
+  % exactly 0.
+  w(isnan(w)) = 0;
+  
+  xo = bsxfun(@times,xi,w);
+
+end
+
+if flags.do_elite  
+  for ii=1:NbGroups,
+    y = sort(abs(xi(:,ii)),'descend');
+    rhs = cumsum(y);
+    rhs = rhs .* lambda ./ (1 + lambda * (1:NbMembers)');
+    M_ii = find(diff(sign(y-rhs)));
+    if (M_ii~=0)
+      tau_ii = lambda * norm(y(1:M_ii),1)/(1+lambda*M_ii);
+    else
+      tau_ii = 0;
+    end        
+    
+    % FIXME: The following line does not work for sparse matrices.
+    xo(:,ii) = thresh(xi(:,ii),tau_ii,flags.iofun,flags.outclass);
+  end
+end;
+
+xo=assert_sigreshape_post(xo,dim,permutedsize,order);
+
+
diff --git a/inst/sigproc/iqam4.m b/inst/sigproc/iqam4.m
new file mode 100644
index 0000000..b53344a
--- /dev/null
+++ b/inst/sigproc/iqam4.m
@@ -0,0 +1,64 @@
+function xo=iqam4(xi)
+%-*- texinfo -*-
+%@deftypefn {Function} iqam4
+%@verbatim
+%IQAM4  Inverse QAM of order 4
+%
+%    IQAM4(xi) demodulates a signal mapping the input coefficients to the
+%    closest complex root of unity, and returning the associated bit
+%    pattern. This is the inverse operation of QAM4.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/iqam4.php}
+%@seealso{qam4, demo_ofdm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Define the optimal ordering of bits
+bitorder=[0;1;3;2];
+
+% nbits is number of bits used. Everything will be ordered
+% in groups of this size.
+nbits=2;
+
+symbols=length(xi);
+L=symbols*nbits;
+
+% We round the argument of the complex numbers to the closest root of
+% unity of order 4
+work=round(angle(xi)/(2*pi)*4);
+
+% work now contains negative numbers. Get rid of these
+work=mod(work,4);
+
+% Reverse the optimal bit ordering.
+reversebitorder=zeros(4,1);
+reversebitorder(bitorder+1)=(0:3).';
+
+% Apply the reverse ordering
+work=reversebitorder(work+1);
+
+xo=zeros(nbits,symbols);
+% Reconstruct the bits
+for bit=1:nbits
+  xo(bit,:)=bitget(work,bit).';
+end;
+
+xo=xo(:);
+
diff --git a/inst/sigproc/jpeg2rgb.m b/inst/sigproc/jpeg2rgb.m
new file mode 100644
index 0000000..ee28f56
--- /dev/null
+++ b/inst/sigproc/jpeg2rgb.m
@@ -0,0 +1,60 @@
+function RGB = jpeg2rgb(YCbCr)
+%-*- texinfo -*-
+%@deftypefn {Function} jpeg2rgb
+%@verbatim
+%JPEG2RGB  Coverts from RGB format to YCbCr format
+%   Usage:  RGB = jpeg2rgb(YCbCr);
+% 
+%   Input parameters:
+%         YCbCr : 3d data-cube, containing the YCbCr information of the
+%                 image
+% 
+%   Output parameters:
+%         RGB   : 3d data-cube, containing RGB information of the image
+% 
+%   'jpeg2rgb(YCbCr)' performs a transformation of the 3d data-cube YCbCr with
+%   dimensions N xM x3, which contains information of
+%   "luminance", "chrominance blue" and "chrominance red".  The output
+%   variable RGB is a 3d data-cube of the same size containing information
+%   about the colours "red", "green" and "blue". The output will be of
+%   the uint8 type.
+% 
+%   For more information, see
+%   http://en.wikipedia.org/wiki/YCbCr and http://de.wikipedia.org/wiki/JPEG
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/jpeg2rgb.php}
+%@seealso{rgb2jpeg}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% AUTHOR:   Markus Faulhuber, February 2013
+
+[s1,s2,s3] = size(YCbCr);
+YCbCr = double(YCbCr);
+
+if s3 ~= 3
+    disp('Sorry, this routine is for YCbCr of dimension NxMx3 only')
+    return;
+end
+
+RGB(:,:,1) = YCbCr(:,:,1)+1.402*(YCbCr(:,:,3)-128);
+RGB(:,:,2) = YCbCr(:,:,1)-0.3441*(YCbCr(:,:,2)-128)-0.7141*(YCbCr(:,:,3)-128);
+RGB(:,:,3) = YCbCr(:,:,1)+1.772*(YCbCr(:,:,2)-128);
+
+RGB = uint8(RGB);
diff --git a/inst/sigproc/largestn.m b/inst/sigproc/largestn.m
new file mode 100644
index 0000000..bae0686
--- /dev/null
+++ b/inst/sigproc/largestn.m
@@ -0,0 +1,99 @@
+function [xo,Nout]=largestn(xi,N,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} largestn
+%@verbatim
+%LARGESTN   Keep N largest coefficients
+%   Usage:  xo=largestn(x,N);
+%           xo=largestn(x,N,mtype);
+%
+%   LARGESTN(x,N) returns an array of the same size as x keeping
+%   the N largest coefficients.
+%
+%   LARGESTN takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'hard'    Perform hard thresholding. This is the default.
+%
+%     'wiener'  Perform empirical Wiener shrinkage. This is in between
+%               soft and hard thresholding.
+%
+%     'soft'    Perform soft thresholding.  
+%
+%     'full'    Returns the output as a full matrix. This is the default.
+%
+%     'sparse'  Returns the output as a sparse matrix.   
+%
+%   If the coefficients represents a signal expanded in an orthonormal
+%   basis then this will be the best N-term approximation.
+%
+%   *Note:* If soft- or Wiener thresholding is selected, only N-1
+%   coefficients will actually be returned. This is caused by the N*'th
+%   coefficient being set to zero.
+%
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/largestn.php}
+%@seealso{largestr}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard and Bruno Torresani.  
+%   TESTING: OK
+%   REFERENCE: OK
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'thresh'};
+[flags,keyvals]=ltfatarghelper({},definput,varargin);
+
+if (prod(size(N))~=1 || ~isnumeric(N))
+  error('N must be a scalar.');
+end;
+
+if flags.do_sparse
+  if ndims(xi)>2
+    error('Sparse output is only supported for 1D/2D input. This is a limitation of Matlab/Octave.');
+  end;
+end;
+
+% Determine the size of the array.
+ss=numel(xi);
+
+% Sort the absolute values of the coefficients.
+sxi=sort(abs(xi(:)));
+
+
+% Find the coeffiecient sitting at position N through the array,
+% and use this as a threshing value. 
+if N<=0
+    % Choose a thresh value higher than max
+    lambda=sxi(end)+1;
+else
+    lambda=sxi(ss-N+1);
+end;
+
+[xo,Nout]=thresh(xi,lambda,flags.outclass,flags.iofun);
+
+
diff --git a/inst/sigproc/largestr.m b/inst/sigproc/largestr.m
new file mode 100644
index 0000000..d430f0c
--- /dev/null
+++ b/inst/sigproc/largestr.m
@@ -0,0 +1,99 @@
+function [xo,Nout]=largestr(xi,p,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} largestr
+%@verbatim
+%LARGESTR   Keep fixed ratio of largest coefficients
+%   Usage:  xo=largestr(x,p);
+%           xo=largestr(x,p,mtype);  
+%           [xo,N]=largestr(...);
+%
+%   LARGESTR(x,p) returns an array of the same size as x keeping
+%   the fraction p of the coefficients. The coefficients with the largest
+%   magnitude are kept.
+%
+%   [xo,n]=LARGESTR(xi,p) additionally returns the number of coefficients
+%   kept.
+% 
+%   *Note:* If the function is used on coefficients coming from a
+%   redundant transform or from a transform where the input signal was
+%   padded, the coefficient array will be larger than the original input
+%   signal. Therefore, the number of coefficients kept might be higher than
+%   expected.
+%
+%   LARGESTR takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'hard'    Perform hard thresholding. This is the default.
+%
+%     'wiener'  Perform empirical Wiener shrinkage. This is in between
+%               soft and hard thresholding.
+%
+%     'soft'    Perform soft thresholding.  
+%
+%     'full'    Returns the output as a full matrix. This is the default.
+%
+%     'sparse'  Returns the output as a sparse matrix.   
+%
+%   *Note:* If soft- or Wiener thresholding is selected, one less
+%   coefficient will actually be returned. This is caused by that
+%   coefficient being set to zero.
+%
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/largestr.php}
+%@seealso{largestn}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+%   TESTING: OK
+%   REFERENCE: OK
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'thresh'};
+[flags,keyvals]=ltfatarghelper({},definput,varargin);
+
+if (prod(size(p))~=1 || ~isnumeric(p))
+  error('p must be a scalar.');
+end;
+
+wascell=iscell(xi);
+
+if wascell
+  [xi,shape]=cell2vec(xi);
+end;
+
+% Determine the size of the array.
+ss=numel(xi);
+
+N=round(ss*p);
+  
+[xo,Nout]=largestn(xi,N,flags.outclass,flags.iofun);
+
+if wascell
+  xo=vec2cell(xo,shape);
+end;
+
diff --git a/inst/sigproc/normalize.m b/inst/sigproc/normalize.m
new file mode 100644
index 0000000..1492641
--- /dev/null
+++ b/inst/sigproc/normalize.m
@@ -0,0 +1,126 @@
+function f=normalize(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} normalize
+%@verbatim
+%NORMALIZE  Normalize input signal by specified norm
+%   Usage:  h=normalize(f,...);
+% 
+%   NORMALIZE(f,...) will normalize the signal f by the specified norm.
+%
+%   The norm is specified as a string and may be one of:
+%
+%     '1'       Normalize the l^1 norm to be 1.
+%
+%     'area'    Normalize the area of the signal to be 1. This is exactly the same as '1'.
+%
+%     '2'       Normalize the l^2 norm to be 1.
+%
+%     'energy'  Normalize the energy of the signal to be 1. This is exactly
+%               the same as '2'.
+%
+%     'inf'     Normalize the l^{inf} norm to be 1.
+%
+%     'peak'    Normalize the peak value of the signal to be 1. This is exactly
+%               the same as 'inf'.
+%
+%     'rms'     Normalize the Root Mean Square (RMS) norm of the
+%               signal to be 1.
+%
+%     's0'      Normalize the S0-norm to be 1.
+%
+%     'wav'     Normalize to the l^{inf} norm to be 0.99 to avoid 
+%               possible clipping introduced by the quantization procedure 
+%               when saving as a wav file. This only works with floating
+%               point data types.
+%
+%     'null'    Do NOT normalize, output is identical to input.
+%
+%
+%   It is possible to specify the dimension:
+%
+%      'dim',d  Work along specified dimension. The default value of []
+%                means to work along the first non-singleton one.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/normalize.php}
+%@seealso{rms, s0norm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if ~isnumeric(f) 
+  error('%s: Input must be numerical.',upper(mfilename));
+end;
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'normalize'};
+definput.keyvals.dim=[];
+
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_null || isempty(f);
+  return
+end;
+
+if isa(f,'integer') && ~flags.do_wav
+   error('%s: Integer data types are unsupported.',upper(mfilename)); 
+end
+
+%% ------ Computation --------------------------
+ 
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim, ...
+                                                  upper(mfilename));
+
+for ii=1:W  
+  
+  if flags.do_1 || flags.do_area
+    f(:,ii)=f(:,ii)/norm(f(:,ii),1);
+  end;
+
+  if flags.do_2 || flags.do_energy 
+    f(:,ii)=f(:,ii)/norm(f(:,ii),2);
+  end;
+
+  if flags.do_inf || flags.do_peak
+    f(:,ii)=f(:,ii)/norm(f(:,ii),Inf);
+  end;
+
+  if flags.do_rms
+    f(:,ii)=f(:,ii)/rms(f(:,ii));
+  end;
+  
+  if flags.do_s0 
+    f(:,ii)=f(:,ii)/s0norm(f(:,ii));
+  end;
+  
+  if flags.do_wav
+    if isa(f,'float')    
+       f(:,ii)=0.99*f(:,ii)/norm(f(:,ii),Inf);
+    else
+       error(['%s: TO DO: Normalizing integer data types not supported ',...
+              'yet.'],upper(mfilename));
+    end
+  end;
+  
+end;
+
+
+f=assert_sigreshape_post(f,kv.dim,permutedsize,order);
+
diff --git a/inst/sigproc/qam4.m b/inst/sigproc/qam4.m
new file mode 100644
index 0000000..cec37dd
--- /dev/null
+++ b/inst/sigproc/qam4.m
@@ -0,0 +1,67 @@
+function xo=qam4(xi)
+%-*- texinfo -*-
+%@deftypefn {Function} qam4
+%@verbatim
+%QAM4  Quadrature amplitude modulation of order 4
+%   Usage:  xo=qam4(xi);
+%
+%   QAM4(xi) converts a vector of 0's and 1's into the complex roots of
+%   unity (QAM4 modulation). Every 2 input coefficients are mapped into 1
+%   output coefficient.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/qam4.php}
+%@seealso{iqam4, demo_ofdm}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Verify input
+
+if ~all((xi==0) + (xi==1))
+  error('Input vector must consist of only 0s and 1s');
+end;
+
+% Define the optimal ordering of bits
+bitorder=[0;1;3;2];
+
+% nbits is number of bits used. Everything will be ordered
+% in groups of this size.
+nbits=2;
+
+L=length(xi);
+symbols=L/nbits;
+
+% nbits must divide L
+if rem(symbols,1)~=0
+  error('Length of input must be a multiple of 2');
+end;
+
+xi=reshape(xi,nbits,symbols);
+
+two_power=(2.^(0:nbits-1)).';
+
+% This could be vectorized by a repmat.
+xo=zeros(symbols,1);
+xo(:)=sum(bsxfun(@times,xi,two_power));
+
+% xo now consist of numbers in the range 0:3
+% Convert to the corresponding complex root of unity.
+xo=exp(2*pi*i*bitorder(xo+1)/4);
+
+
diff --git a/inst/sigproc/rampdown.m b/inst/sigproc/rampdown.m
new file mode 100644
index 0000000..1bb0c0b
--- /dev/null
+++ b/inst/sigproc/rampdown.m
@@ -0,0 +1,48 @@
+function outsig=rampdown(L,wintype)
+%-*- texinfo -*-
+%@deftypefn {Function} rampdown
+%@verbatim
+%RAMPDOWN  Falling ramp function
+%   Usage: outsig=rampdown(siglen);
+%
+%   RAMPDOWN(siglen) will return a falling ramp function of length
+%   siglen. The ramp is a sinusoid starting from one and ending at
+%   zero. The ramp is centered such that the first element is always one and
+%   the last element is not quite zero, such that the ramp fits with
+%   following zeros.
+%
+%   RAMPDOWN(L,wintype) will use another window for ramping. This may be
+%   any of the window types from FIRWIN. Please see the help on FIRWIN
+%   for more information. The default is to use a piece of the Hann window.
+%  
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/rampdown.php}
+%@seealso{rampup, rampsignal, firwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+   
+error(nargchk(1,2,nargin))
+
+if nargin==1
+  wintype='hann';
+end;
+  
+win=firwin(wintype,2*L,'inf');
+outsig=win(1:L);
+
+
diff --git a/inst/sigproc/rampsignal.m b/inst/sigproc/rampsignal.m
new file mode 100644
index 0000000..949d133
--- /dev/null
+++ b/inst/sigproc/rampsignal.m
@@ -0,0 +1,96 @@
+function outsig=rampsignal(insig,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} rampsignal
+%@verbatim
+%RAMPSIGNAL  Ramp signal
+%   Usage: outsig=rampsignal(insig,L);
+%
+%   RAMPSIGNAL(insig,L) applies a ramp function of length L to the
+%   beginning and the end of the input signal. The default ramp is a
+%   sinusoide starting from zero and ending at one (also known as a cosine
+%   squared ramp).
+%
+%   If L is scalar, the starting and ending ramps will be of the same
+%   length. If L is a vector of length 2, the first entry will be used
+%   for the rising ramp, and the second for the falling.
+%
+%   If the input is a matrix or an N-D array, the ramp will be applied
+%   along the first non-singleton dimension.
+%
+%   RAMPSIGNAL(insig) will use a ramp length of half the signal.
+%
+%   RAMPSIGNAL(insig,L,wintype) will use another window for ramping. This
+%   may be any of the window types from FIRWIN. Please see the help on
+%   FIRWIN for more information. The default is to use a piece of the
+%   Hann window.
+%
+%   RAMPSIGNAL accepts the following optional parameters:
+%
+%     'dim',d   Apply the ramp along dimension d. The default value of []
+%               means to use the first non-singleton dimension.     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/rampsignal.php}
+%@seealso{rampdown, rampsignal, firwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+definput.import={'firwin'};
+definput.keyvals.dim=[];
+definput.keyvals.L=[];
+[flags,kv]=ltfatarghelper({'L','dim'},definput,varargin);
+
+[insig,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(insig,[],kv.dim,'RAMPSIGNAL');
+% Note: Meaning of L has changed, it is now the length of the signal.
+
+switch numel(kv.L)
+ case 0
+  L1=L/2;
+  L2=L/2;
+ case 1
+  L1=kv.L;
+  L2=kv.L;
+ case 2
+  L1=kv.L(1);
+  L2=kv.L(2);
+ otherwise
+  error('%s: The length must a scalar or vector.',upper(mfilename));
+end;
+
+if rem(L1,1)~=0 || rem(L2,1)~=0
+  error('The length of the ramp must be an integer.');
+end;
+
+if L<L1+L2
+  error(['%s: The length of the input signal must be greater than the length of the ramps ' ...
+         'combined.'],upper(mfilename));
+end;
+
+r1=rampup(L1,flags.wintype);
+r2=rampdown(L2,flags.wintype);
+
+ramp=[r1;ones(L-L1-L2,1);r2];
+
+% Apply the ramp
+for ii=1:W
+  insig(:,ii)=insig(:,ii).*ramp;
+end;
+
+outsig=assert_sigreshape_post(insig,dim,permutedsize,order);
+
+
diff --git a/inst/sigproc/rampup.m b/inst/sigproc/rampup.m
new file mode 100644
index 0000000..37d1fcc
--- /dev/null
+++ b/inst/sigproc/rampup.m
@@ -0,0 +1,47 @@
+function outsig=rampup(L,wintype)
+%-*- texinfo -*-
+%@deftypefn {Function} rampup
+%@verbatim
+%RAMPUP  Rising ramp function
+%   Usage: outsig=rampup(L);
+%
+%   RAMPUP(L) will return a rising ramp function of length L. The
+%   ramp is a sinusoide starting from zero and ending at one. The ramp
+%   is centered such that the first element is always 0 and the last
+%   element is not quite 1, such that the ramp fits with following ones.
+%
+%   RAMPUP(L,wintype) will use another window for ramping. This may be any
+%   of the window types from FIRWIN. Please see the help on FIRWIN for
+%   more information. The default is to use a piece of the Hann window.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/rampup.php}
+%@seealso{rampdown, rampsignal, firwin}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+error(nargchk(1,2,nargin))
+
+if nargin==1
+  wintype='hann';
+end;
+  
+win=firwin(wintype,2*L,'inf');
+outsig=win(L+1:2*L);
+
+
diff --git a/inst/sigproc/rgb2jpeg.m b/inst/sigproc/rgb2jpeg.m
new file mode 100644
index 0000000..dc1b711
--- /dev/null
+++ b/inst/sigproc/rgb2jpeg.m
@@ -0,0 +1,95 @@
+function YCbCr = rgb2jpeg(RGB)
+%-*- texinfo -*-
+%@deftypefn {Function} rgb2jpeg
+%@verbatim
+%RGB2JPEG  Coverts from RGB format to the YCbCr format used by JPEG 
+%   Usage:  YCbCr = rgb2jpeg(RGB);
+% 
+%   Input parameters:
+%         RGB   : 3d data-cube, containing RGB information of the image
+% 
+%   Output parameters:
+%         YCbCr : 3d data-cube, containing the YCbCr information of the
+%                 image
+% 
+%   'rgb2jpeg(RGB)' performs a transformation of the 3d data-cube RGB with
+%   dimensions N xM x3, which contains information of the
+%   colours "red", "green" and "blue". The output variable YCbCr is a 3d
+%   data-cube of the same size containing information about "luminance",
+%   "chrominance blue" and "chrominance red". The output will be of
+%   the uint8 type.
+%
+%   See http://en.wikipedia.org/wiki/YCbCr and
+%   http://de.wikipedia.org/wiki/JPEG.
+%
+%   Examples:
+%   ---------
+%
+%   In the following example, the Lichtenstein test image is split into
+%   its three components. The very first subplot is the original image:
+%
+%    f=lichtenstein;
+% 
+%    f_jpeg=rgb2jpeg(f);
+% 
+%    subplot(2,2,1);
+%    image(f);axis('image');
+% 
+%    Ymono=zeros(512,512,3,'uint8');
+%    Ymono(:,:,1)=f_jpeg(:,:,1);
+%    Ymono(:,:,2:3)=128;
+%    fmono=jpeg2rgb(Ymono);
+%    subplot(2,2,2);
+%    image(fmono);axis('image');
+% 
+%    Cbmono=zeros(512,512,3,'uint8');
+%    Cbmono(:,:,2)=f_jpeg(:,:,2);
+%    Cbmono(:,:,3)=128;
+%    fmono=jpeg2rgb(Cbmono);
+%    subplot(2,2,3);
+%    image(fmono);axis('image');
+% 
+%    Crmono=zeros(512,512,3,'uint8');
+%    Crmono(:,:,3)=f_jpeg(:,:,3);
+%    Crmono(:,:,2)=128;
+%    fmono=jpeg2rgb(Crmono);
+%    subplot(2,2,4);
+%    image(fmono);axis('image');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/rgb2jpeg.php}
+%@seealso{jpeg2rgb}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+
+% AUTHOR:   Markus Faulhuber, February 2013
+
+[s1,s2,s3] = size(RGB);
+RGB = double(RGB);
+
+if s3 ~= 3
+    disp('Sorry, this routine is for RGB of dimension NxMx3 only')
+    return;
+end
+
+YCbCr(:,:,1) = 0.299*RGB(:,:,1)+0.587*RGB(:,:,2)+0.114*RGB(:,:,3);
+YCbCr(:,:,2) = 128-0.168736*RGB(:,:,1)-0.331264*RGB(:,:,2)+0.5*RGB(:,:,3);
+YCbCr(:,:,3) = 128+0.5*RGB(:,:,1)-0.418688*RGB(:,:,2)-0.081312*RGB(:,:,3);
+
+YCbCr = uint8(YCbCr);
diff --git a/inst/sigproc/rms.m b/inst/sigproc/rms.m
new file mode 100644
index 0000000..887eb72
--- /dev/null
+++ b/inst/sigproc/rms.m
@@ -0,0 +1,91 @@
+function y = rms(f,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} rms
+%@verbatim
+%RMS RMS value of signal
+%   Usage: y = rms(f);
+%          y = rms(f,...);
+%
+%   RMS(f) computes the RMS (Root Mean Square) value of a finite sampled
+%   signal sampled at a uniform sampling rate. This is a vector norm
+%   equal to the l^2 averaged by the length of the signal.
+%
+%   If the input is a matrix or ND-array, the RMS is computed along the
+%   first (non-singleton) dimension, and a vector of values is returned.
+%
+%   The RMS value of a signal x of length N is computed by
+%
+%                            N
+%      rms(f) = 1/sqrt(N) ( sum |f(n)|^2 )^(1/2)
+%                           n=1
+%
+%   RMS takes the following flags at the end of the line of input
+%   parameters:
+%
+%     'ac'       Consider only the AC component of the signal (i.e. the mean is
+%                removed).
+%
+%     'dim',d    Work along specified dimension. The default value of []
+%                means to work along the first non-singleton one.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/rms.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard
+  
+%% ------ Checking of input parameters ---------
+
+if ~isnumeric(f) 
+  error('%s: Input must be numerical.',upper(mfilename));
+end;
+
+if nargin<1
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.keyvals.dim=[];
+definput.flags.mean={'noac','ac'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+%% ------ Computation --------------------------
+
+% It is better to use 'norm' instead of explicitly summing the squares, as
+% norm (hopefully) attempts to avoid numerical overflow.
+ 
+[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],kv.dim, ...
+                                                  upper(mfilename));
+permutedsize(1)=1;
+y=zeros(permutedsize);
+if flags.do_ac
+
+  for ii=1:W        
+    y(1,ii) = norm(f(:,ii)-mean(f(:,ii)))/sqrt(L);
+   end;
+
+else
+
+  for ii=1:W
+    y(1,ii)=norm(f(:,ii))/sqrt(L);
+  end;
+
+end;
+  
+y=assert_sigreshape_post(y,kv.dim,permutedsize,order);
+
diff --git a/inst/sigproc/sigprocinit.m b/inst/sigproc/sigprocinit.m
new file mode 100644
index 0000000..e6ceac8
--- /dev/null
+++ b/inst/sigproc/sigprocinit.m
@@ -0,0 +1,26 @@
+status=1;
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} sigprocinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/sigprocinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/inst/sigproc/thresh.m b/inst/sigproc/thresh.m
new file mode 100644
index 0000000..d1141ab
--- /dev/null
+++ b/inst/sigproc/thresh.m
@@ -0,0 +1,180 @@
+function [xo,N]=thresh(xi,lambda,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} thresh
+%@verbatim
+%THRESH   Coefficient thresholding
+%   Usage:  x=thresh(x,lambda,...);
+%           [x,N]=thresh(x,lambda,...);
+%
+%   THRESH(x,lambda) will perform hard thresholding on x, i.e. all
+%   elements with absolute value less than lambda will be set to zero.
+%
+%   THRESH(x,lambda,'soft') will perform soft thresholding on x,
+%   i.e. lambda will be subtracted from the absolute value of every element
+%   of x.
+%
+%   [x,N]=THRESH(x,lambda) additionally returns a number N specifying
+%   how many numbers where kept.
+%
+%   THRESH takes the following flags at the end of the line of input
+%   arguments:
+%
+%     'hard'    Perform hard thresholding. This is the default.
+%
+%     'wiener'  Perform empirical Wiener shrinkage. This is in between
+%               soft and hard thresholding.
+%
+%     'soft'    Perform soft thresholding.  
+%
+%     'full'    Returns the output as a full matrix. This is the default.
+%
+%     'sparse'  Returns the output as a sparse matrix.
+%
+%   The function wTHRESH in the Matlab Wavelet toolbox implements some of
+%   the same functionality.
+%
+%   The following code produces a plot to demonstrate the difference
+%   between hard and soft thresholding for a simple linear input:
+%
+%     t=linspace(-4,4,100);
+%     plot(t,thresh(t,1,'soft'),'r',...
+%          t,thresh(t,1,'hard'),'.b',...
+%          t,thresh(t,1,'wiener'),'--g');
+%     legend('Soft thresh.','Hard thresh.','Wiener thresh.','Location','NorthWest');
+%
+%
+%   References:
+%     S. Ghael, A. Sayeed, and R. Baraniuk. Improved wavelet denoising via
+%     empirical Wiener filtering. In Proceedings of SPIE, volume 3169, pages
+%     389-399. San Diego, CA, 1997.
+%     
+%     J. Lim and A. Oppenheim. Enhancement and bandwidth compression of noisy
+%     speech. Proceedings of the IEEE, 67(12):1586-1604, 1979.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/thresh.php}
+%@seealso{largestr, largestn}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Kai Siedenburg, Bruno Torresani and Peter L. Soendergaard.
+%   TESTING: OK
+%   REFERENCE: OK
+
+if nargin<2
+  error('Too few input parameters.');k
+end;
+
+if (prod(size(lambda))~=1 || ~isnumeric(lambda))
+  error('lambda must be a scalar.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.import={'thresh'};
+[flags,keyvals]=ltfatarghelper({},definput,varargin);
+
+if flags.do_sparse
+  if ndims(xi)>2
+    error('Sparse output is only supported for 1D/2D input. This is a limitation of Matlab/Octave.');
+  end;
+end;
+
+if flags.do_sparse
+  xo=sparse(size(xi,1),size(xi,2));
+    
+  if flags.do_hard
+    % Create a significance map pointing to the non-zero elements.
+    signifmap=find(abs(xi)>=lambda);
+   
+    xo(signifmap)=xi(signifmap);
+  end;
+  
+  if flags.do_wiener
+    signifmap=find(abs(xi)>lambda);
+    xo(signifmap) = 1 - (lambda./abs(xi(signifmap))).^2;
+    xo(signifmap) = xi(signifmap).*xo(signifmap); 
+  end;
+  
+  if flags.do_soft
+    % Create a significance map pointing to the non-zero elements.
+    signifmap=find(abs(xi)>lambda);
+    
+    %    xo(signifmap)=xi(signifmap) - sign(xi(signifmap))*lambda;
+    xo(signifmap)=(abs(xi(signifmap)) - lambda) .* ...
+        exp(i*angle(xi(signifmap)));
+    % The line above produces very small imaginary values when the input
+    % is real-valued. The next line fixes this
+    if isreal(xi)
+      xo=real(xo);
+    end;
+    
+  end;
+  
+  if nargout==2
+    N=numel(signifmap);
+  end;
+    
+else
+  xo=zeros(size(xi));
+  
+  % Create a mask with a value of 1 for non-zero elements. For full
+  % matrices, this is faster than the significance map.
+
+  if flags.do_hard
+    if nargout==2
+      mask=abs(xi)>=lambda;
+      N=sum(mask(:));
+      xo=xi.*mask;
+    else
+      xo=xi.*(abs(xi)>=lambda);    
+    end;
+    
+  end;
+  
+  if flags.do_soft
+      % In the following lines, the +0 is significant: It turns
+      % -0 into +0, oh! the joy of numerics.
+      
+      if nargout==2
+          xa=abs(xi)-lambda;    
+          mask=xa>=0;
+          xo=(mask.*xa+0).*sign(xi);
+          N=sum(mask(:))-sum(xa(:)==0);      
+      else
+          xa=abs(xi)-lambda;    
+          xo=((xa>=0).*xa+0).*sign(xi);
+      end;
+  end;
+  
+  if flags.do_wiener
+      xa = lambda./abs(xi);
+      xa(isinf(xa)) = 0;
+      xa = 1 - xa.^2;
+      
+      if nargout==2
+          mask = xa>0;
+          xo = xi.*xa.*mask;
+          N = sum(mask(:));
+      else
+          xo = xi.*xa.*(xa>0);
+      end
+      
+  end;
+end;
+
+
diff --git a/inst/sigproc/uquant.m b/inst/sigproc/uquant.m
new file mode 100644
index 0000000..93d0d70
--- /dev/null
+++ b/inst/sigproc/uquant.m
@@ -0,0 +1,107 @@
+function xo=uquant(xi,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} uquant
+%@verbatim
+%UQUANT  Simulate uniform quantization
+%   Usage:  x=uquant(x);
+%           x=uquant(x,nbits,xmax,...);
+%
+%   UQUANT(x,nbits,xmax) simulates the effect of uniform quantization of
+%   x using nbits bits. The output is simply x rounded to 2^{nbits}
+%   different values.  The xmax parameters specify the maximal value that
+%   should be quantifiable.
+%
+%   UQUANT(x,nbits) assumes a maximal quantifiable value of 1.
+%
+%   UQUANT(x) additionally assumes 8 bit quantization.
+%
+%   UQUANT takes the following flags at the end of the input arguments:
+%
+%     'nbits'  Number of bits to use in the quantization. Default is 8.
+%
+%     'xmax'   Maximal quantifiable value. Default is 1.
+%  
+%     's'      Use signed quantization. This assumes that the signal
+%              has a both positive and negative part. Useful for sound
+%              signals. This is the default.
+%
+%     'u'      Use unsigned quantization. Assumes the signal is positive.
+%              Negative values are silently rounded to zero.
+%              Useful for images.
+%
+%   If this function is applied to a complex signal, it will be applied to
+%   the real and imaginary part separately.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/sigproc/uquant.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   AUTHOR : Peter L. Soendergaard and Bruno Torresani.  
+%   TESTING: OK
+%   REFERENCE: OK
+
+if nargin<1
+  error('Too few input parameters.');
+end;
+
+% Define initial value for flags and key/value pairs.
+definput.flags.sign={'s','u'};
+definput.keyvals.nbits=8;
+definput.keyvals.xmax=1;
+[flags,keyvals,nbits,xmax]=ltfatarghelper({'nbits','xmax'},definput,varargin);
+
+% ------ handle complex values ------------------
+if ~isreal(xi)
+  xo = uquant(real(xi),nbits,xmax,varargin{:}) + ...
+	i*uquant(imag(xi),nbits,xmax,varargin{:});
+  return
+end;
+
+if nbits<2
+  error('Must specify at least 2 bits.');
+end;
+
+% Calculate number of buckets.
+nbuck=2^nbits;    
+
+if xmax<max(abs(xi(:)))
+  error('Signal contains values higher than xmax.');
+end;
+
+if flags.do_s
+  
+  % ------------ unsigned case -----------------
+  
+  bucksize=xmax/(nbuck/2-1);
+  
+  xo=round(xi/bucksize)*bucksize;        
+  
+else
+
+  % ------------- signed case------------
+  
+  bucksize=xmax/(nbuck-.51);
+  
+  % Thresh all negative values to zero.
+  xi=xi.*(xi>0);
+  
+  xo=round(xi/bucksize)*bucksize;        
+  
+end;
+
+
diff --git a/inst/wavelets/Contents.m b/inst/wavelets/Contents.m
new file mode 100644
index 0000000..e01601d
--- /dev/null
+++ b/inst/wavelets/Contents.m
@@ -0,0 +1,86 @@
+% LTFAT - Wavelets
+%
+%   Zdenek Prusa, 2013 - 2014.
+%
+%   Basic analysis/synthesis
+%      FWT               - Fast Wavelet Transform 
+%      IFWT              - Inverse Fast Wavelet Transform
+%      FWT2              - 2D Fast Wavelet Transform 
+%      IFWT2             - 2D Inverse Fast Wavelet Transform
+%      UFWT              - Undecimated Fast Wavelet Transform
+%      IUFWT             - Inverse Undecimated Fast Wavelet Transform 
+%      FWTLENGTH         - Length of Wavelet system to expand a signal
+%      FWTCLENGTH        - Lengths of the wavelet coefficients subbands
+%
+%   Advanced analysis/synthesis
+%      WFBT              - Transform using general Wavelet Filterbank Tree 
+%      IWFBT             - Inverse transform using general Wavelet Filterbank Tree
+%      UWFBT             - Undecimated transform using general Wavelet Filterbank Tree 
+%      IUWFBT            - Inverse Undecimated transform using general Wavelet Filterbank Tree
+%      WPFBT             - Wavelet Packet Transform using general Wavelet Filterbank Tree 
+%      IWPFBT            - Inverse Wavelet Packet Transform using general Wavelet Filterbank Tree
+%      UWPFBT            - Undecimated Wavelet Packet Transform using general Wavelet Filterbank Tree 
+%      IUWPFBT           - Inverse Undecimated Wavelet Packet Transform using general Wavelet Filterbank Tree
+%      WPBEST            - Best Tree selection
+%      WFBTLENGTH        - Length of Wavelet filterbank system to expand a signal
+%
+%   Wavelet Filterbank trees manipulation
+%      WFBTINIT          - Wavelet Filterbank tree structure initialization
+%      WFBTPUT           - Puts node (basic filterbank) to the specific  tree coordinates
+%      WFBTREMOVE        - Removes node (basic filterbank) from the specific tree coordinates
+%      WFBT2FILTERBANK   - Creates a non-iterated filterbank using the multirate identity
+%      FWT2FILTERBANK    - Creates a non-iterated filterbank using the multirate identity
+%      FWTINIT           - Basic Wavelet Filters structure initialization
+%  
+%   Plots
+%      PLOTWAVELETS      - Plot wavelet coefficients
+%      WFILTINFO         - Plot wavelet filters impulse and frequency responses and approximation of scaling and wavelet functions
+%
+%   Auxilary
+%      WAVFUN            - Aproximate of the continuous scaling and wavelet functions
+%      WAVCELL2PACK      - Changes wavelet coefficient storing format
+%      WAVPACK2CELL      - Changes wavelet coefficient storing format back
+%
+%   Filters defined in the time-domain
+%      WFILT_ALGMBAND    - An ALGebraic construction of orthonormal M-BAND wavelets with perfect reconstruction
+%      WFILT_APR         - Almost Perfect Reconstruction Filter Bank for Non-redundant, Approximately Shift-Invariant, ComplexWavelet Transforms
+%      WFILT_DB          - DauBechies orthogonal filters (ortonormal base)
+%      WFILT_DDEN        - Double-DENsity dwt filters (tight frame)
+%      WFILT_DGRID       - Dense GRID framelets (tight frame, symmetric)
+%      WFILT_DTREE       - Dual-TREE complex wavelet transform filters (two orthonormal bases)
+%      WFILT_HDEN        - Higher DENsity dwt filters (tight frame, frame)  
+%      WFILT_LEMARIE         - Battle and Lemarie quadrature filters
+%      WFILT_MATLABWTWRAPPER - Wrapper of the wfilters function from the Matlab Wavelet Toolbox 
+%      WFILT_MAXFLAT         - Maximally flat FIR filters
+%      WFILT_MBAND           - M-band filters
+%      WFILT_OPTFS           - Optimized orthogonal filters with improved Frequency Selectivity (ortonormal base)
+%      WFILT_REMEZ           - Wavelet orthonogal filters based on the Remez Exchange algorithm
+%      WFILT_SYMDS           - SYMmetric wavelet Dyadic Siblings (frames)
+%      WFILT_SPLINE          - Biorthogonal spline wavelet filters
+%      WFILT_SYM             - Least asymmetric Daubechies wavelet filters
+%      
+%   Wavelet filters defined in the frequency-domain
+%      WFREQ_LEMARIE         - Battle and Lemarie filters sampled freq. resp.
+%
+%  For help, bug reports, suggestions etc. please send an email to
+%  ltfat-help at lists.sourceforge.net
+%
+%   Url: http://ltfat.sourceforge.net/doc/wavelets/Contents.php
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
diff --git a/inst/wavelets/fwt.m b/inst/wavelets/fwt.m
new file mode 100644
index 0000000..d1604b6
--- /dev/null
+++ b/inst/wavelets/fwt.m
@@ -0,0 +1,207 @@
+function [c,info] = fwt(f,w,J,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} fwt
+%@verbatim
+%FWT   Fast Wavelet Transform 
+%   Usage:  c = fwt(f,w,J);
+%           c = fwt(f,w,J,dim);
+%           [c,info] = fwt(...);
+%
+%   Input parameters:
+%         f     : Input data.
+%         w     : Wavelet definition. 
+%         J     : Number of filterbank iterations.
+%         dim   : Dimension to along which to apply the transform.
+%
+%   Output parameters:
+%         c      : Coefficient vector.
+%         info   : Transform parameters struct.
+%
+%   c=FWT(f,w,J) returns wavelet coefficients c of the input signal f*
+%   using J iterations of the basic wavelet filterbank defined by w*
+%   i.e. the fast wavelet transform algorithm (Mallat's algorithm) is used.
+%   In addition, the function returns struct. info containing transform
+%   parameters. It can be conviniently used for the inverse transform 
+%   IFWT e.g. fhat = iFWT(c,info). It is also required by the 
+%   PLOTWAVELETS function.
+%   
+%   The coefficents c are the Discrete Wavelet transform (DWT) of the input
+%   signal f, if w defines two-channel wavelet filterbank. The following
+%   figure shows DWT with J=3.
+%
+%   The function can apply the Mallat's algorithm using basic filter banks
+%   with any number of the channels. In such case, the transform have a 
+%   different name. 
+%
+%   The basic analysis wavelet filterbank w can be passed in several 
+%   formats. The formats are the same as for the FWTINIT function.
+%
+%   1) Cell array whose first element is the name of the function defining
+%      the basic wavelet filters (wfilt_ prefix) and the other elements
+%      are the parameters of the function. e.g. {'db',10} calls 
+%      wfilt_db(10) internally.
+%
+%   2) Character string as concatenation of the name of the wavelet
+%      filters defining function (as above) and the numeric parameters
+%      delimited by ':' character, e.g. 'db10' has the same effect as above,
+%      'spline4:4' calls wfilt_spline(4,4) internally.
+%
+%   3) Cell array of one dimensional numerical vectors directly defining
+%      the wavelet filter impulse responses.  By default, outputs of the 
+%      filters are subsampled by a factor equal to the number of the 
+%      filters. One can pass additional key-value pair 'a',a (still inside
+%      of the cell array) to define the custom subsampling factors, e.g.: 
+%      {h1,h2,'a',[2,2]}.
+%
+%   4) The fourth option is to pass the structure obtained from the
+%      FWTINIT function. The structure is checked whether it has a valid
+%      format.
+%   
+%   If f is row/collumn vector, the subbands c are stored
+%   in a single row/collumn in a consecutive order with respect to the 
+%   inceasing central frequency of the corresponding effective filter 
+%   frequency responses or equivalently with decreasing wavelet scale. The 
+%   lengths of subbands are stored in info.Lc so the subbands can be easily
+%   extracted using WAVPACK2CELL. Moreover, one can pass an additional
+%   flag 'cell' to obtain the coefficient directly in a cell array. The
+%   cell array can be again converted to a packed format using WAVCELL2PACK.
+%
+%   If the input f is a matrix, the transform is applied to each column 
+%   if dim==1 (default) and [Ls, W]=size(f). If dim==2
+%   the transform is applied to each row [W, Ls]=size(f).
+%   The output is then a matrix and the input orientation is preserved in 
+%   the orientation of the output coefficients. The dim paramerer has to
+%   be passed to the WAVPACK2CELL and WAVCELL2PACK.
+%
+%   Boundary handling:
+%   ------------------
+%
+%   FWT(f,w,J,'per') (default) uses the periodic extension which considers
+%   the input signal as it was a one period of some infinite periodic signal
+%   as is natural for transforms based on the FFT. The resulting wavelet
+%   representation is non-expansive, that is if the input signal length is a
+%   multiple of a J-th power of the subsampling factor and the filterbank
+%   is critically subsampled, the total number of coefficients is equal to
+%   the input signal length. The input signal is padded with zeros to the
+%   next legal length L internally.
+%   
+%   The default periodic extension can result in "false" high wavelet
+%   coefficients near the boundaries due to the possible discontinuity
+%   introduced by the zero padding and periodic boundary treatment.
+%
+%   FWT(f,w,J,ext) with ext other than 'per' computes a slightly
+%   redundant wavelet representation of the input signal f with the chosen
+%   boundary extension ext. The redundancy (expansivity) of the
+%   represenation is the price to pay for using general filterbank and
+%   custom boundary treatment.  The extensions are done at each level of the
+%   transform internally rather than doing the prior explicit padding.
+%
+%   The supported possibilities are:
+%
+%     'per'    Zero padding to the next legal length and periodic boundary
+%              extension. This is the default.
+%
+%     'zero'   Zeros are considered outside of the signal (coefficient)
+%              support. 
+%
+%     'even'   Even symmetric extension.
+%
+%     'odd'    Odd symmetric extension.
+%
+%   Note that the same flag has to be used in the call of the inverse transform
+%   function IFWT if the info struct is not used.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling the FWT function:
+% 
+%     f = greasy;
+%     J = 10;
+%     [c,info] = fwt(f,'db8',J);
+%     plotwavelets(c,info,44100,'dynrange',90);
+%
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwt.php}
+%@seealso{ifwt, plotwavelets, wavpack2cell, wavcell2pack, thresh}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(J) || ~isscalar(J) || isempty(J)
+  error('%s: "J" must be a scalar.',upper(mfilename));
+end;
+
+if(J<1 || rem(J,1)~=0)
+   error('%s: J must be a positive integer.',upper(mfilename)); 
+end
+
+% Initialize the wavelet filters structure
+w = fwtinit(w);
+
+
+%% ----- step 0 : Check inputs -------
+definput.import = {'fwt'};
+definput.keyvals.dim = [];
+definput.flags.cfmt = {'pack','cell'};
+[flags,~,dim]=ltfatarghelper({'dim'},definput,varargin);
+
+
+%% ----- step 1 : Verify f and determine its length -------
+[f,~,Ls,~,dim]=assert_sigreshape_pre(f,[],dim,upper(mfilename));
+
+%% ----- step 2 : Determine number of ceoefficients in each subband *Lc*
+%  and next legal input data length *L*.
+[Lc, L] = fwtclength(Ls,w,J,flags.ext);
+
+% Pad with zeros if the safe length L differ from the Ls.
+if(Ls~=L)
+   f=postpad(f,L); 
+end
+
+%% ----- step 3 : Run computation. 
+c = comp_fwt(f,w.h,J,w.a,flags.ext);
+
+%% ----- FINALIZE: Change format of coefficients.
+if flags.do_pack
+   c = wavcell2pack(c,dim);
+end
+
+%% ----- FILL INFO STRUCT ----------------------
+if nargout>1
+   info.fname = 'fwt';
+   info.wt = w;
+   info.ext = flags.ext;
+   info.Lc = Lc;
+   info.J = J;
+   info.dim = dim;
+   info.Ls = Ls;
+   info.isPacked = flags.do_pack;
+end
+%END FWT
+
diff --git a/inst/wavelets/fwt2.m b/inst/wavelets/fwt2.m
new file mode 100644
index 0000000..1adb351
--- /dev/null
+++ b/inst/wavelets/fwt2.m
@@ -0,0 +1,164 @@
+function c = fwt2(f,w,J,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} fwt2
+%@verbatim
+%FWT2   Fast Wavelet Transform 2D
+%   Usage:  c = fwt2(f,w,J);
+%           c = fwt2(f,w,J,...);
+%
+%   Input parameters:
+%         f     : Input data.
+%         w     : Wavelet Filterbank definition. 
+%         J     : Number of filterbank iterations.
+%
+%   Output parameters:
+%         c      : Coefficients stored in a matrix.
+%
+%   c=FWT2(f,w,J) returns wavelet coefficients c of the input matrix f*
+%   using J iterations of the basic wavelet filterbank defined by h.
+%
+%   FWT2 supports just the non-expansive boundary condition 'per' and 
+%   critically subsampled filterbanks in order to be able to pack the
+%   coefficients in a matrix. Also the J is limited to some maximum value
+%   for the same reason. 
+%
+%   Additional flags make it possible to specify how the algorithm
+%   should subdivide the matrix:
+%
+%     'standard'  (default) This is the standard behaviour of the JPEG 2000
+%                 standard
+%
+%     'tensor'    This corresponds to doing a FWT along each dimension
+%                 of the matrix.
+%   
+%   Examples:
+%   ---------
+%   
+%   Some simple example of calling the FWT2 function, compare with the
+%   CAMERAMAN image. Only the 70 dB largest coefficients are shown, to
+%   make the structures more visible.
+%
+%   The first example uses the standard layout:
+% 
+%     c = fwt2(cameraman,{'db',8},4);
+%     imagesc(dynlimit(20*log10(abs(c)),70));
+%     axis('image'); colormap(gray);
+%
+%   The second example uses the tensor product layout:
+%
+%     c = fwt2(cameraman,{'db',8},4,'tensor');
+%     imagesc(dynlimit(20*log10(abs(c)),70));
+%     axis('image'); colormap(gray);
+%
+%
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwt2.php}
+%@seealso{ifwt2, fwtinit, demo_imagecompression}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(J) || ~isscalar(J)
+  error('%s: "J" must be a scalar.',upper(mfilename));
+end;
+
+if(J<1 || rem(J,1)~=0)
+   error('%s: J must be a positive integer.',upper(mfilename)); 
+end
+
+[M,N]=size(f);
+if(M==1||N==1)
+   error('%s: The input data is vector.',upper(mfilename)); 
+end
+
+% Initialize the wavelet filters structure
+w = fwtinit(w);
+
+if(~all(w.a==length(w.h)))
+   error('%s: Non-critically subsampled filterbanks not supported.',upper(mfilename));  
+end
+
+
+%Do not allow single wavelet coefficient at two consecutive levels
+if(any(w.a(1)^J>size(f)))
+   error('%s: %d-level decomposition of the input is not possible. Maximum J is %d.',upper(mfilename),J,floor(log(max(size(f)))/log(w.a(1))));
+end
+
+%% ----- step 0 : Check inputs -------
+definput.import = {'fwt2'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+nFilts = numel(w.h);
+
+Lcrows = fwtclength(size(f,1),w,J);
+Lccols = fwtclength(size(f,2),w,J);
+
+if(flags.do_standard)
+   Jstep = 1;
+   c = fwt(f,w,Jstep,'dim',1,'per');
+   c = fwt(c,w,Jstep,'dim',2,'per');
+   for jj=1:J-1
+      colRange = 1:Lcrows(end-jj*(nFilts-1)+1);
+      rowRange = 1:Lccols(end-jj*(nFilts-1)+1);
+      c(colRange,rowRange) = fwt(c(colRange,rowRange),w,Jstep,'dim',1,'per');
+      c(colRange,rowRange) = fwt(c(colRange,rowRange),w,Jstep,'dim',2,'per');
+   end
+elseif(flags.do_tensor)
+   c = fwt(f,w,J,'dim',1,'per');
+   c = fwt(c,w,J,'dim',2,'per');
+else
+    error('%s: Should not get here. Bug somewhere else.',upper(mfilename));
+end
+
+
+%% ----- step 1 : Run calc -----------
+% filtNo = length(h.filts);
+% subbNo = filtNo^2-1;
+% c = cell(J*subbNo+1,1);
+% cJidx = J*subbNo+1;
+% cTmp = f;
+% for jj=1:J
+%      cCols = comp_fwt_all(cTmp,h.filts,1,h.a,'dec',flags.ext);
+%      [cColsPack,rows] = wavcell2pack(cCols); 
+%      cRows = comp_fwt_all(cColsPack.',h.filts,1,h.a,'dec',flags.ext);
+%      [cRowsPack,cols] = wavcell2pack(cRows); 
+%      cTmp = cRowsPack(1:cols(1),1:rows(1)).';
+%      
+%      cJidxTmp = cJidx - jj*subbNo+1;
+% 
+%      for cc= 1:filtNo
+%         for rr = 1:filtNo
+%            if(cc==1&&rr==1), continue; end; 
+%            c{cJidxTmp} = cRowsPack(sum(cols(1:cc-1))+1:sum(cols(1:cc)),sum(rows(1:rr-1))+1:sum(rows(1:rr))).';
+%            cJidxTmp = cJidxTmp + 1;
+%         end
+%      end
+% end
+% c{1} = cTmp;
+
+
+
diff --git a/inst/wavelets/fwt2filterbank.m b/inst/wavelets/fwt2filterbank.m
new file mode 100644
index 0000000..7d827c6
--- /dev/null
+++ b/inst/wavelets/fwt2filterbank.m
@@ -0,0 +1,57 @@
+function [g,a] = fwt2filterbank( w, J)
+%-*- texinfo -*-
+%@deftypefn {Function} fwt2filterbank
+%@verbatim
+%FWT2FILTERBANK  FWT equivalent non-iterated filterbank
+%   Usage: [g,a] = fwt2filterbank(wtdef)
+%
+%   Input parameters:
+%          w : Wavelet filters definition
+%          J : Number of filterbank iterations.
+%
+%   Output parameters:
+%         g   : Cell array containing filters
+%         a   : Vector of sub-/upsampling factors
+%
+%   FWT2FILTERBANK( w, J) calculates the impulse responses g and the 
+%   subsampling factors a of non-iterated filterbank, which is equivalent
+%   to the wavelet filterbank tree described by w and J. The returned 
+%   parameters can be used directly in FILTERBANK, UFILTERBANK.
+%   
+%   The filters are scaled if a is not returned. 
+%
+%   The function is wrapper for calling WFBT2FILTERBANK.
+%   
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwt2filterbank.php}
+%@seealso{wfbtinit, wfbt2filterbank, filterbank}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<2)
+    error('%s: Not enough input arguments',upper(mfilename));
+end
+
+if nargout<2
+  g = wfbt2filterbank({w,J,'dwt'});
+elseif nargout == 2
+  [g,a] = wfbt2filterbank({w,J,'dwt'});   
+end
+
+
diff --git a/inst/wavelets/fwtbounds.m b/inst/wavelets/fwtbounds.m
new file mode 100644
index 0000000..ea3c7fe
--- /dev/null
+++ b/inst/wavelets/fwtbounds.m
@@ -0,0 +1,60 @@
+function [AF,BF]=fwtbounds(w,J,L)
+%-*- texinfo -*-
+%@deftypefn {Function} fwtbounds
+%@verbatim
+%FWTBOUNDS Frame bounds of DWT
+%   Usage: fcond=fwtbounds(w,J,L);
+%          [A,B]=fwtbounds(w,J,L);
+%
+%   FWTBOUNDS(w,a,L) calculates the ratio B/A of the frame bounds
+%   of the filterbank specified by w and J for a system of length
+%   L. The ratio is a measure of the stability of the system. 
+%
+%   [A,B]=FWTBOUNDS(w,J,L) returns the lower and upper frame bounds
+%   explicitly. 
+%
+%   See FWT for explanation of parameters w and J.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwtbounds.php}
+%@seealso{fwt, filterbankbounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+% There seem to be two possibilites:
+% 1) Find the frame bounds of the equaivalent uniform filterbank. The
+%    equivalent non-uniform filterbank can be created using fwt2filterbank,
+%    non-uniform to uniform filterbank transform is described in the book:
+%    Beyond Wavelets, chapter 10, Nonuniform filter banks: New results and
+%    open problems by Akkarakaran and Vaidyanathan.
+% 2) Use the recursive polyphase matrix multiplication algorithm from 
+%    Stanhill, D.; Zeevi, Y. Y.: Frame analysis of wavelet-type filter banks 
+
+%ad 1) (shotcut trough wfbtbounds)
+
+if nargout<2
+   AF = wfbtbounds({w,J,'dwt'},L);
+elseif nargout == 2
+   [AF, BF] = wfbtbounds({w,J,'dwt'},L);
+end
+
diff --git a/inst/wavelets/fwtclength.m b/inst/wavelets/fwtclength.m
new file mode 100644
index 0000000..fb06cd4
--- /dev/null
+++ b/inst/wavelets/fwtclength.m
@@ -0,0 +1,85 @@
+function [Lc,L]=fwtclength(Ls,w,J,varargin) 
+%-*- texinfo -*-
+%@deftypefn {Function} fwtclength
+%@verbatim
+%FWTCLENGTH FWT subbands lengths from a signal length
+%   Usage: L=fwtclength(Ls,h,J);
+%          L=fwtclength(Ls,h,J,ext,'ext');
+%
+%   Lc=FWTCLENGTH(Ls,h,J) returns the lengths of the wavelet coefficient
+%   subbands for a signal of length Ls. Please see the help on FWT for
+%   an explanation of the parameters h and J. In addition, the function
+%   returns the next legal length of the input signal for the given extension
+%   type.
+%   
+%   The function support the same boundary-handling flags as the FWT
+%   does.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwtclength.php}
+%@seealso{fwt, fwtlength}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+w = fwtinit(w);
+
+definput.import = {'fwtext'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Get the next legal length
+L = fwtlength(Ls,w,J,flags.ext);
+
+filtNo = length(w.g);
+subbNo = (filtNo-1)*J+1;
+Lc = zeros(subbNo,1);
+runPtr = 0; 
+levelLen = L;
+if flags.do_per
+  % Non-expansive case
+  for jj=1:J
+     for ff=filtNo:-1:2
+        Lc(end-runPtr) = ceil(levelLen/w.a(ff));
+        runPtr = runPtr + 1;
+     end
+     levelLen = ceil(levelLen/w.a(1));
+  end
+elseif flags.do_valid
+  % Valid coef. case
+  filts = w.g;
+  for jj=1:J
+     for ff=filtNo:-1:2
+        Lc(end-runPtr) = floor((levelLen-(length(filts{ff}.h)-1))/w.a(ff));
+        runPtr = runPtr + 1;
+     end
+     levelLen = floor((levelLen-(length(filts{1}.h)-1))/w.a(1));
+  end  
+else
+  % Expansive case
+  filts = w.g;
+  for jj=1:J
+    for ff=filtNo:-1:2
+       skip = w.a(ff) - 1;
+       Lc(end-runPtr) = ceil((levelLen+(length(filts{ff}.h)-1)-skip)/w.a(ff));
+       runPtr = runPtr + 1;
+    end
+    skip = w.a(1) - 1;
+    levelLen = ceil((levelLen+(length(filts{1}.h)-1)-skip)/w.a(1));
+ end
+end
+Lc(1)=levelLen; 
diff --git a/inst/wavelets/fwtinit.m b/inst/wavelets/fwtinit.m
new file mode 100644
index 0000000..77e851d
--- /dev/null
+++ b/inst/wavelets/fwtinit.m
@@ -0,0 +1,475 @@
+function [w] = fwtinit(wdef)
+%-*- texinfo -*-
+%@deftypefn {Function} fwtinit
+%@verbatim
+%FWTINIT  Wavelet Filterbank Structure Initialization
+%   Usage:  w = fwtinit(wdef);
+%
+%   Input parameters:
+%         wdef : Wavelet filters specification.
+%
+%   Output parameters:
+%         w    : Structure defining the filterbank.
+%   
+%   w=FWTINIT(wdef) produces a structure describing the analysis 
+%   (field .h) synthesis (field .g) parts of a one level wavelet-type 
+%   filterbank. The function is a wrapper for calling all the functions 
+%   starting with wfilt_ defined in the LTFAT wavelets directory.
+%
+%   The possible formats of the wdef are the following:
+%
+%   1) Cell array whose first element is the name of the function defining
+%      the basic wavelet filters (wfilt_ prefix) and the other elements
+%      are the parameters of the function. e.g. {'db',10} calls 
+%      wfilt_db(10) internally.
+%
+%   2) Character string as concatenation of the name of the wavelet
+%      filters defining function (as above) and the numeric parameters
+%      delimited by ':' character, e.g. 'db10' has the same effect as above,
+%      'spline4:4' calls wfilt_spline(4,4) internally.
+%
+%   3) Cell array of one dimensional numerical vectors directly defining
+%      the wavelet filter impulse responses.  By default, outputs of the 
+%      filters are subsampled by a factor equal to the number of the 
+%      filters. Pass additional key-value pair 'a',a (still inside of the
+%      cell array) to define the custom subsampling factors, e.g.: 
+%      {h1,h2,'a',[2,2]}.
+%
+%   4) The fourth option is to pass again the structure obtained from the
+%      FWTINIT function. The structure is checked whether it has a valid
+%      format.
+%
+%   5) Two element cell array. First element is the string 'dual' and the
+%      second one is in format 1), 2) or 4). This returns dual of whatever
+%      is passed.
+%
+%   6) Two element cell array. First element is the string 'strict' and the
+%      second one is in format 1), 2), 4) or 5). This ensures the wavelet
+%      filters not forming a tight frame has to be explicitly defined.
+%
+%   Using synthesis filters for analysis and vice versa makes a difference
+%   in case of birtoghonal filters (e.g. 'spline4:4') and filters which 
+%   constructs a general frame (e.g. 'symds2'), in other cases, the analysis
+%   filters are just time-reversed version of synthesis filters. To specify
+%   which filters should be used, one can re-use the items 1) and 2) in the
+%   following way:
+%
+%   1) Add 'ana' or 'syn' as the first element in the cell array e.g. 
+%      {'ana','spline',4,4} or {'syn','spline',4,4}.
+%
+%   2) Add 'ana:' or 'syn:' to the beginning of the string e.g. 
+%      'ana:spline4:4' or 'syn:spline4:4'.
+%
+%   Please note that using e.g. c=fwt(f,'ana:spline4:4',J) and 
+%   fhat=ifwt(c,'ana:spline4:4',J,size(f,1)) will not give a perfect
+%   reconstruction.
+%
+%   The output structure has the following fields:
+%
+%     w.h  Cell array of structures defining the original analysis filter bank.
+%     
+%     w.g  Cell array of structures defining the original synthesis filter bank.
+%
+%     w.a  Subsampling factors.
+%
+%     w.origArgs 
+%          Original parameters in format 1).
+%
+%   w.h, w.g are cell-arrays of structures. Each structure represents 
+%   one filter in the filterbank and it has the following fields:
+%
+%     .offset  Filter delay in samples.
+%
+%     .h       Actual filter impulse response values.
+%
+%   *Remark:* Function names with the wfilt_ prefix cannot contain numbers
+%   and cannot start with 'ana' or 'syn'! 
+%
+%   Choosing wavelet filters
+%   ------------------------
+%   
+%   TO DO: Write something meaningfull.
+%   Determining which wavelet filters to use depends strongly on the type
+%   of the analyzed signal. There are several properties which should be
+%   taken into account.
+%   
+%   orthogonality/biorthogonality/frame
+%   number of vanishing moments of psi
+%   symmetry/linear phase
+%
+%   support of psi
+%   smoothnes/regularity of psi
+%   
+%
+%
+%   References:
+%     S. Mallat. A Wavelet Tour of Signal Processing, Third Edition: The
+%     Sparse Way. Academic Press, 3rd edition, 2008.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwtinit.php}
+%@seealso{fwt, ifwt, wfilt_db}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+% chached last filterbank
+% persistent cachw;
+% cached function parameters passed last
+% persistent cachwDesc;
+
+
+
+% wavelet filters functions definition prefix
+wprefix = 'wfilt_';
+waveletsDir = 'wavelets';
+
+
+% output structure definition
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+w.origArgs = {};
+w.h = {};
+w.g = {};
+w.a = [];
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% return empty struct if no argument was passed
+if nargin<1
+  return;
+end;
+
+if isempty(wdef)
+    error('%s: Input argument is empty.',upper(mfilename)); 
+end
+
+
+do_strict = 0;
+do_dual = 0;
+
+% Check 'strict'
+if iscell(wdef) && ischar(wdef{1}) && strcmpi(wdef{1},'strict')
+   do_strict = 1;
+   wdef = wdef{2:end};
+end
+if iscell(wdef) && ischar(wdef{1}) && strcmpi(wdef{1},'dual')
+   do_dual = 1;
+   wdef = wdef{2:end};
+end
+
+% Disabled caching
+% Was the function called before with the same parameters?
+% if yes, return the chached one
+%  if(isequal(cachwDesc,wdef))
+%     complaina(kv.a,'structure');
+%     w = cachw;
+%     w.filts = decideFilters(w.forceAna,ansyBool,w);
+%     return;
+%  else
+%     cachwDesc = wdef;
+%  end
+
+if isstruct(wdef)
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Process wdef in format 4)%
+    % Do checks and return quicky %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Check the fields
+    if isequal(fieldnames(wdef),fieldnames(w))
+        if ~do_dual && ~do_strict
+           w = wdef;
+           %cachw = w;
+           return;
+        else 
+           if ~isempty(wdef.origArgs)
+              wdef = wdef.origArgs;
+           else
+              error('%s: The structure was not buit using compatible formats.',upper(mfilename));
+           end
+        end
+    else
+       error('%s: Passed structure has different fields.',upper(mfilename)); 
+    end
+end
+
+if iscell(wdef)
+    wname = wdef;
+    if ~ischar(wname{1})
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+       % Process wdef in format 3)%
+       %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+       if isnumeric(wname{1})
+             complainDual(do_dual,'numeric cell array');
+             equalsa = cellfun(@(wEl)strcmp(wEl,'a'),wname);
+             apos = find(equalsa==1);
+             if isempty(apos)
+                apos = numel(wname)+1;
+                w.a = ones(numel(wname),1)*numel(wname);
+             else
+                if apos==numel(wname)-1 && isnumeric(wname{apos+1}) && numel(wname{apos+1})==apos-1
+                   w.a = wname{apos+1};
+                else
+                   error('%s: Key ''a'' have to be followed by a vector of length %i.',upper(mfilename),apos-1);
+                end
+             end
+             w.h = formatFilters(wname(1:apos-1),[]);
+             w.g = formatFilters(wname(1:apos-1),[]);
+       else
+          error('%s: Unrecognizer format of the filterbank definition.',upper(mfilename));
+       end
+       
+       %cachw = w;
+       return;
+    end
+elseif ischar(wdef)
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Process wdef in format 2)%
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+   try
+       wname = parseNameValPair(wdef,wprefix);
+       % Octave does not support the "catch err" stament, so use "lasterror"
+       % instead    
+       %catch err
+   catch
+      err=lasterror;
+      % If failed, clean the cache.
+      cachwDesc = [];
+      cachw = [];
+      error(err.message);
+   end
+else
+    error('%s: First argument must be a string, cell or struct.',upper(mfilename));
+end;
+
+do_forceAna = [];
+is_tight = 0;
+
+% Check whether wavelet definition starts with ana or syn
+if ischar(wname{1}) && numel(wname{1})==3
+   if strcmpi(wname{1},'ana') || strcmpi(wname{1},'syn')
+      % Set field only if ana or syn was explicitly specified.
+      do_forceAna = strcmpi(wname{1},'ana');
+      wname = wname(2:end);
+   end
+end
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% wname now contains wdef in format 1)%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Search for m-file containing string wname
+wfiltFile = dir(fullfile(ltfatbasepath,sprintf('%s/%s%s.m',waveletsDir,wprefix,lower(wname{1}))));
+if(isempty(wfiltFile))
+   error('%s: Unknown wavelet type: %s',upper(mfilename),wname{1}); 
+else
+   % if found, crop '.m' from the filename 
+   tmpFile = wfiltFile.name(1:end-2); 
+end
+
+% There is a bug in nargout in version 3.6 of Octave, but not in later
+% stable versions
+if isoctave
+    octs=strsplit(version,'.');
+    octN=str2num(octs{1})*1000+str2num(octs{2});
+    if octN<3008
+        try
+            feval(tmpFile);
+        catch
+        end;
+    end;
+end;
+    
+wfiltNargout = nargout(tmpFile);
+
+if(nargin(tmpFile)~=numel(wname)-1)
+   error('%s: Incorrect number of parameters to be passed to the %s func.',upper(mfilename),tmpFile);
+end
+
+info = [];
+if(wfiltNargout==3)
+   [tmph, tmpg, w.a] = feval(tmpFile,wname{2:end});
+elseif(wfiltNargout==4) 
+   [tmph, tmpg, w.a, info] = feval(tmpFile,wname{2:end});
+else
+   error('%s: Function %s does not return 3 or 4 arguments.',upper(mfilename),upper(tmpFile));
+end
+
+
+if ~isempty(info)&&isfield(info,'istight')
+   is_tight = info.istight;
+end
+
+d = [];
+if isfield(info,'d')
+   d = info.d;
+end
+
+if numel(tmph)~=numel(w.a) || numel(tmpg)~=numel(w.a)
+   error('%s: Variables returned by %s have different element counts.',upper(mfilename),upper(tmpFile));
+end
+
+if ~is_tight && do_strict && isempty(do_forceAna)
+   error(['%s: %s filters does not form a tight frame. Choose either ''ana:%s'' or ''syn:%s'' '],upper(mfilename),tmpFile,wcell2str(wname),wcell2str(wname));
+end
+ 
+w.h = formatFilters(tmph,d);
+w.g = formatFilters(tmpg,d);
+
+w.origArgs = wname;
+
+if ~isempty(do_forceAna)
+   if do_dual
+      do_forceAna = ~do_forceAna; 
+   end
+   if do_forceAna
+      w.g = w.h;
+      w.origArgs = {'ana',w.origArgs{:}};
+   else
+      w.h = w.g;
+      w.origArgs = {'syn',w.origArgs{:}};
+   end
+end
+
+
+end %END FWTINIT
+
+function filts = formatFilters(cellf,d)
+   noFilts = numel(cellf);
+   filts = cell(noFilts,1);
+   if(isempty(d))
+      d = findFiltDelays(cellf,'half');
+   end
+
+   for ff=1:noFilts
+      %filts{ff} = wfiltstruct('FIR');
+      filts{ff}.h = cellf{ff}(:);
+      filts{ff}.offset = -d(ff);
+   end
+
+end %END FORMATFILTERS
+
+function wcell = parseNameValPair(wchar,wprefix)
+%PARSENAMEVALPAIR
+%Parses string in the following format wnameN1:N2... , where wname have to
+%be name of the existing function with wfilt_ prefix. N1,N2,... are doubles
+%delimited by character ':'.
+%The output is cell array {wname,str2double(N1),str2double(N2),...}
+%The wfilt_ function name cannot contain numbers
+
+wcell = {}; 
+numDelimiter = ':';
+
+% Check whether the first 4 characters are 'ana:' or 'syn:'
+if numel(wchar)>4
+   if strcmpi(wchar(1:4),'ana:')
+      wcell = [wcell,{'ana'}];
+      wchar = wchar(5:end);
+   elseif strcmpi(wchar(1:4),'syn:')
+      wcell = [wcell,{'syn'}];
+      wchar = wchar(5:end);
+   end
+end
+
+% Take out all numbers from the string
+wcharNoNum = wchar(1:find(isstrprop(wchar,'digit')~=0,1)-1);
+
+% List all files satysfying the following: [ltfatbase]/wavelets/wfilt_*.m?
+wfiltFiles = dir(fullfile(ltfatbasepath,sprintf('%s/%s*.m','wavelets',wprefix)));
+% Get just the filanames without the wfilt_ prefix
+wfiltNames = arrayfun(@(fEl) fEl.name(1+find(fEl.name=='_',1):find(fEl.name=='.',1,'last')-1),wfiltFiles,'UniformOutput',0);
+% Compare the filenames with a given string
+wcharMatch = cellfun(@(nEl) strcmpi(wcharNoNum,nEl),wfiltNames);
+% Find index(es) of the matches.
+wcharMatchIdx = find(wcharMatch~=0);
+% Handle faulty results.
+if(isempty(wcharMatchIdx))
+   dirListStr = cell2mat(cellfun(@(wEl) sprintf('%s, ',wEl), wfiltNames(:)','UniformOutput',0));
+   error('%s: Unknown wavelet filter definition string: %s.\nAccepted are:\n%s',upper(mfilename),wcharNoNum,dirListStr(1:end-2));
+end
+if(numel(wcharMatchIdx)>1)
+   error('%s: Ambiguous wavelet filter definition string. Probably bug somewhere.',upper(mfilename));
+end
+
+
+match = wfiltNames{wcharMatchIdx};
+wcell = [wcell,{match}];
+% Extract the numerical parameters from the string (delimited by :)
+numString = wchar(numel(match)+1:end);
+if(isempty(numString))
+   error('%s: No numeric parameter specified in %s.',upper(mfilename),wchar); 
+end
+% Parse the numbers.
+wcharNum = textscan(numString,'%f','Delimiter',numDelimiter);
+if(~isnumeric(wcharNum{1})||any(isnan(wcharNum{1})))
+   error('%s: Incorrect numeric part of the wavelet filter definition string.',upper(mfilename));
+end
+wcell = [wcell, num2cell(wcharNum{1}).'];
+end %END PARSENAMEVALPAIR
+
+function d = findFiltDelays(cellh,type)
+   filtNo = numel(cellh);
+   d = ones(filtNo,1);
+
+   for ff=1:filtNo
+       if(strcmp(type,'half'))
+               d(ff) = floor((length(cellh{ff})+1)/2);
+%        elseif(strcmp(type,'energycent'))
+%            tmphh =cellh{ff};
+%            tmphLen = length(tmphh);
+%            ecent = sum((1:tmphLen-1).*tmphh(2:end).^2)/sum(tmphh.^2);
+%            if(do_ana)
+%                d(ff) = round(ecent)+1;
+%                if(rem(abs(d(ff)-d(1)),2)~=0)
+%                   d(ff)=d(ff)+1;
+%                end
+%            else
+%                anad = round(ecent)+1;
+%                d(ff) = tmphLen-anad;
+%                if(rem(abs(d(ff)-d(1)),2)~=0)
+%                   d(ff)=d(ff)-1;
+%                end
+%            end
+
+       else        
+           error('TO DO: Unsupported type.');
+       end
+  end
+end %END FINDFILTDELAYS
+
+function complainDual(dual,whereStr)
+if dual
+  error('%s: ''dual'' option not allowed for the %s input.',upper(mfilename),whereStr); 
+end
+end % END COMPLAINA
+
+function str = wcell2str(wcell)
+strNums = cellfun(@(wEl) [num2str(wEl),':'],wcell(2:end),'UniformOutput',0);
+strNums = cell2mat(strNums);
+str = [wcell{1},strNums(1:end-1)];
+end
+
+
+
+
+
+
+
+
diff --git a/inst/wavelets/fwtlength.m b/inst/wavelets/fwtlength.m
new file mode 100644
index 0000000..de1ac55
--- /dev/null
+++ b/inst/wavelets/fwtlength.m
@@ -0,0 +1,55 @@
+function L=fwtlength(Ls,w,J,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} fwtlength
+%@verbatim
+%FWTLENGTH  FWT length from signal
+%   Usage: L=fwtlength(Ls,w,J);
+%          L=fwtlength(Ls,w,J,...);
+%
+%   FWTLENGTH(Ls,w,J) returns the length of a Wavelet system that is long
+%   enough to expand a signal of length Ls. Please see the help on
+%   FWT for an explanation of the parameters h and J.
+%
+%   If the returned length is longer than the signal length, the signal
+%   will be zero-padded by FWT to length L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/fwtlength.php}
+%@seealso{fwt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Initialize the wavelet filters structure
+w = fwtinit(w);
+
+definput.import = {'fwtext'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if flags.do_per
+   blocksize=w.a(1)^J;
+   L=ceil(Ls/blocksize)*blocksize;
+elseif flags.do_valid
+   m = numel(w.g{1}.h);
+   a = w.a(1);
+   rred = (a^J-1)/(a-1)*(m-a);
+   blocksize=w.a(1)^J;
+   L=rred+floor((Ls-rred)/blocksize)*blocksize;
+else
+   L = Ls;
+end
+
diff --git a/inst/wavelets/ifwt.m b/inst/wavelets/ifwt.m
new file mode 100644
index 0000000..3051abe
--- /dev/null
+++ b/inst/wavelets/ifwt.m
@@ -0,0 +1,155 @@
+function f = ifwt(c,par,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ifwt
+%@verbatim
+%IFWT   Inverse Fast Wavelet Transform 
+%   Usage:  f = ifwt(c,info)
+%           f = ifwt(c,w,J,Ls)
+%           f = ifwt(c,w,J,Ls,dim)
+%
+%   Input parameters:
+%         c      : Wavelet coefficients.
+%         info,w : Transform parameters struct/Wavelet filters definition.
+%         J      : Number of filterbank iterations.
+%         Ls     : Length of the reconstructed signal.
+%         dim    : Dimension to along which to apply the transform.
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f = IFWT(c,info) reconstructs signal f from the wavelet coefficients
+%   c using parameters from info struct. both returned by FWT
+%   function.
+%
+%   f = IFWT(c,w,J,Ls) reconstructs signal f from the wavelet coefficients
+%   c using J*-iteration synthesis filter bank build from the basic
+%   filterbank defined by w. The Ls parameter is mandatory due to the 
+%   ambiguity of lengths introduced by the subsampling operation and by
+%   boundary treatment methods. Note that the same flag as in the FWT 
+%   function have to be used, otherwise perfect reconstruction cannot be 
+%   obtained.
+%   
+%   In both cases, the fast wavelet transform algorithm (Mallat's algorithm)
+%   is employed. The format of c can be either packed, as returned by the
+%   FWT function or cell-array as returned by WAVPACK2CELL function.
+%
+%   Please see the help on FWT for a detailed description of the parameters.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example showing perfect reconstruction:
+% 
+%     f = gspi;
+%     J = 8;
+%     c = fwt(f,'db8',J);
+%     fhat = ifwt(c,'db8',J,length(f));
+%     % The following should give (almost) zero
+%     norm(f-fhat)
+%   
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/ifwt.php}
+%@seealso{fwt, wavpack2cell, wavcell2pack}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if  ~(iscell(c) || isnumeric(c)) || isempty(c)
+  error('%s: Unrecognized coefficient format.',upper(mfilename));
+end
+
+if(isstruct(par)&&isfield(par,'fname'))
+   if nargin>2
+      error('%s: Too many input parameters.',upper(mfilename));
+   end
+   % process info struct
+   w = fwtinit({'dual',par.wt});
+   J = par.J;
+   Lc = par.Lc;
+   Ls = par.Ls;
+   dim = par.dim;
+   ext = par.ext;
+else
+   if nargin<4
+      error('%s: Too few input parameters.',upper(mfilename));
+   end;
+   
+   %% PARSE INPUT
+   definput.import = {'fwt'};
+   definput.keyvals.dim = [];
+   definput.keyvals.Ls = [];
+   definput.keyvals.J = [];
+   [flags,~,J,Ls,dim]=ltfatarghelper({'J','Ls','dim'},definput,varargin);
+ 
+   ext = flags.ext;
+   %If dim is not specified use the first non-singleton dimension.
+   if(isempty(dim))
+      dim=find(size(c)>1,1);
+   else
+      if(~any(dim==[1,2]))
+         error('%s: Parameter *dim* should be 1 or 2.',upper(mfilename));
+      end
+   end
+   
+   % Initialize the wavelet filters structure
+   w = fwtinit(par);
+
+   %% ----- Determine input data length.
+   L = fwtlength(Ls,w,J,ext);
+
+   %% ----- Determine number of ceoefficients in each subband
+   Lc = fwtclength(L,w,J,ext);
+end
+
+   %% ----- Change c to correct shape according to the dim.
+   if(isnumeric(c))
+      %Check *Lc*
+       if(sum(Lc)~=size(c,dim))
+         error('%s: Coefficient subband lengths does not comply with parameter *Ls*.',upper(mfilename));
+       end
+      %Change format
+      c =  wavpack2cell(c,Lc,dim);
+   elseif(iscell(c))
+      %Just check *Lc*
+      if(~isequal(Lc,cellfun(@(x) size(x,1),c)))
+         error('%s: Coefficient subband lengths does not comply with parameter *Ls*.',upper(mfilename));
+      end
+   else
+      error('%s: Unrecognized coefficient format.',upper(mfilename)); 
+   end;
+
+   %% ----- Run computation 
+   f = comp_ifwt(c,w.g,J,w.a,L,ext);
+ 
+   f = postpad(f,Ls);
+
+   %% ----- FINALIZE: Reshape back according to the dim.
+   if(dim==2)
+       f = f.';
+   end
+%END IFWT
+
diff --git a/inst/wavelets/ifwt2.m b/inst/wavelets/ifwt2.m
new file mode 100644
index 0000000..f08a053
--- /dev/null
+++ b/inst/wavelets/ifwt2.m
@@ -0,0 +1,132 @@
+function f = ifwt2(c,w,J,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ifwt2
+%@verbatim
+%IFWT2   Inverse Fast Wavelet Transform 
+%   Usage:  f = ifwt2(c,w,J)
+%           f = ifwt2(c,w,J,Ls,...)
+%
+%   Input parameters:
+%         c     : Coefficients stored in a matrix.
+%         g     : Wavelet filters definition.
+%         J     : Number of filterbank iterations.
+%         Ls    : Length of the reconstructed signal.
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f = IFWT2(c,g,J) reconstructs signal f from the wavelet coefficients
+%   c using a J*-iteration synthesis filter bank build from the basic synthesis
+%   filterbank defined by g.
+%
+%   This function takes the same optional parameters as FWT2. Please see
+%   the help on FWT2 for a description of the parameters.
+%   
+%
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/ifwt2.php}
+%@seealso{fwt2, fwtinit, demo_imagecompression}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(c)
+  error('%s: Unrecognized coefficient format.',upper(mfilename));
+end;
+
+% Initialize the wavelet filters structure
+w = fwtinit(w);
+
+
+%% PARSE INPUT
+definput.keyvals.Ls=[];    
+definput.import = {'fwt','fwt2'};
+[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+
+if (isempty(Ls))
+   Ls = size(c);
+end
+
+if (numel(Ls)==1)
+  Ls = [Ls,Ls];
+end
+
+Lcrows = fwtclength(Ls(1),w,J,'per');
+Lccols = fwtclength(Ls(2),w,J,'per');
+nFilts = numel(w.g);
+
+if flags.do_standard
+  Jstep = 1;
+  for jj=1:J-1
+    LcIdx =  jj*(nFilts-1)+2;
+    colRange = 1:Lcrows(LcIdx);
+    rowRange = 1:Lccols(LcIdx);
+    c(colRange,rowRange) = ifwt(c(colRange,rowRange),w,Jstep,Lcrows(LcIdx),'dim',1,'per');
+    c(colRange,rowRange) = ifwt(c(colRange,rowRange),w,Jstep,Lccols(LcIdx),'dim',2,'per');
+  end
+
+  c = ifwt(c,w,Jstep,Ls(1),'dim',1,'per');
+  f = ifwt(c,w,Jstep,Ls(2),'dim',2,'per');
+  
+end;
+
+if flags.do_tensor
+  f = ifwt(c,w,J,Ls(1),'dim',1,'per');
+  f = ifwt(f,w,J,Ls(2),'dim',2,'per');
+end;
+
+%% ----- step 1 : Run calc -----------
+% filtNo = length(g.filts);
+% subbNo = filtNo^2-1;
+% cTmp = cell(filtNo,1);
+% cTmp{1} = c{1};
+% cJidxTmp = 2;
+% for jj=1:J
+%    if (jj==J)
+%      cLs = Ls;
+%    else
+%      cLs = size(c{cJidxTmp+subbNo});  
+%    end
+% 
+%    cTmp{1} = comp_ifwt_all({cTmp{1},c{cJidxTmp:cJidxTmp+filtNo-1}},g.filts,1,g.a,cLs(1),'dec',flags.ext).'; 
+%    cJidxTmp = cJidxTmp+filtNo-1;
+%    for cc= 2:filtNo
+%       cTmp{cc} = comp_ifwt_all({c{cJidxTmp:cJidxTmp+filtNo-1}},g.filts,1,g.a,cLs(1),'dec',flags.ext).';
+%       cJidxTmp = cJidxTmp+filtNo;
+%    end
+%    
+%    cTmp{1} = comp_ifwt_all(cTmp,g.filts,1,g.a,cLs(2),'dec',flags.ext).';  
+% end
+% f = cTmp{1};
+
+
+
+
+
+
+
+
diff --git a/inst/wavelets/iufwt.m b/inst/wavelets/iufwt.m
new file mode 100644
index 0000000..7c925df
--- /dev/null
+++ b/inst/wavelets/iufwt.m
@@ -0,0 +1,107 @@
+function f = iufwt(c,par,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iufwt
+%@verbatim
+%IUFWT   Inverse Undecimated Fast Wavelet Transform 
+%   Usage:  f = iufwt(c,info)
+%           f = iufwt(c,w,J);   
+%
+%   Input parameters:
+%         c      : Coefficients stored in L xJ+1 matrix.
+%         info,w : Transform parameters struct/Wavelet filters definition.
+%         J      : Number of filterbank iterations.
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f = IUFWT(c,info) reconstructs signal f from the wavelet 
+%   coefficients c using parameters from info struct. both returned by
+%   UFWT function.
+%
+%   f = IUFWT(c,w,J) reconstructs signal f from the wavelet
+%   coefficients c using the wavelet filterbank consisting of the J 
+%   levels of the basic synthesis filterbank defined by g using the "a-trous"
+%   algorithm. Node that the same flag as in the ufwt function have to be used.
+%
+%   Please see the help on UFWT for a description of the parameters.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example showing perfect reconstruction:
+% 
+%     f = gspi;
+%     J = 8;
+%     c = ufwt(f,'db8',J);
+%     fhat = iufwt(c,'db8',J);
+%     % The following should give (almost) zero
+%     norm(f-fhat)
+%
+%
+%   References:
+%     S. Mallat. A wavelet tour of signal processing. Academic Press, San
+%     Diego, CA, 1998.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/iufwt.php}
+%@seealso{ufwt, plotwavelets}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if nargin<2
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if(isstruct(par)&&isfield(par,'fname'))
+   if nargin>2
+      error('%s: Too many input parameters.',upper(mfilename));
+   end
+   w = fwtinit({'dual',par.wt});
+   J = par.J;
+else
+   if nargin<3
+      error('%s: Too few input parameters.',upper(mfilename));
+   end;
+   definput.keyvals.J = [];
+   [~,~,J]=ltfatarghelper({'J'},definput,varargin);
+
+   if ~isnumeric(J) || ~isscalar(J)
+     error('%s: "J" must be a scalar.',upper(mfilename));
+   end;
+
+   if(J<1 && rem(a,1)~=0)
+      error('%s: J must be a positive integer.',upper(mfilename)); 
+   end
+   
+   % Initialize the wavelet filters structure
+   w = fwtinit(par);
+end
+
+
+%%  Run computation
+f = comp_iufwt(c,w.g,J,w.a);
+
+
+
+
+
+
+
+
diff --git a/inst/wavelets/iuwfbt.m b/inst/wavelets/iuwfbt.m
new file mode 100644
index 0000000..4b3011f
--- /dev/null
+++ b/inst/wavelets/iuwfbt.m
@@ -0,0 +1,81 @@
+function f=iuwfbt(c,par,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iuwfbt
+%@verbatim
+%IUWFBT   Inverse Undecimated Wavelet Filterbank Tree
+%   Usage: f = iuwfbt(c,info) 
+%          f = iuwfbt(c,wt) 
+%
+%   Input parameters:
+%         c      : Coefficients stored in L xM matrix.
+%         info,w : Transform parameters struct/Wavelet tree definition.
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f = IUWFBT(c,info) reconstructs signal f from the coefficients c 
+%   using parameters from info struct. both returned by the UWFBT function.
+%
+%   f = IUWFBT(c,wt) reconstructs signal f from the wavelet coefficients 
+%   c using the undecimated wavelet filterbank tree described by wt using
+%   the "a-trous" algorithm.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example showing perfect reconstruction using the "full decomposition" wavelet tree:
+% 
+%     f = greasy;
+%     J = 6;
+%     c = uwfbt(f,{'db8',J,'full'});
+%     fhat = iuwfbt(c,{'db8',J,'full'});
+%     % The following should give (almost) zero
+%     norm(f-fhat)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/iuwfbt.php}
+%@seealso{uwfbt, plotwavelets}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if(isstruct(par)&&isfield(par,'fname'))
+   if nargin>2
+      error('%s: Too many input parameters.',upper(mfilename));
+   end
+   wt = wfbtinit({'dual',par.wt},par.fOrder);
+else
+   %% PARSE INPUT
+   definput.import = {'wfbtcommon'};
+   flags=ltfatarghelper({},definput,varargin);
+
+   % Initialize the wavelet tree structure
+   wt = wfbtinit(par,flags.forder);
+end
+
+
+%% ----- step 2 : Prepare input parameters
+wtPath = nodesBForder(wt,'rev');
+nodesUps = nodeFiltUps(wtPath,wt);
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+rangeOut = rangeInOutputs(wtPath,wt);
+%% ----- step 3 : Run computation
+f = comp_iuwfbt(c,wt.nodes(wtPath),nodesUps,rangeLoc,rangeOut);
diff --git a/inst/wavelets/iuwpfbt.m b/inst/wavelets/iuwpfbt.m
new file mode 100644
index 0000000..547902a
--- /dev/null
+++ b/inst/wavelets/iuwpfbt.m
@@ -0,0 +1,95 @@
+function f=iuwpfbt(c,par,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iuwpfbt
+%@verbatim
+%IUWPFBT Inverse Undecimated Wavelet Packet Filterbank Tree
+%   Usage:  f=iuwpfbt(c,info);
+%           f=iuwpfbt(c,wt,...);
+%
+%   Input parameters:
+%         c     : Coefficients stored in a cell-array.
+%         wt    : Wavelet Filterbank tree
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f=IUWPFBT(c,wt) reconstructs signal f from coefficients c using the
+%   wavelet filterbank tree wt. 
+%
+%   The following flags are supported:
+%
+%   'per','zpd','sym','symw','asym','asymw','ppd','sp0'
+%          Type of the boundary handling.
+%
+%   'full','dwt'
+%          Type of the tree to be used.
+%
+%   'freq','nat'
+%          Frequency or natural order of the coefficient subbands.
+%
+%   Please see the help on FWT for a description of the flags.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example showing perfect reconstruction using the "full decomposition" wavelet tree:
+% 
+%     f = greasy;
+%     J = 7;
+%     wtdef = {'db10',J,'full'};
+%     c = uwpfbt(f,wtdef);
+%     fhat = iuwpfbt(c,wtdef);
+%     % The following should give (almost) zero
+%     norm(f-fhat)
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/iuwpfbt.php}
+%@seealso{wfbt, wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+if nargin<2
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if(isstruct(par)&&isfield(par,'fname'))
+   if nargin>2
+      error('%s: Too many input parameters.',upper(mfilename));
+   end
+   if ~strcmpi(par.fname,'uwpfbt')
+      error('%s: Wrong func name in info struct. The info parameter was created by %s.',upper(mfilename),par.fname);
+   end
+   wt = wfbtinit({'dual',par.wt},par.fOrder,'syn');
+else
+   %% PARSE INPUT
+   definput.import = {'wfbtcommon'};
+   if(~isnumeric(c))
+       error('%s: Unrecognized coefficient format.',upper(mfilename));
+   end
+
+   [flags,kv]=ltfatarghelper({},definput,varargin);
+
+   % Initialize the wavelet tree structure
+   wt = wfbtinit(par,flags.forder);
+end
+
+wtPath = nodesBForder(wt,'rev');
+[pOutIdxs,chOutIdxs] = rangeWpBF(wt,'rev');
+nodesUps = nodeFiltUps(wtPath,wt);
+f = comp_iuwpfbt(c,wt.nodes(wtPath),nodesUps,pOutIdxs,chOutIdxs);
+
diff --git a/inst/wavelets/iwfbt.m b/inst/wavelets/iwfbt.m
new file mode 100644
index 0000000..a752e72
--- /dev/null
+++ b/inst/wavelets/iwfbt.m
@@ -0,0 +1,112 @@
+function f=iwfbt(c,par,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iwfbt
+%@verbatim
+%IWFBT   Inverse Wavelet Filterbank Tree
+%   Usage:  f=iwfbt(c,info);
+%           f=iwfbt(c,wt,Ls);
+%
+%   Input parameters:
+%         c       : Coefficients stored in a cell-array.
+%         info,wt : Transform parameters struct/Wavelet Filterbank tree
+%         Ls      : Length of the reconstructed signal.
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f = IWFBT(c,info) reconstructs signal f from the coefficients c 
+%   using parameters from info struct. both returned by WFBT function.
+%
+%   f = IWFBT(c,wt,Ls) reconstructs signal f from the coefficients c*
+%   using filter bank tree defined by wt. Plese see WFBT function for
+%   possible formats of wt. The Ls parameter is mandatory due to the 
+%   ambiguity of reconstruction lengths introduced by the subsampling 
+%   operation and by boundary treatment methods. Note that the same flag as
+%   in the WFBT function have to be used, otherwise perfect reconstruction
+%   cannot be obtained. Please see help for WFBT for description of the
+%   flags.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example showing perfect reconstruction using the "full decomposition" wavelet tree:
+% 
+%     f = gspi;
+%     J = 7;
+%     wtdef = {'db10',J,'full'};
+%     c = wfbt(f,wtdef);
+%     fhat = iwfbt(c,wtdef,length(f));
+%     % The following should give (almost) zero
+%     norm(f-fhat)
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/iwfbt.php}
+%@seealso{wfbt, wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if nargin<2
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if(~iscell(c))
+   error('%s: Unrecognized coefficient format.',upper(mfilename));
+end
+
+if(isstruct(par)&&isfield(par,'fname'))
+   if nargin>2
+      error('%s: Too many input parameters.',upper(mfilename));
+   end
+   wt = wfbtinit({'dual',par.wt},par.fOrder);
+   Ls = par.Ls;
+   ext = par.ext;
+   L = wfbtlength(Ls,wt,ext);
+else
+   if nargin<3
+      error('%s: Too few input parameters.',upper(mfilename));
+   end;
+
+   %% PARSE INPUT
+   definput.keyvals.Ls=[];    
+   definput.keyvals.dim=1; 
+   definput.import = {'fwt','wfbtcommon'};
+
+   [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+   ext = flags.ext;
+   % Initialize the wavelet tree structure
+   wt = wfbtinit(par,flags.forder);
+
+   [Lc,L]=wfbtclength(Ls,wt,ext);
+   
+   % Do a sanity check
+   if ~isequal(Lc,cellfun(@(cEl) size(cEl,1),c))
+      error(['%s: The coefficient subband lengths do not comply with the'...
+             ' signal length *Ls*.'],upper(mfilename));
+   end
+end
+
+%% ----- step 3 : Run computation
+wtPath = nodesBForder(wt,'rev');
+outLengths = nodeInLen(wtPath,L,strcmpi(ext,'per'),wt);
+outLengths(end) = L;
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+rangeOut = rangeInOutputs(wtPath,wt);
+f = comp_iwfbt(c,wt.nodes(wtPath),outLengths,rangeLoc,rangeOut,ext);
+f = postpad(f,Ls);
+
diff --git a/inst/wavelets/iwpfbt.m b/inst/wavelets/iwpfbt.m
new file mode 100644
index 0000000..11a58b8
--- /dev/null
+++ b/inst/wavelets/iwpfbt.m
@@ -0,0 +1,115 @@
+function f=iwpfbt(c,par,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iwpfbt
+%@verbatim
+%IWPFBT   Inverse Wavelet Packet Filterbank Tree
+%   Usage:  f=iwpfbt(c,info);
+%           f=iwpfbt(c,wt,Ls);
+%
+%   Input parameters:
+%         c       : Coefficients stored in a cell-array.
+%         info,wt : Transform parameters struct/Wavelet Filterbank tree.
+%         Ls      : Length of the reconstructed signal.
+%
+%   Output parameters:
+%         f     : Reconstructed data.
+%
+%   f = IWPFBT(c,info) reconstructs signal f from the coefficients c 
+%   using parameters from info struct. both returned by WFBT function.
+%
+%   f = IWPFBT(c,wt,Ls) reconstructs signal f from the coefficients c*
+%   using filter bank tree defined by wt. Plese see WFBT function for
+%   possible formats of wt. The Ls parameter is mandatory due to the 
+%   ambiguity of reconstruction lengths introduced by the subsampling 
+%   operation and by boundary treatment methods. Note that the same flag as
+%   in the WFBT function have to be used, otherwise perfect reconstruction
+%   cannot be obtained. Please see help for WFBT for description of the
+%   flags.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example showing perfect reconstruction using the "full decomposition" wavelet tree:
+% 
+%     f = gspi;
+%     J = 7;
+%     wtdef = {'db10',J,'full'};
+%     c = wpfbt(f,wtdef);
+%     fhat = iwpfbt(c,wtdef,length(f));
+%     % The following should give (almost) zero
+%     norm(f-fhat)
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/iwpfbt.php}
+%@seealso{wpfbt, wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+if nargin<2
+   error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if(~iscell(c))
+    error('%s: Unrecognized coefficient format.',upper(mfilename));
+end
+
+
+
+if(isstruct(par)&&isfield(par,'fname'))
+   if nargin>2
+      error('%s: Too many input parameters.',upper(mfilename));
+   end
+   wt = wfbtinit({'dual',par.wt},par.fOrder);
+   Ls = par.Ls;
+   ext = par.ext;
+   do_scale = ~par.isNotScaled;
+
+   % Determine next legal input data length.
+   L = wfbtlength(Ls,wt,ext);
+
+else
+   if nargin<3
+      error('%s: Too few input parameters.',upper(mfilename));
+   end
+   %% PARSE INPUT
+   definput.keyvals.Ls=[];    
+   definput.import = {'fwt','wfbtcommon'};
+   definput.flags.scale = {'scale','noscale'};
+   [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
+   
+   ext = flags.ext;
+   do_scale = flags.scale;
+   % Initialize the wavelet tree structure
+   wt = wfbtinit(par,flags.forder);
+
+   [Lc,L]=wpfbtclength(Ls,wt,ext);
+   
+   % Do a sanity check
+   if ~isequal(Lc,cellfun(@(cEl) size(cEl,1),c))
+      error(['%s: The coefficients subband lengths do not comply with the'...
+             ' signal length *Ls*.'],upper(mfilename));
+   end
+
+end
+
+
+wtPath = nodesBForder(wt,'rev');
+[pOutIdxs,chOutIdxs] = rangeWpBF(wt,'rev');
+f = comp_iwpfbt(c,wt.nodes(wtPath),pOutIdxs,chOutIdxs,L,ext,do_scale);
+f = postpad(f,Ls);
+
diff --git a/inst/wavelets/iwtfft.m b/inst/wavelets/iwtfft.m
new file mode 100644
index 0000000..d1a8db6
--- /dev/null
+++ b/inst/wavelets/iwtfft.m
@@ -0,0 +1,72 @@
+function f = iwtfft(c,G,a,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} iwtfft
+%@verbatim
+%IWTFFT  Inverse Wavelet Transform in the frequency-domain
+%   Usage: f=iwtfft(c,G,a);
+%          f=iwtfft(c,G,a,...);
+%
+%   IWTFFT(c,G,a) computes XXX.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/iwtfft.php}
+%@seealso{wtfft}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+    if nargin<2
+      error('%s: Too few input parameters.',upper(mfilename));
+    end;
+
+
+%% PARSE INPUT
+definput.keyvals.L=[];    
+definput.import = {'wtfft'};
+
+[flags,kv,Ls]=ltfatarghelper({'L'},definput,varargin);
+
+[Gr,Gc] = size(G);
+
+if(isempty(a))
+    a = ones(Gc,1);
+end
+
+L=filterbanklengthcoef(c,a);
+[sigHalfLen,W] = size(c{end});
+f = zeros(L,W);
+
+
+N = zeros(Gc,1);
+for gg=1:Gc
+    N(gg)=size(c{gg},1);
+end
+
+
+for w=1:W
+   for gg=1:Gc
+      f(:,w)=f(:,w)+ifft(repmat(fft(c{gg}(:,w)),a(gg),1).*G(:,gg));
+   end
+end
+
+if ~isempty(Ls)
+  f=postpad(f,Ls);
+else
+  Ls=L;
+end;
+
+
diff --git a/inst/wavelets/plotwavelets.m b/inst/wavelets/plotwavelets.m
new file mode 100644
index 0000000..970ae5a
--- /dev/null
+++ b/inst/wavelets/plotwavelets.m
@@ -0,0 +1,155 @@
+function [C] = plotwavelets(c,info,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} plotwavelets
+%@verbatim
+%PLOTWAVELETS  Plot wavelet coefficients
+%   Usage:  plotwavelets(c,info,fs) 
+%           plotwavelets(c,info,fs,'dynrange',dynrange,...)
+%
+%   plowavelets(c,info) plots the wavelet coefficients c using
+%   additional parameters from struct. info. Both parameters are returned
+%   by any forward transform function in the wavelets directory.
+%
+%   plowavelets(c,info,fs) does the same plot assuming a sampling rate of fs Hz
+%   of the original signal.
+%
+%   plowavelets(c,info,fs,'dynrange',dynrange) additionally limits the dynamic range.
+%
+%   C=plowavelets(...) returns the processed image data used in the
+%   plotting. Inputting this data directly to imagesc or similar functions
+%   will create the plot. This is usefull for custom post-processing of the
+%   image data.
+%
+%   plowavelets supports optional parameters of TFPLOT. Please see
+%   the help of TFPLOT for an exhaustive list.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/plotwavelets.php}
+%@seealso{fwt, tfplot}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+definput.import={'tfplot'};
+definput.flags.fwtplottype = {'tfplot','stem'};
+definput.keyvals.fs = [];
+definput.keyvals.dynrange = [];
+[flags,kv]=ltfatarghelper({'fs','dynrange'},definput,varargin);
+
+if(flags.do_stem)
+   error('%s: Flag %s not supported yet.',upper(mfilename),flags.fwtplottype);
+end
+
+maxSubLen = 800;
+draw_ticks = 1;
+
+if(strcmpi(info.fname,'fwt'))
+%% FWT plot
+   % Change to the cell format
+   if(isnumeric(c))
+       c = wavpack2cell(c,info.Lc,info.dim);
+   end
+   maxSubLen = max(info.Lc);
+   
+   % Only one channel signals can be plotted.
+   if(size(c{1},2)>1)
+      error('%s: Multichannel input not supported.',upper(mfilename));
+   end
+
+   subbNo = numel(c);
+   w = fwtinit(info.wt);
+   aBase = w.a;
+   filtNo = numel(w.h);
+   J = info.J;
+   a = [aBase(1).^J, reshape(aBase(2:end)*aBase(1).^(J-1:-1:0),1,[])]';
+elseif(strcmpi(info.fname,'ufwt'))
+   
+   % Only one channel signals can be plotted.
+   if(ndims(c)>2)
+      error('%s: Multichannel not supported.',upper(mfilename));
+   end
+
+   subbNo = size(c,2);
+   a = ones(subbNo,1);
+
+   w = fwtinit(info.wt);
+   filtNo = numel(w.h);
+   J = info.J; 
+elseif(strcmpi(info.fname,'wfbt'))
+   % Only one channel signals can be plotted.
+   if(size(c{1},2)>1)
+      error('%s: Multichannel input not supported.',upper(mfilename));
+   end
+   maxSubLen = max(cellfun(@(cEl) size(cEl,1),c));
+   a = treeSub(info.wt);
+   subbNo = numel(c);
+   draw_ticks = 0;
+elseif(strcmpi(info.fname,'uwfbt'))
+   % Only one channel signals can be plotted.
+   if(ndims(c)>2)
+      error('%s: Multichannel not supported.',upper(mfilename));
+   end
+
+   subbNo = size(c,2);
+   a = ones(subbNo,1);
+   draw_ticks = 0;
+elseif(strcmpi(info.fname,'wpfbt'))
+   % Only one channel signals can be plotted.
+   if(size(c{1},2)>1)
+      error('%s: Multichannel input not supported.',upper(mfilename));
+   end
+   maxSubLen = max(cellfun(@(cEl) size(cEl,1),c));
+   aCell = nodeSub(nodesBForder(info.wt),info.wt);
+   a = cell2mat(cellfun(@(aEl) aEl(:)',aCell,'UniformOutput',0));
+   draw_ticks = 0;
+elseif(strcmpi(info.fname,'uwpfbt'))
+   % Only one channel signals can be plotted.
+   if(ndims(c)>2)
+      error('%s: Multichannel not supported.',upper(mfilename));
+   end
+
+   subbNo = size(c,2);
+   a = ones(subbNo,1);
+   draw_ticks = 0;
+else
+   error('%s: Unknown function name %s.',upper(mfilename),info.fname);
+end
+
+% Use plotfilterbank
+C=plotfilterbank(c,a,[],kv.fs,kv.dynrange,flags.plottype,...
+  flags.log,flags.colorbar,flags.display,'fontsize',kv.fontsize,'clim',kv.clim,'xres',min([maxSubLen,800]));
+
+if(draw_ticks)
+   % Redo the yticks and ylabel
+   yTickLabels = cell(1,subbNo);
+   yTickLabels{1} = sprintf('a%d',J);
+   Jtmp = ones(filtNo-1,1)*(J:-1:1);
+   for ii=1:subbNo-1
+      yTickLabels{ii+1} = sprintf('d%d',Jtmp(ii));
+   end
+
+   ylabel('Subbands','fontsize',kv.fontsize);
+   set(gca,'ytick',1:subbNo);
+   set(gca,'ytickLabel',yTickLabels,'fontsize',kv.fontsize);
+end
+
+
+
diff --git a/inst/wavelets/ufwt.m b/inst/wavelets/ufwt.m
new file mode 100644
index 0000000..6d975f8
--- /dev/null
+++ b/inst/wavelets/ufwt.m
@@ -0,0 +1,123 @@
+function [c,info] = ufwt(f,w,J,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} ufwt
+%@verbatim
+%UFWT  Undecimated Fast Wavelet Transform 
+%   Usage:  c = ufwt(f,w,J);
+%           [c,info] = ufwt(...);
+%
+%   Input parameters:
+%         f     : Input data.
+%         w     : Wavelet Filterbank. 
+%         J     : Number of filterbank iterations.
+%
+%   Output parameters:
+%         c     : Coefficients stored in L xJ+1 matrix.
+%         info  : Transform paramaters struct.
+%
+%   c=UFWT(f,w,J) computes redundant time (or shift) invariant
+%   wavelet representation c of the input signal f using the "a-trous"
+%   algorithm. In addition, the function returns struct. info containing
+%   the transform parameters. It can be conviniently used for the inverse 
+%   transform IUFWT e.g. fhat = iUFWT(c,info). It is also required by 
+%   the PLOTWAVELETS function.
+%
+%   The coefficents c are so called Undecimated Discrete Wavelet transform
+%   of the input signal f, if w defines two-channel wavelet filterbank.
+%   Other names for this version of the wavelet transform are: the
+%   time-invariant wavelet transform, the stationary wavelet transform, 
+%   maximal overlap discrete wavelet transform or even the "continuous" 
+%   wavelet transform (as the time step is one sample). However, the 
+%   function accepts any number filters (referred to as M) in the basic 
+%   wavelet filterbank and the number of columns of c is then J(M-1)+1.
+%
+%   For all accepted formats of the parameter w see the FWT function.
+%
+%   For one-dimensional input f of length L, the coefficients c are 
+%   stored as columns of a matrix. The columns are ordered with inceasing
+%   central frequency of the corresponding effective filter frequency 
+%   response or equivalently with decreasing wavelet scale.
+%
+%   If the input f is L xW matrix, the transform is applied 
+%   to each column and the outputs are stacked along third dimension in the
+%   L xJ(M-1)+1 xW data cube.
+%
+%   Boundary handling:
+%   ------------------
+%
+%   c=UFWT(f,w,J) uses periodic boundary extension. The extensions are 
+%   done internally at each level of the transform, rather than doing the 
+%   prior explicit padding.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling the UFWT function:
+% 
+%     f = greasy;
+%     J = 8;
+%     [c,info] = ufwt(f,'db8',J);
+%     %plotwavelets(c,info,16000,'dynrange',90);
+%
+%
+%   References:
+%     M. Holschneider, R. Kronland-Martinet, J. Morlet, and P. Tchamitchian.
+%     A real-time algorithm for signal analysis with the help of the wavelet
+%     transform. In Wavelets. Time-Frequency Methods and Phase Space,
+%     volume 1, page 286, 1989.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/ufwt.php}
+%@seealso{iufwt, plotwavelets}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(J) || ~isscalar(J)
+  error('%s: "J" must be a scalar.',upper(mfilename));
+end;
+
+if(J<1 && rem(a,1)~=0)
+   error('%s: J must be a positive integer.',upper(mfilename)); 
+end
+
+% Initialize the wavelet filters structure
+w = fwtinit(w);
+
+%% ----- step 1 : Verify f and determine its length -------
+% Change f to correct shape.
+[f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0);
+if(Ls<2)
+   error('%s: Input signal seems not to be a vector of length > 1.',upper(mfilename));  
+end
+ 
+%% ----- step 2 : Run computation
+ c = comp_ufwt(f,w.h,J,w.a);
+ 
+%% ----- Optionally : Fill info struct ----
+if nargout>1
+   info.fname = 'ufwt';
+   info.wt = w;
+   info.J = J;
+end
+
+
+
diff --git a/inst/wavelets/uwfbt.m b/inst/wavelets/uwfbt.m
new file mode 100644
index 0000000..bc22e8d
--- /dev/null
+++ b/inst/wavelets/uwfbt.m
@@ -0,0 +1,93 @@
+function [c,info]=uwfbt(f,wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} uwfbt
+%@verbatim
+%UWFBT   Undecimated Wavelet FilterBank Tree
+%   Usage:  c=uwfbt(f,wt);
+%           [c,info]=uwfbt(...);
+%
+%   Input parameters:
+%         f   : Input data.
+%         wt  : Wavelet Filterbank tree
+%
+%   Output parameters:
+%         c     : Coefficients stored in L xM matrix.
+%
+%   c=UWFBT(f,wt) computes redundant time (or shift) representation c 
+%   of the input signal f using the filterbank tree definition in wt and
+%   using the "a-trous" algorithm. Number of columns in c (*M*) is defined
+%   by the total number of outputs of the leaf nodes of the tree.
+%   In addition, the function returns struct. info containing the transform
+%   parameters. It can be conviniently used for the inverse transform IUWFBT
+%   e.g. fhat = iUWFBT(c,info). It is also required by the PLOTWAVELETS
+%   function.
+%
+%   If f is a matrix, the transformation is applied to each of W columns
+%   and the coefficients in c are stacked along the third dimension.
+%
+%   Please see help for WFBT description of possible formats of wt and
+%   description of frequency and natural ordering of the coefficient subbands.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling the UWFBT function using the "full decomposition" wavelet tree:
+% 
+%     f = greasy;
+%     J = 8;
+%     [c,info] = uwfbt(f,{'sym10',J,'full'});
+%     plotwavelets(c,info,16000,'dynrange',90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/uwfbt.php}
+%@seealso{iuwfbt, wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(nargin<2)
+   error('%s: Too few input parameters.',upper(mfilename));  
+end
+
+definput.import = {'wfbtcommon'};
+flags=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet tree structure
+wt = wfbtinit(wt,flags.forder);
+
+%% ----- step 1 : Verify f and determine its length -------
+[f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0);
+if(Ls<2)
+   error('%s: Input signal seems not to be a vector of length > 1.',upper(mfilename));  
+end
+
+%% ----- step 2 : Prepare input parameters
+wtPath = nodesBForder(wt);
+nodesUps = nodeFiltUps(wtPath,wt);
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+rangeOut = rangeInOutputs(wtPath,wt);
+%% ----- step 3 : Run computation
+c = comp_uwfbt(f,wt.nodes(wtPath),nodesUps,rangeLoc,rangeOut);
+
+%% ----- Optional : Fill the info struct. -----
+if nargout>1
+   info.fname = 'uwfbt';
+   info.wt = wt;
+   info.fOrder = flags.forder;
+   info.isPacked = 0;
+end
+
diff --git a/inst/wavelets/uwpfbt.m b/inst/wavelets/uwpfbt.m
new file mode 100644
index 0000000..b340873
--- /dev/null
+++ b/inst/wavelets/uwpfbt.m
@@ -0,0 +1,92 @@
+function [c,info]=uwpfbt(f,wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} uwpfbt
+%@verbatim
+%UWPFBT Undecimated Wavelet Packet FilterBank Tree
+%   Usage:  c=uwpfbt(f,wt);
+%           c=uwpfbt(f,wt,...);
+%
+%   Input parameters:
+%         f   : Input data.
+%         wt  : Wavelet Filterbank tree
+%
+%   Output parameters:
+%         c   : Coefficients in a L xM matrix.
+%
+%   c=UWPFBT(f,wt) returns coefficients c obtained by applying the 
+%   undecimated wavelet filterbank tree defined by wt to the input data 
+%   f using the "a-trous" algorithm. Number of columns in c (*M*) is 
+%   defined by the total number of outputs of each node. The outputs c(:,jj)
+%   are ordered in the breadth-first node order manner.
+%   In addition, the function returns struct. info containing the transform
+%   parameters. It can be conviniently used for the inverse transform IUWPFBT
+%   e.g. fhat = iUWPFBT(c,info). It is also required by the PLOTWAVELETS
+%   function.
+%
+%   If f is a matrix, the transformation is applied to each of W columns
+%   and the coefficients in c are stacked along the third dimension.
+%
+%   Please see help for WFBT description of possible formats of wt.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling the UWPFBT function using the "full
+%   decomposition" wavelet tree:
+% 
+%     f = greasy;
+%     J = 6;
+%     [c,info] = uwpfbt(f,{'db10',J,'full'});
+%     plotwavelets(c,info,44100,'dynrange',90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/uwpfbt.php}
+%@seealso{iuwpfbt, wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<2)
+   error('%s: Too few input parameters.',upper(mfilename));  
+end
+
+definput.import = {'wfbtcommon'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet tree structure
+wt = wfbtinit(wt,flags.forder);
+    
+%% ----- step 1 : Verify f and determine its length -------
+[f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0);
+if(Ls<2)
+   error('%s: Input signal seems not to be a vector of length > 1.',upper(mfilename));  
+end
+
+%% ----- step 3 : Run computation
+wtPath = nodesBForder(wt);
+nodesUps = nodeFiltUps(wtPath,wt);
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+c = comp_uwpfbt(f,wt.nodes(wtPath),rangeLoc,nodesUps);
+
+%% ----- Optional : Fill the info struct. -----
+if nargout>1
+   info.fname = 'uwpfbt';
+   info.wt = wt;
+   info.fOrder = flags.forder;
+   info.isPacked = 0;
+end
diff --git a/inst/wavelets/wavcell2pack.m b/inst/wavelets/wavcell2pack.m
new file mode 100644
index 0000000..5a15154
--- /dev/null
+++ b/inst/wavelets/wavcell2pack.m
@@ -0,0 +1,71 @@
+function [cvec,Lc] = wavcell2pack(ccell,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wavcell2pack
+%@verbatim
+%WAVCELL2PACK Changes wavelet coefficients storing format
+%   Usage:  [cvec,Lc] = wavcell2pack(ccell);
+%           [cvec,Lc] = wavcell2pack(ccell,dim);
+%
+%   Input parameters:
+%         ccell    : Coefficients stored in a collumn cell-array.
+%         dim      : Dimension along which the data were transformed. 
+%
+%   Output parameters:
+%         cvec     : Coefficients in packed format.
+%         Lc       : Vector containing coefficients lengths.
+%
+%   [cvec,Lc] = WAVCELL2PACK(ccell) assembles a column vector or a matrix
+%   cvec using elements of the cell-array ccell in the following
+%   manner:
+%
+%      cvec(1+sum(Lc(1:j-1)):sum(Lc(1:j),:)=ccell{j};
+%
+%   where Lc is a vector of length numel(ccell) containing number of
+%   rows of each element of ccell.
+%
+%   [cvec,Lc] = WAVCELL2PACK(ccell,dim) with dim==2 returns a
+%   transposition of the previous.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wavcell2pack.php}
+%@seealso{wavpack2cell, fwt, wfbt, wpfbt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(nargin<1)
+    error('%s: Too few input parameters.',upper(mfilename));
+end
+
+definput.keyvals.dim = 1;
+[flags,kv,dim]=ltfatarghelper({'dim'},definput,varargin);
+if(dim>2)
+    error('%s: Multidimensional data is not accepted.',upper(mfilename));
+end
+
+% Actual computation
+Lc = cellfun(@(x) size(x,1), ccell);
+cvec = cell2mat(ccell);
+
+% Reshape back to rows
+if(dim==2)
+    cvec = cvec.';
+end
+
+
+
+
diff --git a/inst/wavelets/waveletsinit.m b/inst/wavelets/waveletsinit.m
new file mode 100644
index 0000000..e589b39
--- /dev/null
+++ b/inst/wavelets/waveletsinit.m
@@ -0,0 +1,28 @@
+status = 1;
+
+p=[bp,'wavelets',filesep];
+
+addpath([p,'wfbtmanip']);
+%-*- texinfo -*-
+%@deftypefn {Function} waveletsinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/waveletsinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+addpath([p,'wfbtmanip']);
diff --git a/inst/wavelets/wavfun.m b/inst/wavelets/wavfun.m
new file mode 100644
index 0000000..e8fc603
--- /dev/null
+++ b/inst/wavelets/wavfun.m
@@ -0,0 +1,146 @@
+function [wfunc,sfunc,xvals] = wavfun(w,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wavfun
+%@verbatim
+% WAVFUN  Wavelet Function
+%   Usage: [w,s,xvals] = wavfun(g) 
+%           [w,s,xvals] = wavfun(g,N) 
+%
+%   Input parameters:
+%         w     : Wavelet filterbank
+%         N     : Number of iterations
+%   Output parameters:
+%         wfunc : Approximation of wavelet function(s)
+%         sfunc : Approximation of the scaling function
+%         xvals : Correct x-axis values
+%
+%   Iteratively generate (*N iterations) a discrete approximation of wavelet
+%   and scaling functions using filters obtained from w. The possible formats of w*
+%   are the same as for the FWT function. The algorithm is equal to the 
+%   DWT reconstruction of a single coefficient at level N set to 1. xvals*
+%   contains correct x-axis values. All but alst collumns belong to the
+%   wfunc, last one to the sfunc.
+%   
+%   The following flags are supported (first is default):
+%   
+%   'fft', 'conv'
+%     How to do the computations. Whatever is faster depends on
+%     the speed of the conv2 function.
+%
+%   *WARNING**: The output array lengths L depend on N exponentially like:
+%   
+%      L=(m-1)*(a^N-1)/(a-1) + 1
+%
+%   where a is subsamling factor after the lowpass filter in the wavelet
+%   filterbank and m is length of the filters. Expect issues for
+%   high N e.g. 'db10' (m=20) and N=20 yields a ~150MB array.
+%
+%   Examples:
+%   ---------
+%   
+%   Approximation of a Daubechies wavelet and scaling functions from the
+%   12 tap filters:
+% 
+%     [wfn,sfn,xvals] = wavfun('db6');
+%     plot(xvals,[wfn,sfn]);
+%     legend('wavelet function','scaling function');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wavfun.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+definput.keyvals.N = 6;
+definput.flags.howcomp = {'conv','fft'};
+[flags,kv,N]=ltfatarghelper({'N'},definput,varargin);
+w = fwtinit({'strict',w});
+a = w.a(1);
+filtNo = length(w.g);
+
+% Copy impulse responses as columns of a single matrix.
+lo = w.g{1}.h(:);
+wtemp = zeros(length(lo),filtNo);
+for ff=1:filtNo
+    wtemp(:,ff) =  w.g{ff}.h(:);
+end
+
+filtsAreReal = isreal(wtemp);
+
+if(flags.do_conv)
+   % Linear convolutions in the time domain.
+   for n=2:N
+      wtemp = conv2(comp_ups(wtemp,a,1),lo);
+   end
+elseif(flags.do_fft)
+   % Cyclic convolutions and upsampling in freqency domain.
+   m = length(lo);
+   L = (m-1)*(a^N-1)/(a-1) + 1;
+   % Initial padding with zeros to avoid time aliasing.
+   wtmpFFT = fft(wtemp,nextfastfft(2*m-1));
+   for n=2:N
+      loFFT = fft(lo,a*size(wtmpFFT,1));
+      wtmpFFT = bsxfun(@times,repmat(wtmpFFT,a,1),loFFT);
+   end
+
+   wtemp = ifft(wtmpFFT);
+   wtemp = wtemp(1:L,:);
+else
+   error('%s: Unexpected flag.',upper(mfilename));
+end
+
+% Final fomating
+if filtsAreReal
+   sfunc = real(wtemp(:,1));
+   wfunc = real(wtemp(:,2:end));
+else
+   sfunc = wtemp(:,1);
+   wfunc = wtemp(:,2:end);
+end
+
+
+if(nargout>2)
+    % Calculate xvals
+    xvals = zeros(length(sfunc),filtNo);
+    zeroPos = findFuncZeroPos(-w.g{1}.offset,a,N);
+    sxvals = -zeroPos + (1:length(sfunc));
+    xvals(:,end)= (length(lo)-1)*sxvals/length(sfunc);%linspace(0,length(lo)-1,length(s));
+
+    for ii=1:filtNo-1 
+       zeroPos = findFuncZeroPos(-w.g{ii+1}.offset,a,N);
+       sxvals = -zeroPos + (1:length(sfunc));
+       xvals(:,ii)= (length(lo)-1)*sxvals/length(sfunc);%linspace(0,length(lo)-1,length(s));
+    end
+end
+%END WAVFUN
+
+
+function zeroPos = findFuncZeroPos(baseZeroPos,a1,N)
+%FINDFUNCZEROPOS Finds zero index position in the *N* iteration approfimation of 
+%                the wavelet or scaling functions.
+
+zeroPos = baseZeroPos;
+for n=2:N
+   zeroPos = zeroPos*a1-(a1-1) + baseZeroPos-1;
+end
+
+
+
+
+
+
+
diff --git a/inst/wavelets/wavpack2cell.m b/inst/wavelets/wavpack2cell.m
new file mode 100644
index 0000000..006dc7b
--- /dev/null
+++ b/inst/wavelets/wavpack2cell.m
@@ -0,0 +1,89 @@
+function [ccell,dim] = wavpack2cell(cvec,Lc,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wavpack2cell
+%@verbatim
+%WAVPACK2CELL Changes wavelet coefficients storing format
+%   Usage:  
+%          ccell = wavpack2cell(cvec,Lc);
+%          ccell = wavpack2cell(cvec,Lc,dim);
+%
+%   Input parameters:
+%         cvec     : Coefficients in packed format.
+%         Lc       : Vector containing coefficients lengths.
+%         dim      : Dimension along which the data were transformed. 
+%
+%   Output parameters:
+%         ccell    : Coefficients stored in a cell-array. Each element is
+%                    a column vector or a matrix.
+%         dim      : Return used dim. Usefull as an input of the
+%                    complementary function WAVCELL2PACK.
+%
+%   ccell = WAVPACK2CELL(cvec,Lc) copies coefficients from a single column
+%   vector or collumns of a matrix cvec of size [sum(Lc), W] to the cell
+%   array ccell of length length(Lc). Size of j*-th element of ccell*
+%   is [Lc(j), W] and it is obtained by:
+% 
+%      ccell{j}=cvec(1+sum(Lc(1:j-1)):sum(Lc(1:j),:);
+%
+%   ccell = WAVPACK2CELL(cvec,Lc,dim) allows specifying along which
+%   dimension the coefficients are stored in cvec. dim==1 (default)
+%   considers columns (as above) and dim==2 rows to be coefficients 
+%   belonging to separate channels. Other values are not supported. For 
+%   dim=2, cvec size is [W, sum(Lc)], Size of j*-th element of ccell*
+%   is [Lc(j), W] and it is obtained by:
+% 
+%      ccell{j}=cvec(:,1+sum(Lc(1:j-1)):sum(Lc(1:j)).';
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wavpack2cell.php}
+%@seealso{wavcell2pack, fwt, wfbt, wpfbt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<2)
+    error('%s: Too few input parameters.',upper(mfilename));
+end
+
+if(~isnumeric(cvec))
+    error('%s: *cvec* is not a numeric array.',upper(mfilename));
+end
+
+definput.keyvals.dim = [];
+[flags,kv,dim]=ltfatarghelper({'dim'},definput,varargin);
+
+%If dim is not specified use first non-singleton dimension.
+if(isempty(dim))
+    dim=find(size(cvec)>1,1);
+end
+
+if(dim>2)
+    error('%s: Multidimensional data is not accepted.',upper(mfilename));
+end
+
+if(dim==2)
+    cvec = cvec.';
+end
+
+if(sum(Lc)~=size(cvec,1))
+    error('%s: Sum of elements of Lc is not equal to vector length along dimension %d. Possibly wrong dim?',upper(mfilename),dim);
+end
+
+% Actual computation
+ccell = mat2cell(cvec,Lc);
+
diff --git a/inst/wavelets/wfbt.m b/inst/wavelets/wfbt.m
new file mode 100644
index 0000000..03f5133
--- /dev/null
+++ b/inst/wavelets/wfbt.m
@@ -0,0 +1,134 @@
+function [c,info]=wfbt(f,wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wfbt
+%@verbatim
+%WFBT   Wavelet FilterBank Tree
+%   Usage:  c=wfbt(f,wt);
+%           [c,info]=wfbt(...);
+%
+%   Input parameters:
+%         f     : Input data.
+%         wt    : Wavelet Filterbank tree definition.
+%
+%   Output parameters:
+%         c    : Coefficients stored in a cell-array.
+%         info : Transform parameters struct.
+%
+%   c=WFBT(f,wt) returns coefficients c obtained by applying a wavelet 
+%   filterbank tree defined by wt to the input data f. In addition, the
+%   function returns struct. info containing transform parameters. It can
+%   be conviniently used for the inverse transform IWFBT e.g. 
+%   fhat = iWFBT(c,info). It is also required by the PLOTWAVELETS function.
+%
+%   wt defines a tree shaped filterbank structure build from the 
+%   elementary two (or more) channel wavelet filters. The tree can have any
+%   shape and thus provide a flexible frequency covering. The outputs of the
+%   tree leaves are stored in c.
+%
+%   The wt parameter can have two formats:
+%
+%   1) Cell array containing 3 elements {w,J,treetype}, where w is
+%      the basic wavelet filterbank definition as in FWT function, J*
+%      stands for the depth of the tree and the flag treetype defines 
+%      the type of the tree to be used. Supported options are:
+%
+%      'dwt'  
+%        DWT tree. Just the low-pass output is decomposed further.
+%
+%      'full'
+%        Full decomposition tree. Each output is decomposed up to level J.
+%
+%   2) Structure returned by the WFBTINIT function and possibly
+%      modified by WFBTPUT and WFBTREMOVE.
+%
+%   If f is row/column vector, the coefficient vectors c{jj} are columns.
+%   
+%   If f is a matrix, the transformation is by default applied to each of
+%   W columns [Ls, W]=size(f).
+%
+%   In addition, the following flag groups are supported:
+%
+%   'per','zero','odd','even'
+%     Type of the boundary handling.
+%
+%   'freq','nat'
+%     Frequency or natural ordering of the coefficient subbands. The direct
+%     usage of the wavelet tree ('nat' option) does not produce coefficient
+%     subbans ordered according to the frequency. To achieve that, some 
+%     filter shuffling has to be done ('freq' option).  
+%
+%   Please see the help on FWT for a description of the boundary condition flags.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling the WFBT function using the "full decomposition" wavelet tree:
+% 
+%     f = gspi;
+%     J = 7;
+%     [c,info] = wfbt(f,{'sym10',J,'full'});
+%     plotwavelets(c,info,44100,'dynrange',90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbt.php}
+%@seealso{iwfbt, wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<2)
+   error('%s: Too few input parameters.',upper(mfilename));  
+end
+
+definput.import = {'fwt','wfbtcommon'};
+definput.keyvals.dim = [];
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet tree structure
+wt = wfbtinit(wt,flags.forder);
+    
+%% ----- step 1 : Verify f and determine its length -------
+[f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0);
+
+% Determine next legal input data length.
+L = wfbtlength(Ls,wt,flags.ext);
+
+% Pad with zeros if the safe length L differ from the Ls.
+if(Ls~=L)
+   f=postpad(f,L); 
+end
+
+%% ----- step 3 : Run computation
+wtPath = nodesBForder(wt);
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+rangeOut = rangeInOutputs(wtPath,wt); % very slow
+c = comp_wfbt(f,wt.nodes(wtPath),rangeLoc,rangeOut,flags.ext);
+
+%% ----- Optionally : Fill info struct ----
+if nargout>1
+   info.fname = 'wfbt';
+   info.wt = wt;
+   info.ext = flags.ext;
+   info.Lc = cellfun(@(cEl) size(cEl,1),c);
+   info.Ls = Ls;
+   info.fOrder = flags.forder;
+   info.isPacked = 0;
+end
+
+
+
diff --git a/inst/wavelets/wfbt2filterbank.m b/inst/wavelets/wfbt2filterbank.m
new file mode 100644
index 0000000..a57d17c
--- /dev/null
+++ b/inst/wavelets/wfbt2filterbank.m
@@ -0,0 +1,102 @@
+function [g,a] = wfbt2filterbank( wtdef, varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wfbt2filterbank
+%@verbatim
+%WFBT2FILTERBANK  WFBT equivalent non-iterated filterbank
+%   Usage: [g,a] = wfbt2filterbank(wtdef)
+%
+%   Input parameters:
+%         wtdef : Wavelet filter tree definition
+%
+%   Output parameters:
+%         g   : Cell array containing filters
+%         a   : Vector of sub-/upsampling factors
+%
+%   wfbtmultid(wtdef) calculates the impulse responses g and the 
+%   subsampling factors a of non-iterated filterbank, which is equivalent
+%   to the wavelet filterbank tree described by wtdef. The returned 
+%   parameters can be used directly in FILTERBANK, UFILTERBANK or 
+%   FILTERBANK. 
+%   
+%   The filters are scaled if a is not returned. 
+%
+%   The function internally calls WFBTINIT and passes wtdef and all 
+%   additional parameters to it.   
+%   
+%   Examples:
+%   --------- 
+%   
+%   The following two examples create a multirate identity filterbank
+%   using a tree of depth 3. In the first example, the filterbank is
+%   identical to the DWT tree:
+%
+%     [g,a] = wfbt2filterbank({'db10',3,'dwt'});
+%     
+%
+%   In the second example, the filterbank is identical to the full
+%   wavelet tree:
+%
+%     [g,a] = wfbt2filterbank({'db10',3,'full'});
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbt2filterbank.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<1)
+    error('%s: Not enough input arguments',upper(mfilename));
+end
+
+% build the tree
+wt = wfbtinit({'strict',wtdef},varargin{:});
+
+% Pick just nodes with outputs
+wtPath = 1:numel(wt.nodes);
+wtPath(noOfNodeOutputs(1:numel(wt.nodes),wt)==0)=[];
+
+
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+rangeOut = rangeInOutputs(wtPath,wt); 
+
+[g,a] = nodesMultid(wtPath,rangeLoc,rangeOut,wt);
+
+if nargout<2
+   % Scale filters if a is not returned
+   for nn=1:numel(g)
+       g{nn}.h = g{nn}.h/sqrt(a(nn));
+   end
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inst/wavelets/wfbtbounds.m b/inst/wavelets/wfbtbounds.m
new file mode 100644
index 0000000..8ed2fbe
--- /dev/null
+++ b/inst/wavelets/wfbtbounds.m
@@ -0,0 +1,71 @@
+function [AF,BF]=wfbtbounds(wt,L)
+%-*- texinfo -*-
+%@deftypefn {Function} wfbtbounds
+%@verbatim
+%WFBTBOUNDS Frame bounds of WFBT
+%   Usage: fcond=wfbtbounds(wt,L);
+%          [A,B]=wfbtbounds(wt,L);
+%
+%   WFBTBOUNDS(wt,L) calculates the ratio B/A of the frame bounds
+%   of the filterbank specified by wt for a system of length
+%   L. The ratio is a measure of the stability of the system. 
+%
+%   [A,B]=WFBTBOUNDS(wt,L) returns the lower and upper frame bounds
+%   explicitly. 
+%
+%   See WFBT for explanation of parameter wt.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtbounds.php}
+%@seealso{wfbt, filterbankbounds}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if nargin<2
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+wt = wfbtinit({'strict',wt},'nat');
+
+if L~=wfbtlength(L,wt)
+    error(['%s: Specified length L is incompatible with the length of ' ...
+           'the time shifts.'],upper(mfilename));
+end;
+
+
+for ii=1:numel(wt.nodes)
+   a = wt.nodes{ii}.a;
+   assert(all(a==a(1)),'%s: One of the basic wavelet filterbanks is not uniform.',upper(mfilename));
+end
+
+% Do the equivalent filterbank using multirate identity property
+[gmultid,amultid] = wfbt2filterbank(wt);
+
+% Check L
+%maxGlen = max(cellfun(@(gEl) numel(gEl.h),gmultid));
+%assert(L>=maxGlen,'%s: One of the filters is longer than L.',upper(mfilename));
+
+% Do the equivalent uniform filterbank
+[gu,au] = nonu2ufilterbank(gmultid,amultid);
+
+if nargout<2
+   AF = filterbankbounds(gu,au,L);
+elseif nargout == 2
+   [AF, BF] = filterbankbounds(gu,au,L);
+end
diff --git a/inst/wavelets/wfbtclength.m b/inst/wavelets/wfbtclength.m
new file mode 100644
index 0000000..e8dac10
--- /dev/null
+++ b/inst/wavelets/wfbtclength.m
@@ -0,0 +1,56 @@
+function [Lc,L]=wfbtclength(Ls,wt,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} wfbtclength
+%@verbatim
+%WFBTLENGTH  WFBT subband lengthf from a signal length
+%   Usage: L=wfbtlength(Ls,wt);
+%          L=wfbtlength(Ls,wt,...);
+%
+%   wfbtlength(Ls,wt) returns the length of a Wavelet system that is long
+%   enough to expand a signal of length Ls. Please see the help on
+%   WFBT for an explanation of the parameter wt.
+%
+%   If the returned length is longer than the signal length, the signal
+%   will be zero-padded by WFBT to length L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtclength.php}
+%@seealso{wfbt, fwt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+definput.import = {'fwt'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet filters structure
+wt = wfbtinit(wt);
+
+
+
+if(flags.do_per)
+   a = treeSub(wt);
+   L = filterbanklength(Ls,a);
+   Lc = L./a;
+else
+   L = Ls;
+   Lc = treeOutLen(L,0,wt);
+end
+
+
+
diff --git a/inst/wavelets/wfbtinit.m b/inst/wavelets/wfbtinit.m
new file mode 100644
index 0000000..2d9a4f3
--- /dev/null
+++ b/inst/wavelets/wfbtinit.m
@@ -0,0 +1,189 @@
+ function wt = wfbtinit(wtdef,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wfbtinit
+%@verbatim
+%WFBTINIT Initialize Filterbank Tree
+%   Usage:  wt = wfbtinit(wtdef);
+%
+%   Input parameters:
+%         wtdef : Filterbank tree definition.
+%
+%   Output parameters:
+%         wt    : Structure describing the filter tree.
+%
+%   WFBTINIT() creates empty structure. The structure describing the 
+%   tree has the following fields:
+%
+%     .nodes     Actual impulse responses
+%   
+%     .children  Indexes of children nodes
+% 
+%     .parents   Indexes of a parent node
+%
+%     .forder    Frequency ordering of the resultant frequency bands.
+%
+%   wfbt=WFBTINIT({w,J,flag}) creates a filterbank tree of depth J. The
+%   parameter w defines a basic wavelet filterbank. For all possible formats
+%   see FWT.  The following optional flags (still inside of the
+%   cell-array) are recognized:
+%
+%   'dwt','full'
+%     Type of the tree to be created.
+%
+%   Additional flags:
+%
+%   'freq','nat'
+%     Frequency or natural ordering of the coefficient subbands. The direct
+%     usage of the wavelet tree ('nat' option) does not produce coefficient
+%     subbans ordered according to the frequency. To achieve that, some 
+%     filter shuffling has to be done ('freq' option).  
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtinit.php}
+%@seealso{wfbtput, wfbtremove}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% TO DO: Do some caching
+
+% Output structure definition.
+% Effectively, it describes a ADT tree.
+% .nodes, .children, .parents ale all arrays of the same length and the j-th
+% node in the tree is desribed by wt.nodes{j}, wt.children{j} and
+% wt.parents(j). wt.nodes{j} is the actual data stored in the tree node 
+% (a structure returned form fwtinit) and wt.parents(j) and wt.children{j}
+% define relationship to other nodes. wt.parents(j) is an index of the
+% parent in the arrays. wt.children{j} is an array of indexes of the
+% children nodes.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+wt.nodes = {}; 
+wt.children = {};
+wt.parents = [];
+wt.freqOrder = 0;
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% return empty struct if no argument was passed
+if(nargin<1)
+    return;
+end
+
+
+do_strict = 0;
+do_dual = 0;
+
+% Check 'strict'
+if iscell(wtdef) && ischar(wtdef{1}) && strcmpi(wtdef{1},'strict')
+   do_strict = 1;
+   wtdef = wtdef{2:end};
+end
+% Check 'dual'
+if iscell(wtdef) && ischar(wtdef{1}) && strcmpi(wtdef{1},'dual')
+   do_dual = 1;
+   wtdef = wtdef{2:end};
+end
+
+definput.import = {'wfbtcommon'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% If wtdef is already a structure
+if (isstruct(wtdef)&&isfield(wtdef,'nodes'))
+    wt = wtdef;
+    
+    if do_dual || do_strict
+       nodesArg = wt.nodes;
+       if do_dual
+          nodesArg = cellfun(@(nEl) {'dual',nEl},nodesArg,'UniformOutput',0);
+       end
+       if do_strict
+          nodesArg = cellfun(@(nEl) {'strict',nEl},nodesArg,'UniformOutput',0);
+       end
+       wt.nodes = cellfun(@(nEl) fwtinit(nEl),nodesArg,'UniformOutput',0);
+       % Do the filter frequency shuffling again, since the filters were
+       % overwritten in fwtinit.
+       if wt.freqOrder
+          wt = nat2freqOrder(wt); 
+       end
+    end
+
+    % Do filter shuffling if flags.do_freq differs from the wt.freqOrder.
+    % Frequency and natural oreding coincide for DWT.
+    if wt.freqOrder ~= flags.do_freq
+       wt = nat2freqOrder(wt); 
+       wt.freqOrder = ~wt.freqOrder;
+    end
+    return;
+end
+
+% break if the input parameter is not in the correct format
+if ~(iscell(wtdef)) || isempty(wtdef)
+    error('%s: Unsupported filterbank tree definition.',upper(mfilename));
+end
+
+% Creating new tree
+% Now wtdef is this {w,J,flag}
+wdef = wtdef{1};
+definput = [];
+definput.flags.treetype = {'full','dwt','root'};
+definput.keyvals.J = [];
+[flags2,kv2,J]=ltfatarghelper({'J'},definput,wtdef(2:end));
+
+if do_dual
+   wdef = {'dual',wdef};
+end
+
+if do_strict
+   wdef = {'strict',wdef};
+end
+
+w = fwtinit(wdef);
+
+% Doing one-node tree
+if flags2.do_root
+   J = 1;
+end
+
+if isempty(J)
+   error('%s: Unspecified J.',upper(mfilename));
+end
+
+if flags2.do_dwt || J==1
+   % fill the structure to represent a DWT tree
+   for jj=0:J-1
+      wt = wfbtput(jj,0,w,wt);
+   end
+elseif flags2.do_full
+   % fill the structure to represent a full wavelet tree
+   for jj=0:J-1
+     % for ii=0:numel(w.g)^(jj)-1
+         wt = wfbtput(jj,0:numel(w.g)^(jj)-1,w,wt);
+     % end
+   end
+end
+
+% Do filter shuffling if frequency ordering is required,
+if flags.do_freq
+   wt = nat2freqOrder(wt); 
+   wt.freqOrder = 1;
+else
+   wt.freqOrder = 0;
+end
+
+
+
+
+
diff --git a/inst/wavelets/wfbtlength.m b/inst/wavelets/wfbtlength.m
new file mode 100644
index 0000000..35a2f05
--- /dev/null
+++ b/inst/wavelets/wfbtlength.m
@@ -0,0 +1,50 @@
+function L=wfbtlength(Ls,wt,varargin);
+%-*- texinfo -*-
+%@deftypefn {Function} wfbtlength
+%@verbatim
+%WFBTLENGTH  WFBT length from signal
+%   Usage: L=wfbtlength(Ls,wt);
+%          L=wfbtlength(Ls,wt,...);
+%
+%   WFBTLENGTH(Ls,wt) returns the length of a Wavelet system that is long
+%   enough to expand a signal of length Ls. Please see the help on
+%   WFBT for an explanation of the parameter wt.
+%
+%   If the returned length is longer than the signal length, the signal
+%   will be zero-padded by WFBT to length L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtlength.php}
+%@seealso{wfbt, fwt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+definput.import = {'fwt'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet filters structure
+wt = wfbtinit(wt);
+
+if(flags.do_per)
+   a = treeSub(wt);
+   L = filterbanklength(Ls,a);
+else
+   L = Ls;
+end
+
diff --git a/inst/wavelets/wfbtmanip/deleteNode.m b/inst/wavelets/wfbtmanip/deleteNode.m
new file mode 100644
index 0000000..ec18e14
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/deleteNode.m
@@ -0,0 +1,56 @@
+function wt = deleteNode(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} deleteNode
+%@verbatim
+%DELETENODE Removes specified node from the tree
+%   Usage:  wt = deleteNode(nodeNo,wt)
+%
+%   Input parameters:
+%         nodeNo   : Node index.
+%         wt       : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         wt       : Modified wt.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/deleteNode.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(~isempty(find(wt.children{nodeNo}~=0)))
+    error('Deleting non-leaf node!');
+end
+
+parId = wt.parents(nodeNo);
+toZero = find(wt.children{parId}==nodeNo);
+wt.children{parId}(toZero) = 0;
+
+newIdx = 1:length(wt.nodes);
+newIdx = newIdx(find(newIdx~=nodeNo));
+wt.nodes = wt.nodes(newIdx);
+%treeStruct.a = {treeStruct.a{newIdx}};
+%treeStruct.origins = {treeStruct.origins{newIdx}};
+wt.parents = wt.parents(newIdx); 
+wt.children = wt.children(newIdx);
+
+% and all children and parents with higher idx are lessened
+ for ii =1:length(wt.children)
+     biggerIdx = find(wt.children{ii}>nodeNo);
+     wt.children{ii}(biggerIdx) = wt.children{ii}(biggerIdx)-1;
+ end
+ biggerIdx = find(wt.parents>nodeNo);
+ wt.parents(biggerIdx) = wt.parents(biggerIdx)-1;
diff --git a/inst/wavelets/wfbtmanip/deleteSubtree.m b/inst/wavelets/wfbtmanip/deleteSubtree.m
new file mode 100644
index 0000000..d7814a2
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/deleteSubtree.m
@@ -0,0 +1,41 @@
+function wt = deleteSubtree(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} deleteSubtree
+%@verbatim
+%DELETESUBTREE Removes subtree with root node
+%   Usage:  wt = deleteSubtree(nodeNo,wt)
+%
+%   Input parameters:
+%         nodeNo   : Node index.
+%         wt       : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         wt       : Modified wt.
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/deleteSubtree.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+toDelete = nodeSubtreeBF(nodeNo,wt);
+
+for ii = length(toDelete):-1:1
+  wt = deleteNode(toDelete(ii),wt); 
+  biggerIdx = find(toDelete>toDelete(ii));
+  toDelete(biggerIdx) = toDelete(biggerIdx) - 1;
+end
+wt = deleteNode(nodeNo,wt); 
diff --git a/inst/wavelets/wfbtmanip/depthIndex2NodeNo.m b/inst/wavelets/wfbtmanip/depthIndex2NodeNo.m
new file mode 100644
index 0000000..2c51ad9
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/depthIndex2NodeNo.m
@@ -0,0 +1,122 @@
+function [nodeNo,nodeChildIdx] = depthIndex2NodeNo(d,k,wt)
+
+if(d==0)
+    nodeNo=0;
+    nodeChildIdx=0;
+    return;
+end
+
+%-*- texinfo -*-
+%@deftypefn {Function} depthIndex2NodeNo
+%@verbatim
+% find ordered nodes at depth d-1
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/depthIndex2NodeNo.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+nodesNo = getNodesInDepth(d,wt);
+if(isempty(nodesNo))
+   error('%s: Depth of the tree is less than given d.',mfilename); 
+end
+
+% k is index in children of ordered nodes at depth d
+
+nodeNo = zeros(numel(k),1);
+nodeChildIdx = zeros(numel(k),1);
+chNo = cumsum(cellfun( @(nEl) length(nEl.g),wt.nodes(nodesNo)));
+chNoZ = [0;chNo(:)];
+
+for kIdx=1:numel(k)
+    ktmp = k(kIdx);
+    idx = find(chNo>ktmp,1);
+    if isempty(idx)
+       error('%s: Index k=%i out of bounds.',mfilename,ktmp); 
+    end    
+    nodeNo(kIdx) = nodesNo(idx);
+    nodeChildIdx(kIdx) = ktmp-chNoZ(idx)+1;
+end
+
+% ktemp = k;
+% chNo = cellfun( @(nEl) numel(nEl.g),wt.nodes(nodesNo));
+% for ii=1:length(nodesNo)
+%     if(ktemp<chNo(ii))
+%         nodeChildIdx = ktemp+1;
+%         nodeNo = nodesNo(ii);
+%         if mynodeNo~=nodeNo || mynodeChildIdx ~= nodeChildIdx
+%             error('mas to tu spatne');
+%         end
+%         return;
+%     else
+%         ktemp = ktemp-chNo(ii);
+%     end
+% end
+% error('%s: Index k out of bounds.',mfilename);
+
+
+
+
+function nodd = getNodesInDepth(d,wt)
+% find all nodes with d steps to the root ordered
+if d==1
+    % return root
+    nodd = find(wt.parents==0);
+    return;
+end    
+
+nbf = nodesBForder(wt);
+nbfTmp = nbf;
+tempd = 0;
+while tempd<d
+    nbf(nbfTmp==0) = [];
+    nbfTmp(nbfTmp==0) = [];
+    nbfTmp = wt.parents(nbfTmp);
+    tempd = tempd+1;
+end
+nodd = nbf(nbfTmp==0);
+
+% 
+% nbfPar = wt.parents(nbf);
+% 
+% for ii=1:numel(nbf)
+%    
+% end
+
+% nodd = [];
+% toGoTrough = {};
+% 
+% 
+%    nodeNo = find(wt.parents==0);
+%    toGoTrough = cell(d+1,1);
+%    toGoTrough{1} = nodeNo;
+%    tempd = 1;
+% 
+% 
+% while(tempd<d)
+%     
+%     for jj=1:length(toGoTrough{tempd})
+%        actNod = toGoTrough{tempd}(jj);
+%        childrenIdx = find(wt.children{actNod}~=0);
+%        ch = wt.children{actNod}(childrenIdx);
+%        toGoTrough{tempd+1} = [toGoTrough{tempd+1},ch];
+%     end
+% 
+%     tempd = tempd+1;
+% end
+% 
+% nodd=toGoTrough{d};
+
diff --git a/inst/wavelets/wfbtmanip/maxTreeSub.m b/inst/wavelets/wfbtmanip/maxTreeSub.m
new file mode 100644
index 0000000..a6e3c5d
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/maxTreeSub.m
@@ -0,0 +1,39 @@
+function a = maxTreeSub(wt)
+%-*- texinfo -*-
+%@deftypefn {Function} maxTreeSub
+%@verbatim
+%MAXTREESUB
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/maxTreeSub.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% All nodes with at least one final output.
+termN = find(noOfNodeOutputs(1:numel(wt.nodes),wt)~=0);
+% Range in filter outputs
+outRangeTermN = rangeInLocalOutputs(termN,wt);
+
+% Subsampling factors of the terminal nodes
+subTermN = nodeSub(termN,wt);
+
+a = [];
+for ii=1:numel(termN)
+   a = [a; subTermN{ii}(outRangeTermN{ii})];
+end
+
+a = max(a);
diff --git a/inst/wavelets/wfbtmanip/nat2freqOrder.m b/inst/wavelets/wfbtmanip/nat2freqOrder.m
new file mode 100644
index 0000000..7a21844
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nat2freqOrder.m
@@ -0,0 +1,66 @@
+function wt = nat2freqOrder(wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nat2freqOrder
+%@verbatim
+%NAT2FREQORDER Natural To Frequency Ordering
+%   Usage:  wt = nat2freqOrder(wt);
+%
+%   Input parameters:
+%         wt    : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         wt    : Structure containing description of the filter tree.
+%
+%   NAT2FREQORDER(wt) Creates new wavelet filterbank tree definition
+%   with permuted order of some filters for purposes of the correct frequency
+%   ordering of the resultant identical filters. For definition of the
+%   structure see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nat2freqOrder.php}
+%@seealso{wfbtinit, wfbtmultid, nodesbforder}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+treePath = nodesBForder(wt);
+%skip root
+treePath = treePath(2:end);
+
+for ii=1:length(treePath)
+    % should not be zero
+    nodeId = treePath(ii);
+    parentId = wt.parents(nodeId);
+    % local index of the parent output connected to the treePath(ii) node,
+    % is in range 1:chan
+    locIdx = find(wt.children{parentId}==nodeId,1);
+    
+    % do nothing if the node is connected to the first (hopefully lowpass)
+    % output
+    if(rem(locIdx,2)~=1)
+       % now for the filter reordering
+       chan = numel(wt.nodes{nodeId}.g);
+       wt.nodes{nodeId}.g = wt.nodes{nodeId}.g(chan:-1:1);
+       wt.nodes{nodeId}.h = wt.nodes{nodeId}.h(chan:-1:1);
+       wt.nodes{nodeId}.a = wt.nodes{nodeId}.a(chan:-1:1);
+    end    
+    
+end
+
+
+
diff --git a/inst/wavelets/wfbtmanip/noOfChildOutputs.m b/inst/wavelets/wfbtmanip/noOfChildOutputs.m
new file mode 100644
index 0000000..ed6ae47
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/noOfChildOutputs.m
@@ -0,0 +1,36 @@
+function noOut = noOfChildOutputs(nodeNo,wt)
+
+
+noOut = 0;
+childrenIdx = find(wt.children{nodeNo}~=0);
+children = wt.children{nodeNo}(childrenIdx);
+for nn=1:length(children)
+   chNodeNo = children(nn);
+   chan = numel(wt.nodes{chNodeNo}.g); 
+   child = numel(find(wt.children{chNodeNo}~=0));
+   noOut = noOut + chan - child;
+   noOut = noOut + noOfChildOutputs(chNodeNo,wt);
+end
+%-*- texinfo -*-
+%@deftypefn {Function} noOfChildOutputs
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/noOfChildOutputs.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+end
diff --git a/inst/wavelets/wfbtmanip/noOfNodeOutputs.m b/inst/wavelets/wfbtmanip/noOfNodeOutputs.m
new file mode 100644
index 0000000..51baede
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/noOfNodeOutputs.m
@@ -0,0 +1,61 @@
+function noOut = noOfNodeOutputs(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} noOfNodeOutputs
+%@verbatim
+%NOOFNODEOUTPUTS Number of node Outputs
+%   Usage:  noOut = noOfNodeOutputs(nodeNo,wt);
+%
+%   Input parameters:
+%         nodeNo  : Node index.
+%         wt      : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         noOut      : Number of node outputs. 
+%
+%   NOOFNODEOUTPUTS(nodeNo,wt) Return number of the terminal 
+%   outputs of the node nodeNo. For definition of the structure
+%   see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/noOfNodeOutputs.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(any(nodeNo>numel(wt.nodes)))
+   error('%s: Invalid node index range. Number of nodes is %d.\n',upper(mfilename),numel(wt.nodes));
+end
+
+%This is slow..
+noOut = cellfun(@(nEl) numel(nEl.g), wt.nodes(nodeNo)) -...
+        cellfun(@(chEl) numel(chEl(chEl~=0)), wt.children(nodeNo));
+
+%This is even slower
+% nodesCount = numel(nodeNo);
+% noOut = zeros(nodesCount,1);
+% for ii = 1:nodesCount
+%    noOut(ii) = numel(wt.nodes{ii}.filts) - numel(find(wt.children{ii}~=0));
+% end
+
+%  chan = max([length(wt.nodes{nodeNo}.g), length(wt.nodes{nodeNo}.h)]);
+%  child = length(find(wt.children{nodeNo}~=0));
+%  noOut = chan -child;
+
+
+
diff --git a/inst/wavelets/wfbtmanip/noOfOutputs.m b/inst/wavelets/wfbtmanip/noOfOutputs.m
new file mode 100644
index 0000000..714137c
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/noOfOutputs.m
@@ -0,0 +1,49 @@
+function noOut = noOfOutputs(wt)
+%-*- texinfo -*-
+%@deftypefn {Function} noOfOutputs
+%@verbatim
+%NOOFOUTPUTS Returns number of outputs of the filter tree 
+%   Usage:  noOut=noOfOutputs(treeStruct)
+%
+%   Input parameters:
+%         wt  : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         noOut       : Number of outputs of the whole filter tree.
+%
+%   NOOFOUTPUTS(wt) For definition of the structure see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/noOfOutputs.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+noOut = sum(noOfNodeOutputs(1:numel(wt.nodes),wt));
+
+%noOut = sum( cellfun(@(nEl) numel(nEl.filts),wt.nodes) -...
+%        cellfun(@(chEl) numel(chEl(chEl~=0)), wt.children) );
+
+% Equivalent:     
+% noOut = 0;
+% for jj =1:length(wt.nodes)
+%     chan = max([length(wt.nodes{jj}.filts), length(wt.nodes{jj}.h)]);
+%     children = length(find(wt.children{jj}~=0));
+%     noOut = noOut + chan-children;
+% end
diff --git a/inst/wavelets/wfbtmanip/noOfSubtreeOutputs.m b/inst/wavelets/wfbtmanip/noOfSubtreeOutputs.m
new file mode 100644
index 0000000..33e24fd
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/noOfSubtreeOutputs.m
@@ -0,0 +1,29 @@
+function noOut = noOfSubtreeOutputs(nodeNo,wt)
+
+noChildOut = noOfChildOutputs(nodeNo,wt);
+chan = numel(wt.nodes{nodeNo}.g);
+child = length(find(wt.children{nodeNo}~=0));
+noOut = chan -child + noChildOut;
+%-*- texinfo -*-
+%@deftypefn {Function} noOfSubtreeOutputs
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/noOfSubtreeOutputs.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+noOut = chan -child + noChildOut;
diff --git a/inst/wavelets/wfbtmanip/nodeFiltUps.m b/inst/wavelets/wfbtmanip/nodeFiltUps.m
new file mode 100644
index 0000000..e73b2d8
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodeFiltUps.m
@@ -0,0 +1,54 @@
+function upsNo = nodeFiltUps(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nodeFiltUps
+%@verbatim
+%NODEFILTUPS  Node upsamplig factor
+%   Usage:  upsNo = nodeFiltUps(nodeNo,wt)
+%
+%   Input parameters:
+%         wt  : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         upsNo : Accumulated upsampling factor along path to root.
+%
+%   NODEFILTUPS(wt) Returns upsampling factor, which can be used to
+%   upsample the node filters using the a-trous algorithm.
+%   For definition of the structure see WFBINIT.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodeFiltUps.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(any(nodeNo>numel(wt.nodes)))
+   error('%s: Invalid node index range. Number of nodes is %d.\n',upper(mfilename),numel(wt.nodes));
+end
+
+nodesCount = numel(nodeNo);
+upsNo = zeros(nodesCount,1);
+for ii=1:nodesCount
+   tmpNodeNo = nodeNo(ii);
+   upsNo(ii) = 1;
+   while(wt.parents(tmpNodeNo))
+       parentNo = wt.parents(tmpNodeNo);
+       upsNo(ii)=upsNo(ii)*wt.nodes{parentNo}.a(wt.children{parentNo}==tmpNodeNo);
+       tmpNodeNo=parentNo;
+   end
+end
diff --git a/inst/wavelets/wfbtmanip/nodeInLen.m b/inst/wavelets/wfbtmanip/nodeInLen.m
new file mode 100644
index 0000000..9760c6f
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodeInLen.m
@@ -0,0 +1,71 @@
+function L = nodeInLen(nodeNo,inLen,doNoExt,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nodeInLen
+%@verbatim
+%NODEINLEN Length of the node input signal
+%   Usage:  L = nodeInLen(nodeNo,inLen,doExt,treeStruct);
+%
+%   Input parameters:
+%         nodeNo     : Node index.
+%         inLen      : Filter thee input signal length.
+%         doNoExt    : Expansive representation indicator.
+%         wt         : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         Lin        : Length of the node input signal 
+%
+%   NODEINLEN(nodeNo,inLen,doExt,treeStruct) return length of the input
+%   signal of the node nodeNo. For definition of the structure see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodeInLen.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+L = zeros(numel(nodeNo),1);
+for nn=1:length(nodeNo)
+    subPat = [];
+    filtLenPat = [];
+    tmpNodeNo = nodeNo(nn);
+
+    while(wt.parents(tmpNodeNo))
+       parentNo = wt.parents(tmpNodeNo);
+       tmpIdx = find(wt.children{parentNo}==tmpNodeNo);
+       subPat(end+1) = wt.nodes{parentNo}.a(tmpIdx);
+       filtLenPat(end+1) = length(wt.nodes{parentNo}.g{tmpIdx}.h);
+       tmpNodeNo=parentNo;
+    end
+
+    subPat = subPat(end:-1:1);
+    filtLenPat = filtLenPat(end:-1:1);
+
+    L(nn) = inLen;
+    if(~doNoExt)
+        for ii=1:length(subPat)
+            L(nn) = floor((L(nn)+filtLenPat(ii)-1)/subPat(ii));
+        end
+    else
+        for ii=1:length(subPat)
+            L(nn) = ceil(L(nn)/subPat(ii)); 
+        end
+    end
+end
+
+
diff --git a/inst/wavelets/wfbtmanip/nodeOutLen.m b/inst/wavelets/wfbtmanip/nodeOutLen.m
new file mode 100644
index 0000000..a32a27c
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodeOutLen.m
@@ -0,0 +1,70 @@
+function Lc = nodeOutLen(nodeNo,L,outRange,doNoExt,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nodeOutLen
+%@verbatim
+%NODEINLEN Length of the node output
+%   Usage:  Lc = nodeInLen(nodeNo,inLen,doExt,wt);
+%
+%   Input parameters:
+%         nodeNo     : Node index(es).
+%         inLen      : Filter thee input signal length.
+%         outRange   : Cell array. Each element is a vector of local out.
+%         indexes.
+%         doNoExt    : Expansive representation indicator.
+%         wt         : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         Lin        : Length of the node input signal 
+%
+%   nodeInLen(nodeNo,inLen,doExt,treeStruct) return length of the input
+%   signal of the node nodeNo. For definition of the structure see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodeOutLen.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+if isempty(outRange)
+    outRange = cellfun(@(nEl) 1:numel(nEl.g),wt.nodes(nodeNo),'UniformOutput',0);
+end
+
+Lc = zeros(sum(cellfun(@numel,outRange)),1);
+
+inLens = nodeInLen(nodeNo,L,doNoExt,wt);
+
+Lcidx = 1;
+for ii=1:numel(inLens)
+    nodeHlen = cellfun(@(nEl) numel(nEl.h),...
+               wt.nodes{nodeNo(ii)}.g(outRange{ii}));
+    nodea =  wt.nodes{nodeNo(ii)}.a(outRange{ii});
+    
+    if(~doNoExt)
+       Lc(Lcidx:Lcidx+numel(nodeHlen)-1) = floor((inLens(ii)...
+                                            +nodeHlen(:)-1)./nodea(:));
+    else
+       Lc(Lcidx:Lcidx+numel(nodeHlen)-1) = ceil(inLens(ii)./nodea(:)); 
+    end
+    Lcidx = Lcidx + numel(nodeHlen);
+end
+
+
+
+
+
+
diff --git a/inst/wavelets/wfbtmanip/nodePredecesors.m b/inst/wavelets/wfbtmanip/nodePredecesors.m
new file mode 100644
index 0000000..0a8c5a5
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodePredecesors.m
@@ -0,0 +1,30 @@
+function pred = nodePredecesors(nodeNo,treeStruct)
+pred = [];
+tmpNodeNo = nodeNo;
+while treeStruct.parents(tmpNodeNo)~=0
+   tmpNodeNo = treeStruct.parents(tmpNodeNo);
+   pred(end+1) = tmpNodeNo;
+end
+%-*- texinfo -*-
+%@deftypefn {Function} nodePredecesors
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodePredecesors.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+end
diff --git a/inst/wavelets/wfbtmanip/nodeSub.m b/inst/wavelets/wfbtmanip/nodeSub.m
new file mode 100644
index 0000000..488c372
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodeSub.m
@@ -0,0 +1,44 @@
+function subNo = nodeSub(nodeNo,wt)
+
+
+if(any(nodeNo>numel(wt.nodes)))
+   error('%s: Invalid node index range. Number of nodes is %d.\n',upper(mfilename),numel(wt.nodes));
+end
+
+nodeNoa = cellfun(@(nEl) nEl.a,wt.nodes(nodeNo),'UniformOutput',0);
+nodeNoUps = nodeFiltUps(nodeNo,wt);
+
+nodesCount = numel(nodeNo);
+subNo = cell(1,nodesCount);
+for ii=1:nodesCount
+   subNo{ii} = nodeNoUps(ii)*nodeNoa{ii};
+end
+
+%-*- texinfo -*-
+%@deftypefn {Function} nodeSub
+%@verbatim
+% if(nodesCount==1)
+%    subNo = subNo{1};
+% end
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodeSub.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%subNo = nodeFiltUps(nodeNo,wt).*wt.nodes{nodeNo}.a;
diff --git a/inst/wavelets/wfbtmanip/nodeSubtreeBF.m b/inst/wavelets/wfbtmanip/nodeSubtreeBF.m
new file mode 100644
index 0000000..ba50813
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodeSubtreeBF.m
@@ -0,0 +1,52 @@
+function nodesIdxs = nodeSubtreeBF(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nodeSubtreeBF
+%@verbatim
+%NODESUBTREEBF Node subtree nodes in Breath-First order
+%   Usage:  noOut = nodeSubtreeBF(nodeNo,wt);
+%
+%   Input parameters:
+%         nodeNo  : Node index.
+%         wt      : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         noOut   : Nodes in a Breath-First order. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodeSubtreeBF.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% subtreeIdx = [];
+% 
+% children = treeStruct.children{nodeNo}(find(treeStruct.children{nodeNo}~=0));
+% subtreeIdx(end+1:end+length(children)) = children;
+% 
+% for ii=1:length(children)
+%    tmpSbIdx = nodeSubtreeBF(children(ii),treeStruct);
+%    subtreeIdx(end+1:end+length(tmpSbIdx)) = tmpSbIdx;
+% end
+
+toGoTrough = [nodeNo];
+nodesIdxs = [];
+while ~isempty(toGoTrough)
+  % chtmp = find(wt.children{toGoTrough(1)}~=0);
+   chIdxtmp = wt.children{toGoTrough(1)}(wt.children{toGoTrough(1)}~=0);
+   nodesIdxs = [nodesIdxs,chIdxtmp];
+   toGoTrough = [toGoTrough(2:end),chIdxtmp];
+end
diff --git a/inst/wavelets/wfbtmanip/nodeSubtreeDF.m b/inst/wavelets/wfbtmanip/nodeSubtreeDF.m
new file mode 100644
index 0000000..4ad076b
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodeSubtreeDF.m
@@ -0,0 +1,57 @@
+function nodesIdxs = nodeSubtreeDF(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nodeSubtreeDF
+%@verbatim
+%NODESUBTREEBF Node subtree nodes in Depth-First order
+%   Usage:  noOut = nodeSubtreeDF(nodeNo,wt);
+%
+%   Input parameters:
+%         nodeNo  : Node index.
+%         wt      : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         noOut   : Nodes in a Depth-First order. 
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodeSubtreeDF.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+% subtreeIdx = [];
+% 
+% children = treeStruct.children{nodeNo}(find(treeStruct.children{nodeNo}~=0));
+% subtreeIdx(end+1:end+length(children)) = children;
+% 
+% for ii=1:length(children)
+%    tmpSbIdx = nodeSubtreeBF(children(ii),treeStruct);
+%    subtreeIdx(end+1:end+length(tmpSbIdx)) = tmpSbIdx;
+% end
+
+toGoTrough = nodeNo;
+nodesIdxs = [];
+while ~isempty(toGoTrough)
+   chtmp = find(wt.children{toGoTrough(1)}~=0);
+   chIdxtmp = wt.children{toGoTrough(1)}(chtmp);
+   nodesIdxs = [nodesIdxs,toGoTrough(1)];
+   toGoTrough = [chIdxtmp,toGoTrough(2:end)];
+end
+
+% remove the nodeNo. Just to be consistent with nodeSubtreeBF
+% TO DO: is it wise?
+nodesIdxs = nodesIdxs(2:end);
diff --git a/inst/wavelets/wfbtmanip/nodesBForder.m b/inst/wavelets/wfbtmanip/nodesBForder.m
new file mode 100644
index 0000000..a519f54
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodesBForder.m
@@ -0,0 +1,53 @@
+function nodesIdxs = nodesBForder(wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} nodesBForder
+%@verbatim
+%NODESBFORDER Nodes in the Breadth-First search order
+%  Usage:  nodesIdxs = nodesBForder(treeStruct,order)
+%
+%   Input parameters:
+%         treeStruct  : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         nodesIdxs   : Node indexes in the Breadth-First search order.
+%
+%   NODESBFORDER(treeStruct) For definition of the structure see
+%   wfbinit.
+%
+%   Supported flags:
+%
+%             'ord','rev'
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodesBForder.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%find root
+nodeNo = find(wt.parents==0);
+nodesIdxs = [nodeNo,nodeSubtreeBF(nodeNo,wt)];
+
+if(~isempty(varargin))
+    if(strcmpi(varargin{1},'rev'))
+       nodesIdxs = nodesIdxs(end:-1:1); 
+    end
+end
+
diff --git a/inst/wavelets/wfbtmanip/nodesDForder.m b/inst/wavelets/wfbtmanip/nodesDForder.m
new file mode 100644
index 0000000..bbc5113
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodesDForder.m
@@ -0,0 +1,53 @@
+function nodesIdxs = nodesDForder(wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} nodesDForder
+%@verbatim
+%NODESBFORDER Nodes in the Breadth-First search order
+%  Usage:  nodesIdxs = nodesBForder(treeStruct)
+%
+%   Input parameters:
+%         treeStruct  : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         nodesIdxs   : Node indexes in the Breadth-First search order.
+%
+%   nodesBForder(treeStruct) For definition of the structure see
+%   wfbinit.
+%
+%   Supported flags:
+%
+%             'ord','rev'
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodesDForder.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%find root
+nodeNo = find(wt.parents==0);
+nodesIdxs = [nodeNo,nodeSubtreeDF(nodeNo,wt)];
+
+
+if(~isempty(varargin))
+    if(strcmpi(varargin{1},'rev'))
+       nodesIdxs = nodesIdxs(end:-1:1); 
+    end
+end
diff --git a/inst/wavelets/wfbtmanip/nodesLevelsBForder.m b/inst/wavelets/wfbtmanip/nodesLevelsBForder.m
new file mode 100644
index 0000000..5a0fbd5
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodesLevelsBForder.m
@@ -0,0 +1,72 @@
+function nodesIdxs = nodesLevelsBForder(treeStruct)
+%-*- texinfo -*-
+%@deftypefn {Function} nodesLevelsBForder
+%@verbatim
+%NODESBFORDER Nodes in the Breadth-First search order
+%  Usage:  nodesIdxs = nodesBForder(treeStruct)
+%
+%   Input parameters:
+%         treeStruct  : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         nodesIdxs   : Node indexes in the Breadth-First search order.
+%
+%   nodesBForder(treeStruct) For definition of the structure see
+%   wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodesLevelsBForder.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+%find root
+nodeNo = find(treeStruct.parents==0);
+toGoTrough = [nodeNo];
+nodesIdxs = {nodeNo};
+inLevel = [1];
+counter = 0;
+level = 2;
+chIdxSum = 0;
+while ~isempty(toGoTrough)
+   chtmp = find(treeStruct.children{toGoTrough(1)}~=0);
+   chIdxtmp = treeStruct.children{toGoTrough(1)}(chtmp);
+   counter = counter + 1;
+
+   if(length(nodesIdxs)<level&&~isempty(chIdxtmp))
+       nodesIdxs = {nodesIdxs{:},[]}; 
+   end
+   
+   chIdxSum = chIdxSum + length(chIdxtmp);
+   if(~isempty(chIdxtmp))
+       nodesIdxs{level} = [nodesIdxs{level},chIdxtmp];
+   end
+   
+   toGoTrough = [toGoTrough(2:end),chIdxtmp];
+
+   if(counter==inLevel(level-1))
+       counter = 0;
+       inLevel(level) = chIdxSum;
+       level = level + 1;
+       chIdxSum = 0;
+   end
+end
+
+
diff --git a/inst/wavelets/wfbtmanip/nodesMultid.m b/inst/wavelets/wfbtmanip/nodesMultid.m
new file mode 100644
index 0000000..bfa85e0
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/nodesMultid.m
@@ -0,0 +1,122 @@
+function [g,a] = nodesMultid(wtPath,rangeLoc,rangeOut,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} nodesMultid
+%@verbatim
+%NODESMULTID Filter tree multirate identity filterbank
+%   Usage:  [g,a]=nodesMultid(wtPath,rangeLoc,rangeOut,wt);
+%
+%   Input parameters:
+%         wtPath   : Indexes of nodes to be processed in that order.
+%         rangeLoc : Idxs of each node terminal outputs. Length  
+%                    cell array of vectors.
+%         rangeOut : Output subband idxs of each node terminal outputs.
+%         wt       : Filter-Tree defining structure.
+%
+%   Output parameters:
+%         g   : Cell array containing filters
+%         a   : Vector of subsampling factors
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/nodesMultid.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%clean cache
+nodePredecesorsMultId();
+
+
+% number of outputs of the tree
+treeOutputs = sum(cellfun(@(rEl) numel(rEl),rangeOut));
+
+g = cell(treeOutputs,1);
+a = zeros(treeOutputs,1);
+
+for ii = 1:numel(wtPath)
+   iiNode = wtPath(ii);
+   hmi = nodePredecesorsMultId(iiNode,wt);
+   locRange = rangeLoc{ii};
+   outRange = rangeOut{ii};
+   for jj = 1:length(locRange)
+      tmpUpsFac = nodeFiltUps(iiNode,wt);
+      tmpFilt = wt.nodes{iiNode}.g{locRange(jj)};
+      g{outRange(jj)} = struct();
+                % 
+      g{outRange(jj)}.h = conj(flipud(conv2(hmi,comp_ups(tmpFilt.h(:),tmpUpsFac,1))));
+      g{outRange(jj)}.offset = 1-numel(g{outRange(jj)}.h)+nodePredecesorsOrig(-tmpFilt.offset,iiNode,wt);
+   end
+   atmp = nodeSub(iiNode,wt);
+   a(outRange) = atmp{1}(locRange);
+end
+        
+        
+% clean the cache
+nodePredecesorsMultId();
+
+
+function hmi = nodePredecesorsMultId(nodeNo,treeStruct)
+% Build multirate identity of nodes preceeding nodeNo
+% chache of the intermediate multirate identities
+persistent multIdPre;
+% if no paramerer passed, clear the cache
+if(nargin==0),  multIdPre = {}; return; end
+% in case nodePredecesorsMultId with nodeNo was called before
+
+% if(~isempty(multIdPre))
+%   if(length(multIdPre)>=nodeNo&&~isempty(multIdPre{pre(jj)}))
+%     hmi = multIdPre{nodeNo};
+%   end
+% end
+
+startIdx = 1;
+hmi = [1];
+pre = nodePredecesors(nodeNo,treeStruct);
+pre = [nodeNo,pre];
+for jj = 1:length(pre)
+  if(~isempty(multIdPre))
+     if(length(multIdPre)>=pre(jj)&&~isempty(multIdPre{pre(jj)}))
+       hmi = multIdPre{pre(jj)};
+       startIdx = length(pre)+1 -jj;
+       break;
+     end
+  end
+end
+
+pre = pre(end:-1:1);
+
+for ii=startIdx:length(pre)-1
+    id = pre(ii);
+    hcurr = treeStruct.nodes{id}.g{treeStruct.children{id}==pre(ii+1)}.h(:);
+    hcurr = comp_ups(hcurr,nodeFiltUps(id,treeStruct),1);
+    hmi = conv2(hmi,hcurr);
+end
+
+function predori = nodePredecesorsOrig(baseOrig,nodeNo,treeStruct)
+pre = nodePredecesors(nodeNo,treeStruct);
+pre = pre(end:-1:1);
+if(isempty(pre))
+ predori = baseOrig;
+ return;
+end
+
+pre(end+1) = nodeNo;
+predori = baseOrig;
+for ii=2:length(pre)
+    id = pre(ii);
+    predori = nodeFiltUps(id,treeStruct)*baseOrig + predori;
+end
+
+
diff --git a/inst/wavelets/wfbtmanip/rangeInLocalOutputs.m b/inst/wavelets/wfbtmanip/rangeInLocalOutputs.m
new file mode 100644
index 0000000..32e21cf
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/rangeInLocalOutputs.m
@@ -0,0 +1,85 @@
+function outRange = rangeInLocalOutputs(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} rangeInLocalOutputs
+%@verbatim
+%RANGEINLOCALOUTPUTS Node output index range of the terminal outputs
+%   Usage:  outRange = rangeInLocalOutputs(nodeNo,wt);
+%
+%   Input parameters:
+%         nodeNo     : Node index.
+%         wt : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         noOut      : Index range. 
+%
+%   RANGEINLOCALOUTPUTS(nodeNo,wt) Return range of indexes of the
+%   terminal outputs of the node nodeNo. For definition of the structure
+%   see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/rangeInLocalOutputs.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(any(nodeNo>numel(wt.nodes)))
+   error('%s: Invalid node index range. Number of nodes is %d.\n',upper(mfilename),numel(wt.nodes));
+end
+
+
+nodesCount = length(nodeNo);
+outRange = cell(nodesCount,1); 
+
+
+nodeChans = cellfun(@(nEl) numel(nEl.g), wt.nodes(nodeNo));
+chIdx = cellfun(@(chEl) find(chEl~=0), wt.children(nodeNo),'UniformOutput',0);
+
+
+for ii = 1:nodesCount
+ outRangeTmp = 1:nodeChans(ii);
+ outRangeTmp(chIdx{ii}) = [];
+ outRange{ii} = outRangeTmp;
+% outRange{ii} = setdiff(1:nodeChans(ii),chIdx{ii}); 
+
+%    outNodes = zeros(nodeChans(ii),1);
+%    outNodes(chIdx{ii}) = 1;
+%    zeroIdx = find(outNodes==0);
+%    if(~isempty(zeroIdx))
+%       outRange{ii} = zeroIdx;
+%    end
+end
+
+% if(numel(outRange)==1)
+%    outRange = outRange{1};
+% end
+
+
+% for ii = 1:nodesCount
+%    chIdx = find(wt.children{nodeNo(ii)}~=0);
+%    chan = max([length(wt.nodes{nodeNo(ii)}.g), length(wt.nodes{nodeNo(ii)}.h)]);
+%    outNodes = zeros(chan,1);
+%    outNodes(chIdx) = wt.children{nodeNo(ii)}(chIdx);
+%    if(iscell(outRange))
+%       outRange{ii} = find(outNodes==0);
+%    else
+%       outRange = find(outNodes==0);
+%    end
+% end
+
+
diff --git a/inst/wavelets/wfbtmanip/rangeInNodeOutputs.m b/inst/wavelets/wfbtmanip/rangeInNodeOutputs.m
new file mode 100644
index 0000000..6e67422
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/rangeInNodeOutputs.m
@@ -0,0 +1,53 @@
+function outRange = rangeInNodeOutputs(nodeNo,treeStruct)
+%-*- texinfo -*-
+%@deftypefn {Function} rangeInNodeOutputs
+%@verbatim
+%RANGEINNODEOUTPUTS Index range of the node outputs
+%   Usage:  outRange = rangeInNodeOutputs(nodeNo,treeStruct)
+%
+%   Input parameters:
+%         nodeNo     : Node index.
+%         treeStruct : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         outRange   : Index range. 
+%
+%   RANGEINNODEOUTPUTS(nodeNo,treeStruct) For definition of the structure
+%   see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/rangeInNodeOutputs.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+chIdx = find(treeStruct.children{nodeNo}~=0);
+chan = numel(treeStruct.nodes{nodeNo}.g);
+outNodes = zeros(chan,1);
+outNodes(chIdx) = treeStruct.children{nodeNo}(chIdx);
+
+outRangeStart = 0;
+outRange = [];
+for ii=1:chan
+   if(outNodes(ii)==0)
+       outRange(end+1) = outRangeStart+1;
+       outRangeStart = outRangeStart+1;
+   else
+      outRangeStart=outRangeStart + noOfSubtreeOutputs(outNodes(ii),treeStruct);
+   end
+end
diff --git a/inst/wavelets/wfbtmanip/rangeInOutputs.m b/inst/wavelets/wfbtmanip/rangeInOutputs.m
new file mode 100644
index 0000000..fd97e44
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/rangeInOutputs.m
@@ -0,0 +1,102 @@
+function outRange = rangeInOutputs(nodeNo,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} rangeInOutputs
+%@verbatim
+%RANGEINOUTPUTS Index range of the outputs
+%   Usage:  outRange = rangeInOutputs(nodeNo,treeStruct);
+%
+%   Input parameters:
+%         nodeNo     : Node index.
+%         wt         : Structure containing description of the filter tree.
+%
+%   Output parameters:
+%         outRange   : Subband idx range.
+%
+%   RANGEINOUTPUTS(nodeNo,wt) Returns index range in the global
+%   tree subbands associated with node nodeNo. Empty matrix is returned if
+%   node has all outputs connected do children nodes. For definition of the
+%   structure see wfbinit.
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/rangeInOutputs.php}
+%@seealso{wfbtinit}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+nodesBFo = nodesBForder(wt,'rev');
+nOuts = noOfNodeOutputs(nodesBFo,wt);
+nSubtOut = zeros(numel(nodesBFo),1);
+for ii=1:numel(nodesBFo)
+   childTmp = wt.children{nodesBFo(ii)};
+   childTmp(childTmp==0)=[];
+   nSubtOut(nodesBFo(ii)) = nOuts(ii) + sum(nSubtOut(childTmp));
+end
+
+nodesCount = length(nodeNo);
+outRange = cell(nodesCount,1); 
+
+% tic;
+% noOut = cellfun(@(nEl) numel(nEl.filts), wt.nodes(nodeNo)) -...
+%         cellfun(@(chEl) numel(chEl(chEl~=0)), wt.children(nodeNo));
+% toc;
+
+t = 0;
+for jj=1:nodesCount
+   %tic;
+   outRangeTmp = rangeInNodeOutputs(nodeNo(jj),wt);
+   %t=t+toc;
+
+
+    if(isempty(outRangeTmp))
+        continue;
+    end
+    %rootId = find(treeStruct.parents==0);
+    rootId = nodeNo(jj);
+    higherNodes = [];
+
+%tic;
+    while wt.parents(rootId)
+         parId = wt.parents(rootId);
+          % save idx of all higher nodes
+         ch = wt.children{parId};
+         childIdx = find(ch==rootId);
+         higherNodes(end+1:end+(childIdx-1))=ch(1:childIdx-1);
+         rootId = parId;
+    end
+%t=t+toc;
+%tic;
+    noOutPrev = 0;
+    for ii=1:length(higherNodes)
+        if(higherNodes(ii)==0) 
+           noOutPrev=noOutPrev+1; 
+        else
+          % noOutPrev = noOutPrev + noOfSubtreeOutputs(higherNodes(ii),wt);
+          noOutPrev = noOutPrev + nSubtOut(higherNodes(ii));
+        end
+    end
+%t=t+toc;
+
+    outRange{jj} = outRangeTmp + noOutPrev;
+end
+
+%disp(sprintf('Spend %d ms.',1000*t));
+
+
+
diff --git a/inst/wavelets/wfbtmanip/rangeInWpOutputs.m b/inst/wavelets/wfbtmanip/rangeInWpOutputs.m
new file mode 100644
index 0000000..18bbbab
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/rangeInWpOutputs.m
@@ -0,0 +1,40 @@
+function [pOutIdxs,chOutIdxs] = rangeInWpOutputs(wt)
+
+treePath = nodesBForder(wt);
+trLen = length(treePath);
+pOutIdxs = zeros(1,trLen);
+chOutIdxs = cell(1,trLen);
+pRunIdx = [0];
+chRunIdx = 1;
+%-*- texinfo -*-
+%@deftypefn {Function} rangeInWpOutputs
+%@verbatim
+% do trough tree and look for nodeNo and its parrent
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/rangeInWpOutputs.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+for ii=1:trLen
+    tmpfiltNo = length(wt.nodes{treePath(ii)}.filts);
+    chOutIdxs{ii} = chRunIdx:chRunIdx+tmpfiltNo-1;
+    chRunIdx = chRunIdx + tmpfiltNo;
+    pOutIdxs(ii) = pRunIdx(1);
+    pRunIdx = [pRunIdx(2:end),chOutIdxs{ii}];
+end
+
+
diff --git a/inst/wavelets/wfbtmanip/rangeWpBF.m b/inst/wavelets/wfbtmanip/rangeWpBF.m
new file mode 100644
index 0000000..bff1a0d
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/rangeWpBF.m
@@ -0,0 +1,51 @@
+function [pOutIdxs,chOutIdxs] = rangeWpBF(wt,varargin)
+
+treePath = nodesBForder(wt);
+trLen = numel(treePath);
+pOutIdxs = zeros(1,trLen);
+chOutIdxs = cell(1,trLen);
+pRunIdx = [0];
+chRunIdx = 1;
+%-*- texinfo -*-
+%@deftypefn {Function} rangeWpBF
+%@verbatim
+% do trough tree and look for nodeNo and its parent
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/rangeWpBF.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+for ii=1:trLen
+    tmpfiltNo = length(wt.nodes{treePath(ii)}.g);
+    locRange = rangeInLocalOutputs(treePath(ii),wt);
+    diffRange = 1:tmpfiltNo;
+    diffRange(locRange{1})=[];
+    chOutIdxs{ii} = chRunIdx:chRunIdx+tmpfiltNo-1;
+    chRunIdx = chRunIdx + tmpfiltNo;
+    pOutIdxs(ii) = pRunIdx(1);
+    pRunIdx = [pRunIdx(2:end),chOutIdxs{ii}(diffRange)];
+end
+
+
+if(~isempty(varargin))
+    if(strcmpi(varargin{1},'rev'))
+       pOutIdxs = pOutIdxs(end:-1:1); 
+       chOutIdxs = chOutIdxs(end:-1:1);
+    end
+end
+
+
diff --git a/inst/wavelets/wfbtmanip/treeOutLen.m b/inst/wavelets/wfbtmanip/treeOutLen.m
new file mode 100644
index 0000000..1286825
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/treeOutLen.m
@@ -0,0 +1,45 @@
+function Lc = treeOutLen(L,doNoExt,wt)
+%-*- texinfo -*-
+%@deftypefn {Function} treeOutLen
+%@verbatim
+%TREESUB
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/treeOutLen.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% All nodes with at least one final output.
+termN = find(noOfNodeOutputs(1:numel(wt.nodes),wt)~=0);
+% Range in filter outputs
+outRange = rangeInLocalOutputs(termN,wt);
+cRange = cell2mat(cellfun(@(rEl) rEl(:),rangeInOutputs(termN,wt),...
+                  'UniformOutput',0));
+
+
+Lctmp = nodeOutLen(termN,L,outRange,doNoExt,wt);
+Lc = zeros(size(Lctmp));
+
+Lc(cRange) = Lctmp;
+
+
+
+
+
+
+
+
diff --git a/inst/wavelets/wfbtmanip/treeSub.m b/inst/wavelets/wfbtmanip/treeSub.m
new file mode 100644
index 0000000..2c2974c
--- /dev/null
+++ b/inst/wavelets/wfbtmanip/treeSub.m
@@ -0,0 +1,42 @@
+function a = treeSub(wt)
+%-*- texinfo -*-
+%@deftypefn {Function} treeSub
+%@verbatim
+%TREESUB
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtmanip/treeSub.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% All nodes with at least one final output.
+termN = find(noOfNodeOutputs(1:numel(wt.nodes),wt)~=0);
+% Range in filter outputs
+outRangeTermN = rangeInLocalOutputs(termN,wt);
+
+cRangeTermN = rangeInOutputs(termN,wt);
+
+noOut = noOfOutputs(wt);
+% Subsampling factors of the terminal nodes
+subTermN = nodeSub(termN,wt);
+
+a = zeros(noOut, 1);
+for ii=1:numel(termN)
+   a(cRangeTermN{ii}) = subTermN{ii}(outRangeTermN{ii});
+end
+
+
diff --git a/inst/wavelets/wfbtput.m b/inst/wavelets/wfbtput.m
new file mode 100644
index 0000000..3451e55
--- /dev/null
+++ b/inst/wavelets/wfbtput.m
@@ -0,0 +1,125 @@
+function wt = wfbtput(d,k,w,wt,forceStr)
+%-*- texinfo -*-
+%@deftypefn {Function} wfbtput
+%@verbatim
+%WFBTPUT  Put node to the filterbank tree
+%   Usage:  wt = wfbtput(d,k,w,wt);
+%           wt = wfbtput(d,k,w,wt,'force');
+%
+%   Input parameters:
+%           d   : Level in the tree (0 - root).
+%           k   : Index (array of indexes) of the node at level d (starting at 0).
+%           w   : Node, basic wavelet filterbank.
+%           wt  : Wavelet filterbank tree structure (as returned from
+%                 WFBTINIT).
+%
+%   Output parameters:
+%           wt : Modified filterbank structure.
+%
+%   WFBTPUT(d,k,w,wt) puts the basic filterbank filt to the filter
+%   tree structure wt at level d and index k. The output is a
+%   modified tree structure. d and k have to specify unconnected output
+%   of the leaf node. Error is issued if d and k points to already
+%   existing node. For possible formats of parameter w see help of FWT.
+%   Parameter wt has to be a structure returned by WFBTINIT.
+%
+%   WFBTPUT(d,k,w,wt,'force') does the same but replaces node at d and k*
+%   if it already exists. If the node to be replaced has any children, 
+%   the number of outputs of the replacing node have to be equal to number of
+%   outputs of the node beeing replaced.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtput.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+  
+if nargin<4
+   error('%s: Too few input parameters.',upper(mfilename)); 
+end
+
+do_force = 0;
+if nargin==5
+    if ~ischar(forceStr)
+        error('%s: Fifth parameter should be a string.',upper(mfilename));
+    end
+    if strcmpi(forceStr,'force')
+        do_force = 1;
+    end
+end
+
+% This was replaced. Calling ltfatargheler was too slow.
+%definput.flags.force = {'noforce','force'};
+%[flags,kv]=ltfatarghelper({},definput,varargin);
+
+node = fwtinit(w);
+
+[nodeNoArray,nodeChildIdxArray] = depthIndex2NodeNo(d,k,wt);
+
+for ii=1:numel(nodeNoArray)
+ nodeNo = nodeNoArray(ii);
+ nodeChildIdx = nodeChildIdxArray(ii);
+if(nodeNo==0)
+    % adding root 
+    if(~isempty(find(wt.parents==0,1)))
+        if(do_force)
+           rootId = find(wt.parents==0,1);
+           % if root has children, check if the new root has the same
+           % number of them
+           if(~isempty(find(wt.children{rootId}~=0,1)))
+              if(length(w)~=length(wt.nodes{rootId}))
+                 error('%s: The replacing root have to have %d filters.',mfilename,length(wt.nodes{rootId})); 
+              end
+           end
+        else
+            error('%s: Root already defined. Use FORCE option to replace.',mfilename);  
+        end
+        wt.nodes{rootId} = node;
+        return;
+    end
+    wt.nodes{end+1} = node;
+    wt.parents(end+1) = nodeNo;
+    wt.children{end+1} = [];
+    return;
+end
+
+childrenIdx = find(wt.children{nodeNo}~=0);
+found = find(childrenIdx==nodeChildIdx,1);
+if(~isempty(found))
+   if(do_force)
+     %check if childrenIdx has any children
+     tmpnode = wt.children{nodeNo}(found);  
+     if(~isempty(find(wt.children{tmpnode}~=0, 1)))
+         if(length(w)~=length(wt.nodes{tmpnode}))
+            error('%s: The replacing node have to have %d filters.',mfilename,length(wt.nodes{childrenIdx})); 
+         end
+     end
+     wt.nodes{tmpnode} = node;
+     %wtree.a{tmpnode} = a;
+     return;
+   else
+       error('%s: Such node (depth=%d, idx=%d) already exists. Use FORCE option to replace.',mfilename,d,k); 
+   end
+end
+
+
+wt.nodes{end+1} = node;
+wt.parents(end+1) = nodeNo;
+wt.children{end+1} = [];
+wt.children{nodeNo}(nodeChildIdx) = numel(wt.parents);
+
+end
diff --git a/inst/wavelets/wfbtremove.m b/inst/wavelets/wfbtremove.m
new file mode 100644
index 0000000..34eca8f
--- /dev/null
+++ b/inst/wavelets/wfbtremove.m
@@ -0,0 +1,98 @@
+function wt = wfbtremove(d,kk,wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wfbtremove
+%@verbatim
+%WFBTREMOVE Remove node from the filterbank tree
+%   Usage:  wt = wbftremove(d,kk,wt);
+%           wt = wfbtremove(d,kk,wt,'force');
+%
+%   Input parameters:
+%           d   : Level in the tree (0 - root).
+%           kk  : Index of the node at level d (starting at 0) or array 
+%                 of indexes. 
+%           wt  : Wavelet filterbank tree structure (as returned from
+%                 WFBTINIT).
+%
+%   Output parameters:
+%           wt : Modified filterbank structure.
+%   
+%   WFBTREMOVE(d,kk,wt) removes existing node at level d and index kk*
+%   from the filterbank tree structure wt. The function fails if the 
+%   node has any children (is not a leaf node).
+%
+%   WFBTREMOVE(d,k,wt,'force') does the same, but any childern of the
+%   node are removed too.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfbtremove.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if(nargin<3)
+   error('%s: Too few input parameters.',upper(mfilename)); 
+end
+
+definput.flags.force = {'noforce','force'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+if(isempty(wt.nodes))
+   error('%s: Tree is empty.',mfilename); 
+end
+
+for i=1:numel(kk)
+   k=kk(i);
+   [nodeNo,nodeChildIdx] = depthIndex2NodeNo(d,k,wt);
+   if(nodeNo==0)
+       % removing root 
+       rootNo = find(wt.parents==0);
+       % check for any children of the root
+       if(isempty(find(wt.children{rootNo}~=0,1)))
+           wt = wfbtinit();
+       else
+           if(flags.do_force)
+               wt = wfbtinit();
+           else
+               error('%s: Deleting root node. To delete the whole tree use FORCE option.',mfilename,d,k); 
+           end
+       end
+   end
+
+   % check if node exists
+   childrenIdx = find(wt.children{nodeNo}~=0);
+   found = find(childrenIdx==nodeChildIdx,1);
+
+   if(isempty(found))
+        error('%s: Such node (depth=%d, idx=%d) does not exist.',mfilename,d,k); 
+   end
+
+
+   nodeToDelete = wt.children{nodeNo}(nodeChildIdx);
+   % Check if it is a leaf (terminal node)
+   if(~isempty(find(wt.children{nodeToDelete}~=0,1)))
+       if(flags.do_force)
+           wt = deleteSubtree(nodeToDelete,wt);
+           return;
+       else
+           error('%s: Deleting non-leaf node. To delete whole subtree use FORCE option.',mfilename);
+       end
+   else
+       wt = deleteNode(nodeToDelete,wt); 
+   end
+end
+%wtree = deleteNode(nodeToDelete,wtree);
+
diff --git a/inst/wavelets/wfilt_algmband.m b/inst/wavelets/wfilt_algmband.m
new file mode 100644
index 0000000..01fb6a6
--- /dev/null
+++ b/inst/wavelets/wfilt_algmband.m
@@ -0,0 +1,84 @@
+function [h,g,a,info] = wfilt_algmband(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_algmband
+%@verbatim
+%WFILT_ALGMBAND  An ALGebraic construction of orthonormal M-BAND wavelets with perfect reconstruction
+%   Usage: [h,g,a] = wfilt_algmband(N);
+%
+%   [h,g,a]=WFILT_ALGMBAND(N) computes an algebraic construction of
+%   orthonormal m-band wavelets with perfect reconstruction. Critically
+%   subsampled.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('algmband2');   
+%
+%   References:
+%     T. Lin, S. Xu, Q. Shi, and P. Hao. An algebraic construction of
+%     orthonormal M-band wavelets with perfect reconstruction. Applied
+%     mathematics and computation, 172(2):717-730, 2006.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_algmband.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
+
+switch(N)
+   case 1
+   % from the paper Example 1.
+      garr = [
+              0.33838609728386 -0.11737701613483 0.40363686892892
+              0.53083618701374 0.54433105395181 -0.62853936105471
+              0.72328627674361 -0.01870574735313 0.46060475252131
+              0.23896417190576 -0.69911956479289 -0.40363686892892
+              0.04651408217589 -0.13608276348796 -0.07856742013185
+             -0.14593600755399 0.42695403781698 0.24650202866523
+             ];
+      a= [3;3;3];
+   case 2
+      garr = [
+              0.0857130200  -0.1045086525 0.2560950163  0.1839986022
+              0.1931394393  0.1183282069  -0.2048089157 -0.6622893130
+              0.3491805097  -0.1011065044 -0.2503433230 0.6880085746
+              0.5616494215  -0.0115563891 -0.2484277272 -0.1379502447
+              0.4955029828  0.6005913823  0.4477496752  0.0446493766
+              0.4145647737  -0.2550401616 0.0010274000  -0.0823301969
+              0.2190308939  -0.4264277361 -0.0621881917 -0.0923899104
+             -0.1145361261 -0.0827398180 0.5562313118  -0.0233349758
+             -0.0952930728 0.0722022649  -0.2245618041 0.0290655661
+             -0.1306948909 0.2684936992  -0.3300536827 0.0702950474
+             -0.0827496793 0.1691549718  -0.2088643503 0.0443561794
+              0.0719795354  -0.4437039320 0.2202951830  -0.0918374833
+              0.0140770701  0.0849964877  0.0207171125  0.0128845052
+              0.0229906779  0.1388163056  0.0338351983  0.0210429802
+              0.0145382757  0.0877812188  0.0213958651  0.0133066389
+             -0.0190928308 -0.1152813433 -0.0280987676 -0.0174753464
+             ];
+       a= [4;4;4;4];
+  otherwise
+        error('%s: No such orthonormal M-band wavelet filter bank.',upper(mfilename));
+end
+g=mat2cell(garr,size(garr,1),ones(1,size(garr,2)));
+h = g;
+info.istight=1;
+
diff --git a/inst/wavelets/wfilt_apr.m b/inst/wavelets/wfilt_apr.m
new file mode 100644
index 0000000..9e3dc76
--- /dev/null
+++ b/inst/wavelets/wfilt_apr.m
@@ -0,0 +1,91 @@
+function [h,g,a,info] = wfilt_apr(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_apr
+%@verbatim
+%WFILT_APR Almost Perfect Reconstruction Filter Bank for Non-redundant, Approximately Shift-Invariant, ComplexWavelet Transforms
+%   Usage: [h,g,a] = wfilt_apr(N);
+%
+%   [h,g,a] = WFILT_APR(N) computes an almost perfect reconstruction
+%   filter bank for non-redundant, approximately shift-invariant,
+%   Complex Wavelet Transforms. Critically subsampled. 
+%
+%   References:
+%     R. Hosseini and M. Vafadust. Almost perfect reconstruction filter bank
+%     for non-redundant, approximately shift-invariant, complex wavelet
+%     transforms. Journal of Wavelet Theory and Applications, 2(1):1-14,
+%     2008.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_apr.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+a= [3;3;3];
+switch(N)
+    case 1
+% from the software package filters1.m
+harr = [
+-0.0195   (-0.0046 - 0.0018*i) (-0.0046 + 0.0018*i)
+-0.0028   (0.0160 - 0.0205*i)  (0.0160 + 0.0205*i)
+-0.0373   (-0.0050 - 0.0079*i) (-0.0050 + 0.0079*i)
+-0.0271   (0.0530 - 0.0753*i)  (0.0530 + 0.0753*i)
+ 0.2735   (0.0504 + 0.0402*i)  (0.0504 - 0.0402*i)
+ 0.0127   (0.1180 - 0.1403*i)  (0.1180 + 0.1403*i)
+ 0.6495   (0.3612 + 0.3391*i)  (0.3612 - 0.3391*i) 
+ 0.0369   (-0.4554 + 0.4554*i)  (-0.4554 - 0.4554*i)
+ 0.6495   (-0.3391 - 0.3612*i)  (-0.3391 + 0.3612*i) 
+ 0.0127   (0.1403 - 0.1180*i)  (0.1403 + 0.1180*i) 
+ 0.2735   (-0.0402 - 0.0504*i) (-0.0402 + 0.0504*i)
+-0.0271   (0.0753 - 0.0530*i)  (0.0753 + 0.0530*i)
+-0.0373   (0.0079 + 0.0050*i)  (0.0079 - 0.0050*i)
+-0.0028   (0.0205 - 0.0160*i)  (0.0205 + 0.0160*i)
+-0.0195   (0.0018 + 0.0046*i)  (0.0018 - 0.0046*i)
+];
+    case 2
+   harr = [
+-0.0124  (-0.0002 + 0.0041*i)  (-0.0002 - 0.0041*i)
+ 0.0062  (-0.0095 + 0.0090*i)  (-0.0095 - 0.0090*i)
+-0.0184  (-0.0014 + 0.0032*i)  (-0.0014 - 0.0032*i)
+ 0.0306  (-0.0280 + 0.0134*i)  (-0.0280 - 0.0134*i)
+ 0.0611  ( 0.0024 - 0.0351*i)  ( 0.0024 + 0.0351*i)
+ 0.0171  (-0.0304 + 0.0042*i)  (-0.0304 - 0.0042*i)
+ 0.0883  ( 0.0372 - 0.1169*i)  ( 0.0372 + 0.1169*i)
+-0.2966  ( 0.0352 + 0.0177*i)  ( 0.0352 - 0.0177*i)
+-0.0589  ( 0.0938 - 0.1716*i)  ( 0.0938 + 0.1716*i)
+-0.6231  ( 0.3841 + 0.3107*i)  ( 0.3841 - 0.3107*i)
+-0.1181  (-0.4446 + 0.4446*i)  (-0.4446 - 0.4446*i)
+-0.6231  (-0.3107 - 0.3841*i)  (-0.3107 + 0.3841*i)
+-0.0589  ( 0.1716 - 0.0938*i)  ( 0.1716 + 0.0938*i)
+-0.2966  (-0.0177 - 0.0352*i)  (-0.0177 + 0.0352*i)
+ 0.0883  ( 0.1169 - 0.0372*i)  ( 0.1169 + 0.0372*i)
+ 0.0171  (-0.0042 + 0.0304*i)  (-0.0042 - 0.0304*i)
+ 0.0611  ( 0.0351 - 0.0024*i)  ( 0.0351 + 0.0024*i)
+ 0.0306  (-0.0134 + 0.0280*i)  (-0.0134 - 0.0280*i)
+-0.0184  (-0.0032 + 0.0014*i)  (-0.0032 - 0.0014*i)
+ 0.0062  (-0.0090 + 0.0095*i)  (-0.0090 - 0.0095*i)
+-0.0124  (-0.0041 + 0.0002*i)  (-0.0041 - 0.0002*i)  
+        ];
+
+    otherwise
+        error('%s: No such Almost Perfect Reconstruction Filter Bank filter. ',upper(mfilename));
+end;
+
+h=mat2cell(harr.',[1,1,1],length(harr));
+g = h;
+info.istight = 1;
+
diff --git a/inst/wavelets/wfilt_cmband.m b/inst/wavelets/wfilt_cmband.m
new file mode 100644
index 0000000..599e9f4
--- /dev/null
+++ b/inst/wavelets/wfilt_cmband.m
@@ -0,0 +1,112 @@
+function [h,g,a,info] = wfilt_cmband(M)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_cmband
+%@verbatim
+%WFILT_CMBAND  Generates M-Band cosine modulated wavelet filters
+%   Usage: [h,g,a] = wfilt_cmband(M);
+%
+%   Input parameters:
+%         M     : Number of channels.
+%
+%   [h,g,a]=WFILT_CMBAND(M,K) returns smooth, 1*-regular Cosine modulated
+%   M*-band wavelet filters. The length of the filters is 4M.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('cmband5');
+%
+%
+%   References:
+%     R. Gopinath and C. Burrus. On cosine-modulated wavelet orthonormal
+%     bases. Image Processing, IEEE Transactions on, 4(2):162-176, Feb 1995.
+%     
+%     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_cmband.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% if K<1 || rem(K,1) ~= 0
+%     error('%s: Regularity K has to be at least 1.',upper(mfilename));
+% end
+
+if M<2 || rem(M,1) ~= 0
+    error('%s: Number of channels M has to be at least 2.',upper(mfilename));
+end
+
+h = cell(M,1);
+
+if 0
+    N = 2*M;
+    n=0:N-1;
+    p = sin(pi*(2*n+1)/(2*N));
+    for m=0:M-1
+        c = zeros(1,N);
+        for n=0:N-1
+            c(n+1) = cos(pi*(2*m+1)*(n-(2*M-1)/2)/(2*M)+(-1)^m*pi/4);
+        end
+        h{m+1} = p.*c;
+    end
+    scal = sqrt(M)/sum(h{1});
+    h = cellfun(@(hEl) hEl*scal,h,'UniformOutput',0);
+else
+    N = 4*M;
+    gamma = 0.4717 + exp(-0.00032084024272*M^3 + 0.01619976915653*M^2 - ...
+            0.39479347799199*M - 2.24633148545678);
+    beta = zeros(1,M);
+    for n=0:M-1
+        beta(n+1) = gamma + n*(pi-4*gamma)/(2*(M-1));
+    end
+    beta = repmat([beta, beta(end:-1:1)],1,2);
+    n=0:N-1;
+    p = sqrt(1/(2*M))*(cos(beta)- cos(pi*(2*n+1)/(4*M)) );
+    
+    for m=0:M-1
+        c = zeros(1,N);
+        for n=0:N-1
+            c(n+1) = cos(pi*(2*m+1)*(n-(2*M-1)/2)/(2*M)+(-1)^m*pi/4);
+        end
+        h{m+1} = p.*c;
+    end
+    scal = sqrt(M)/sum(h{1});
+    h = cellfun(@(hEl) hEl*scal,h,'UniformOutput',0);
+end
+
+g = h;
+info.istight = 1;
+a = M*ones(M,1);
+
+
+
+
+
+
+
+
+
+
+
+
+
+%g=mat2cell(harr,size(harr,1),ones(1,size(harr,2)));
+%h = g;
+%info.istight = 1;
+
diff --git a/inst/wavelets/wfilt_db.m b/inst/wavelets/wfilt_db.m
new file mode 100644
index 0000000..e991bfe
--- /dev/null
+++ b/inst/wavelets/wfilt_db.m
@@ -0,0 +1,117 @@
+function [h, g, a, info] = wfilt_db(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_db
+%@verbatim
+%WFILT_DB    Daubechies FIR filterbank
+%   Usage:  [h,g] = wfilt_db(N);
+%
+%   Input parameters:
+%         N     : Order of Daubechies filters. 
+%   Output parameters:
+%         H     : cell array of analysing filters impulse reponses
+%         G     : cell array of synthetizing filters impulse reponses
+%         a     : array of subsampling (or hop) factors accociated with
+%                 corresponding filters
+%
+%   [H,G] = dbfilt(N) computes a two-channel Daubechies FIR filterbank
+%   from prototype maximum-phase analysing lowpass filter obtained by
+%   spectral factorization of the Lagrange interpolator filter.  N also
+%   denotes the number of zeros at z=-1 of the lowpass filters of length
+%   2N.  The prototype lowpass filter has the following form (all roots of
+%   R(z) are outside of the unit circle):
+%                 
+%      H_l(z)=(1+z^-1)^N*R(z),
+%
+%   where R(z) is a spectral factor of the Legrange interpolator P(z)=2R(z)*R(z^{-1})
+%   All subsequent filters of the two-channel filterbank are derived as
+%   follows:
+%
+%      H_h(z)=H_l((-z)^-1)
+%      G_l(z)=H_l(z^-1)
+%      G_h(z)=-H_l(-z)
+%
+%   making them an orthogonal causal perfect-reconstruction QMF.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('db8');
+%
+%   References:
+%     I. Daubechies. Ten Lectures on Wavelets. Society for Industrial and
+%     Applied Mathematics, Philadelphia, PA, USA, 1992.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_db.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<1)
+   error('%s: Too few input parameters.',upper(mfilename));
+end
+
+if(N<1)
+    error('Minimum N is 1.');
+end
+if(N>20)
+    warning('Instability may occur when N is too large.');
+end
+
+
+h = cell(2,1);
+flen = 2*N;
+
+% Calculating Lagrange interpolator coefficients
+sup = [-N+1:N];
+a = zeros(1,N);
+for n = 1:N
+    non  = sup(sup ~= n);
+    a(n) = prod(0.5-non)/prod(n-non);
+end
+P = zeros(1,2*N-1);
+P(1:2:end) = a;
+P = [P(end:-1:1),1,P];
+
+R = roots(P);
+R = R(abs(R)<1 & real(R)>0);
+
+% roots of the 2*conv(lo_a,lo_r) filter
+hroots = [R(:);-ones(N,1)];
+
+
+% building synthetizing low-pass filter from roots
+h{1}= real(poly(hroots));
+% normalize
+h{1}= h{1}/norm(h{1});
+% QMF modulation low-pass -> highpass
+h{2}= (-1).^(1:flen).*h{1}(end:-1:1);
+
+g=h;
+a = [2;2];
+info.istight=1;
+
+
+
+
+
+
+
+
diff --git a/inst/wavelets/wfilt_dden.m b/inst/wavelets/wfilt_dden.m
new file mode 100644
index 0000000..c711797
--- /dev/null
+++ b/inst/wavelets/wfilt_dden.m
@@ -0,0 +1,144 @@
+function [h,g,a,info] = wfilt_dden(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_dden
+%@verbatim
+%WFILT_DDEN  Double-DENsity DWT filters (tight frame)
+%   Usage: [h,g,a] = wfilt_dden(N);
+%
+%   [h,g,a]=WFILT_DDEN(N) computes oversampled dyadic double-density DWT
+%   filters. The redundancy is equal to 2.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('dden5');
+%
+%   References:
+%     A. A. Petrosian and F. G. Meyer, editors. Wavelets in Signal and Image
+%     Analysis: From Theory to Practice, chapter The Double Density DWT,
+%     pages 39-66. Kluwer, 1 edition, 2001.
+%     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_dden.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
+switch(N)
+    case 1
+% from the software package filters1.m
+garr = [
+  0.14301535070442  -0.01850334430500  -0.04603639605741
+  0.51743439976158  -0.06694572860103  -0.16656124565526
+  0.63958409200212  -0.07389654873135   0.00312998080994
+  0.24429938448107   0.00042268944277   0.67756935957555
+ -0.07549266151999   0.58114390323763  -0.46810169867282
+ -0.05462700305610  -0.42222097104302   0
+];
+
+    case 2
+% from the software package filters2.m
+garr = [
+  0.00069616789827  -0.00014203017443   0.00014203017443
+ -0.02692519074183   0.00549320005590  -0.00549320005590
+ -0.04145457368920   0.01098019299363  -0.00927404236573
+  0.19056483888763  -0.13644909765612   0.07046152309968
+  0.58422553883167  -0.21696226276259   0.13542356651691
+  0.58422553883167   0.33707999754362  -0.64578354990472
+  0.19056483888763   0.33707999754362   0.64578354990472
+ -0.04145457368920  -0.21696226276259  -0.13542356651691
+ -0.02692519074183  -0.13644909765612  -0.07046152309968
+  0.00069616789827   0.01098019299363   0.00927404236573
+  0                  0.00549320005590   0.00549320005590
+  0                 -0.00014203017443  -0.00014203017443
+];
+
+    case 3
+% from the paper Table 2.2.
+garr = [
+  0.14301535070442  -0.08558263399002  -0.43390145071794
+  0.51743439976158  -0.30964087862262   0.73950431733582
+  0.63958409200212   0.56730336474330  -0.17730428251781
+  0.24429938448107   0.04536039941690  -0.12829858410007
+ -0.07549266151999  -0.12615420862311   0
+ -0.05462700305610  -0.09128604292445   0
+];
+
+    case 4
+% from the paper Table 2.3.
+garr = [
+  0.14301535070442  -0.04961575871056  -0.06973280238342
+  0.51743439976158  -0.17951150139240  -0.25229564915399
+  0.63958409200212  -0.02465426871823   0.71378970545825
+  0.24429938448107   0.62884602337929  -0.39176125392083
+ -0.07549266151999  -0.21760444148150   0
+ -0.05462700305610  -0.15746005307660   0
+];
+
+    case 5
+% from the paper Table 2.4.
+garr = [
+  0.14301535070442  -0.01850334430500  -0.04603639605741
+  0.51743439976158  -0.06694572860103  -0.16656124565526
+  0.63958409200212  -0.07389654873135   0.00312998080994
+  0.24429938448107   0.00042268944277   0.67756935957555
+ -0.07549266151999   0.58114390323763  -0.46810169867282
+ -0.05462700305610  -0.42222097104302   0
+];
+
+    case 6
+% from the paper Table 2.5.
+garr = [
+                 0                  0                  0
+  0.05857000614054  -0.01533062192062   0.00887131217814
+  0.30400518363062  -0.07957295618112  -0.33001182554443
+  0.60500290681752  -0.10085811812745   0.74577631077164
+  0.52582892852883   0.52906821581280  -0.38690622229177
+  0.09438203761968  -0.15144941570477  -0.14689062498210
+ -0.14096408166391  -0.23774566907201   0.06822592840635
+ -0.06179010337508  -0.05558739119206   0.04093512146217
+  0.01823675069101   0.06967275075248   0
+  0.01094193398389   0.04180320563276   0
+];
+
+    case 7
+% from the paper Table 2.6.
+garr = [
+                 0                  0                  0
+  0.05857000614054   0.00194831075352   0.00699621691962
+  0.30400518363062   0.01011262602523   0.03631357326930
+  0.60500290681752   0.02176698144741   0.04759817780411
+  0.52582892852883   0.02601306210369  -0.06523665620369
+  0.09438203761968  -0.01747727200822  -0.22001495718527
+ -0.14096408166391  -0.18498449534896  -0.11614112361411
+ -0.06179010337508  -0.19373607227976   0.64842789652539
+  0.01823675069101   0.66529265123158  -0.33794312751535
+  0.01094193398389  -0.32893579192449   0
+];
+    otherwise
+        error('%s: No such Double Density DWT filter',upper(mfilename));
+end;
+
+g=mat2cell(garr,size(garr,1),ones(1,size(garr,2)));
+h = g;
+a= [2;2;2];
+info.istight=1;
+
diff --git a/inst/wavelets/wfilt_dgrid.m b/inst/wavelets/wfilt_dgrid.m
new file mode 100644
index 0000000..d93a9d3
--- /dev/null
+++ b/inst/wavelets/wfilt_dgrid.m
@@ -0,0 +1,92 @@
+function [h,g,a,info] = wfilt_dgrid(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_dgrid
+%@verbatim
+%WFILT_DGRID  Dense GRID framelets (tight frame, symmetric)
+%   Usage: [h,g,a] = wfilt_dgrid(N);
+%
+%   [h,g,a]=WFILT_DGRID(N) computes Dense GRID framelets. Redundancy
+%   equal to 2.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('dgrid3');
+%
+%   References:
+%     A. Abdelnour. Dense grid framelets with symmetric lowpass and bandpass
+%     filters. In Signal Processing and Its Applications, 2007. ISSPA 2007.
+%     9th International Symposium on, volume 172, pages 1-4, 2007.
+%     
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_dgrid.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
+switch(N)
+case 1
+harr = [
+  0              0               0              0   
+  -sqrt(2)/32    -sqrt(2)/32     0.0104677975   0
+  0              -2*sqrt(2)/32   0.0370823430   0.0104677975
+  9*sqrt(2)/32   7*sqrt(2)/32    0.0651503417   0.0370823430
+  16*sqrt(2)/32  0               0.0897493772   0.0651503417
+  9*sqrt(2)/32   -7*sqrt(2)/32   -0.575618139   0.0897493772
+  0              2*sqrt(2)/32    0.3731682798   -0.575618139
+  -sqrt(2)/32    sqrt(2)/32      0              0.3731682798
+];
+case 2
+harr = [
+  -5*sqrt(2)/256       -5*sqrt(2)/256     0.0422028267     0
+  -7*sqrt(2)/256       23*sqrt(2)/256     0.0784808462     0.0422028267 
+  35*sqrt(2)/256       -13*sqrt(2)/256    0.0274495253     0.0784808462
+  105*sqrt(2)/256      -41*sqrt(2)/256    -0.1272844093    0.0274495253
+  105*sqrt(2)/256      41*sqrt(2)/256     -0.4611848140    -0.1272844093   
+  35*sqrt(2)/256       13*sqrt(2)/256     0.5488035631     -0.4611848140            
+  -7*sqrt(2)/256       -23*sqrt(2)/256    -0.1084675382    0.5488035631 
+  -5*sqrt(2)/256       5*sqrt(2)/256      0                -0.1084675382
+]; 
+case 3
+harr = [
+  -7*sqrt(2)/1024       -7*sqrt(2)/1024     0.0019452732     0
+  -27*sqrt(2)/1024       43*sqrt(2)/1024    -0.0020062621    0.0019452732  
+  0                    -80*sqrt(2)/1024     0.0070362139     -0.0020062621
+  168*sqrt(2)/1024      8*sqrt(2)/1024      -0.0305577537    0.0070362139
+  378*sqrt(2)/1024      138*sqrt(2)/1024    -0.1131305218    -0.0305577537  
+  378*sqrt(2)/1024      -138*sqrt(2)/1024   -0.0700905154    -0.1131305218  
+  168*sqrt(2)/1024      -8*sqrt(2)/1024     0.0845961181     -0.0700905154  
+  0                     80*sqrt(2)/1024     0.6026545312     0.0845961181
+  -27*sqrt(2)/1024      -43*sqrt(2)/1024    -0.4804470835    0.6026545312
+  -7*sqrt(2)/1024       7*sqrt(2)/1024      0                -0.4804470835
+]; 
+
+    otherwise
+        error('%s: No such Dense Grid Framelet filters.',upper(mfilename));
+end;
+
+garr = flipud(harr);
+g=mat2cell(garr,size(garr,1),ones(1,size(garr,2)));
+h = g;
+a = [2;2;2;2];
+info.istight=1;
+
diff --git a/inst/wavelets/wfilt_dtree.m b/inst/wavelets/wfilt_dtree.m
new file mode 100644
index 0000000..071c464
--- /dev/null
+++ b/inst/wavelets/wfilt_dtree.m
@@ -0,0 +1,103 @@
+function [h,g,a] = wfilt_dtree(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_dtree
+%@verbatim
+%WFILT_DTREE  Dual-TREE complex wavelet transform filters
+%   Usage: [h,g,a] = wfilt_dtree(N);
+%
+%   [h,g,a]=WFILT_DTREE(N) computes filters used in the dual-tree complex wavelet transform. 
+%
+%   References:
+%     I. Selesnick, R. Baraniuk, and N. Kingsbury. The dual-tree complex
+%     wavelet transform. Signal Processing Magazine, IEEE, 22(6):123 - 151,
+%     nov. 2005.
+%     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_dtree.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+switch(N)
+case 1
+harr = [
+                  0                  0
+  -0.08838834764832  -0.01122679215254
+   0.08838834764832   0.01122679215254
+   0.69587998903400   0.08838834764832
+   0.69587998903400   0.08838834764832
+   0.08838834764832  -0.69587998903400
+  -0.08838834764832   0.69587998903400
+   0.01122679215254  -0.08838834764832
+   0.01122679215254  -0.08838834764832
+                  0                  0
+];
+case 2
+harr = [
+  0.01122679215254                   0
+   0.01122679215254                  0
+  -0.08838834764832  -0.08838834764832
+   0.08838834764832  -0.08838834764832
+   0.69587998903400   0.69587998903400
+   0.69587998903400  -0.69587998903400
+   0.08838834764832   0.08838834764832
+  -0.08838834764832   0.08838834764832
+                  0   0.01122679215254
+                  0  -0.01122679215254
+];
+
+case 3
+harr = [
+   0.03516384000000                  0
+                  0                  0
+  -0.08832942000000  -0.11430184000000
+   0.23389032000000                  0
+   0.76027237000000   0.58751830000000
+   0.58751830000000  -0.76027237000000
+                  0   0.23389032000000
+  -0.11430184000000   0.08832942000000
+                  0                  0
+                  0  -0.03516384000000
+];
+
+case 4
+harr = [
+                  0  -0.03516384000000
+                  0                  0
+  -0.11430184000000   0.08832942000000
+                  0   0.23389032000000
+   0.58751830000000  -0.76027237000000
+   0.76027237000000   0.58751830000000
+   0.23389032000000                  0
+  -0.08832942000000  -0.11430184000000
+                  0                  0
+   0.03516384000000                  0
+];
+
+ otherwise
+        error('%s: No such Dual-Tree Complex Wavelet Transform Filters..',upper(mfilename));
+end
+a= [2;2];
+
+h=mat2cell(harr.',[1,1],length(harr));
+
+if(nargout>1)
+    garr = harr(end:-1:1, :);
+    g=mat2cell(garr.',[1,1],length(garr));
+end
diff --git a/inst/wavelets/wfilt_hden.m b/inst/wavelets/wfilt_hden.m
new file mode 100644
index 0000000..b0e155d
--- /dev/null
+++ b/inst/wavelets/wfilt_hden.m
@@ -0,0 +1,134 @@
+function [h,g,a,info] = wfilt_hden(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_hden
+%@verbatim
+%WFILT_HDEN  Higher DENsity dwt filters (tight frame, frame)
+%   Usage: [h,g,a] = wfilt_hden(N);
+%
+%   [h,g,a]=WFILT_HDEN(N) computes Higher DENsity dwt filters (tight frame, frame).
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('hden3');
+%
+%   References:
+%     I. Selesnick. A higher density discrete wavelet transform. IEEE
+%     Transactions on Signal Processing, 54(8):3039-3048, 2006.
+%     
+%     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_hden.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+a= [2;2;1];
+info.istight = 1;
+switch(N)
+case 1
+% from the paper Example 1.
+harr = [
+    0                   0                    0 
+    0.353553390593274   0.353553390593274    0.5
+    0.707106781186548   0                    -0.5
+    0.353553390593274   -0.353553390593274   0
+];
+
+case 2
+% from the paper Example 2.
+harr = [
+    0                 0                0 
+    0.189604909379    0.025752563665   0.010167956157
+    0.631450512121    0.075463998066   0.046750380120
+    0.655505518357   -0.064333341412  -0.009172584871
+    0.099615139800   -0.327704691428  -0.354664087684
+    -0.163756210215   0.228185687127   0.499004628714
+    -0.023958870736   0.252240693362  -0.192086292435
+    0.025752563665   -0.189604909379   0
+];
+
+case 3
+% from the paper Example 3.
+harr = [
+   0                 0                0
+   0.022033327573    0.048477254777   0.031294135831
+   0.015381522616    0.019991451948   0.013248398005
+  -0.088169084245   -0.304530024033  -0.311552292833
+   0.051120949834    0.165478923930   0.497594326648
+   0.574161374258    0.308884916012  -0.235117092484
+   0.717567366340   -0.214155508410  -0.020594576659
+   0.247558418377   -0.074865474330   0.015375249485
+  -0.076963057605    0.028685132531   0.009751852004
+  -0.048477254777    0.022033327573   0
+];
+
+case 4
+    info.istight = 0;
+    % from the paper Example 5. Is not a tight frame!
+    harr = [
+       0          0           0 
+       0          0           0
+       0.027222   0.044889    0
+       0.011217   0.005671    0.027671
+      -0.112709  -0.286349    0.007159 
+       0.096078   0.235789   -0.277671 
+       0.685299   0.235789    0.485682 
+       0.685299   -0.286349  -0.277671 
+       0.096078   0.005671    0.007159 
+      -0.112709   0.044889    0.027671 
+       0.011217   0           0 
+       0.027222   0           0  
+    ];
+    harr = flipud(harr);
+    h=mat2cell(harr,size(harr,1),ones(1,size(harr,2)));
+
+
+        garr = [
+            0          0          0
+           -0.039237   0.023794   0.011029
+           -0.073518   0.037784   0.019204
+            0.181733  -0.070538  -0.020024
+            0.638129  -0.253037  -0.269204
+            0.638129   0.261996   0.517991
+            0.181733   0.261996  -0.269204
+           -0.073518  -0.253037  -0.020024
+           -0.039237  -0.070538   0.019204
+            0          0.037784   0.011029
+            0          0.023794   0
+            0          0          0
+        ];   
+
+        g=mat2cell(garr,size(garr,1),ones(1,size(garr,2)));
+
+
+    return;
+
+
+otherwise
+        error('%s: No such Higher Density Wavelet Transform Filters..',upper(mfilename));
+end
+
+garr = flipud(harr);
+g=mat2cell(garr,size(garr,1),ones(1,size(garr,2)));
+h = g;
+
+
+
diff --git a/inst/wavelets/wfilt_lemarie.m b/inst/wavelets/wfilt_lemarie.m
new file mode 100644
index 0000000..732aba0
--- /dev/null
+++ b/inst/wavelets/wfilt_lemarie.m
@@ -0,0 +1,73 @@
+function [h,g,a,info]=wfilt_lemarie(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_lemarie
+%@verbatim
+%WFILT_LEMARIE  Battle and Lemarie filters
+%   Usage: [h,g,a]=wfilt_lemarie(N)
+%
+%   Input parameters:
+%         N     : Filter length.
+%
+%   [h,g,a]=WFILT_LEMARIE(N) calculates coeficients of orthonormal
+%   Battle-Lemarie wavelets. Filter coefficients are obtainded by
+%   frequency domain sampling and trunctating the impulse response.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('lemarie50');
+%
+%   References:
+%     S. G. Mallat. A theory for multiresolution signal decomposition: The
+%     wavelet representation. IEEE Trans. Pattern Anal. Mach. Intell.,
+%     11(7):674-693, July 1989. [1]http ]
+%     
+%     References
+%     
+%     1. http://dx.doi.org/10.1109/34.192463
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_lemarie.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Original copyright goes to:
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+% Author: Jose Martin Garcia
+% e-mail: Uvi_Wave at tsc.uvigo.es
+
+num_coefs = N;
+L = 1024;
+H = wfreq_lemarie(L);
+hh=real(ifft(H{1},L));
+hh=[ hh(L-floor(num_coefs/2)+1:L) hh(1:ceil(num_coefs/2))];
+hh=hh/norm(hh);
+
+g{1} = fliplr(hh);
+g{2} = -(-1).^(1:length(hh)).*g{1}(end:-1:1);
+ 
+h=g;
+
+a= [2;2];
+info.istight = 1;
+
+
+
+
+
diff --git a/inst/wavelets/wfilt_matlabwtwrapper.m b/inst/wavelets/wfilt_matlabwtwrapper.m
new file mode 100644
index 0000000..e845f72
--- /dev/null
+++ b/inst/wavelets/wfilt_matlabwtwrapper.m
@@ -0,0 +1,49 @@
+function [h,g,a,info] = wfilt_matlabwtwrapper(wname)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_matlabwtwrapper
+%@verbatim
+%WFILT_MATLABWTWRAPPER Wrapper of the Matlab Wavelet Toolbox wfilters function
+%   Usage: [h,g,a] = wfilt_matlabwtwrapper(wname);
+%
+%   [h,g,a]=WFILT_MATLABWTWRAPPER(wname) calls Matlab Wavelet Toolbox
+%   function wfilters and passes the parameter wname. This function
+%   requires the Matlab Wavelet Toolbox.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_matlabwtwrapper.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+a = [2;2];
+[lo,hi,lo_s,hi_s] = wfilters(wname);
+
+h=cell(2,1);
+h{1} = lo(:);
+h{2} = hi(:);
+
+g=cell(2,1);
+g{1} = flipud(lo_s(:));
+g{2} = flipud(hi_s(:));
+
+if all(h{1}==g{1}) && all(h{2}==g{2})
+  info.istight = 1;
+else
+  info.istight = 0; 
+end
+
+
diff --git a/inst/wavelets/wfilt_maxflat.m b/inst/wavelets/wfilt_maxflat.m
new file mode 100644
index 0000000..689d7d0
--- /dev/null
+++ b/inst/wavelets/wfilt_maxflat.m
@@ -0,0 +1,163 @@
+function [h,g,a,info]=wfilt_maxflat(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_maxflat
+%@verbatim
+%WFILT_MAXFLAT Generates maximally flat FIR filters
+%   Usage: [h,g,a] = wfilt_maxflat(N);
+%
+%   [h,g,a]=WFILT_MAXFLAT(N) calculates half-band maximally flat FIR filters,
+%   where (N-1) is the degree of flatness at w=0 and w=pi radians. 
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('maxflat6');
+%
+%   References:
+%     P. Vaidyanathan. Multirate Systems ans Filter Banks. Prentise-Hall,
+%     Englewood Clifs, NJ, 1993.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_maxflat.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Original copyright goes to:
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+% Author: Jose Martin Garcia
+% e-mail: Uvi_Wave at tsc.uvigo.es
+
+
+
+Npi=N;
+
+poly=[];		% Calculate trigonometric polynomial
+for i=1:N
+	poly=[poly , 2*numcomb(Npi+i-2,i-1)];
+end
+poly=poly(length(poly):-1:1);
+zerospoly=roots(poly);	% Calculate roots
+
+% Transform roots
+
+rootsz=[];
+
+for i=1:length(zerospoly)
+    rooty=zerospoly(i);
+    rootz1=(1-2*rooty)-2*sqrt(rooty*(rooty-1));
+    rootz2=(1-2*rooty)+2*sqrt(rooty*(rooty-1));
+    rootsz=[rootsz,rootz1,rootz2];
+end     
+
+zeros=rootsz;
+N=length(zeros);
+
+% To construct rh for the minimum phase choice, we choose all the zeros 
+% inside the unit circle. 
+
+modulus=abs(zeros);
+
+j=1;
+for i=1:N
+	if modulus(i)<1
+		zerosinside(j)=zeros(i);
+		j=j+1;
+	end
+end
+
+An=poly(1);
+
+realzeros=[];
+imagzeros=[];
+numrealzeros=0;
+numimagzeros=0;
+
+
+Ni=length(zerosinside);
+
+for i=1:(Ni)
+	if (imag(zerosinside(i))==0)
+		numrealzeros=numrealzeros+1;
+		realzeros(numrealzeros)=zerosinside(i);
+	else
+		numimagzeros=numimagzeros+1;
+		imagzeros(numimagzeros)=zerosinside(i);	
+		
+	end
+end
+
+% Construction of rh from its zeros
+
+rh=[1 1];
+
+for i=2:N
+	rh=conv(rh,[1 1]);
+end
+
+for i=1:numrealzeros
+	rh=conv(rh,[1 -realzeros(i)]);
+end
+
+for i=1:2:numimagzeros
+	rh=conv(rh,[1 -2*real(imagzeros(i)) abs(imagzeros(i))^2]);
+end
+
+% Normalization
+
+rh=sqrt(2)/sum(rh)*rh;
+
+g{1} = rh;
+g{2} = -(-1).^(1:length(rh)).*g{1}(end:-1:1);
+ 
+h = g;
+
+a= [2;2];
+info.istight= 1;
+
+function y=numcomb(n,k)
+
+if n==k,
+   y=1;
+elseif k==0,
+   y=1;
+elseif k==1,
+   y=n;
+else 
+   y=fact(n)/(fact(k)*fact(n-k));
+end
+
+function y=fact(x)
+
+for j=1:length(x)
+    if x(j)==0,
+       y(j)=1;
+    else
+       y(j)=x(j)*fact(x(j)-1);
+    end
+end
+
+
+
+      
+
+
+
+
+
diff --git a/inst/wavelets/wfilt_mband.m b/inst/wavelets/wfilt_mband.m
new file mode 100644
index 0000000..65680b7
--- /dev/null
+++ b/inst/wavelets/wfilt_mband.m
@@ -0,0 +1,128 @@
+function [h,g,a,info] = wfilt_mband(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_mband
+%@verbatim
+%WFILT_MBAND  Generates M-Band coders
+%   Usage: [h,g,a] = wfilt_mband(N);
+%
+%   [h,g,a]=WFILT_MBAND(N) returns linear-phase M-band wavelet filters. 
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('mband1');
+%
+%   References:
+%     O. Alkin and H. Caglar. Design of efficient M-band coders with
+%     linear-phase and perfect-reconstruction properties. Signal Processing,
+%     IEEE Transactions on, 43(7):1579 -1590, jul 1995.
+%     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_mband.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+a= [4;4;4;4];
+
+switch(N)
+case 1
+harr = [
+[ 0.036796442259
+-0.024067904384
+-0.064951364125
+-0.042483542576
+-0.030838286810
+ 0.174767766545
+ 0.409804433561
+ 0.540933249858
+ 0.540933249858
+ 0.409804433561
+ 0.174767766545
+-0.030838286810
+-0.042483542576
+-0.064951364125
+-0.024067904384
+ 0.036796442259
+ ],...
+ [
+ 0.024067904384
+-0.036796442259
+-0.042483542576
+-0.064951364125
+-0.174767766545
+ 0.030838286810
+ 0.540933249858
+ 0.409804433561
+-0.409804433561
+-0.540933249858
+-0.030838286810
+ 0.174767766545
+ 0.064951364125
+ 0.042483542576
+ 0.036796442259
+-0.024067904384
+],...
+[
+ 0.024067904384
+ 0.036796442259
+-0.042483542576
+ 0.064951364125
+-0.174767766544
+-0.030838286810
+ 0.540933249858
+-0.409804433561
+-0.409804433561
+ 0.540933249858
+-0.030838286810
+-0.174767766545
+ 0.064951364125
+-0.042483542576
+ 0.036796442259
+ 0.024067904384
+],...
+[ 
+ 0.036796442259
+ 0.024067904384
+-0.064951364125
+ 0.042483542576
+-0.030838286810
+-0.174767766545
+ 0.409804433561
+-0.540933249858
+ 0.540933249858
+-0.409804433561
+ 0.174767766545
+ 0.030838286810
+-0.042483542576
+ 0.064951364125
+-0.024067904384
+-0.036796442259
+]
+];
+
+otherwise
+        error('%s: No such M-Band filters.',upper(mfilename));
+end
+
+g=mat2cell(harr,size(harr,1),ones(1,size(harr,2)));
+h = g;
+
+info.istight = 1;
+
diff --git a/inst/wavelets/wfilt_optfs.m b/inst/wavelets/wfilt_optfs.m
new file mode 100644
index 0000000..177231c
--- /dev/null
+++ b/inst/wavelets/wfilt_optfs.m
@@ -0,0 +1,166 @@
+function [h,g,a,info] = wfilt_optfs(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_optfs
+%@verbatim
+%WFILT_OPTFS Improved frequency separation filters 
+%   Usage: [h,g,a] = wfilt_optfs(N);
+%
+%   [h,g,a]=WFILT_OPTFS(N) returns wavelet filters with better frequency
+%   band sepparation (compared to Daubeschies filters of the same length)
+%   having at least two vanishing moments.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('optfs4');
+%
+%   References:
+%     H. M. Paiva and R. K. H. Galvao. Optimized orthonormal wavelet filters
+%     with improved frequency separation. Digital Signal Processing,
+%     22(4):622 - 627, 2012. [1]http ]
+%     
+%     References
+%     
+%     1. http://www.sciencedirect.com/science/article/pii/S1051200412000735
+%     
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_optfs.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+a = [2,2];
+h = cell(2,1);
+switch(N)
+    case 1
+     h{1}=[0.3452 
+           0.7549 
+           0.5039 
+          -0.0636 
+          -0.2117 
+           0.0476 
+           0.0697 
+          -0.0319]; 
+    case 2
+     h{1}=[0.2657 
+           0.7055 
+           0.5955 
+           0.0292 
+          -0.2416
+          -0.0248
+           0.1238 
+          -0.0165 
+          -0.0363
+           0.0137];
+    case 3
+     h{1}=[0.2670 
+           0.6761 
+           0.6096 
+           0.0688 
+          -0.2564
+          -0.0577
+           0.1334 
+           0.0297 
+          -0.0792
+           0.0031
+           0.0327
+          -0.0129];
+    case 4
+     h{1}=[0.2183 
+           0.6298 
+           0.6509 
+           0.1535 
+          -0.2487
+          -0.1174
+           0.1317 
+           0.0687 
+          -0.0788
+          -0.0345
+           0.0534
+           0.0002
+          -0.0197
+           0.0068];
+    case 5
+     h{1}=[0.2181 
+           0.6109 
+           0.6541 
+           0.1797 
+          -0.2430
+          -0.1420
+           0.1249 
+           0.0959 
+          -0.0806
+          -0.0552
+           0.0531
+           0.0286
+          -0.0378
+          -0.0043
+           0.0184
+          -0.0066];
+    case 6
+     h{1}=[0.1847 
+           0.5703 
+           0.6728 
+           0.2491 
+          -0.2185
+          -0.1849
+           0.1026 
+           0.1253 
+          -0.0624
+          -0.0823
+           0.0455
+           0.0486
+          -0.0329
+          -0.0265
+           0.0273
+           0.0036
+          -0.0120
+           0.0039];  
+    case 7
+     h{1}=[0.1838
+           0.5566 
+           0.6719 
+           0.2682 
+          -0.2071
+          -0.2012
+           0.0905 
+           0.1406 
+          -0.0529
+          -0.0958
+           0.0359
+           0.0657
+          -0.0301
+          -0.0400
+           0.0240
+           0.0220
+          -0.0203
+          -0.0052
+           0.0114
+          -0.0038]; 
+
+    otherwise
+        error('%s: No such optimized orthonormal wavelet filter.',upper(mfilename));
+end;
+
+
+flen = length(h{1});
+h{2} = (-1).^(1:flen).'.*h{1}(end:-1:1);
+g = h;
+info.istight = 1;
+
diff --git a/inst/wavelets/wfilt_remez.m b/inst/wavelets/wfilt_remez.m
new file mode 100644
index 0000000..37a58f7
--- /dev/null
+++ b/inst/wavelets/wfilt_remez.m
@@ -0,0 +1,441 @@
+function [h,g,a,info]=wfilt_remez(L,K,B)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_remez
+%@verbatim
+%WFILT_REMEZ Filters designed using Remez exchange algorithm
+%   Usage: [h,g,a]=wfilt_remez(L,K,B)
+%
+%   Input parameters:
+%         L     : Length of the filters.
+%         K     : Degree of flatness at z=-1. 
+%         B     : Normalized transition bandwidth.
+%
+%   [h,g,a]=WFILT_REMEZ(L,K,B) calculates a set of wavelet filters. You
+%   can control regularity, frequency selectivity, and length of the
+%   filters.  It works performing a factorization based on the complex
+%   cepstrum of the polynomial.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('remez50:2:0.1');
+%
+%   References:
+%     O. Rioul and P. Duhamel. A remez exchange algorithm for orthonormal
+%     wavelets. Circuits and Systems II: Analog and Digital Signal
+%     Processing, IEEE Transactions on, 41(8):550 -560, aug 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_remez.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Original copyright goes to:
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+% Author: Jose Martin Garcia
+% e-mail: Uvi_Wave at tsc.uvigo.es
+
+if(nargin<3)
+     error('%s: Too few input parameters.',upper(mfilename)); 
+end
+
+
+poly=remezwav(L,K,B);
+rh=fc_cceps(poly);
+
+g{1} = rh;
+g{2} = -(-1).^(1:length(rh)).*g{1}(end:-1:1);
+ 
+h = g;
+
+a= [2;2];
+info.istight = 1;
+
+function [p,r]=remezwav(L,K,B)
+
+%REMEZWAV    P=REMEZWAV(L,K,B) gives impulse response of maximally
+%	     frequency selective P(z), product filter of paraunitary
+%	     filter bank solution H(z) of length L satisfying K flatness
+%	     constraints (wavelet filter), with normalized transition
+%	     bandwidth B (optional argument if K==L/2).
+% 
+%	     [P,R]=REMEZWAV(L,K,B) also gives the roots of P(z) which can
+%	     be used to determine H(z).
+%
+%	     See also: REMEZFLT, FC_CCEPS.
+%
+%	     References: O. Rioul and P. Duhamel, "A Remez Exchange Algorithm
+%			 for Orthonormal Wavelets", IEEE Trans. Circuits and
+%			 Systems - II: Analog and Digital Signal Processing,
+%			 41(8), August 1994
+%                                                                          
+%       Author: Olivier Rioul, Nov. 1, 1992 (taken from the
+%		above reference)
+%  Modified by: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+
+computeroots=(nargout>1);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%% STEP 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%
+if rem(L,2), error('L must be even'); end
+if rem(L/2-K,2), K=K+1; end
+N=L/2-K;
+%%%%%%%%%%%%%%%%%%%%%%%%%% STEP 2  %%%%%%%%%%%%%%%%%%%%%%%%%%
+% Daubechies solution
+% PK(z)=z^(-2K-1))+AK(z^2)
+if K==0, AK=0;
+else
+   binom=pascal(2*K,1);
+   AK=binom(2*K,1:K)./(2*K-1:-2:1);
+   AK=[AK AK(K:-1:1)];
+   AK=AK/sum(AK);
+end
+%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP 2' %%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Daubechies factor
+% PK(z)=((1+z^(-1))/2)^2*K QK(z)
+if computeroots && K>0
+   QK=binom(2*K,1:K);
+   QK=QK.*abs(QK);
+   QK=cumsum(QK);
+   QK=QK./abs(binom(2*K-1,1:K));
+   QK=[QK QK(K-1:-1:1)];
+   QK=QK/sum(QK)*2;
+end
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% output Daubechies solution PK(z)
+if K==L/2
+   p=zeros(1,2*L-1);
+   p(1:2:2*L-1)=AK; p(L)=1;
+   if computeroots
+      r=[roots(QK); -ones(L,1)];
+   end
+   return
+end
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP 4 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Daubechies polinomial
+% PK(x)=1+x*DK(x^2)
+if K==0, DK=0;
+else
+   binom=pascal(K,1);
+   binom=binom(K,:);
+   DK=binom./(1:2:2*K-1);
+   DK=fliplr(DK)/sum(DK);
+end
+
+wp=(1/2-B)*pi;  % cut-off frequency
+gridens=16*(N+1);  % grid density
+found=0;  % boolean for Remez loop
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP I %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Initial estimate of yk
+a=min(4,K)/10;
+yk=linspace(0,1-a,N+1);
+yk=(yk.^2).*(3+a-(2+a)*yk);
+yk=1-(1-yk)*(1-cos(wp)^2);
+ykold=yk;
+
+iter=0;
+while 1  % REMEZ LOOP
+iter=iter+1;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP II %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Compute delta
+Wyk=sqrt(yk).*((1-yk).^K);
+Dyk=(1-sqrt(yk).*polyval(DK,yk))./Wyk;
+for k=1:N+1
+   dy=yk-yk(k); dy(k)=[];
+   dy=dy(1:N/2).*dy(N:-1:N/2+1);
+   Lk(k)=prod(dy);
+end
+invW(1:2:N+1)=2./Wyk(1:2:N+1);
+delta=sum(Dyk./Lk)/sum(invW./Lk);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP III %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% compute R(y) on fine grid
+Ryk=Dyk-delta.*invW; Ryk(N+1)=[];
+Lk=(yk(1:N)-yk(N+1))./Lk(1:N);
+y=linspace(cos(wp)^2,1-K*1e-7,gridens);
+yy=ones(N,1)*y-yk(1:N)'*ones(1,gridens);
+% yy contain y-yk on each line
+ind=find(yy==0);  % avoid division by 0
+if ~isempty(ind)
+   yy(ind)=1e-30*ones(size(ind));
+end
+yy=1./yy;
+Ry=((Ryk.*Lk)*yy)./(Lk*yy);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP IV %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% find next yk
+Ey=1-delta-sqrt(y).*(polyval(DK,y)+((1-y).^K).*Ry);
+k=find(abs(diff(sign(diff(Ey))))==2)+1;
+% N extrema
+if length(k)>N
+% may happen if L and K are large 
+   k=k(1:N);
+end
+yk=[yk(1) y(k)];
+% N+1 extrema including wp
+if K==0, yk=[yk 1]; end
+% extrema at y==1 added
+if all(yk==ykold), break; end
+ykold=yk;
+
+end  % REMEZ LOOP
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  STEP A %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% compute impulse response
+w=(0:2*N-2)*pi/(2*N-1);
+y=cos(w).^2;
+yy=ones(N,1)*y-yk(1:N)'*ones(1,2*N-1);
+ind=find(yy==0);
+if ~isempty(ind)
+   yy(ind)=1e-30*ones(size(ind));
+end
+yy=1./yy;
+Ry=((Ryk.*Lk)*yy)./(Lk*yy);
+Ry(2:2:2*N-2)=-Ry(2:2:2*N-2);
+r=Ry*cos(w'*(2*(0:N-1)+1));
+% partial real IDFT done
+r=r/(2*N-1);
+r=[r r(N-1:-1:1)];
+p1=[r 0]+[0 r];
+pp=p1;  % save p1 for later use
+for k=1:2*K
+   p1=[p1 0]-[0 p1];
+end
+if rem(K,2), p1=-p1; end
+p1=p1/2^(2*K+1);
+p1(N+1:N+2*K)=p1(N+1:N+2*K)+AK;
+% add Daubechies response:
+p(1:2:2*L-1)=p1; p(L)=1;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEP A' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% compute roots
+if computeroots
+   Q(1:2:2*length(pp)-1)=pp;
+   for k=1:2*K
+     Q=[Q 0]-[0 Q];
+   end
+   if rem(K,2), Q=-Q; end
+   Q=Q/2;
+   if K>0  % add Daubechies factor QK
+      Q(2*N+1:L-1)=Q(2*N+1:L-1)+QK;
+   else
+      Q(L)=1;
+   end
+   r=[roots(Q); -ones(2*K,1)];
+end
+
+
+
+function  h=fc_cceps(poly,ro)
+
+%FC_CCEPS    Performs a factorization using complex cepstrum.
+%
+%	     H = FC_CCEPS (POLY,RO) provides H that is the spectral
+%	     factor of a FIR transfer function POLY(z) with non-negative 
+%	     frequency response. This methode let us obtain lowpass
+%	     filters of a bank structure without finding the POLY zeros.
+%	     The filter obtained is minimum phase (all zeros are inside
+%	     unit circle).
+%		
+%	     RO is a parameter used to move zeros out of unit circle.
+%	     It is optional and the default value is RO=1.02.
+%
+%	     See also: INVCCEPS, MYCCEPS, REMEZWAV.
+%
+%	     References: P.P Vaidyanathan, "Multirate Systems and Filter
+%			 Banks", pp. 849-857, Prentice-Hall, 1993
+
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+if nargin < 2
+	ro=1.02;
+end
+
+L=4096;   % number points of fft.
+
+N=(length(poly)-1)/2;
+
+%% Moving zeros out of unit circle
+roo=(ro).^[0:2*N];
+g=poly./roo;
+
+%% Calculate complex cepstrum of secuence g
+ghat=mycceps(g,L);
+
+%% Fold the anticausal part of ghat, add it to the causal part and divide by 2
+gcausal=ghat(1 : L/2);
+gaux1=ghat(L/2+1 : L);
+gaux2=gaux1(L/2 :-1: 1);
+gantic=[0 gaux2(1 : L/2-1)];
+
+xhat=0.5*(gcausal+gantic);
+
+%% Calculate cepstral inversion
+h=invcceps(xhat,N+1);
+ 
+%% Low-pass filter has energie sqrt(2)
+h=h*sqrt(2)/sum(h);
+
+
+function  x=invcceps(xhat,L)
+
+%INVCCEPS    Complex cepstrum Inversion
+%
+%	     X= INVCCEPS (CX,L) recovers X from its complex cepstrum sequence 
+%	     CX. X has to be real, causal, and stable (X(z) has no zeros  
+%	     outside unit circle) and x(0)>0. L is the length of the 
+%	     recovered secuence.
+%
+%	     See also: MYCCEPS, FC_CCEPS, REMEZWAV.
+%
+%	     References: P.P Vaidyanathan, "Multirate Systems and Filter
+%			 Banks", pp. 849-857, Prentice-Hall, 1993
+
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+
+x=zeros(1,L);
+
+%% First point of x
+x(1)=exp(xhat(1));
+
+%% Recursion to obtain the other point of x
+for muestra=1:L-1
+   for k=1:muestra
+	x(muestra+1)=x(muestra+1)+k/muestra*xhat(k+1)*x(muestra-k+1);
+   end
+end
+
+
+function xhat=mycceps(x,L)
+
+%MYCCEPS     Complex Cepstrum
+%
+%	     CX = MYCCEPS (X,L) calculates complex cepstrum of the
+%	     real sequence X. L is the number of points of the fft
+%	     used. L is optional and its default value is 1024 points.
+%
+%	     See also: FC_CEPS, INVCCEPS, REMEZWAV.
+
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+if nargin < 2
+   L=1024;
+end
+
+H = fft(x,L);
+
+%% H must not be zero
+ind=find(abs(H)==0);
+if length(ind) > 0 
+   H(ind)=H(ind)+1e-25;
+end
+
+logH = log(abs(H))+sqrt(-1)*rcunwrap(angle(H));
+
+xhat = real(ifft(logH));
+
+
+function y = rcunwrap(x)
+%RCUNWRAP Phase unwrap utility used by CCEPS.
+%	RCUNWRAP(X) unwraps the phase and removes phase corresponding
+%	to integer lag.  See also: UNWRAP, CCEPS.
+
+%	Author(s): L. Shure, 1988
+%		   L. Shure and help from PL, 3-30-92, revised
+%	Copyright (c) 1984-94 by The MathWorks, Inc.
+%       $Revision: 1.4 $  $Date: 1994/01/25 17:59:42 $
+
+n = max(size(x));
+y = unwrap(x);
+nh = fix((n+1)/2);
+y(:) = y(:)' - pi*round(y(nh+1)/pi)*(0:(n-1))/nh;
+
+
+
+
+
+
diff --git a/inst/wavelets/wfilt_spline.m b/inst/wavelets/wfilt_spline.m
new file mode 100644
index 0000000..74313ac
--- /dev/null
+++ b/inst/wavelets/wfilt_spline.m
@@ -0,0 +1,275 @@
+function [h,g,a,info]=wfilt_spline(m,n)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_spline
+%@verbatim
+% WFILT_SPLINE  Birthogonal spline wavelets
+%   Usage: [h,g,a]=wfilt_spline(m,n);
+%
+%   Input parameters:
+%         m     : Number of zeros at z=-1 of the lowpass filter in g{1}
+%         n     : Number of zeros at z=-1 of the lowpass filter in
+%                 h{1}. m+n must be even. 
+%
+%   [h,g,a]=WFILT_SPLINE(m,n) returns the analysis and synthesis filters
+%   corresponding to a biortoghonal scheme with spline wavelets of compact
+%   support.
+%
+%   Examples:
+%   ---------
+%   :
+%     figure(1);
+%     wfiltinfo('ana:spline4:4');
+%     figure(2);
+%     wfiltinfo('syn:spline4:4');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_spline.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+%   Original copyright goes to:
+%   Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%   Author: Jose Martin Garcia
+%   e-mail: Uvi_Wave at tsc.uvigo.es
+
+if(nargin<2)
+     error('%s: Too few input parameters.',upper(mfilename)); 
+end
+
+if(rem(m+n,2)~=0)
+    error('%s: M+N must be even.',upper(mfilename)); 
+end
+
+% Calculate rh coefficients, RH(z)=sqrt(2)*((1+z^-1)/2)^m;
+
+rh=sqrt(2)*(1/2)^m*binewton(m);
+
+% Calculate h coefficients, H(-z)=sqrt(2)*((1+z^-1)/2)^n*P(z)
+
+% First calculate P(z) (pol)
+
+if (rem(n,2)==0)
+   N=n/2+m/2;
+else
+   N=(n+m-2)/2+1;
+end
+
+pol=trigpol(N);
+
+% Now calculate ((1+z*-1)/2)^n;
+
+r0=(1/2)^n*binewton(n);
+
+
+hrev=sqrt(2)*conv(r0,pol);
+
+l=length(hrev);
+hh=hrev(l:-1:1);
+
+
+[h{2}, g{2}]=calhpf(hh,rh);
+h{1} = hh;
+g{1} = rh;
+
+if(length(h{1})>length(h{2}))
+    if(rem(length(h{1}),2)~=1)
+       r0 = (length(h{1})-length(h{2}))/2;
+       l0 = r0;
+    else
+       r0 = (length(h{1})-length(h{2}))/2+1;
+       l0 = (length(h{1})-length(h{2}))/2-1;
+    end
+      h{2} = [zeros(1,l0), h{2}, zeros(1,r0) ];
+else
+    if(rem(length(h{1}),2)~=1)
+       r0 = (length(h{2})-length(h{1}))/2;
+       l0 = r0;
+    else
+       r0 = (length(h{2})-length(h{1}))/2+1;
+       l0 = (length(h{2})-length(h{1}))/2-1;
+    end
+      h{1} = [zeros(1,l0), h{1}, zeros(1,r0) ];
+end
+
+if(length(g{1})>length(g{2}))
+    if(rem(length(g{1}),2)~=1)
+       r0 = (length(g{1})-length(g{2}))/2;
+       l0 = r0;
+    else
+       r0 = (length(g{1})-length(g{2}))/2+1;
+       l0 = (length(g{1})-length(g{2}))/2-1;
+    end
+      g{2} = [zeros(1,l0), g{2}, zeros(1,r0) ];
+else
+    if(rem(length(g{1}),2)~=1)
+       r0 = (length(g{2})-length(g{1}))/2;
+       l0 = r0;
+    else
+       r0 = (length(g{2})-length(g{1}))/2+1;
+       l0 = (length(g{2})-length(g{1}))/2-1;
+    end
+      g{1} = [zeros(1,l0), g{1}, zeros(1,r0) ];
+end
+
+% adding "the convenience" zero
+if(rem(length(h{1}),2))
+    h{1}= [0, h{1}];
+    h{2}= [0, h{2}];
+    g{1}= [0, g{1}];
+    g{2}= [0, g{2}];
+end
+
+h = cellfun(@(hEl) hEl(end:-1:1),h,'UniformOutput',0);
+a= [2;2];
+info.istight = 0;
+
+
+function c=binewton(N)
+
+% BINEWTON generate coefficients of Newton binomial.
+%        
+%          BINEWTON(N) generates the N+1 coefficients of
+%          the Nth order Newton binomial.
+%
+%          See also: NUMCOMB   
+
+%-------------------------------------------------------- 
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Nuria Gonzalez Prelcic
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+c=[1];
+for j=1:N,
+    c=[c,numcomb(N,j)];
+end
+
+function y=numcomb(n,k)
+
+if n==k,
+   y=1;
+elseif k==0,
+   y=1;
+elseif k==1,
+   y=n;
+else 
+   y=fact(n)/(fact(k)*fact(n-k));
+end
+
+function y=fact(x)
+
+for j=1:length(x)
+    if x(j)==0,
+       y(j)=1;
+    else
+       y(j)=x(j)*fact(x(j)-1);
+    end
+end
+
+function polinomio=trigpol(N)
+
+coefs=zeros(N,2*N-1);
+coefs(1,N)=1;
+
+ 
+for i=1:N-1
+	fila=[1 -2 1];
+	for j=2:i
+		fila=conv(fila,[1 -2 1]);
+	end;
+	fila=numcomb(N-1+i,i)*(-0.25)^i*fila;
+	fila=[ zeros(1,(N-i-1))  fila zeros(1,(N-i-1))];
+	coefs(i+1,:)=fila;
+end
+
+for i=0:(2*(N-1))
+	polinomio(i+1)=0;
+	for j=1:N
+		polinomio(i+1)=polinomio(i+1)+coefs(j,i+1);
+	end
+end;
+
+
+function [g,rg]=calhpf(h,rh)
+
+% CALHPF   Obtain high pass analysis and synthesis filters 
+%          in a biortoghonal filterbank.
+
+lrh=length(rh);    
+
+if (rem(lrh,2))   % rh has odd length 
+   nrh=(lrh-1)/2; % Support [-nrh,nrh]            
+else              % rh has even length
+   nrh=lrh/2-1;     % Support [-nrh,nrh+1]
+end 
+
+
+if (rem(nrh,2))   % nrh is odd
+   flag=1;
+else              % nrh is even 
+   flag=0;
+end 
+
+grev=chsign(rh(lrh:-1:1),flag);
+g=grev(lrh:-1:1);
+
+
+lh=length(h);
+
+if (rem(lh,2))   % h has odd length 
+   nh=(lh-1)/2; % Support [-nh,nh]
+else              % h has even length
+   nh=lh/2-1;     % Support [-nh,nh+1]
+end
+
+if (rem(nh,2))% nh is odd
+      flag=1;
+else
+      flag=0;     % nh is even  
+end
+
+rg=chsign(h,flag);
+
+
+function y=chsign(x,flag)
+lx=length(x);
+if (flag==1)
+   y=(-1).^(1:lx).*x;
+else
+   y=-(-1).^(1:lx).*x;
+end 
+
+
+
+
diff --git a/inst/wavelets/wfilt_sym.m b/inst/wavelets/wfilt_sym.m
new file mode 100644
index 0000000..c6fa731
--- /dev/null
+++ b/inst/wavelets/wfilt_sym.m
@@ -0,0 +1,419 @@
+function [h,g,a,info]=wfilt_sym(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_sym
+%@verbatim
+%WFILT_SYM Symlet filters 
+%   Usage: [h,g,a]=wfilt_sym(N);    
+%
+%   [h,g,a]=WFILT_SYM(N) generates the "least asymmetric" Daubechies'
+%   wavelets or "symlets".  Zeros of the trigonometrical polynomial the
+%   filters of are selected alternatingly inside and outside the unit
+%   circle.
+%
+%   Examples:
+%   ---------
+%   :
+%
+%     wfiltinfo('sym8');
+%   
+%   References:
+%     I. Daubechies. Ten Lectures on Wavelets. Society for Industrial and
+%     Applied Mathematics, Philadelphia, PA, USA, 1992.
+%     
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_sym.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Original copyright goes to:
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+% Author: Jose Martin Garcia
+% e-mail: Uvi_Wave at tsc.uvigo.es
+
+num_coefs = 2*N;
+a = [2;2];
+info.istight = 1;
+
+if num_coefs==2	    % Haar filters
+	g{1} = 0.5*[sqrt(2) sqrt(2)];
+    g{2} = 0.5*[sqrt(2) -sqrt(2)];
+    h = g;
+	return
+end
+
+N=num_coefs/2;
+
+poly=trigpol(N);    %Calculate trigonometric polynomial 
+
+ceros=roots(poly);  %Calculate roots
+
+realzeros=[];
+imagzeros=[];
+numrealzeros=0;
+numimagzeros=0;
+
+for i=1:2*(N-1)
+	if (imag(ceros(i))==0)
+		numrealzeros=numrealzeros+1;
+		realzeros(numrealzeros)=ceros(i);
+	else
+		numimagzeros=numimagzeros+1;
+		imagzeros(numimagzeros)=ceros(i);
+	end
+end
+
+
+%% complex zeros are grouped together
+i=0;
+for cont=1:numimagzeros/4
+	modulos(cont)=abs(imagzeros(cont+i));
+	alfa(cont)=angle(imagzeros(cont+i));
+	i=i+1;
+end
+
+%% Calculate phase contribution of complex and real zeros for all the
+%% combination of these zeros. Each group of zeros is identified with a binary
+%% number.
+
+indice=2^(numimagzeros/4+numrealzeros/2);
+fase=zeros(indice,1001);
+for cont=0:indice-1,
+	bin=dec2bina(cont,log2(indice));
+   	for i=1:length(bin)-numrealzeros/2
+		if bin(i)
+			R=1/modulos(i);
+		else
+			R=modulos(i);
+		end
+		alf=alfa(i);
+		fase(cont+1,:)=fase(cont+1,:)+atang1(R,alf);
+	end
+	ind=1;
+	for i=length(bin)-numrealzeros/2+1:length(bin)
+		if bin(i)
+			R=realzeros(ind+1);		
+			R=realzeros(ind+1);
+		else
+			R=realzeros(ind);
+		end
+		ind=ind+2;
+	 	fase(cont+1,:)=fase(cont+1,:)+atang2(R);
+
+	end	
+end
+
+%% To retain only the non linear part of the phase.
+
+fas=linealiz(fase);
+
+imagzeros=[];
+zerosreales=[];
+
+
+%% To see which phase is closer to zero we select the one with minimun variance
+
+[maximo,pos]=min(sum(fas'.^2));  
+
+bin=dec2bina(pos-1,log2(indice));
+
+for i=1:length(bin)-numrealzeros/2
+	if bin(i)
+		z1=1/modulos(i)*exp(j*alfa(i));
+	else
+		z1=modulos(i)*exp(j*alfa(i));	
+	end
+	imagzeros=[imagzeros z1 conj(z1)];
+end
+
+ind=1;
+for i=length(bin)-numrealzeros/2+1:length(bin)
+	if bin(i)
+		zerosreales=[zerosreales realzeros(ind+1)];
+	else
+		zerosreales=[zerosreales realzeros(ind)];
+	end
+	ind=ind+2;
+end
+
+% Construction of rh from its zeros
+
+numrealzeros=numrealzeros/2;
+numimagzeros=numimagzeros/2;
+
+rh=[1 1];
+
+for i=2:N
+	rh=conv(rh,[1 1]);
+end
+
+for i=1:numrealzeros
+	rh=conv(rh,[1 -zerosreales(i)]);
+end
+
+for i=1:2:numimagzeros
+	rh=conv(rh,[1 -2*real(imagzeros(i)) abs(imagzeros(i))^2]);
+end
+
+% Once ho is factorized in its zeros, it must be normalized multiplying by "cte".
+
+cte=sqrt(2)/sum(rh);
+rh=cte*rh;
+fLen = length(rh);
+
+g{1} = rh;
+g{2} = -(-1).^(1:fLen).*g{1}(end:-1:1);
+ 
+h = g;
+
+
+
+function  bin=dec2bina(num,bits)
+
+%DEC2BINA    BIN = DEC2BINA(NUM,BITS) returns a vector which contains 
+%	     the decimal number NUM in binary format, with a number of 
+%	     digits equal to BITS. It is an auxiliary function used by
+%	     SYMLETS.
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+
+if nargin<2
+	flag=0;
+else
+	flag=1;
+end
+
+bin=[];
+coc=num;
+while coc>1
+	bin=[rem(coc,2) bin];
+	coc=fix(coc/2);
+end
+bin=[coc bin];
+if flag 
+ 	if length(bin)<bits
+		bin=[zeros(1,bits-length(bin)) bin];
+	end
+end
+
+function fase=atang1(R,alfa)
+
+%ATANG1    PHASE=ATANG1(R,ALFA) returns the phase contribution
+%	   of a complex pair of zeros. Linear terms have been
+%	   removed. It is an auxiliary function used by SYMLETS.
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+
+w=[0:2*pi/1e3:2*pi];		%frequency axis
+
+fas=atan( (1-R^2)*sin(w)./((1+R^2)*cos(w)-2*R*cos(alfa)) );
+
+zero=acos(2*R*cos(alfa)/(1+R^2));
+u1=ceil(zero*1000/(2*pi))+1;
+u2=ceil((2*pi-zero)*1000/(2*pi))+1;
+if (1-R^2)*sin(zero)<0
+	cte=pi;
+	fase=fas+w;
+else
+	fase=fas-w;
+	cte=-pi;
+end
+fase(u1:1001)=fase(u1:1001)-cte;
+fase(u2:1001)=fase(u2:1001)-cte;
+
+function fase=atang2(R)
+
+%ATANG2    PHASE=ATANG2(R) returns the phase contribution of
+%	   a real zero. Linear terms have been removed. It is
+%	   an auxiliary function used by SYMLETS.
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+
+w=[0:2*pi/1e3:2*pi];	%frequency axis
+
+fas=atan( (1+R)/(1-R)*tan(w/2) );
+
+if R<1
+	fase=fas-w;
+	cte=-pi;
+else
+	fase=fas+w;
+	cte=pi;
+end;
+u=ceil(pi*1000/(2*pi))+2;
+fase(u:1001)=fase(u:1001)-cte;
+
+function fase=linealiz(f)
+
+%LINEALIZ     PHASE = LINEALIZ(F) is an auxiliary function used
+%	      by SYMLETS. It eliminates the linearity of the
+%	      phase vector F.
+
+
+%--------------------------------------------------------
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+%                                                      
+%                                                      
+% Uvi_Wave is free software; you can redistribute it and/or modify it      
+% under the terms of the GNU General Public License as published by the    
+% Free Software Foundation; either version 2, or (at your option) any      
+% later version.                                                           
+%                                                                          
+% Uvi_Wave 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 Uvi_Wave; see the file COPYING.  If not, write to the Free    
+% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.             
+%                                                                          
+%       Author: Jose Martin Garcia
+%       e-mail: Uvi_Wave at tsc.uvigo.es
+%--------------------------------------------------------
+
+
+if abs(sum(f(1,:))) >0.0001
+	w=[0:2*pi/1e3:2*pi];
+	[m,n]=size(f);
+	fase=zeros(m,n);
+	for cont=1 : m
+		if sum(f(cont,:)) >0
+			fase(cont,:)=f(cont,:)-w/2;
+		else
+			fase(cont,:)=f(cont,:)+w/2;
+		end
+	end
+else
+	fase=f;
+end 
+
+function polinomio=trigpol(N)
+
+coefs=zeros(N,2*N-1);
+coefs(1,N)=1;
+
+ 
+for i=1:N-1
+	fila=[1 -2 1];
+	for j=2:i
+		fila=conv(fila,[1 -2 1]);
+	end;
+	fila=numcomb(N-1+i,i)*(-0.25)^i*fila;
+	fila=[ zeros(1,(N-i-1))  fila zeros(1,(N-i-1))];
+	coefs(i+1,:)=fila;
+end
+
+for i=0:(2*(N-1))
+	polinomio(i+1)=0;
+	for j=1:N
+		polinomio(i+1)=polinomio(i+1)+coefs(j,i+1);
+	end
+end; 
+
+function y=numcomb(n,k)
+
+if n==k,
+   y=1;
+elseif k==0,
+   y=1;
+elseif k==1,
+   y=n;
+else 
+   y=fact(n)/(fact(k)*fact(n-k));
+end
+
+function y=fact(x)
+
+% FACT   Factorial.
+%        FACT(X) is the factorial of the elements in X vector.
+
+for j=1:length(x)
+    if x(j)==0,
+       y(j)=1;
+    else
+       y(j)=x(j)*fact(x(j)-1);
+    end
+end
+
+
+
+
diff --git a/inst/wavelets/wfilt_symds.m b/inst/wavelets/wfilt_symds.m
new file mode 100644
index 0000000..935b554
--- /dev/null
+++ b/inst/wavelets/wfilt_symds.m
@@ -0,0 +1,235 @@
+function [h,g,a,info] = wfilt_symds(N)
+%-*- texinfo -*-
+%@deftypefn {Function} wfilt_symds
+%@verbatim
+%WFILT_SYMDS  Symmetric wavelets dyadic sibling
+%   Usage: [h,g,a] = wfilt_symds(N);
+%
+%   [h,g,a]=WFILT_SYMDS(N) Returns symmetric dyadic sibling wavelet filters.
+%   The redundancy is equal to 2.
+%
+%   Examples:
+%   ---------
+%   :
+%     figure(1);
+%     wfiltinfo('ana:symds3');
+%     figure(2);
+%     wfiltinfo('syn:symds3');
+% 
+%   References:
+%     F. Abdelnour. Symmetric wavelets dyadic sibling and dual frames. Signal
+%     Processing, 92(5):1216 - 1229, 2012. [1]http ]
+%     
+%     
+%     References
+%     
+%     1. http://www.sciencedirect.com/science/article/pii/S0165168411003963
+%     
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfilt_symds.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+info.istight = 0;
+a = [2;2;2;2];
+
+switch(N)
+ case 1
+    % Example 1. Not a tight frame!
+    harr = [
+        -5    3     -1   0
+        -7    17    -2   -1
+        35    11    -3   -2
+        105   -31   12   -3
+        105   -31   -3   12
+        35    11    -2   -3
+        -7    17    -1   -2
+        -5    3     0    -1
+    ];
+    harr(:,1)=harr(:,1)*sqrt(2)/2^8;
+    harr(:,2)=harr(:,2)/2^7;
+    harr(:,3:4)=harr(:,3:4)/2^4;
+
+
+    if(nargout>1)
+    garr = [
+        0    0     0    0
+        -3   -5    0    -1
+        5    -13   -1   -2
+        30   18    -2   6
+        30   18    6    -2
+        5    -13   -2   -1
+        -3   -5    -1   0
+        0    0     0    0
+    ]; 
+    garr(:,1)=garr(:,1)*sqrt(2)/2^6;
+    garr(:,2)=garr(:,2)/2^6;
+    garr(:,3:4)=garr(:,3:4)/2^3;
+    end;
+case 2
+    % Example 2. Not a tight frame!
+    harr = [
+       0                  0                  0           0 
+       0                  0                  0           0 
+       0                  -sqrt(2)/2^5       -1/2^3      0        
+       -sqrt(2)/2^5       -4*sqrt(2)/2^5     -2/2^3      -1/2^3 
+       0                  sqrt(2)/2^5        6/2^3       -2/2^3
+       9*sqrt(2)/2^5      8*sqrt(2)/2^5      -2/2^3      6/2^3 
+       16*sqrt(2)/2^5     sqrt(2)/2^5        -1/2^3      -2/2^3
+       9*sqrt(2)/2^5      -4*sqrt(2)/2^5     0           -1/2^3
+       0                  -sqrt(2)/2^5       0           0
+       -sqrt(2)/2^5       0                  0           0
+    ];
+
+    if(nargout>1)
+    garr = [
+           -sqrt(2)/2^5       0                  0           1/2^6 
+           0                  -sqrt(2)/2^5       1/2^6       2/2^6
+           9*sqrt(2)/2^5      -4*sqrt(2)/2^5     2/2^6       0 
+           16*sqrt(2)/2^5     sqrt(2)/2^5        0           -18/2^6
+           9*sqrt(2)/2^5      8*sqrt(2)/2^5      -18/2^6     30/2^6
+           0                  sqrt(2)/2^5        30/2^6      -18/2^6
+           -sqrt(2)/2^5       -4*sqrt(2)/2^5     -18/2^6     0
+           0                  -sqrt(2)/2^5       0           2/2^6
+           0                  0                  2/2^6       1/2^6
+           0                  0                  1/2^6       0
+         ];   
+    end;
+    
+case 3
+    % Example 3. Not a tight frame!
+    harr = [
+       0                       35*sqrt(2)/2^12       0.003385355341795    0    
+       35*sqrt(2)/2^12         185*sqrt(2)/2^12      0.011757930078244    0.003385355341795
+       -45*sqrt(2)/2^12        208*sqrt(2)/2^12      0.038383315957975    0.011757930078244
+       -252*sqrt(2)/2^12       -648*sqrt(2)/2^12     0.127426546608992    0.038383315957975
+       420*sqrt(2)/2^12        -706*sqrt(2)/2^12     -0.112865104706813   0.127426546608992
+       1890*sqrt(2)/2^12       706*sqrt(2)/2^12      -0.710280910094278   -0.112865104706813
+       1890*sqrt(2)/2^12       648*sqrt(2)/2^12      0.710280910094278    -0.710280910094278
+       420*sqrt(2)/2^12        -208*sqrt(2)/2^12     0.112865104706813    0.710280910094278
+       -252*sqrt(2)/2^12       -185*sqrt(2)/2^12     -0.127426546608992   0.112865104706813
+       -45*sqrt(2)/2^12        -35*sqrt(2)/2^12      -0.038383315957975   -0.127426546608992
+       35*sqrt(2)/2^12         0                     -0.011757930078244   -0.038383315957975
+       0                       0                     -0.003385355341795   -0.011757930078244
+       0                       0                     0                    -0.003385355341795
+    ];
+
+    if(nargout>1)
+    garr = [
+%            0	                  0	                   0	                   0
+            0	                  0	                   0	                   0
+            35*sqrt(2)/2^12	      0	                   0	                   -0.043136204314165
+            -45*sqrt(2)/2^12	  35*sqrt(2)/2^12	   -0.043136204314165	   -0.022725249453801
+            -252*sqrt(2)/2^12	  185*sqrt(2)/2^12	   -0.022725249453801	   -0.016002341917868
+            420*sqrt(2)/2^12	  208*sqrt(2)/2^12	   -0.016002341917868	   0.463586703221768
+            1890*sqrt(2)/2^12	  -648*sqrt(2)/2^12	   0.463586703221768	   -0.463586703221768
+            1890*sqrt(2)/2^12	  -706*sqrt(2)/2^12	   -0.463586703221768	   0.016002341917868
+            420*sqrt(2)/2^12	  706*sqrt(2)/2^12	   0.016002341917868	   0.022725249453801
+            -252*sqrt(2)/2^12	  648*sqrt(2)/2^12	   0.022725249453801	   0.043136204314165
+            -45*sqrt(2)/2^12	  -208*sqrt(2)/2^12	   0.043136204314165	   0
+            35*sqrt(2)/2^12	      -185*sqrt(2)/2^12	   0	                   0
+            0	                  -35*sqrt(2)/2^12	   0	                   0
+      ];   
+    end;
+case 4
+    % Example 4. Not a tight frame!
+    harr = [
+       0       99        0.0008317898274     0 
+       99      837       0.00527762349601    0.0008317898274
+       351     2630      0.01705880266437    0.00527762349601 
+       -286    2778      0.02633268946272    0.01705880266437
+       -2574   -3195     0.03753999326488    0.02633268946272    
+       -1287   -10429    -0.00195902477575   0.03753999326488   
+       10725   -6348     -0.0711227784702    -0.00195902477575
+       25740   6348      -0.54534348089652   -0.0711227784702    
+       25740   10429     0.54534348089652    -0.54534348089652  
+       10725   3195      0.0711227784702     0.54534348089652   
+       -1287   -2778     0.00195902477575    0.0711227784702
+       -2574   -2630     -0.03753999326488   0.00195902477575
+       -286    -837      -0.02633268946272   -0.03753999326488
+       351     -99       -0.01705880266437   -0.02633268946272
+       99       0         -0.00527762349601   -0.01705880266437
+       0       0         -0.0008317898274    -0.00527762349601
+       0       0         0                   -0.0008317898274
+  ];
+   harr(:,1:2)=harr(:,1:2)*sqrt(2)/2^16;
+
+    if(nargout>1)
+    garr = [
+    %     0        0        0                  0 
+         0        0        0                  0
+         99       0        0                  -0.0054868984046
+         351      99       -0.0054868984046   -0.03102895771555
+         -286     837      -0.03102895771555  -0.05109382225012
+         -2574    2630     -0.05109382225012  -0.05321999995116
+         -1287    2778     -0.05321999995116   0.1089262550963
+         10725    -3195    0.1089262550963     0.6365944921083
+         25740    -10429   0.6365944921083     -0.6365944921083
+         25740    -6348    -0.6365944921083    -0.1089262550963
+         10725    6348     -0.1089262550963    0.05321999995116
+         -1287    10429    0.05321999995116    0.05109382225012
+         -2574    3195     0.05109382225012    0.03102895771555
+         -286     -2778    0.03102895771555    0.0054868984046
+         351      -2630    0.0054868984046     0
+         99       -837     0                   0
+         0        -99      0                   0
+
+      ];   
+     garr(:,1:2)=garr(:,1:2)*sqrt(2)/2^16;
+    end;
+case 5
+    % Example 5. Not a tight frame!
+    harr = [
+        -5   35     0      5
+        -7   -35    35     -7
+        35   -665   -35    -35
+        105  665    -665   105
+        105  665    665    -105
+        35   -665   665    35
+        -7   -35    -665   7
+        -5   35     -35    -5
+        0    0      35     0
+   ];
+   harr(:,[1 4])=harr(:,[1 4])*sqrt(2)/2^8;
+   harr(:,2:3)=harr(:,2:3)*sqrt(2)/2^12;
+
+    if(nargout>1)
+    garr = [
+      %  0    0    0     0
+        -5   0    -1    -5
+        -7   -1   -1    7
+        35   -1   2     35
+        105  2    2     -105
+        105  2    -1    105
+        35   -1   -1    -35
+        -7   -1   0     -7
+        -5   0    0     5
+      ];   
+     garr(:,[1 4])=garr(:,[1 4])*sqrt(2)/2^8;
+     garr(:,2:3)=garr(:,2:3)*sqrt(2)/2^3;
+    end;
+  otherwise
+        error('%s: No such filters.',upper(mfilename)); 
+
+end
+
+g=mat2cell(garr,size(garr,1),ones(1,size(garr,2)));
+h=mat2cell(flipud(harr),size(harr,1),ones(1,size(harr,2)));
+
+
diff --git a/inst/wavelets/wfiltinfo.m b/inst/wavelets/wfiltinfo.m
new file mode 100644
index 0000000..8779226
--- /dev/null
+++ b/inst/wavelets/wfiltinfo.m
@@ -0,0 +1,139 @@
+function wfiltinfo(w)
+%-*- texinfo -*-
+%@deftypefn {Function} wfiltinfo
+%@verbatim
+%WFILTINFO Plots filters info
+%   Usage: wfiltinfo(w);
+%
+%   Input parameters:
+%         w     : Wavelet filterbank
+%
+%   Plots impulse responses, frequency responses and approximation of
+%   the scaling of the wavelet function(s) associated withthe wavelet filters
+%   defined by w in a single figure. Format of w is the same as in FWT.
+%
+%   Examples:
+%   ---------
+%   
+%   Details of the 'syn:spline8:8' wavelet filters (see WFILT_SPLINE):
+%   
+%      wfiltinfo('syn:spline8:8');
+%   
+%   Details of the 'ana:spline8:8' wavelet filters:
+%
+%      wfiltinfo('ana:spline8:8');
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfiltinfo.php}
+%@seealso{wfilt_db}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+w = fwtinit({'strict',w});
+filtNo = length(w.g);
+
+grayLevel = [0.6,0.6,0.6];
+
+
+colorAr = repmat('rbkcmg',1,filtNo);
+
+subplot(4,filtNo,1);
+title('Scaling imp. response');
+loAna = w.g{1}.h;
+loShift = -w.g{1}.offset;
+xvals = -loShift + (1:length(loAna));
+hold on;
+if ~isempty(loAna(loAna==0))
+   stem(xvals(loAna==0),loAna(loAna==0),'Color',grayLevel);
+end
+
+loAnaNZ = find(loAna~=0);
+stem(xvals(loAnaNZ),loAna(loAnaNZ),colorAr(1));
+axis tight;
+hold off;
+
+for ff=2:filtNo
+    subplot(4,filtNo,ff);
+    title(sprintf('Wavelet imp. response no: %i',ff-1));
+    filtAna = w.g{ff}.h;
+    filtShift = -w.g{ff}.offset;
+    xvals = -filtShift + (1:length(filtAna));
+    filtNZ = find(filtAna~=0);
+    hold on;
+    
+    if ~isempty(filtAna(filtAna==0))
+       stem(xvals(filtAna==0),filtAna(filtAna==0),'Color',grayLevel);
+    end
+    
+    stem(xvals(filtNZ),filtAna(filtNZ),colorAr(ff));
+    axis tight;
+    hold off;
+end
+
+[wfn,sfn,xvals] = wavfun(w,'fft');
+subplot(4,filtNo,[filtNo+1]);
+
+plot(xvals(:,end),sfn,colorAr(1));
+axis tight;
+title('Scaling function');
+
+for ff=2:filtNo
+   subplot(4,filtNo,[filtNo+ff]);
+   plot(xvals(:,ff-1),wfn(:,ff-1),colorAr(ff));
+   axis tight;
+   title(sprintf('Wavelet function: %i',ff-1));
+end
+
+subplot(4,filtNo,2*filtNo + (1:filtNo) );
+title('Magnitude frequency response');
+maxLen=max(cellfun(@(gEl) numel(gEl.h),w.g));
+Ls = nextfastfft(max([maxLen,1024]));
+H = zeros(Ls,filtNo);
+for ii=1:filtNo
+   H(:,ii) = comp_transferfunction(w.g{ii},Ls);
+end
+
+%[H] = wtfftfreqz(w.g);
+plotH = 20*log10(abs(H));
+xVals = linspace(0,1,numel(H(:,1)));
+hold on;
+for ff=1:filtNo
+   plot(xVals,plotH(:,ff),colorAr(ff));
+   axis tight;
+end
+ylim([-30,max(plotH(:))])
+ylabel('|\itH|[dB]');
+xlabel('\omega [-]')
+hold off;
+
+subplot(4,filtNo,3*filtNo + (1:filtNo) );
+title('Phase frequency response');
+hold on;
+for ff=1:filtNo
+   plot(xVals,unwrap(angle((H(:,ff))))/pi,colorAr(ff));
+   axis tight;
+end
+ylabel('arg H(\omega)[\pi rad]');
+xlabel('\omega [-]')
+
+axis tight;
+% plot(unwrap(angle([H])));
+% axis tight;
+hold off;
+
diff --git a/inst/wavelets/wfreq_lemarie.m b/inst/wavelets/wfreq_lemarie.m
new file mode 100644
index 0000000..985213b
--- /dev/null
+++ b/inst/wavelets/wfreq_lemarie.m
@@ -0,0 +1,74 @@
+function [H,G] = wfreq_lemarie(L)
+%-*- texinfo -*-
+%@deftypefn {Function} wfreq_lemarie
+%@verbatim
+%WFREQ_LEMARIE  Battle and Lemarie filters frequency resp. sampling
+%   Usage: [H,G]=wfreq_lemarie(L)
+%
+%   Input parameters:
+%         N     : Number of samples of the frequency response.
+%
+%   [H,G]=wfreq_lemaire(L) calculates L samples of the Battle and
+%   Lemarie filters frequency responses.
+%
+%   References:
+%     S. G. Mallat. A theory for multiresolution signal decomposition: The
+%     wavelet representation. IEEE Trans. Pattern Anal. Mach. Intell.,
+%     11(7):674-693, July 1989. [1]http ]
+%     
+%     References
+%     
+%     1. http://dx.doi.org/10.1109/34.192463
+%     
+%
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wfreq_lemarie.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+% Original copyright goes to:
+% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo 
+% Author: Jose Martin Garcia
+% e-mail: Uvi_Wave at tsc.uvigo.es
+
+
+% frequency axis
+w=[0:2*pi/L:2*pi*(1-1/L)];
+w(1)=eps;
+w(L/2+1)=w(L/2+1)+1e-15;
+
+% calculation of frequency response of analysis lowpass filter 
+num=0;den=0;
+K=36;
+for k=-K:K,
+	num=1./((w+2*pi*k).^8)+num;
+	den=1./((2*w+2*pi*k).^8)+den;
+end
+H = cell(2,1);
+H{1}=sqrt(num./(2.^8*den));
+H{1}(1)=1;
+
+H{2} = fftshift(H{1});
+G = cell(2,1);
+G{1} = fliplr(H{1});
+G{2} = fliplr(H{2});
+
+
+
+
diff --git a/inst/wavelets/wpbest.m b/inst/wavelets/wpbest.m
new file mode 100644
index 0000000..859fa6b
--- /dev/null
+++ b/inst/wavelets/wpbest.m
@@ -0,0 +1,395 @@
+function [c,info] = wpbest(f,w,J,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wpbest
+%@verbatim
+%WPBEST  Best Tree selection
+%   Usage: c = wpbest(f,w,J,cost);
+%          [c,info] = wpbest(...);
+%
+%   Input parameters:
+%         f   : Input data.
+%         w   : Wavelet Filterbank.
+%         J   : Maximum depth of the tree.
+%
+%   Output parameters:
+%         c     : Coefficients stored in a cell-array.
+%         info  : Transform parameters struct.
+%
+%   [c,info]=WPBEST(f,w,J,cost) selects the best sub-tree info.wt from 
+%   the full tree with max. depth J, which minimizes the cost function.
+%
+%   Only one-dimensional input f is accepted. The supported formats of 
+%   the parameter w can be found in help for FWT. The format of the
+%   coefficients c and the info struct is the same as in WFBT. 
+%
+%   First, the depth J wavelet packet decomposition is performed using WPFBT.
+%   Then the nodes are traversed in the breadth-first and bottom-up order
+%   and the value of the cost function of the node input and cost of the 
+%   combined node outputs is compared. If the node input cost function value
+%   is less than the combined output cost, the current node and all 
+%   possible descendant nodes are marked to be deleted, if not, the input is
+%   assigned the combined output cost. At the end, the marked nodes are 
+%   removed and the resulting tree is considered to be a best basis (or 
+%   near-best basis) in the chosen cost function sense.
+%
+%   The cost parameter can be a cell array or an user-defined function handle. 
+%   accepting a single column vector. The cell array should consist of a 
+%   string, followed by a numerical arguments.
+%   The possible formats are listed in the following text.
+%
+%   Additive costs:
+%   ---------------
+%
+%   The additive cost E of a vector x is a real valued cost function
+%   such that:
+%
+%                    
+%      E(x) = sum E(x(k)), 
+%              k  
+%
+%   and E(0)=0. Given a collection of vectors x_i being coefficients in
+%   orthonormal bases B_i, the best basis relative to E is the one for 
+%   which the E(x_i) is minimal. 
+%
+%   Additive cost functions allows using the fast best-basis search algorithm
+%   since the costs can be precomputed and combined cost of two vectors is 
+%   just a sum of their costs.
+%
+%   {'shannon'}
+%      A cost function derived from the Shannon entropy:
+%
+%                       
+%         E_sh(x) = -sum |x(k)|^2 log(|x(k)|^2), 
+%                 k:x(k)~=0  
+%
+%   {'log'}
+%      A logarithm of energy:
+%
+%                       
+%         E_log(x) = sum log(|x(k)|^2), 
+%                  k:x(k)~=0  
+%
+%   {'lpnorm',p}
+%      Concentration in l^p norm:
+%
+%                       
+%         E_lp(x) = ( sum (|x(k)|^p) ), 
+%                      k  
+%
+%   {'thre',th}
+%      Number of coefficients above a threshold th.
+%
+%
+%   Non-additive costs:
+%   -------------------
+%
+%   Cost function, which is not additive cost but which is used for the
+%   basis selection is called a non-additive cost. The resulting basis for
+%   which the cost is minimal is called near-best, because the non-additive
+%   cost cannot guarantee the selection of a best basis relative to the 
+%   cost function.
+%
+%   {'wlpnorm',p}
+%      The weak-l^p norm cost function:
+%
+%                       
+%         E_wlp(x) = max k^{\frac{1}{p}}v_k(x), 
+%
+%      where 0<p<= 2 and v_k(x) denotes the k*-th largest absolute value
+%      of x.
+%
+%   {'compn',p,f}
+%      Compression number cost:
+%
+%                       
+%         E_cn(x) = arg min |w_k(x,p) - f|, 
+%                     k
+%                   
+%      where 0<p<= 2, 0<f<1 and w_k(u,p) denotes decreasingly sorted,
+%      powered, cumulateively summed and renormalized vector:
+%
+%                     k              N
+%         w_k(x,p) = sum v_j^p(x) / sum v_j^p(x)
+%                    j=1            j=1 
+%
+%      where v_k(x) denotes the k*-th largest absolute value of x and
+%      N is the number of elements of x.
+%
+%   {'compa',p}
+%      Compression area cost:
+%
+%                       
+%         E_ca(x) = N - sum w_k(x,p), 
+%                        k
+%                   
+%      where 0<p<= 2 and w_k(u,p) and N as in the previous case.
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling WPBEST :
+%     
+%     f = gspi;
+%     J = 8;
+%     [c,info] = wpbest(f,'sym10',J,'cost','shannon');
+%
+%     % Use 2/3 of the space for the first plot, 1/3 for the second.
+%     subplot(3,3,[1 2 4 5 7 8]);
+%     plotwavelets(c,info,44100,90);
+%
+%     subplot(3,3,[3 6 9]);
+%     N=cellfun(@numel,c); L=sum(N); a=L./N;
+%     plot(a,'o');
+%     xlim([1,numel(N)]);
+%     view(90,-90);
+%     xlabel('Channel no.');
+%     ylabel('Subsampling rate / samples');
+%
+%   References:
+%     M. V. Wickerhauser. Lectures on wavelet packet algorithms. In INRIA
+%     Lecture notes. Citeseer, 1991.
+%     
+%     C. Taswell. Near-best basis selection algorithms with non-additive
+%     information cost functions. In Proceedings of the IEEE International
+%     Symposium on Time-Frequency and Time-Scale Analysis, pages 13-16. IEEE
+%     Press, 1994.
+%     
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wpbest.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if nargin<3
+  error('%s: Too few input parameters.',upper(mfilename));
+end;
+
+if ~isnumeric(J) || ~isscalar(J)
+  error('%s: "J" must be a scalar.',upper(mfilename));
+end;
+
+if(J<1 || rem(J,1)~=0)
+   error('%s: J must be a positive integer.',upper(mfilename)); 
+end
+
+if numel(nonzeros(size(f)>1))>1
+   error('%s: Function accepts only single channel inputs.',upper(mfilename));
+end
+
+definput.import = {'fwt'};
+definput.flags.buildOrder = {'bottomup','topdown'};
+definput.flags.bestWhat = {'tree','level'};
+definput.keyvals.cost = {'shannon'};
+[flags,kv]=ltfatarghelper({'cost'},definput,varargin);
+
+
+if flags.do_topdown 
+    error('%s: Flag %s not supported yet.',upper(mfilename),flags.buildOrder);
+end
+
+if flags.do_level 
+    error('%s: Flag %s not supported yet.',upper(mfilename),flags.bestWhat);
+end
+
+if(~iscell(kv.cost))
+   kv.cost = {kv.cost}; 
+end
+
+% test if the chosen entropy measure is additive
+do_additive = isAdditive(kv.cost);
+
+if(flags.do_bottomup)
+   % Do full-tree Wavelet Packet decomposition beforehand and prune.
+   wt = wfbtinit({w,J,'full'},'nat');
+   c = wpfbt(f,wt,'nat',flags.ext,'noscale');
+    
+   % Nodes in the reverse BF order
+   treePath = nodesBForder(wt,'rev');
+   % Relationships between nodes
+   [pOutIdxs,chOutIdxs] = rangeWpBF(wt,'rev');
+   % Nodes to be removed
+   removeNodes = [];
+
+   % Energy normalization
+   % totalE = sum(cellfun(@(cEl) sum(cEl.^2),c));
+   % c = cellfun(@(cEl) cEl.^2/totalE,c,'UniformOutput',0);
+   
+   if do_additive
+       % pre-calculate entropy of all subbands
+       cEnt = cellfun(@(cEl) wcostwrap(cEl,kv.cost,0),c);
+       for ii=1:length(pOutIdxs)-1
+          pEnt = cEnt(pOutIdxs(ii));
+          chEnt = sum(cEnt(chOutIdxs{ii}));
+          if pEnt<=chEnt
+             removeNodes(end+1) = treePath(ii);
+          else
+             % Set parent entropy to the sum of the children entropy. 
+             cEnt(pOutIdxs(ii)) = chEnt;
+          end
+       end
+   else
+       cEnt = cell(numel(c),1);
+       for ii=1:length(pOutIdxs)-1 
+          
+          if isempty(cEnt{pOutIdxs(ii)})
+             pEnt = wcostwrap(c(pOutIdxs(ii)),kv.cost,0);
+             cEnt{pOutIdxs(ii)} = pEnt;
+          else
+             pEnt = cEnt(pOutIdxs(ii));
+          end
+          
+          chEnt = wcostwrap(c(chOutIdxs{ii}),kv.cost,0);
+          % Set parent entropy to value obtanied by concatenating child
+          % subbands.
+          if(pEnt<=chEnt)
+             removeNodes(end+1) = treePath(ii);
+          else
+             % Set parent entropy to the concatenation of the children entropy. 
+             cEnt{pOutIdxs(ii)} = chEnt;
+          end
+ 
+       end    
+   end
+   
+
+   % Do tree prunning.
+   for ii=1:length(removeNodes)
+       wt = deleteSubtree(removeNodes(ii),wt);
+   end
+
+end
+
+% Finally do the analysis using the created best tree. with correct
+% frequency bands order
+[c,info] = wfbt(f,wt,flags.ext,'freq'); 
+%END WPBEST
+
+function ad = isAdditive(entFunc)
+x = 1:5;
+%x = x./norm(x);
+ent1 = wcostwrap(x',entFunc,0);
+ent2 = sum(arrayfun(@(xEl) wcostwrap(xEl,entFunc,0),x));
+ad = ent1==ent2;
+
+function E = wcostwrap(x,fname,do_normalization)
+%WENTWRAP Entropy functions wrapper
+%   Usage:  E = wentwrap(x,fname,varargin)
+%
+%   `E = wentwrap(x,fname,varargin)` passes given parameters further to the
+%   appropriate function.
+%
+
+if iscell(x)
+   x = cell2mat(x);
+end
+
+if do_normalization
+   x = x./norm(x);
+end
+
+if isa(fname,'function_handle')
+   E = fname(x);
+   return;
+end
+
+if numel(fname)>1
+   E = feval(sprintf('%s%s','wcost_',fname{1}),x,fname{2:end});
+else
+   E = feval(sprintf('%s%s','wcost_',fname{1}),x);
+end
+
+%%%%%%%%%%%%%%%%%%
+% ADDITIVE COSTS %
+%%%%%%%%%%%%%%%%%%
+
+function E = wcost_shannon(x)
+% Cost function derived from the Shannon-Weaver entropy.
+
+u = abs(x(x~=0)).^2;
+E = -sum(u.*log(u));
+
+function E = wcost_log(x)
+% Logarithm of energy.
+% It may be interpreted as the entropy of a Gauss-Markov process, composed
+% of numel(x) uncorrelated Gaussian random variables of variences
+% x(1),..,x(end). Minimizing the function finds the best approximation to
+% the Karhuen-loeve basis for the process.
+
+x = x(x~=0);
+E = sum(log(x(:).^2));
+
+function E = wcost_thre(x,th)
+% Number of coefficients above a treshold.
+% It gives a number of coefficients needed to transimt the signal to
+% precision th.
+
+E = numel(x(abs(x)>th));
+
+function E = wcost_lpnorm(x,p)
+% Concentration in l^p norm, p<2
+% The smaller is the l^p norm of a signal with l^2 equal to 1, the more
+% concentrated is its energy into a few coefficients.
+assert(0<p&&p<2,'%s: Parameter p have to be in the range ]0,2[',upper(mfilename));
+E = sum(abs(x(:)).^p);
+
+%%%%%%%%%%%%%%%%%%%%%%
+% NON-ADDITIVE COSTS %
+%%%%%%%%%%%%%%%%%%%%%%
+
+function E = wcost_wlpnorm(x,p)
+% Weak Lp-norm 
+
+v = sort(abs(x(:)),'descend');
+
+k = 1:length(v);
+E = max((k.'.^(1/p)).*v);
+
+function E = wcost_compa(x,p)
+% Compresion Area Entropy, p<2
+% 
+
+% 0<p<=2
+assert(0<p&&p<=2,'Parameter p have to be in the range ]0,2]');
+N = numel(x);
+%u = x./norm(x);
+v = sort(abs(x(:)),'descend');
+
+wnom = cumsum(v.^p);
+w = wnom./wnom(end);
+
+E=N-sum(w);
+
+function E = wcost_compn(x,p,f)
+% Compresion Number entropy
+% Represents a minimum number of coefficients containing 100*f% of the total
+% p norm of x.
+
+
+% 0<p<=2
+assert(0<p&&p<=2,'Parameter p have to be in the range ]0,2]');
+assert(0<f&&f<1,'Parameter f  have to be in the range ]0,1[');
+
+%u = x./norm(x);
+v = sort(abs(x(:)),'descend');
+
+wnom = cumsum(v.^p);
+w = wnom./wnom(end);
+
+[~,E]=min(abs(w-f));
+
+
+
diff --git a/inst/wavelets/wpfbt.m b/inst/wavelets/wpfbt.m
new file mode 100644
index 0000000..3aa2689
--- /dev/null
+++ b/inst/wavelets/wpfbt.m
@@ -0,0 +1,115 @@
+function [c,info]=wpfbt(f,wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wpfbt
+%@verbatim
+%WPFBT   Wavelet Packet FilterBank Tree
+%   Usage:  c=wpfbt(f,wt);
+%           [c,info]=wpfbt(...);
+%
+%   Input parameters:
+%         f   : Input data.
+%         wt  : Wavelet Filterbank tree definition.
+%
+%   Output parameters:
+%         c    : Coefficients stored in a cell-array.
+%         info : Transform parameters struct.
+%
+%   c=WPFBT(f,wt) returns wavelet packet coefficients c obtained by
+%   applying a wavelet filterbank tree defined by wt to the input data
+%   f. In addition, the function returns struct. info containing transform
+%   parameters. It can be conviniently used for the inverse transform IWPFBT
+%   e.g. fhat = iWPFBT(c,info). It is also required by the PLOTWAVELETS 
+%   function.
+%
+%   In contrast to the WFBT, the c contain every intermediate output
+%   of each node in the tree. The c{jj} are ordered in the breadth-first
+%   node order manner.
+%
+%   If f is row/column vector, the coefficient vectors c{jj} are 
+%   columns. If f is a matrix, the transformation is applied to each of 
+%   column of the matrix.
+%
+%   By default, the function scales all intermediate outputs in the tree
+%   which are not terminal ones in order to preserve energy. Passing a 
+%   'noscale' flag overrides this behavior. This is necessary for the
+%   WPBEST function to correctly work with the cost measures.
+%
+%   Please see help for WFBT description of possible formats of wt and
+%   of the additional flags.
+%
+%
+%   Examples:
+%   ---------
+%   
+%   A simple example of calling the WPFBT function using the "full
+%   decomposition" wavelet tree:
+% 
+%     f = gspi;
+%     J = 6;
+%     [c,info] = wpfbt(f,{'sym10',J,'full'});
+%     plotwavelets(c,info,44100,'dynrange',90);
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wpfbt.php}
+%@seealso{wfbt, iwpfbt, wfbtinit, plotwavelets, wpbest}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+if(nargin<2)
+   error('%s: Too few input parameters.',upper(mfilename));  
+end
+
+definput.import = {'fwt','wfbtcommon'};
+definput.flags.scale = {'scale','noscale'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet tree structure
+wt = wfbtinit(wt,flags.forder);
+    
+%% ----- step 1 : Verify f and determine its length -------
+[f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0);
+if(Ls<2)
+   error('%s: Input signal seems not to be a vector of length > 1.',upper(mfilename));  
+end
+
+% Determine next legal input data length.
+L = wfbtlength(Ls,wt,flags.ext);
+
+% Pad with zeros if the safe length L differ from the Ls.
+if(Ls~=L)
+   f=postpad(f,L); 
+end
+
+%% ----- step 3 : Run computation
+wtPath = nodesBForder(wt);
+rangeLoc = rangeInLocalOutputs(wtPath,wt);
+c = comp_wpfbt(f,wt.nodes(wtPath),rangeLoc,flags.ext,flags.do_scale);
+
+%% ----- Optional : Fill the info struct. -----
+if nargout>1
+   info.fname = 'wpfbt';
+   info.wt = wt;
+   info.ext = flags.ext;
+   info.Lc = cellfun(@(cEl) size(cEl,1),c);
+   info.Ls = Ls;
+   info.fOrder = flags.forder;
+   info.isPacked = 0;
+   info.isNotScaled = ~flags.do_scale;
+end
+
diff --git a/inst/wavelets/wpfbtclength.m b/inst/wavelets/wpfbtclength.m
new file mode 100644
index 0000000..05fc9b3
--- /dev/null
+++ b/inst/wavelets/wpfbtclength.m
@@ -0,0 +1,56 @@
+function [Lc,L]=wpfbtclength(Ls,wt,varargin)
+%-*- texinfo -*-
+%@deftypefn {Function} wpfbtclength
+%@verbatim
+%WFBTLENGTH  WPFBT subband length from a signal length
+%   Usage: L=wfbtlength(Ls,wt);
+%          L=wfbtlength(Ls,wt,...);
+%
+%   [Lc,L]=WPFBTCLENGTH(Ls,wt) returns the length L of a wavelet system
+%   that is long enough to expand a signal of length Ls and associated
+%   vector subband lengths Lc. Please see the help on
+%   WFBT for an explanation of the parameter wt.
+%
+%   If the returned length is longer than the signal length, the signal
+%   will be zero-padded by WFBT to length L.
+%
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/wavelets/wpfbtclength.php}
+%@seealso{wfbt, fwt}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+definput.import = {'fwt'};
+[flags,kv]=ltfatarghelper({},definput,varargin);
+
+% Initialize the wavelet filters structure
+wt = wfbtinit(wt);
+
+if(flags.do_per)
+   a = treeSub(wt);
+   L = filterbanklength(Ls,a);
+else
+   L = Ls;
+end
+
+wtPath = nodesBForder(wt);
+Lc = nodeOutLen(wtPath,L,[],flags.do_per,wt);
+
+
+
diff --git a/oct/Makefile_mac b/oct/Makefile_mac
new file mode 100644
index 0000000..eaf824c
--- /dev/null
+++ b/oct/Makefile_mac
@@ -0,0 +1 @@
+include Makefile_unix
diff --git a/oct/Makefile_mingwoct b/oct/Makefile_mingwoct
new file mode 100644
index 0000000..f2110de
--- /dev/null
+++ b/oct/Makefile_mingwoct
@@ -0,0 +1,32 @@
+# Use GNU Make to process this file.
+# mingw32-make -f Makefile_mingw32
+
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default (probably wrong) MATLABROOT="c:\Octave\Octave3.6.4_gcc4.6.2")
+  MATLABROOT=c:\Octave\Octave3.6.4_gcc4.6.2
+endif
+
+ifndef EXT
+  EXT=oct
+endif
+
+include ../src/ostools.mk
+
+OCTSCC   = $(shell ls comp_*.cc)
+
+	
+OCTSBASE = $(basename $(OCTSCC))
+OCTS     = $(addsuffix .$(EXT),$(OCTSBASE))
+ADDITIONALIBS = -L../lib -lltfat -lltfatf -lblas -lfftw3 -lfftw3f -llapack 
+
+
+all:	$(OCTS)
+
+%.$(EXT): %.cc
+	mkoctfile --strip -v -Wall -I../src/thirdparty -I. -I../src $(ADDITIONALIBS)  $<
+	del *.o
+
+clean:
+	del *.o *.$(EXT)
+
+.PHONY: all clean
diff --git a/oct/Makefile_unix b/oct/Makefile_unix
new file mode 100644
index 0000000..c42d42a
--- /dev/null
+++ b/oct/Makefile_unix
@@ -0,0 +1,32 @@
+# Use GNU Make to process this file.
+
+ifndef EXT
+  EXT=oct
+endif
+
+OCTSCC   = $(shell ls comp_*.cc)
+OCTSBASE = $(basename $(OCTSCC))
+OCTS     = $(addsuffix .$(EXT),$(OCTSBASE))
+
+MKOCTFILE ?= mkoctfile
+
+ifndef LAPACK_LIBS
+LAPACK_LIBS := $(shell $(MKOCTFILE) -p LAPACK_LIBS)
+endif
+ifndef BLAS_LIBS
+BLAS_LIBS := $(shell $(MKOCTFILE) -p BLAS_LIBS)
+endif
+ifndef FLIBS
+FLIBS := $(shell $(MKOCTFILE) -p FLIBS)
+endif
+LFLAGS := $(shell $(MKOCTFILE) -p LFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
+
+all:	$(OCTS)
+
+%.$(EXT): %.cc
+	$(MKOCTFILE) -strip -Wall -I../thirdparty -I. -I../src -I../src/thirdparty -L../lib -lltfat -lltfatf $<
+
+clean:
+	-rm *.o *.$(EXT)
+
+.PHONY: all clean
diff --git a/oct/comp_atrousfilterbank_td.cc b/oct/comp_atrousfilterbank_td.cc
new file mode 100644
index 0000000..1e46ef2
--- /dev/null
+++ b/oct/comp_atrousfilterbank_td.cc
@@ -0,0 +1,110 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_atrousfilterbank_td // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=atrousfilterbank_td(...);\n Yeah."
+#define _DEBUG
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_atrousfilterbank_td(const Complex *f, const Complex *g[],
+                        const ltfatInt L, const ltfatInt gl[],
+                        const ltfatInt W, const ltfatInt a[],
+                        const ltfatInt offset[], const ltfatInt M,
+                        Complex *c, ltfatExtType ext)
+{
+    atrousfilterbank_td_cd(reinterpret_cast<const double _Complex *>(f),
+                           reinterpret_cast<const double _Complex **>(g),
+                           L,gl,W,a,offset,M,
+                           reinterpret_cast<double _Complex *>(c),
+                           ext);
+}
+
+static inline void
+fwd_atrousfilterbank_td(const FloatComplex *f, const FloatComplex *g[],
+                        const ltfatInt L, const ltfatInt gl[],
+                        const ltfatInt W, const ltfatInt a[],
+                        const ltfatInt offset[], const ltfatInt M,
+                        FloatComplex *c, ltfatExtType ext)
+{
+    atrousfilterbank_td_cs(reinterpret_cast<const float _Complex *>(f),
+                           reinterpret_cast<const float _Complex **>(g),
+                           L,gl,W,a,offset,M,
+                           reinterpret_cast<float _Complex *>(c),
+                           ext);
+}
+
+static inline void
+fwd_atrousfilterbank_td(const double *f, const double *g[],
+                        const ltfatInt L, const ltfatInt gl[],
+                        const ltfatInt W, const ltfatInt a[],
+                        const ltfatInt offset[], const ltfatInt M,
+                        double *c, ltfatExtType ext)
+{
+    atrousfilterbank_td_d(reinterpret_cast<const double *>(f),
+                          reinterpret_cast<const double **>(g),
+                          L,gl,W,a,offset,M,
+                          reinterpret_cast<double *>(c),
+                          ext);
+}
+
+static inline void
+fwd_atrousfilterbank_td(const float *f, const float *g[],
+                        const ltfatInt L, const ltfatInt gl[],
+                        const ltfatInt W, const ltfatInt a[],
+                        const ltfatInt offset[], const ltfatInt M,
+                        float *c, ltfatExtType ext)
+{
+    atrousfilterbank_td_s(reinterpret_cast<const float *>(f),
+                          reinterpret_cast<const float **>(g),
+                          L,gl,W,a,offset,M,
+                          reinterpret_cast<float *>(c),
+                          ext);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+    //DEBUGINFO;
+    // Input data
+    MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+    MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+    Matrix aDouble = args(2).matrix_value();
+    Matrix offsetDouble = args(3).matrix_value();
+
+    // Input length
+    const octave_idx_type L  = f.rows();
+    // Number of channels
+    const octave_idx_type W  = f.columns();
+    // Number of filters
+    const octave_idx_type M = g.columns();
+    const octave_idx_type filtLen = g.rows();
+
+    // Allocating temporary arrays
+    OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, gPtrs, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, a, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, offset, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, filtLens, M);
+
+    for(octave_idx_type m=0; m<M; m++)
+    {
+        a[m] = (ltfatInt) aDouble(0);
+        offset[m] = (ltfatInt) offsetDouble(m);
+        filtLens[m] = (ltfatInt) filtLen;
+        gPtrs[m] = g.data() +  m*filtLen;
+    }
+
+    dim_vector dims_out(L,M,W);
+    dims_out.chop_trailing_singletons();
+    MArray<LTFAT_TYPE> c(dims_out);
+
+    fwd_atrousfilterbank_td(f.data(),gPtrs,L,
+                            filtLens,W,a,offset,M,c.fortran_vec(),PER);
+
+    return octave_value(c);
+}
diff --git a/oct/comp_cellcoef2tf.cc b/oct/comp_cellcoef2tf.cc
new file mode 100644
index 0000000..10521ac
--- /dev/null
+++ b/oct/comp_cellcoef2tf.cc
@@ -0,0 +1,64 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_cellcoef2tf // change to filename
+#define OCTFILEHELP "Cell to tf-layout.\n" \
+                    "Usage: coef = comp_cellcoef2tf(coef,dim)\n Yeah."
+
+#include "ltfat_oct_template_helper.h"
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list 
+octFunction(const octave_value_list& args, int nargout)
+{
+   int nargin = args.length();
+
+   Cell c = args(0).cell_value();
+
+   double maxLen = 0.0;
+
+   if(nargin>1)
+   {
+        maxLen = args(1).double_value();     
+   }
+   octave_idx_type M = c.numel();
+   OCTAVE_LOCAL_BUFFER(const LTFAT_TYPE*, cPtrs, M);
+   OCTAVE_LOCAL_BUFFER(octave_idx_type, cLens, M);
+    octave_idx_type maxClen = 0;
+   for(octave_idx_type m=0;m<M;m++)
+   {
+       cLens[m] = c.elem(m).rows();
+       if(cLens[m]>maxClen)
+       {
+            maxClen = cLens[m];
+       }
+
+       MArray<LTFAT_TYPE> cTmp = ltfatOctArray<LTFAT_TYPE>(c.elem(m)); 
+       cPtrs[m] = cTmp.data(); 
+   }
+
+   if(maxLen>0.0)
+   {
+        maxClen= maxLen<maxClen?maxLen:maxClen;
+   }
+
+
+   MArray<LTFAT_TYPE> cout(dim_vector(M,maxClen));
+   LTFAT_TYPE* coutPtr = (LTFAT_TYPE*) cout.fortran_vec();
+
+  for(octave_idx_type m=0;m<M;m++)
+   {
+      const LTFAT_TYPE* coefElPtrTmp = cPtrs[m];
+      LTFAT_TYPE* coefOutPtrTmp = coutPtr+m;
+      double lenRatio = ((double)cLens[m]-1)/((double)maxClen-1);
+      for(octave_idx_type ii=0;ii<maxClen;ii++)
+      {
+         *coefOutPtrTmp = coefElPtrTmp[(octave_idx_type)((ii*lenRatio)+0.5)];
+         coefOutPtrTmp += M;
+      }
+   }
+
+
+
+   return octave_value(cout);
+}
diff --git a/oct/comp_chirpzt.cc b/oct/comp_chirpzt.cc
new file mode 100644
index 0000000..edca138
--- /dev/null
+++ b/oct/comp_chirpzt.cc
@@ -0,0 +1,64 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_chirpzt // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=chzt(...);\n Yeah."
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+static inline void
+fwd_chzt(const Complex *fPtr, const octave_idx_type L, const octave_idx_type W,
+         const octave_idx_type K, const double deltao, const double o, Complex *cPtr )
+{
+   chzt_cd(reinterpret_cast<const double _Complex *>(fPtr),
+           L,W,K,deltao,o,
+           reinterpret_cast<double _Complex *>(cPtr));
+}
+
+static inline void 
+fwd_chzt(const FloatComplex *fPtr, const octave_idx_type L, const octave_idx_type W,
+         const octave_idx_type K, const double deltao, const double o, FloatComplex *cPtr )
+{
+   chzt_cs(reinterpret_cast<const float _Complex *>(fPtr),
+           L,W,K,deltao,o,
+           reinterpret_cast<float _Complex *>(cPtr));
+}
+
+static inline void 
+fwd_chzt(const double *fPtr, const octave_idx_type L, const octave_idx_type W,
+         const octave_idx_type K, const double deltao, const double o, Complex *cPtr )
+{
+   chzt_d(fPtr,L,W,K,deltao,o,reinterpret_cast<double _Complex *>(cPtr));
+}
+
+static inline void 
+fwd_chzt(const float *fPtr,const octave_idx_type L, const octave_idx_type W,
+         const octave_idx_type K, const double deltao, const double o, FloatComplex *cPtr )
+{
+   chzt_s(fPtr, L,W,K,deltao,o,reinterpret_cast<float _Complex *>(cPtr));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+   //DEBUGINFO;
+   // Input data
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   const octave_idx_type K = (octave_idx_type) args(1).double_value();
+   const double deltao = args(2).double_value();
+   const double o = args(3).double_value();
+   
+  // Input length
+   const octave_idx_type L  = f.rows();
+   // Number of channels
+   const octave_idx_type W  = f.columns();
+
+   //dims_out.chop_trailing_singletons();
+   MArray<LTFAT_COMPLEX> c(dim_vector(K,W));
+   
+   fwd_chzt(f.data(),L,W,K,deltao,o,c.fortran_vec());
+   
+   return octave_value(c);
+}
diff --git a/oct/comp_col2diag.cc b/oct/comp_col2diag.cc
new file mode 100644
index 0000000..6ee642d
--- /dev/null
+++ b/oct/comp_col2diag.cc
@@ -0,0 +1,52 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_col2diag // change to filename
+#define OCTFILEHELP "Computes spreading permutation.\n Usage: cout=comp_col2diag(cin);\n Yeah."
+
+#include "ltfat_oct_template_helper.h"
+
+/*
+  col2diag forwarders
+*/
+
+static inline void
+fwd_col2diag(const Complex *cin, const octave_idx_type L,Complex *cout)
+{
+   col2diag_cd(reinterpret_cast<const double _Complex*>(cin),L,
+               reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void
+fwd_col2diag(const FloatComplex *cin, const octave_idx_type L, FloatComplex *cout)
+{
+   col2diag_cs(reinterpret_cast<const float _Complex*>(cin),L,
+               reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void 
+fwd_col2diag(const double *cin, const octave_idx_type L,double *cout)
+{
+   col2diag_d(cin,L,cout);
+}
+
+static inline void 
+fwd_col2diag(const float *cin, const octave_idx_type L, float *cout)
+{
+   col2diag_s(cin,L,cout);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list 
+octFunction(const octave_value_list& args, int nargout)
+{
+   MArray<LTFAT_TYPE> cin = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> cout(cin.dims());
+   cout.fill(0);
+
+   const octave_idx_type L = cin.rows();
+
+   fwd_col2diag(cin.data(),L,cout.fortran_vec());
+
+   return octave_value(cout);
+}
diff --git a/oct/comp_dct.cc b/oct/comp_dct.cc
new file mode 100644
index 0000000..08d0678
--- /dev/null
+++ b/oct/comp_dct.cc
@@ -0,0 +1,88 @@
+#define TYPEDEPARGS 0
+#define REALARGS
+#define COMPLEXARGS
+#define SINGLEARGS
+#define OCTFILENAME comp_dct // change to filename
+#define OCTFILEHELP "This function calls FFTW library.\n Yeah."
+
+#include "ltfat_oct_template_helper.h"
+#include "config.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_dct(const double *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           double *c,
+                           const dct_kind kind)
+{
+    dct_d(f,L,W,c,kind);
+}
+
+static inline void fwd_dct(const float *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           float *c,
+                           const dct_kind kind)
+{
+   dct_s(f,L,W,c,kind);
+}
+
+static inline void fwd_dct(const Complex *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           Complex *c,
+                           const dct_kind kind)
+{
+   dct_cd(reinterpret_cast<const double _Complex *>(f),
+          L,W,
+          reinterpret_cast<double _Complex *>(c),
+          kind);  
+}
+
+static inline void fwd_dct(const FloatComplex *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           FloatComplex* c,
+                           const dct_kind kind)
+{
+    dct_cs(reinterpret_cast<const float _Complex *>(f),
+           L,W,
+           reinterpret_cast<float _Complex *>(c),
+           kind);  
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   dct_kind kind = DCTI;
+   const octave_idx_type type = args(1).int_value();
+   MArray<LTFAT_TYPE> f = MArray<LTFAT_TYPE>(ltfatOctArray<LTFAT_TYPE>(args(0)));
+   const octave_idx_type L  = f.rows();
+   const octave_idx_type W  = f.columns();
+   MArray<LTFAT_TYPE> c(dim_vector(L,W));
+
+   switch(type)
+   {
+      case 1:
+         kind = DCTI;
+         break;
+      case 2:
+         kind = DCTII;
+         break;
+      case 3:
+         kind = DCTIII;
+         break;
+      case 4:
+         kind = DCTIV;
+         break;
+      default:
+         error("Unknown type.");
+   }
+
+   fwd_dct(f.data(),L,W,c.fortran_vec(),kind);
+
+   return octave_value(c);
+}
+
+
diff --git a/oct/comp_dgt_ola.cc b/oct/comp_dgt_ola.cc
new file mode 100644
index 0000000..febbaf2
--- /dev/null
+++ b/oct/comp_dgt_ola.cc
@@ -0,0 +1,64 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_dgt_ola // change to filename
+#define OCTFILEHELP "This function calls the C-library\n  c=comp_dgt_ola(f,g,a,M,bl);\n Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  dgt_ola forwarders
+*/
+
+static inline void
+fwd_dgt_ola(const Complex *f, const Complex *g, const octave_idx_type L,
+            const octave_idx_type gl, const octave_idx_type W,
+            const octave_idx_type a, const octave_idx_type M,
+            const octave_idx_type bl, Complex *cout)
+{
+   dgt_ola_d(reinterpret_cast<const double _Complex*>(f),
+             reinterpret_cast<const double _Complex*>(g),
+             L,gl,W,a,M,bl,
+             reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void 
+fwd_dgt_ola(const FloatComplex *f, const FloatComplex *g,
+            const octave_idx_type L, const octave_idx_type gl,
+            const octave_idx_type W, const octave_idx_type a,
+            const octave_idx_type M, const octave_idx_type bl,
+            FloatComplex *cout)
+{
+   dgt_ola_s(reinterpret_cast<const float _Complex*>(f),
+             reinterpret_cast<const float _Complex*>(g),
+             L,gl,W,a,M,bl,
+             reinterpret_cast<float _Complex*>(cout));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list 
+octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   const octave_idx_type a  = args(2).int_value();
+   const octave_idx_type M  = args(3).int_value();
+   const octave_idx_type bl = args(4).int_value();
+   
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+    
+   const octave_idx_type L  = f.rows();
+   const octave_idx_type W  = f.columns();
+   const octave_idx_type gl = g.rows();
+   const octave_idx_type N = L/a;
+ 
+   dim_vector dims_out(M,N,W);  
+   dims_out.chop_trailing_singletons();
+
+   MArray<LTFAT_TYPE> cout(dims_out); 
+    
+   fwd_dgt_ola(f.data(),g.data(),L,gl,W,a,M,bl,cout.fortran_vec());
+    
+   return octave_value(cout);
+}
diff --git a/oct/comp_dgtreal_ola.cc b/oct/comp_dgtreal_ola.cc
new file mode 100644
index 0000000..156ef20
--- /dev/null
+++ b/oct/comp_dgtreal_ola.cc
@@ -0,0 +1,63 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define REALARGS
+#define OCTFILENAME comp_dgtreal_ola // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     c=comp_dgtreal_ola(f,g,a,M,bl);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  dgtreal_ola forwarders
+*/
+
+static inline void 
+fwd_dgtreal_ola(const double *f, const double *g,
+                const octave_idx_type L, const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type a,
+                const octave_idx_type M, const octave_idx_type bl,
+                Complex *cout)
+{
+   dgtreal_ola_d(f,g,L,gl,W,a,M,bl,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void
+fwd_dgtreal_ola(const float *f, const float *g,
+                const octave_idx_type L, const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type a,
+                const octave_idx_type M, const octave_idx_type bl,
+                FloatComplex *cout)
+{
+   dgtreal_ola_s(f,g,L,gl,W,a,M,bl,reinterpret_cast<float _Complex*>(cout));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   const octave_idx_type a  = args(2).int_value();
+   const octave_idx_type M  = args(3).int_value();
+   const octave_idx_type bl = args(4).int_value();
+
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+  
+   const octave_idx_type L  = f.rows();
+   const octave_idx_type W  = f.columns();
+   const octave_idx_type gl = g.rows();
+   const octave_idx_type N = L/a;
+
+   const octave_idx_type M2 = M/2+1;
+  
+   dim_vector dims_out(M2,N,W);  
+   dims_out.chop_trailing_singletons();
+
+   MArray<LTFAT_COMPLEX> cout(dims_out); 
+    
+   fwd_dgtreal_ola(f.data(),g.data(),L,gl,W,a,M,bl,cout.fortran_vec());
+    
+   return octave_value(cout);
+}
diff --git a/oct/comp_dst.cc b/oct/comp_dst.cc
new file mode 100644
index 0000000..41dc2c8
--- /dev/null
+++ b/oct/comp_dst.cc
@@ -0,0 +1,89 @@
+#define TYPEDEPARGS 0
+#define REALARGS
+#define COMPLEXARGS
+#define SINGLEARGS
+#define OCTFILENAME comp_dst // change to filename
+#define OCTFILEHELP "This function calls FFTW library.\n Yeah."
+
+#include "ltfat_oct_template_helper.h"
+#include "config.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_dst(const double *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           double *c,
+                           const dst_kind kind)
+{
+    dst_d(f,L,W,c,kind);
+}
+
+static inline void fwd_dst(const float *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           float *c,
+                           const dst_kind kind)
+{
+    dst_s(f,L,W,c,kind);
+}
+
+static inline void fwd_dst(const Complex *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           Complex *c,
+                           const dst_kind kind)
+{
+    dst_cd(reinterpret_cast<const double _Complex *>(f),
+           L,W,
+           reinterpret_cast<double _Complex *>(c),
+           kind);
+}
+
+static inline void fwd_dst(const FloatComplex *f,
+                           const octave_idx_type L,
+                           const octave_idx_type W,
+                           FloatComplex* c,
+                           const dst_kind kind)
+{
+    dst_cs(reinterpret_cast<const float _Complex *>(f),
+           L,W,
+           reinterpret_cast<float _Complex *>(c),
+           kind);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    DEBUGINFO;
+    dst_kind kind = DSTI;
+    const octave_idx_type type = args(1).int_value();
+    MArray<LTFAT_TYPE> f = MArray<LTFAT_TYPE>(ltfatOctArray<LTFAT_TYPE>(args(0)));
+    const octave_idx_type L  = f.rows();
+    const octave_idx_type W  = f.columns();
+    MArray<LTFAT_TYPE> c(dim_vector(L,W));
+
+    switch(type)
+    {
+    case 1:
+        kind = DSTI;
+        break;
+    case 2:
+        kind = DSTII;
+        break;
+    case 3:
+        kind = DSTIII;
+        break;
+    case 4:
+        kind = DSTIV;
+        break;
+    default:
+        error("Unknown type.");
+    }
+
+    fwd_dst(f.data(),L,W,c.fortran_vec(),kind);
+
+    return octave_value(c);
+}
+
+
+
diff --git a/oct/comp_dwilt.cc b/oct/comp_dwilt.cc
new file mode 100644
index 0000000..6c8efe7
--- /dev/null
+++ b/oct/comp_dwilt.cc
@@ -0,0 +1,123 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_dwilt // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     coef=comp_dwilt_fb(f,g,M,L);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  dgtreal_ola forwarders
+*/
+
+static inline void
+fwd_dwilt_fb(const Complex *f, const Complex *g,
+             const octave_idx_type L, const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             Complex *cout)
+{
+   dwilt_fb_cd(reinterpret_cast<const double _Complex*>(f),
+               reinterpret_cast<const double _Complex*>(g),
+               L, gl, W,M, reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void 
+fwd_dwilt_fb(const FloatComplex *f, const FloatComplex *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             FloatComplex *cout)
+{
+   dwilt_fb_cs(reinterpret_cast<const float _Complex*>(f),
+               reinterpret_cast<const float _Complex*>(g),
+               L, gl,W,M,
+               reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void
+fwd_dwilt_fb(const double *f, const double *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             double *cout)
+{
+   dwilt_fb_d(f,g,L,gl,W,M,cout);
+}
+
+static inline void
+fwd_dwilt_fb(const float *f, const float *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             float *cout)
+{
+   dwilt_fb_s(f,g,L,gl,W,M,cout);
+}
+
+static inline void
+fwd_dwilt_long(const Complex *f, const Complex *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, Complex *cout)
+{
+   dwilt_long_cd(reinterpret_cast<const double _Complex*>(f),
+                 reinterpret_cast<const double _Complex*>(g),
+                 L,W,M, reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void 
+fwd_dwilt_long(const FloatComplex *f, const FloatComplex *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, FloatComplex *cout)
+{
+   dwilt_long_cs(reinterpret_cast<const float _Complex*>(f),
+                 reinterpret_cast<const float _Complex*>(g),
+                 L,W,M, reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void
+fwd_dwilt_long(const double *f, const double *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, double *cout)
+{
+   dwilt_long_d(f,g,L,W,M,cout);
+}
+
+static inline void
+fwd_dwilt_long(const float *f, const float *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, float *cout)
+{
+   dwilt_long_s(f,g,L,W,M,cout);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   const octave_idx_type M = args(2).int_value();
+
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+   const octave_idx_type gl = g.nelem();
+   const octave_idx_type W = f.columns();
+   const octave_idx_type L = f.rows();
+   const octave_idx_type N = L/M;
+
+
+   dim_vector dims_out(2*M,N/2,W);  
+   dims_out.chop_trailing_singletons();
+
+   MArray<LTFAT_TYPE> cout(dims_out); 
+
+   if(gl<L)
+   {     
+      fwd_dwilt_fb(f.data(),g.data(),L, gl, W, M,cout.fortran_vec());
+   }
+   else
+   {
+      fwd_dwilt_long(f.data(),g.data(),L, W, M,cout.fortran_vec());
+   }
+
+   return octave_value(cout);
+}
+
diff --git a/oct/comp_dwiltiii.cc b/oct/comp_dwiltiii.cc
new file mode 100644
index 0000000..82a132d
--- /dev/null
+++ b/oct/comp_dwiltiii.cc
@@ -0,0 +1,118 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_dwiltiii // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     coef=comp_dwilt_fb(f,g,M,L);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void
+fwd_dwiltiii_fb(const Complex *f, const Complex *g,
+                const octave_idx_type L, const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type M, 
+                Complex *cout)
+{
+   dwiltiii_fb_cd(reinterpret_cast<const double _Complex*>(f),
+                  reinterpret_cast<const double _Complex*>(g),
+                  L, gl, W,M, reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void
+fwd_dwiltiii_fb(const FloatComplex *f, const FloatComplex *g,
+                const octave_idx_type L,  const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type M, 
+                FloatComplex *cout)
+{
+   dwiltiii_fb_cs(reinterpret_cast<const float _Complex*>(f),
+                  reinterpret_cast<const float _Complex*>(g),
+                  L, gl,W,M, reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void
+fwd_dwiltiii_fb(const double *f, const double *g,
+                const octave_idx_type L,  const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type M, 
+                double *cout)
+{
+   dwiltiii_fb_d(f,g,L,gl,W,M,cout);
+}
+
+static inline void
+fwd_dwiltiii_fb(const float *f, const float *g,
+                const octave_idx_type L,  const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type M, 
+                float *cout)
+{
+   dwiltiii_fb_s(f,g,L,gl,W,M,cout);
+}
+
+static inline void
+fwd_dwiltiii_long(const Complex *f, const Complex *g,
+                  const octave_idx_type L, const octave_idx_type W, 
+                  const octave_idx_type M, Complex *cout)
+{
+   dwiltiii_long_cd(reinterpret_cast<const double _Complex*>(f),
+                    reinterpret_cast<const double _Complex*>(g),
+                    L,W,M, reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void
+fwd_dwiltiii_long(const FloatComplex *f, const FloatComplex *g,
+                  const octave_idx_type L, const octave_idx_type W, 
+                  const octave_idx_type M, FloatComplex *cout)
+{
+   dwiltiii_long_cs(reinterpret_cast<const float _Complex*>(f),
+                    reinterpret_cast<const float _Complex*>(g),
+                    L,W,M, reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void
+fwd_dwiltiii_long(const double *f, const double *g,
+                  const octave_idx_type L, const octave_idx_type W, 
+                  const octave_idx_type M, double *cout)
+{
+   dwiltiii_long_d(f,g,L,W,M,cout);
+}
+
+static inline void
+fwd_dwiltiii_long(const float *f, const float *g,
+                  const octave_idx_type L, const octave_idx_type W, 
+                  const octave_idx_type M, float *cout)
+{
+   dwiltiii_long_s(f,g,L,W,M,cout);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   const octave_idx_type M = args(2).int_value();
+
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+   const octave_idx_type gl = g.nelem();
+   const octave_idx_type W = f.columns();
+   const octave_idx_type L = f.rows();
+   const octave_idx_type N = L/M;
+
+   dim_vector dims_out(M,N,W);  
+   dims_out.chop_trailing_singletons();
+
+   MArray<LTFAT_TYPE> cout(dims_out); 
+     
+   if(gl<L)
+   {    
+      fwd_dwiltiii_fb(f.data(),g.data(),L, gl, W, M,cout.fortran_vec());
+   }
+   else
+   {
+      fwd_dwiltiii_long(f.data(),g.data(),L, W, M,cout.fortran_vec());
+   }
+         
+   return octave_value(cout);
+}
+
diff --git a/oct/comp_fftreal.cc b/oct/comp_fftreal.cc
new file mode 100644
index 0000000..40d09db
--- /dev/null
+++ b/oct/comp_fftreal.cc
@@ -0,0 +1,51 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define REALARGS
+#define OCTFILENAME comp_fftreal // change to filename
+#define OCTFILEHELP "This function calls the FFTW3 real FFT\n\
+                     c=comp_fftreal(f);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+#include "config.h"
+#include "fftw3.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_fftreal(const double *f,
+                               const octave_idx_type L,
+                               const octave_idx_type W,
+                               Complex *cout)
+{
+   fftreal_d( const_cast<double*>(f),
+            L,W,
+            reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_fftreal(const float *f,
+                               const octave_idx_type L,
+                               const octave_idx_type W,
+                               FloatComplex *cout)
+{
+  fftreal_s( const_cast<float*>(f),
+            L,W,
+            reinterpret_cast<float _Complex*>(cout));  
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+     DEBUGINFO;
+     MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+
+     const octave_idx_type L = f.rows();
+     const octave_idx_type W = f.columns();
+     const octave_idx_type L2 = (L/2)+1;
+
+     MArray<LTFAT_COMPLEX> cout(dim_vector(L2,W)); 
+
+     fwd_fftreal(f.data(),L,W,cout.fortran_vec());
+
+     return octave_value(cout);
+}
+
diff --git a/oct/comp_filterbank_fft.cc b/oct/comp_filterbank_fft.cc
new file mode 100644
index 0000000..fda4c24
--- /dev/null
+++ b/oct/comp_filterbank_fft.cc
@@ -0,0 +1,84 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_filterbank_fft // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=convsub_fft(...);\n Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_filterbank_fft(const Complex *F, const Complex *G[],
+                   const ltfatInt L, const ltfatInt W,
+                   const ltfatInt a[], const ltfatInt M,
+                   Complex *c[])
+{
+    filterbank_fft_d(reinterpret_cast<const double _Complex *>(F),
+                     reinterpret_cast<const double _Complex **>(G),
+                     L,W,a,M,
+                     reinterpret_cast<double _Complex **>(c));
+}
+
+static inline void
+fwd_filterbank_fft(const FloatComplex *F, const FloatComplex *G[],
+                   const ltfatInt L, const ltfatInt W,
+                   const ltfatInt a[], const ltfatInt M,
+                   FloatComplex *c[])
+{
+    filterbank_fft_s(reinterpret_cast<const float _Complex *>(F),
+                     reinterpret_cast<const float _Complex **>(G),
+                     L,W,a,M,
+                     reinterpret_cast<float _Complex **>(c));
+}
+
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    // Input data
+    MArray<LTFAT_TYPE> F = ltfatOctArray<LTFAT_TYPE>(args(0));
+    // Cell aray containing impulse responses
+    Cell G = args(1).cell_value();
+    // Subsampling factors
+    Matrix aDouble = args(2).matrix_value();
+
+    // Input length
+    const octave_idx_type L  = F.rows();
+    // Number of channels
+    const octave_idx_type W  = F.columns();
+    // Number of filters
+    const octave_idx_type M = G.nelem();
+
+    // Allocating temporary arrays
+    // Output subband lengths
+    OCTAVE_LOCAL_BUFFER (ltfatInt, a, M);
+    // Impulse responses pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, GPtrs, M);
+    // Output subbands pointers
+    OCTAVE_LOCAL_BUFFER (LTFAT_TYPE*, cPtrs, M);
+    // Output cell elements array,
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, gElems, M);
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, c_elems, M);
+
+    for(octave_idx_type m=0; m<M; m++)
+    {
+        a[m]=(ltfatInt)aDouble(m);
+        gElems[m] = ltfatOctArray<LTFAT_TYPE>(G.elem(m));
+        GPtrs[m] = gElems[m].data();
+        octave_idx_type outLen = (octave_idx_type) ceil( L/aDouble(m) );
+        c_elems[m] = MArray<LTFAT_TYPE>(dim_vector(outLen, W));
+        cPtrs[m] = c_elems[m].fortran_vec();
+    }
+
+    fwd_filterbank_fft(F.data(), GPtrs, L, W, a, M, cPtrs);
+
+    Cell c(dim_vector(M,1));
+    for(octave_idx_type m=0; m<M; ++m)
+    {
+        c.elem(m) = c_elems[m];
+    }
+
+    return octave_value(c);
+}
diff --git a/oct/comp_filterbank_fftbl.cc b/oct/comp_filterbank_fftbl.cc
new file mode 100644
index 0000000..8ce265e
--- /dev/null
+++ b/oct/comp_filterbank_fftbl.cc
@@ -0,0 +1,105 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_filterbank_fftbl // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=convsub_fftbl(...);\n Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_filterbank_fftbl(const Complex *F, const Complex *G[],
+                     const ltfatInt L, const ltfatInt Gl[],
+                     const ltfatInt W, const double afrac[],
+                     const ltfatInt M, const ltfatInt foff[],
+                     const int realonly[], Complex *c[])
+{
+    filterbank_fftbl_d(reinterpret_cast<const double _Complex *>(F),
+                       reinterpret_cast<const double _Complex **>(G),
+                       L,Gl,W,afrac,M,foff,realonly,
+                       reinterpret_cast<double _Complex **>(c));
+}
+
+static inline void
+fwd_filterbank_fftbl(const FloatComplex *F, const FloatComplex *G[],
+                     const ltfatInt L, const ltfatInt Gl[],
+                     const ltfatInt W, const double afrac[],
+                     const ltfatInt M, const ltfatInt foff[],
+                     const int realonly[], FloatComplex *c[])
+{
+    
+    filterbank_fftbl_s(reinterpret_cast<const float _Complex *>(F),
+                       reinterpret_cast<const float _Complex **>(G),
+                       L,Gl,W,afrac,M,foff,realonly,
+                       reinterpret_cast<float _Complex **>(c));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    // Input data
+    MArray<LTFAT_TYPE> F = ltfatOctArray<LTFAT_TYPE>(args(0));
+    // Cell aray containing impulse responses
+    Cell G = args(1).cell_value();
+    Matrix foffDouble = args(2).matrix_value();
+    Matrix a = args(3).matrix_value();
+    Matrix realonlyDouble = args(4).matrix_value();
+
+    // Input length
+    const octave_idx_type L  = F.rows();
+    // Number of channels
+    const octave_idx_type W  = F.columns();
+    // Number of filters
+    const octave_idx_type M = G.nelem();
+
+
+    OCTAVE_LOCAL_BUFFER (double, afrac, M);
+    if( a.columns()>1)
+    {
+        for(octave_idx_type m=0; m<M; m++)
+            afrac[m] = a(m)/a(m+M);
+    }
+    else
+    {
+        for(octave_idx_type m=0; m<M; m++)
+            afrac[m] = a(m);
+    }
+
+    // Allocating temporary arrays
+    // Filter lengts
+    OCTAVE_LOCAL_BUFFER (ltfatInt, Gl, M);
+    // Output subband lengths
+    OCTAVE_LOCAL_BUFFER (ltfatInt, foff, M);
+    OCTAVE_LOCAL_BUFFER (int, realonly, M);
+    // Impulse responses pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, GPtrs, M);
+    // Output subbands pointers
+    OCTAVE_LOCAL_BUFFER (LTFAT_TYPE*, cPtrs, M);
+    //
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, g_elems, M);
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, c_elems, M);
+
+    for(octave_idx_type m=0; m<M; m++)
+    {
+        realonly[m] = (int) (realonlyDouble(m)>1e-3);
+        foff[m] = (ltfatInt) foffDouble(m);
+        g_elems[m] = ltfatOctArray<LTFAT_TYPE>(G.elem(m));
+        GPtrs[m] = g_elems[m].data();
+        Gl[m] = (ltfatInt) g_elems[m].numel();
+        octave_idx_type outLen = (octave_idx_type) floor( L/afrac[m] + 0.5);
+        c_elems[m] = MArray<LTFAT_TYPE>(dim_vector(outLen, W));
+        cPtrs[m] = c_elems[m].fortran_vec();
+    }
+ 
+    fwd_filterbank_fftbl(F.data(),GPtrs,L,Gl,W,afrac,M,foff,realonly,cPtrs);
+
+    Cell c(dim_vector(M,1));
+    for(octave_idx_type m=0; m<M; ++m)
+    {
+        c.elem(m) = c_elems[m];
+    }
+
+    return octave_value(c);
+}
diff --git a/oct/comp_filterbank_td.cc b/oct/comp_filterbank_td.cc
new file mode 100644
index 0000000..0233d36
--- /dev/null
+++ b/oct/comp_filterbank_td.cc
@@ -0,0 +1,117 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_filterbank_td // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=convsub_td(...);\n Yeah."
+#define _DEBUG
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void 
+fwd_filterbank_td(const Complex *f, const Complex *g[],
+                  const ltfatInt L, const ltfatInt gl[],
+                  const ltfatInt W, const ltfatInt a[],
+                  const ltfatInt offset[], const ltfatInt M,
+                  Complex *c[], ltfatExtType ext)
+{
+   filterbank_td_cd(reinterpret_cast<const double _Complex *>(f),
+                    reinterpret_cast<const double _Complex **>(g),
+                    L, gl, W,a,offset,M,
+                    reinterpret_cast<double _Complex **>(c),
+                    ext);
+}
+
+static inline void 
+fwd_filterbank_td(const FloatComplex *f, const FloatComplex *g[],
+                  const ltfatInt L, const ltfatInt gl[],
+                  const ltfatInt W, const ltfatInt a[],
+                  const ltfatInt offset[], const ltfatInt M,
+                  FloatComplex *c[], ltfatExtType ext)
+{
+   filterbank_td_cs(reinterpret_cast<const float _Complex *>(f),
+                    reinterpret_cast<const float _Complex **>(g),
+                    L, gl, W,a,offset,M,
+                    reinterpret_cast<float _Complex **>(c),
+                    ext);
+}
+
+static inline void 
+fwd_filterbank_td(const double *f, const double *g[],
+                  const ltfatInt L, const ltfatInt gl[],
+                  const ltfatInt W, const ltfatInt a[],
+                  const ltfatInt offset[], const ltfatInt M,
+                  double *c[], ltfatExtType ext)
+{
+   filterbank_td_d(f,g,L, gl, W,a,offset,M,c,ext);
+}
+
+static inline void 
+fwd_filterbank_td(const float *f, const float *g[],
+                  const ltfatInt L, const ltfatInt gl[],
+                  const ltfatInt W, const ltfatInt a[],
+                  const ltfatInt offset[], const ltfatInt M,
+                  float *c[], ltfatExtType ext)
+{
+   filterbank_td_s(f,g,L, gl, W,a,offset,M,c,ext);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+	 // Input data
+	 MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+	 // Cell aray containing impulse responses
+	 Cell g = args(1).cell_value();
+	 // Subsampling factors
+	 Matrix aDouble = args(2).matrix_value();
+	 // Skips
+	 Matrix offsetDouble = args(3).matrix_value();
+	 charMatrix extMat = args(4).char_matrix_value();
+     ltfatExtType ext = ltfatExtStringToEnum(extMat.row_as_string(0).c_str());
+	 // Input length
+	 const octave_idx_type L  = f.rows();
+	 // Number of channels
+     const octave_idx_type W  = f.columns();
+	 // Number of filters
+     const octave_idx_type M = g.nelem();
+
+	 // Allocating temporary arrays
+	 // Filter lengts
+	 OCTAVE_LOCAL_BUFFER (ltfatInt, filtLen, M);
+	 OCTAVE_LOCAL_BUFFER (ltfatInt, a, M);
+	 OCTAVE_LOCAL_BUFFER (ltfatInt, offset , M);
+	 // Impulse responses pointers
+	 OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, gPtrs, M);
+	 // Output subbands pointers
+	 OCTAVE_LOCAL_BUFFER (LTFAT_TYPE*, cPtrs, M);
+	 // Output cell elements array,
+	 OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, c_elems, M);
+	 //
+	 OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, g_elems, M);
+
+	 for(octave_idx_type m=0;m<M;m++)
+     {
+        a[m]= (ltfatInt) aDouble(m);
+        offset[m] = (ltfatInt) offsetDouble(m);
+	    g_elems[m] = ltfatOctArray<LTFAT_TYPE>(g.elem(m));
+	    gPtrs[m] = g_elems[m].data();
+        filtLen[m] = (ltfatInt) g_elems[m].numel();
+        octave_idx_type outLen = (octave_idx_type) 
+                                 filterbank_td_size(L,a[m],filtLen[m],
+                                                    offset[m],ext);	 
+        c_elems[m] = MArray<LTFAT_TYPE>(dim_vector(outLen, W));
+		cPtrs[m] = c_elems[m].fortran_vec();
+     }
+
+     fwd_filterbank_td(f.data(),gPtrs,L,filtLen,W,a,offset,M,cPtrs,ext);
+
+	 Cell c(dim_vector(M,1));
+	 for(octave_idx_type m=0;m<M;++m)
+     {
+	    c.elem(m) = c_elems[m];
+	 }
+     return octave_value(c);
+}
diff --git a/oct/comp_gabdual_long.cc b/oct/comp_gabdual_long.cc
new file mode 100644
index 0000000..14c4089
--- /dev/null
+++ b/oct/comp_gabdual_long.cc
@@ -0,0 +1,69 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_gabdual_long // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                    gd=comp_gabdual_long(g,a,M);\n\
+                    Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  gabdual_long forwarders
+*/
+
+static inline void 
+fwd_gabdual_long(const Complex *g, const octave_idx_type L, 
+                 const octave_idx_type R, const octave_idx_type a, 
+                 const octave_idx_type M, Complex *gd)
+{
+   gabdual_long_cd(reinterpret_cast<const _Complex double*>(g),
+                   L,R,a,M,
+                   reinterpret_cast<_Complex double*>(gd));
+}
+
+static inline void 
+fwd_gabdual_long(const FloatComplex *g, const octave_idx_type L, 
+                 const octave_idx_type R, const octave_idx_type a, 
+                 const octave_idx_type M, FloatComplex *gd)
+{
+   gabdual_long_cs(reinterpret_cast<const _Complex float*>(g),
+                   L,R,a,M,
+                   reinterpret_cast<_Complex float*>(gd));
+}
+
+static inline void 
+fwd_gabdual_long(const double *g, const octave_idx_type L, 
+                 const octave_idx_type R, const octave_idx_type a, 
+                 const octave_idx_type M, double *gd)
+{
+   gabdual_long_d(g,L,R,a,M,gd);
+}
+
+static inline void 
+fwd_gabdual_long(const float *g, const octave_idx_type L, 
+                 const octave_idx_type R, const octave_idx_type a, 
+                 const octave_idx_type M, float *gd)
+{
+   gabdual_long_s(g,L,R,a,M,gd);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(0));
+   const octave_idx_type L = g.rows();
+   const octave_idx_type R = g.columns();
+   const octave_idx_type a = args(1).int_value();
+   const octave_idx_type M = args(2).int_value();
+  
+   MArray<LTFAT_TYPE> gd(dim_vector(L,R)); 
+    
+   fwd_gabdual_long(g.data(),L, R, a, M,gd.fortran_vec());
+    
+   return octave_value(gd);
+}
+
diff --git a/oct/comp_gabreassign.cc b/oct/comp_gabreassign.cc
new file mode 100644
index 0000000..381bc33
--- /dev/null
+++ b/oct/comp_gabreassign.cc
@@ -0,0 +1,53 @@
+#define TYPEDEPARGS 0, 1, 2
+#define SINGLEARGS
+#define REALARGS
+#define OCTFILENAME comp_gabreassign // change to filename
+#define OCTFILEHELP "Computes spreading permutation.\n\
+                     Usage: sr=comp_gabreassign(s,itime,ifreq,a);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  gabreassign forwarders
+*/
+
+static inline void
+fwd_gabreassign(const double *s, const double *tgrad, const double *fgrad,
+                const octave_idx_type L, const octave_idx_type W,
+                const octave_idx_type a, const octave_idx_type M,
+                double *sr)
+{
+   gabreassign_d(s,tgrad,fgrad,L,W,a,M,sr);
+}
+
+static inline void 
+fwd_gabreassign(const float *s, const float *tgrad, const float *fgrad,
+                const octave_idx_type L, const octave_idx_type W,
+                const octave_idx_type a, const octave_idx_type M,
+                float *sr)
+{
+   gabreassign_s(s,tgrad,fgrad,L,W,a,M,sr);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+    
+   MArray<LTFAT_TYPE> s = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> tgrad = ltfatOctArray<LTFAT_TYPE>(args(1));
+   MArray<LTFAT_TYPE> fgrad = ltfatOctArray<LTFAT_TYPE>(args(2));
+   const octave_idx_type a  = args(3).int_value();
+   const octave_idx_type M  = s.rows();
+   const octave_idx_type N  = s.columns();
+   const octave_idx_type L  = N*a;
+
+   MArray<LTFAT_TYPE> sr(dim_vector(M,N)); 
+    
+   fwd_gabreassign(s.data(),tgrad.data(),fgrad.data(),L,1,a,M,sr.fortran_vec());
+    
+   return octave_value(sr);
+}
diff --git a/oct/comp_gabtight_long.cc b/oct/comp_gabtight_long.cc
new file mode 100644
index 0000000..41ad61a
--- /dev/null
+++ b/oct/comp_gabtight_long.cc
@@ -0,0 +1,64 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_gabtight_long // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     gd=comp_gabtight_long(g,a,M);\n\
+                     Yeah."
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_gabtight_long(const Complex *g, const octave_idx_type L,
+                  const octave_idx_type R, const octave_idx_type a,
+                  const octave_idx_type M, Complex *gd)
+{
+   gabtight_long_cd(reinterpret_cast<const _Complex double*>(g),
+                    L,R,a,M,
+          reinterpret_cast<_Complex double*>(gd));
+}
+
+static inline void
+fwd_gabtight_long(const FloatComplex *g, const octave_idx_type L,
+                  const octave_idx_type R, const octave_idx_type a,
+                  const octave_idx_type M, FloatComplex *gd)
+{
+   gabtight_long_cs(reinterpret_cast<const _Complex float*>(g),
+                    L,R,a,M,
+                    reinterpret_cast<_Complex float*>(gd));
+}
+
+static inline void 
+fwd_gabtight_long(const double *g, const octave_idx_type L,
+                  const octave_idx_type R, const octave_idx_type a,
+                  const octave_idx_type M, double *gd)
+{
+   gabtight_long_d(g,L,R,a,M,gd);
+}
+
+static inline void 
+fwd_gabtight_long(const float *g, const octave_idx_type L,
+                  const octave_idx_type R, const octave_idx_type a,
+                  const octave_idx_type M, float *gd)
+{
+   gabtight_long_s(g,L,R,a,M,gd);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(0));
+   const octave_idx_type L = g.rows();
+   const octave_idx_type R = g.columns();
+   const octave_idx_type a = args(1).int_value();
+   const octave_idx_type M = args(2).int_value();
+    
+   MArray<LTFAT_TYPE> gd(dim_vector(L,R)); 
+    
+   fwd_gabtight_long(g.data(),L,R,a,M,gd.fortran_vec());
+    
+   return octave_value(gd);
+}
diff --git a/oct/comp_gga.cc b/oct/comp_gga.cc
new file mode 100644
index 0000000..5b0004b
--- /dev/null
+++ b/oct/comp_gga.cc
@@ -0,0 +1,74 @@
+#define TYPEDEPARGS 0
+#define MATCHEDARGS 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_gga // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=gga(...);\n Yeah."
+//#define _DEBUG
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+ 
+
+static inline void
+fwd_gga(const Complex *fPtr, const double*  indVecPtr,
+        const octave_idx_type L, const octave_idx_type W,
+        const octave_idx_type M, Complex *cPtr )
+{
+   gga_cd(reinterpret_cast<const double _Complex *>(fPtr),
+          indVecPtr,L,W,M,
+          reinterpret_cast<double _Complex *>(cPtr));
+}
+
+static inline void
+fwd_gga(const FloatComplex *fPtr, const float*  indVecPtr,
+        const octave_idx_type L, const octave_idx_type W,
+        const octave_idx_type M, FloatComplex *cPtr )
+{
+   gga_cs(reinterpret_cast<const float _Complex *>(fPtr),
+          indVecPtr,L,W,M,
+          reinterpret_cast<float _Complex *>(cPtr));
+}
+
+static inline void
+fwd_gga(const double *fPtr, const double*  indVecPtr,
+        const octave_idx_type L, const octave_idx_type W,
+        const octave_idx_type M, Complex *cPtr )
+{
+   gga_d(fPtr, indVecPtr,L,W,M,
+         reinterpret_cast<double _Complex *>(cPtr));
+}
+
+static inline void
+fwd_gga(const float *fPtr, const float*  indVecPtr,
+        const octave_idx_type L, const octave_idx_type W,
+        const octave_idx_type M, FloatComplex *cPtr )
+{
+   gga_s(fPtr, indVecPtr,L,W,M,
+         reinterpret_cast<float _Complex *>(cPtr));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list
+octFunction(const octave_value_list& args, int nargout)
+{
+   //DEBUGINFO;
+   // Input data
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_REAL> indVec = ltfatOctArray<LTFAT_REAL>(args(1));
+    
+   // Input length
+   const octave_idx_type L  = f.rows();
+   // Number of channels
+   const octave_idx_type W  = f.columns();
+   // Number of coefficients
+   const octave_idx_type M = indVec.nelem();
+
+   //dims_out.chop_trailing_singletons();
+   MArray<LTFAT_COMPLEX> c(dim_vector(M,W));
+    
+   fwd_gga(f.data(),indVec.data(),L,W,M,c.fortran_vec());
+
+   return octave_value(c);
+}
diff --git a/oct/comp_heapint.cc b/oct/comp_heapint.cc
new file mode 100644
index 0000000..a521269
--- /dev/null
+++ b/oct/comp_heapint.cc
@@ -0,0 +1,48 @@
+#define TYPEDEPARGS 0, 1, 2
+#define SINGLEARGS
+#define REALARGS
+#define OCTFILENAME comp_heapint // change to filename
+#define OCTFILEHELP "Computes heapint.\n\
+                    Usage: c = comp_heapint(s, itime, ifreq, a, tol);\n\
+                    Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+
+static inline void fwd_heapint(const double *s, const double *tgrad, const double *fgrad,
+                                  const octave_idx_type a, const octave_idx_type M,
+								  const octave_idx_type L, const octave_idx_type W,
+								  double tol, double *phase)
+{
+   heapint_d(s,tgrad,fgrad,a,M,L,W,tol,phase);
+}
+
+static inline void fwd_heapint(const float *s, const float *tgrad, const float *fgrad,
+                               const octave_idx_type a, const octave_idx_type M,
+							   const octave_idx_type L, const octave_idx_type W,
+							   float tol, float *phase)
+{
+   heapint_s(s,tgrad,fgrad,a,M,L,W,tol,phase);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+	 MArray<LTFAT_TYPE> s = ltfatOctArray<LTFAT_TYPE>(args(0));
+	 MArray<LTFAT_TYPE> tgrad = ltfatOctArray<LTFAT_TYPE>(args(1));
+	 MArray<LTFAT_TYPE> fgrad = ltfatOctArray<LTFAT_TYPE>(args(2));
+	 const octave_idx_type a  = args(3).int_value();
+     const double tol   = args(4).double_value();
+
+     const octave_idx_type M = args(0).rows();
+     const octave_idx_type N = args(0).columns();
+     const octave_idx_type L = N*a;
+
+     MArray<LTFAT_TYPE> phase(dim_vector(M,N)); 
+	 
+	 fwd_heapint(s.data(),tgrad.data(),fgrad.data(),a,M,L,1,tol,phase.fortran_vec());
+	 
+     return octave_value(phase);
+}
diff --git a/oct/comp_iatrousfilterbank_td.cc b/oct/comp_iatrousfilterbank_td.cc
new file mode 100644
index 0000000..6123115
--- /dev/null
+++ b/oct/comp_iatrousfilterbank_td.cc
@@ -0,0 +1,102 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_iatrousfilterbank_td // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=upconv_td(...);\n Yeah."
+#define _DEBUG
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void 
+fwd_iatrousfilterbank_td(const Complex *c, const Complex *g[], 
+                         const ltfatInt L, const ltfatInt gl[],
+                         const ltfatInt W, const ltfatInt a[],
+                         const ltfatInt offset[], const ltfatInt M,
+                         Complex *f, ltfatExtType ext)
+{
+   iatrousfilterbank_td_cd(reinterpret_cast<const double _Complex *>(c),
+                           reinterpret_cast<const double _Complex **>(g), 
+                           L,gl,W,a,offset,M,
+                           reinterpret_cast<double _Complex *>(f),
+                           ext);
+}
+
+static inline void 
+fwd_iatrousfilterbank_td(const FloatComplex *c, const FloatComplex *g[], 
+                         const ltfatInt L, const ltfatInt gl[],
+                         const ltfatInt W, const ltfatInt a[],
+                         const ltfatInt offset[], const ltfatInt M,
+                         FloatComplex *f, ltfatExtType ext)
+{
+   iatrousfilterbank_td_cs(reinterpret_cast<const float _Complex *>(c),
+                           reinterpret_cast<const float _Complex **>(g), 
+                           L,gl,W,a,offset,M,
+                           reinterpret_cast<float _Complex *>(f),
+                           ext);
+}
+
+static inline void 
+fwd_iatrousfilterbank_td(const double *c, const double *g[], 
+                         const ltfatInt L, const ltfatInt gl[],
+                         const ltfatInt W, const ltfatInt a[],
+                         const ltfatInt offset[], const ltfatInt M,
+                         double *f, ltfatExtType ext)
+{
+   iatrousfilterbank_td_d(c,g,L,gl,W,a,offset,M,f,ext);
+}
+
+static inline void 
+fwd_iatrousfilterbank_td(const float *c, const float *g[], 
+                         const ltfatInt L, const ltfatInt gl[],
+                         const ltfatInt W, const ltfatInt a[],
+                         const ltfatInt offset[], const ltfatInt M,
+                         float *f, ltfatExtType ext)
+{
+   iatrousfilterbank_td_s(c,g,L,gl,W,a,offset,M,f,ext);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+	 //DEBUGINFO;
+	 // Input data
+	 MArray<LTFAT_TYPE> c = ltfatOctArray<LTFAT_TYPE>(args(0));
+	 // Cell aray containing impulse responses
+	 MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+	 // Subsampling factors
+	 Matrix aDouble = args(2).matrix_value();
+	 Matrix offsetDouble = args(3).matrix_value();
+
+	 const octave_idx_type L = c.dim1();
+	 const octave_idx_type M = c.dim2();
+	 octave_idx_type W = 1;
+	 if(c.ndims()>2)
+	 {
+	  W = c.dim3();
+	 }
+
+     const octave_idx_type filtLen = g.rows();
+
+	 OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, gPtrs, M);
+     OCTAVE_LOCAL_BUFFER (ltfatInt, filtLens, M);
+     OCTAVE_LOCAL_BUFFER (ltfatInt, a, M);
+     OCTAVE_LOCAL_BUFFER (ltfatInt, offset, M);
+
+
+	 for(octave_idx_type m=0;m<M;m++)
+     {
+        filtLens[m] = (ltfatInt) filtLen;
+        a[m] = (ltfatInt) aDouble(0); 
+        offset[m] = (ltfatInt) offsetDouble(m);
+	    gPtrs[m] = g.data() +  m*filtLen;
+     }
+
+	 MArray<LTFAT_TYPE> f(dim_vector(L,W));
+
+   fwd_iatrousfilterbank_td(c.data(), gPtrs, L, filtLens, W, a, offset, M, f.fortran_vec(), PER);
+
+     return octave_value(f);
+}
diff --git a/oct/comp_idwilt.cc b/oct/comp_idwilt.cc
new file mode 100644
index 0000000..59330d0
--- /dev/null
+++ b/oct/comp_idwilt.cc
@@ -0,0 +1,120 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_idwilt // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     coef=comp_dwilt_fb(f,g,M,L);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  dgtreal_ola forwarders
+*/
+
+static inline void
+fwd_idwilt_fb(const Complex *c, const Complex *g,
+             const octave_idx_type L, const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             Complex *f)
+{
+   idwilt_fb_cd(reinterpret_cast<const double _Complex*>(c),
+               reinterpret_cast<const double _Complex*>(g),
+               L, gl, W,M, reinterpret_cast<double _Complex*>(f));
+}
+
+static inline void 
+fwd_idwilt_fb(const FloatComplex *c, const FloatComplex *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             FloatComplex *f)
+{
+   idwilt_fb_cs(reinterpret_cast<const float _Complex*>(c),
+               reinterpret_cast<const float _Complex*>(g),
+               L, gl,W,M,
+               reinterpret_cast<float _Complex*>(f));
+}
+
+static inline void
+fwd_idwilt_fb(const double *c, const double *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             double *f)
+{
+   idwilt_fb_d(c,g,L,gl,W,M,f);
+}
+
+static inline void
+fwd_idwilt_fb(const float *c, const float *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             float *f)
+{
+   idwilt_fb_s(c,g,L,gl,W,M,f);
+}
+
+static inline void
+fwd_idwilt_long(const Complex *c, const Complex *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, Complex *f)
+{
+   idwilt_long_cd(reinterpret_cast<const double _Complex*>(c),
+                 reinterpret_cast<const double _Complex*>(g),
+                 L,W,M, reinterpret_cast<double _Complex*>(f));
+}
+
+static inline void 
+fwd_idwilt_long(const FloatComplex *c, const FloatComplex *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, FloatComplex *f)
+{
+   idwilt_long_cs(reinterpret_cast<const float _Complex*>(c),
+                 reinterpret_cast<const float _Complex*>(g),
+                 L,W,M, reinterpret_cast<float _Complex*>(f));
+}
+
+static inline void
+fwd_idwilt_long(const double *c, const double *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, double *f)
+{
+   idwilt_long_d(c,g,L,W,M,f);
+}
+
+static inline void
+fwd_idwilt_long(const float *c, const float *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, float *f)
+{
+   idwilt_long_s(c,g,L,W,M,f);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+
+   MArray<LTFAT_TYPE> c = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+   
+   const octave_idx_type M = c.rows()/2;
+   const octave_idx_type gl = g.nelem();
+   const octave_idx_type N = 2*c.columns();
+   const octave_idx_type L = N*M;
+   const octave_idx_type W = c.nelem()/L;
+
+   MArray<LTFAT_TYPE> f(dim_vector(L,W)); 
+
+   if(gl<L)
+   {     
+      fwd_idwilt_fb(c.data(),g.data(),L, gl, W, M,f.fortran_vec());
+   }
+   else
+   {
+      fwd_idwilt_long(c.data(),g.data(),L, W, M,f.fortran_vec());
+   }
+
+   return octave_value(f);
+}
+
diff --git a/oct/comp_idwiltiii.cc b/oct/comp_idwiltiii.cc
new file mode 100644
index 0000000..43bbc37
--- /dev/null
+++ b/oct/comp_idwiltiii.cc
@@ -0,0 +1,121 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_idwiltiii // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     coef=comp_dwilt_fb(f,g,M,L);\n\
+                     Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+  dgtreal_ola forwarders
+*/
+
+static inline void
+fwd_idwiltiii_fb(const Complex *c, const Complex *g,
+             const octave_idx_type L, const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             Complex *f)
+{
+   idwiltiii_fb_cd(reinterpret_cast<const double _Complex*>(c),
+               reinterpret_cast<const double _Complex*>(g),
+               L, gl, W,M, reinterpret_cast<double _Complex*>(f));
+}
+
+static inline void 
+fwd_idwiltiii_fb(const FloatComplex *c, const FloatComplex *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             FloatComplex *f)
+{
+   idwiltiii_fb_cs(reinterpret_cast<const float _Complex*>(c),
+               reinterpret_cast<const float _Complex*>(g),
+               L, gl,W,M,
+               reinterpret_cast<float _Complex*>(f));
+}
+
+static inline void
+fwd_idwiltiii_fb(const double *c, const double *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             double *f)
+{
+   idwiltiii_fb_d(c,g,L,gl,W,M,f);
+}
+
+static inline void
+fwd_idwiltiii_fb(const float *c, const float *g,
+             const octave_idx_type L,  const octave_idx_type gl,
+             const octave_idx_type W, const octave_idx_type M, 
+             float *f)
+{
+   idwiltiii_fb_s(c,g,L,gl,W,M,f);
+}
+
+static inline void
+fwd_idwiltiii_long(const Complex *c, const Complex *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, Complex *f)
+{
+   idwiltiii_long_cd(reinterpret_cast<const double _Complex*>(c),
+                 reinterpret_cast<const double _Complex*>(g),
+                 L,W,M, reinterpret_cast<double _Complex*>(f));
+}
+
+static inline void 
+fwd_idwiltiii_long(const FloatComplex *c, const FloatComplex *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, FloatComplex *f)
+{
+   idwiltiii_long_cs(reinterpret_cast<const float _Complex*>(c),
+                 reinterpret_cast<const float _Complex*>(g),
+                 L,W,M, reinterpret_cast<float _Complex*>(f));
+}
+
+static inline void
+fwd_idwiltiii_long(const double *c, const double *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, double *f)
+{
+   idwiltiii_long_d(c,g,L,W,M,f);
+}
+
+static inline void
+fwd_idwiltiii_long(const float *c, const float *g,
+               const octave_idx_type L, const octave_idx_type W, 
+               const octave_idx_type M, float *f)
+{
+   idwiltiii_long_s(c,g,L,W,M,f);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+
+   MArray<LTFAT_TYPE> c = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+   
+   const octave_idx_type M = c.rows();
+   const octave_idx_type gl = g.nelem();
+   const octave_idx_type N = c.columns();
+   const octave_idx_type L = N*M;
+   const octave_idx_type W = c.nelem()/L;
+
+
+   MArray<LTFAT_TYPE> f(dim_vector(L,W)); 
+
+   if(gl<L)
+   {     
+      fwd_idwiltiii_fb(c.data(),g.data(),L, gl, W, M,f.fortran_vec());
+   }
+   else
+   {
+      fwd_idwiltiii_long(c.data(),g.data(),L, W, M,f.fortran_vec());
+   }
+
+   return octave_value(f);
+}
+
diff --git a/oct/comp_ifftreal.cc b/oct/comp_ifftreal.cc
new file mode 100644
index 0000000..ba24982
--- /dev/null
+++ b/oct/comp_ifftreal.cc
@@ -0,0 +1,47 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_ifftreal // change to filename
+#define OCTFILEHELP "This function calls the FFTW3 real FFT\n\
+                    f=comp_ifftreal(c,L2);\n\
+                    Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+#include "config.h"
+#include "fftw3.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_ifftreal(const Complex *c,
+                                const octave_idx_type L,
+                                const octave_idx_type W,
+                                double *f)
+{
+  ifftreal_d(const_cast<double _Complex*>(reinterpret_cast<const double _Complex*>(c)),
+           L,W,f);
+}
+
+static inline void fwd_ifftreal(const FloatComplex *c,
+                                const octave_idx_type L,
+                                const octave_idx_type W,
+                                float *f)
+{
+   ifftreal_s(const_cast<float _Complex*>(reinterpret_cast<const float _Complex*>(c)),
+           L,W,f);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+     MArray<LTFAT_TYPE> c = ltfatOctArray<LTFAT_TYPE>(args(0));
+  
+     const octave_idx_type W  = c.columns();
+     const octave_idx_type L = args(1).int_value();
+  
+     MArray<LTFAT_REAL> f(dim_vector(L,W)); 
+         
+     fwd_ifftreal(c.data(),L,W,f.fortran_vec());
+         
+     return octave_value(f);
+}
+
diff --git a/oct/comp_ifilterbank_fft.cc b/oct/comp_ifilterbank_fft.cc
new file mode 100644
index 0000000..a6db729
--- /dev/null
+++ b/oct/comp_ifilterbank_fft.cc
@@ -0,0 +1,85 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_ifilterbank_fft // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=upconv_fft(...);\n Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_ifilterbank_fft(const Complex *c[], const Complex *filt[],
+                    const ltfatInt L, const ltfatInt W,
+                    const ltfatInt a[], const ltfatInt M,
+                    Complex *f)
+{
+    ifilterbank_fft_d(reinterpret_cast<const double _Complex **>(c),
+                      reinterpret_cast<const double _Complex **>(filt),
+                      L,W,a,M,
+                      reinterpret_cast<double _Complex *>(f));
+}
+
+static inline void
+fwd_ifilterbank_fft(const FloatComplex *c[], const FloatComplex *filt[],
+                    const ltfatInt L, const ltfatInt W,
+                    const ltfatInt a[], const ltfatInt M,
+                    FloatComplex *f)
+{
+    ifilterbank_fft_s(reinterpret_cast<const float _Complex **>(c),
+                      reinterpret_cast<const float _Complex **>(filt),
+                      L,W,a,M,
+                      reinterpret_cast<float _Complex *>(f));
+}
+
+
+// Calling convention:
+// F = comp_ifilterbank_fft(c,G,a)
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    // Input data
+    Cell c = args(0).cell_value();
+    // Cell aray containing impulse responses
+    Cell G = args(1).cell_value();
+    // Subsampling factors
+    Matrix aDouble = args(2).matrix_value();
+
+    // Output length
+    const octave_idx_type L  = G.elem(0).rows();
+    // Number of channels
+    const octave_idx_type W  = c.elem(0).columns();
+    // Number of filters
+    const octave_idx_type M = G.nelem();
+
+    // Output signal
+    MArray<LTFAT_COMPLEX> F(dim_vector(L,W));
+
+
+    // Allocating temporary arrays
+    // Output subband lengths
+    // Impulse responses pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_COMPLEX*, GPtrs, M);
+    // Output subbands pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_COMPLEX*, cPtrs, M);
+    // Output cell elements array,
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_COMPLEX>, cElems, M);
+    //
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_COMPLEX>, GElems, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, a, M);
+
+    for(octave_idx_type m=0; m<M; m++)
+    {
+        a[m] = (ltfatInt) aDouble(m); 
+        GElems[m] = ltfatOctArray<LTFAT_COMPLEX>(G.elem(m));
+        GPtrs[m] = GElems[m].data();
+        cElems[m] = ltfatOctArray<LTFAT_COMPLEX>(c.elem(m));
+        cPtrs[m] = cElems[m].data();
+    }
+
+
+    fwd_ifilterbank_fft(cPtrs,GPtrs,L,W,a,M,F.fortran_vec());
+
+    return octave_value(F);
+}
diff --git a/oct/comp_ifilterbank_fftbl.cc b/oct/comp_ifilterbank_fftbl.cc
new file mode 100644
index 0000000..05a5bee
--- /dev/null
+++ b/oct/comp_ifilterbank_fftbl.cc
@@ -0,0 +1,104 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_ifilterbank_fftbl // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=upconv_fftbl(...);\n Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_ifilterbank_fftbl(const Complex *c[], const Complex *G[],
+                      const ltfatInt L, const ltfatInt Gl[],
+                      const ltfatInt W, const double afrac[],
+                      const ltfatInt M, const ltfatInt foff[],
+                      const int realonly[], Complex *F)
+{
+    ifilterbank_fftbl_d(reinterpret_cast<const double _Complex **>(c),
+                        reinterpret_cast<const double _Complex **>(G),
+                        L,Gl,W,afrac,M,foff,realonly,
+                        reinterpret_cast<double _Complex *>(F));
+}
+
+static inline void
+fwd_ifilterbank_fftbl(const FloatComplex *c[], const FloatComplex *G[],
+                      const ltfatInt L, const ltfatInt Gl[],
+                      const ltfatInt W, const double afrac[],
+                      const ltfatInt M, const ltfatInt foff[],
+                      const int realonly[], FloatComplex *F)
+{
+    ifilterbank_fftbl_s(reinterpret_cast<const float _Complex **>(c),
+                        reinterpret_cast<const float _Complex **>(G),
+                        L,Gl,W,afrac,M,foff,realonly,
+                        reinterpret_cast<float _Complex *>(F));
+}
+
+
+// Calling convention:
+// F = comp_ifilterbank_fftbl(c,G,foff,a,realonly)
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    // Input data
+    Cell c = args(0).cell_value();
+    // Cell aray containing impulse responses
+    Cell G = args(1).cell_value();
+    // Subsampling factors
+    Matrix foffDouble = args(2).matrix_value();
+    const double* a = args(3).matrix_value().data();
+    Matrix realonlyDouble = args(4).matrix_value();
+
+    octave_idx_type acols = args(3).matrix_value().columns();
+    // Number of channels
+    const octave_idx_type W  = c.elem(0).columns();
+    // Number of filters
+    const octave_idx_type M = G.nelem();
+
+    OCTAVE_LOCAL_BUFFER (double, afrac, M);
+    memcpy(afrac,a,M*sizeof(double));
+    if(acols>1)
+    {
+        for(octave_idx_type m=0; m<M; m++)
+        {
+            afrac[m]/=a[M+m];
+        }
+    }
+
+    // Allocating
+    // Output subband lengths
+    OCTAVE_LOCAL_BUFFER (ltfatInt, foff, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, Gl, M);
+    OCTAVE_LOCAL_BUFFER (int, realonly, M);
+    // Impulse responses pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_COMPLEX*, GPtrs, M);
+    // Output subbands pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_COMPLEX*, cPtrs, M);
+    // Output cell elements array,
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_COMPLEX>, cElems, M);
+    //
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_COMPLEX>, GElems, M);
+
+    for(octave_idx_type m=0; m<M; m++)
+    {
+        realonly[m] = (realonlyDouble(m)>1e-3);
+        foff[m] = foffDouble(m);
+        GElems[m] = ltfatOctArray<LTFAT_COMPLEX>(G.elem(m));
+        GPtrs[m] = GElems[m].data();
+        cElems[m] = ltfatOctArray<LTFAT_COMPLEX>(c.elem(m));
+        cPtrs[m] = cElems[m].data();
+        Gl[m] = GElems[m].nelem();
+    }
+
+    // Output length
+    octave_idx_type Lc = c.elem(0).rows();
+    const octave_idx_type L  = floor(afrac[0]*Lc+0.5);
+    // Output signal
+    MArray<LTFAT_COMPLEX> F(dim_vector(L,W));
+
+    fwd_ifilterbank_fftbl(cPtrs,GPtrs,L,Gl,W,afrac,M,
+                          foff,realonly,F.fortran_vec());
+
+    return octave_value(F);
+}
diff --git a/oct/comp_ifilterbank_td.cc b/oct/comp_ifilterbank_td.cc
new file mode 100644
index 0000000..818e620
--- /dev/null
+++ b/oct/comp_ifilterbank_td.cc
@@ -0,0 +1,112 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_ifilterbank_td // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=upconv_td(...);\n Yeah."
+#define _DEBUG
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+
+
+static inline void
+fwd_ifilterbank_td(const Complex *c[],  const Complex *g[],
+                   const ltfatInt L, const ltfatInt gl[],
+                   const ltfatInt W, const ltfatInt a[],
+                   const ltfatInt offset[],const ltfatInt M,
+                   Complex *f, ltfatExtType ext)
+{
+    ifilterbank_td_cd(reinterpret_cast<const double _Complex **>(c),
+                        reinterpret_cast<const double _Complex **>(g),
+                        L,gl,W,a,offset,M,
+                        reinterpret_cast<double _Complex *>(f),
+                        ext);
+}
+
+static inline void
+fwd_ifilterbank_td(const FloatComplex *c[],  const FloatComplex *g[],
+                   const ltfatInt L, const ltfatInt gl[],
+                   const ltfatInt W, const ltfatInt a[],
+                   const ltfatInt offset[],const ltfatInt M,
+                   FloatComplex *f, ltfatExtType ext)
+{
+    ifilterbank_td_cs(reinterpret_cast<const float _Complex **>(c),
+                        reinterpret_cast<const float _Complex **>(g),
+                        L,gl,W,a,offset,M,
+                        reinterpret_cast<float _Complex *>(f),
+                        ext);
+}
+
+static inline void
+fwd_ifilterbank_td(const double *c[],  const double *g[],
+                   const ltfatInt L, const ltfatInt gl[],
+                   const ltfatInt W, const ltfatInt a[],
+                   const ltfatInt offset[],const ltfatInt M,
+                   double *f, ltfatExtType ext)
+{
+    ifilterbank_td_d(c,g,L,gl,W,a,offset,M,f,ext);
+}
+
+static inline void
+fwd_ifilterbank_td(const float *c[],  const float *g[],
+                   const ltfatInt L, const ltfatInt gl[],
+                   const ltfatInt W, const ltfatInt a[],
+                   const ltfatInt offset[],const ltfatInt M,
+                   float *f, ltfatExtType ext)
+{
+    ifilterbank_td_s(c,g,L,gl,W,a,offset,M,f,ext);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    //DEBUGINFO;
+    // Input data
+    Cell c = args(0).cell_value();
+    // Cell aray containing impulse responses
+    Cell g = args(1).cell_value();
+    // Subsampling factors
+    Matrix aDouble = args(2).matrix_value();
+    // Skips
+    const octave_idx_type L = args(3).int_value();
+    Matrix offsetDouble = args(4).matrix_value();
+
+    charMatrix extMat = args(5).char_matrix_value();
+    ltfatExtType ext = ltfatExtStringToEnum(extMat.row_as_string(0).c_str());
+    // Number of filters
+    const octave_idx_type M = g.nelem();
+
+    // Allocating temporary arrays
+    // Filter lengts
+    OCTAVE_LOCAL_BUFFER (ltfatInt, filtLen, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, a, M);
+    OCTAVE_LOCAL_BUFFER (ltfatInt, offset, M);
+    // Impulse responses pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, gPtrs, M);
+    // Output subbands pointers
+    OCTAVE_LOCAL_BUFFER (const LTFAT_TYPE*, cPtrs, M);
+    // Input cell elements array,
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, c_elems, M);
+    //
+    OCTAVE_LOCAL_BUFFER (MArray<LTFAT_TYPE>, g_elems, M);
+
+    for(octave_idx_type m=0; m<M; m++)
+    {
+        a[m] = (ltfatInt) aDouble(m);
+        offset[m] = (ltfatInt) offsetDouble(m);
+        g_elems[m] = ltfatOctArray<LTFAT_TYPE>(g.elem(m));
+        c_elems[m] = ltfatOctArray<LTFAT_TYPE>(c.elem(m));
+        gPtrs[m] = g_elems[m].data();
+        cPtrs[m] = c_elems[m].data();
+        filtLen[m] = (ltfatInt) g_elems[m].nelem();
+    }
+
+    const octave_idx_type W  = c_elems[0].columns();
+
+    MArray<LTFAT_TYPE> f(dim_vector(L,W));
+
+    fwd_ifilterbank_td(cPtrs,gPtrs,L,filtLen,W,a,offset,M,f.fortran_vec(),ext);
+
+    return octave_value(f);
+}
diff --git a/oct/comp_isepdgt.cc b/oct/comp_isepdgt.cc
new file mode 100644
index 0000000..0b56f9e
--- /dev/null
+++ b/oct/comp_isepdgt.cc
@@ -0,0 +1,83 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_isepdgt // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                    c=comp_idgt_fb(coef,g,L,a,M);\n\
+                    Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void
+fwd_idgt_fb(const Complex *coef, const Complex *gf,
+            const octave_idx_type L,const octave_idx_type gl,
+            const octave_idx_type W,const octave_idx_type a,
+            const octave_idx_type M,Complex *f)
+{
+   idgt_fb_d(reinterpret_cast<const double _Complex*>(coef),
+             reinterpret_cast<const double _Complex*>(gf),
+             L,gl,W,a,M,reinterpret_cast<double _Complex*>(f));
+}
+
+static inline void
+fwd_idgt_fb(const FloatComplex *coef, const FloatComplex *gf,
+            const octave_idx_type L,const octave_idx_type gl, 
+            const octave_idx_type W,const octave_idx_type a,
+            const octave_idx_type M,FloatComplex *f)
+{
+   idgt_fb_s(reinterpret_cast<const float _Complex*>(coef),
+             reinterpret_cast<const float _Complex*>(gf),
+             L,gl,W,a,M,reinterpret_cast<float _Complex*>(f));
+}
+
+static inline void
+fwd_idgt_long(const Complex *coef, const Complex *gf,
+              const octave_idx_type L, const octave_idx_type W,
+              const octave_idx_type a, const octave_idx_type M,
+              Complex *f)
+{
+   idgt_long_d(reinterpret_cast<const double _Complex*>(coef),
+               reinterpret_cast<const double _Complex*>(gf),
+               L,W,a,M,
+               reinterpret_cast<double _Complex*>(f));
+}
+
+static inline void 
+fwd_idgt_long(const FloatComplex *coef, const FloatComplex *gf,
+              const octave_idx_type L, const octave_idx_type W, 
+              const octave_idx_type a, const octave_idx_type M,
+              FloatComplex *f)
+{
+   idgt_long_s(reinterpret_cast<const float _Complex*>(coef),
+               reinterpret_cast<const float _Complex*>(gf),
+               L,W,a,M,
+               reinterpret_cast<float _Complex*>(f));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   MArray<LTFAT_TYPE> coef = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> gf = ltfatOctArray<LTFAT_TYPE>(args(1));
+   const octave_idx_type L = args(2).int_value();
+   const octave_idx_type a = args(3).int_value();
+   const octave_idx_type M = args(4).int_value();
+   const octave_idx_type N = L/a;
+   const octave_idx_type gl = gf.rows();
+
+   const octave_idx_type W = coef.nelem()/(M*N);
+
+   MArray<LTFAT_COMPLEX> f(dim_vector(L,W)); 
+
+   if(gl<L)
+   {
+      fwd_idgt_fb(coef.data(),gf.data(),L,gl,W,a,M,f.fortran_vec());
+   }
+   else
+   {
+      fwd_idgt_long(coef.data(),gf.data(),L,W,a,M,f.fortran_vec());
+   }
+   return octave_value(f);
+}
diff --git a/oct/comp_isepdgtreal.cc b/oct/comp_isepdgtreal.cc
new file mode 100644
index 0000000..f1f8fc9
--- /dev/null
+++ b/oct/comp_isepdgtreal.cc
@@ -0,0 +1,80 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define MATCHEDARGS 1
+#define COMPLEXARGS
+#define OCTFILENAME comp_isepdgtreal // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                    c=comp_idgtereal_fb(c,g,L,a,M);\n\
+                    Yeah.\n"
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void
+fwd_idgtreal_fb(const Complex *coef, const double *gf,
+                const octave_idx_type L, const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type a,
+                const octave_idx_type M, double *f)
+{
+   idgtreal_fb_d(reinterpret_cast<const double _Complex*>(coef),
+                 gf,L,gl,W,a,M,f);
+}
+
+static inline void
+fwd_idgtreal_fb(const FloatComplex *coef, const float *gf,
+                const octave_idx_type L, const octave_idx_type gl,
+                const octave_idx_type W, const octave_idx_type a,
+                const octave_idx_type M, float *f)
+{
+   idgtreal_fb_s(reinterpret_cast<const float _Complex*>(coef),
+                 gf,L,gl,W,a,M,f);
+}
+
+static inline void
+fwd_idgtreal_long(const Complex *coef, const double *gf,
+                  const octave_idx_type L, const octave_idx_type W,
+                  const octave_idx_type a, const octave_idx_type M,
+                  double *f)
+{
+   idgtreal_long_d(reinterpret_cast<const double _Complex*>(coef),
+                   gf,L,W,a,M,f);
+}
+
+static inline void
+fwd_idgtreal_long(const FloatComplex *coef, const float *gf,
+                  const octave_idx_type L, const octave_idx_type W, 
+                  const octave_idx_type a, const octave_idx_type M,
+                  float *f)
+{
+   idgtreal_long_s(reinterpret_cast<const float _Complex*>(coef),
+                   gf,L,W,a,M,f);
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+
+   MArray<LTFAT_TYPE> coef = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_REAL> gf = ltfatOctArray<LTFAT_REAL>(args(1));
+   const octave_idx_type L = args(2).int_value();
+   const octave_idx_type a = args(3).int_value();
+   const octave_idx_type M = args(4).int_value();
+   const octave_idx_type N = L/a;
+   const octave_idx_type M2 = M/2 +1;
+   const octave_idx_type W = coef.nelem()/(N*M2);
+   const octave_idx_type gl = gf.rows();
+
+   MArray<LTFAT_REAL> f(dim_vector(L,W)); 
+   
+   if(gl<L)
+   {
+      fwd_idgtreal_fb(coef.data(),gf.data(),L,gl,W,a,M,f.fortran_vec());
+   }
+   else
+   {
+      fwd_idgtreal_long(coef.data(),gf.data(),L,W,a,M,f.fortran_vec());
+   }
+   return octave_value(f);
+}
diff --git a/oct/comp_iwfac.cc b/oct/comp_iwfac.cc
new file mode 100644
index 0000000..f31907f
--- /dev/null
+++ b/oct/comp_iwfac.cc
@@ -0,0 +1,49 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_iwfac // change to filename
+#define OCTFILEHELP "Computes inverse window factorization.\n\
+                    Usage: c=comp_iwfac(gf,L,a,M);\n\
+                    Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_iwfac( const Complex *gf,
+                               const octave_idx_type L, const octave_idx_type R,
+							   const octave_idx_type a, const octave_idx_type M,
+							   Complex *g)
+{
+   iwfac_cd(reinterpret_cast<const double _Complex*>(gf),
+           L,R,a,M,
+		   reinterpret_cast<double _Complex*>(g));
+}
+
+static inline void fwd_iwfac( const FloatComplex *gf,
+                               const octave_idx_type L, const octave_idx_type R, 
+							   const octave_idx_type a, const octave_idx_type M,
+							   FloatComplex *g)
+{
+   iwfac_cs(reinterpret_cast<const float _Complex*>(gf),
+           L,R,a,M,
+		   reinterpret_cast<float _Complex*>(g));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+     DEBUGINFO;
+	 
+	 MArray<LTFAT_TYPE> gf = ltfatOctArray<LTFAT_TYPE>(args(0));
+	 const octave_idx_type L = args(1).int_value();
+     const octave_idx_type R = gf.numel()/L;
+     const octave_idx_type a = args(2).int_value();
+     const octave_idx_type M = args(3).int_value();
+
+     MArray<LTFAT_COMPLEX> g(dim_vector(L,1)); 
+	 
+	 fwd_iwfac(gf.data(),L,R,a,M,g.fortran_vec());
+	 
+     return octave_value(g);
+}
diff --git a/oct/comp_nonsepdgt_multi.cc b/oct/comp_nonsepdgt_multi.cc
new file mode 100644
index 0000000..70f07e2
--- /dev/null
+++ b/oct/comp_nonsepdgt_multi.cc
@@ -0,0 +1,68 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_nonsepdgt_multi // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     c=comp_nonsepdgt_multi(f,g,a,M,lt);\n"
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+
+
+static inline void
+fwd_dgt_multi( const Complex *f,const Complex *g,
+               const octave_idx_type L, const octave_idx_type Lg,
+               const octave_idx_type W, const octave_idx_type a,
+               const octave_idx_type M, const octave_idx_type lt1,
+               const octave_idx_type lt2, Complex *cout)
+{
+    dgt_multi_d(
+        reinterpret_cast<const double _Complex *>(f),
+        reinterpret_cast<const double _Complex *>(g),
+        L,Lg,W,a,M,lt1,lt2,
+        reinterpret_cast<double _Complex *>(cout));
+}
+
+static inline void
+fwd_dgt_multi( const FloatComplex *f,const FloatComplex *g,
+               const octave_idx_type L, const octave_idx_type Lg,
+               const octave_idx_type W, const octave_idx_type a,
+               const octave_idx_type M, const octave_idx_type lt1,
+               const octave_idx_type lt2, FloatComplex *cout)
+{
+    dgt_multi_s(
+        reinterpret_cast<const float _Complex *>(f),
+        reinterpret_cast<const float _Complex *>(g),
+        L,Lg,W,a,M,lt1,lt2,
+        reinterpret_cast<float _Complex *>(cout));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    DEBUGINFO;
+    MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+    MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+    const int    a        = args(2).int_value();
+    const double M        = args(3).int_value();
+    const Matrix lt       = args(4).matrix_value();
+
+    const int L  = f.rows();
+    const int W  = f.cols();
+    const int Lg = g.rows();
+    const int N  = L/a;
+
+    const int lt1 = ltfat_round(lt(0));
+    const int lt2 = ltfat_round(lt(1));
+
+    dim_vector dims_out(M,N,W);
+    dims_out.chop_trailing_singletons();
+
+    MArray<LTFAT_COMPLEX> cout(dims_out);
+
+    fwd_dgt_multi(f.data(),g.data(),L,Lg,W,a,M,lt1,lt2,cout.fortran_vec());
+
+    return octave_value(cout);
+}
diff --git a/oct/comp_nonsepdgt_shear.cc b/oct/comp_nonsepdgt_shear.cc
new file mode 100644
index 0000000..db25e39
--- /dev/null
+++ b/oct/comp_nonsepdgt_shear.cc
@@ -0,0 +1,62 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_nonsepdgt_shear // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                     c=comp_nonsepdgt_shear(f,g,a,M,s0,s1,br);\n"
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_dgt_shear( const Complex *f,const Complex *g,
+                               const octave_idx_type L, const octave_idx_type W,
+							   const octave_idx_type a, const octave_idx_type M,
+							   const octave_idx_type s0, const octave_idx_type s1,
+							   const octave_idx_type br, Complex *cout)
+{
+   dgt_shear_d(
+           reinterpret_cast<const double _Complex *>(f),
+           reinterpret_cast<const double _Complex *>(g),
+           L,W,a,M,s0,s1,br,
+		   reinterpret_cast<double _Complex *>(cout));
+}
+
+static inline void fwd_dgt_shear( const FloatComplex *f,const FloatComplex *g,
+                               const octave_idx_type L, const octave_idx_type W,
+							   const octave_idx_type a, const octave_idx_type M,
+							   const octave_idx_type s0, const octave_idx_type s1,
+							   const octave_idx_type br, FloatComplex *cout)
+{
+   dgt_shear_s(
+           reinterpret_cast<const float _Complex *>(f),
+           reinterpret_cast<const float _Complex *>(g),
+           L,W,a,M,s0,s1,br,
+		   reinterpret_cast<float _Complex *>(cout));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+     DEBUGINFO;
+	 MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+	 MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+     const octave_idx_type    a        = args(2).int_value();
+     const octave_idx_type    M        = args(3).int_value();
+     const octave_idx_type    s0       = args(4).int_value();
+     const octave_idx_type    s1       = args(5).int_value();
+     const octave_idx_type    br       = args(6).int_value();
+   
+     const octave_idx_type L = f.rows();
+     const octave_idx_type W = f.cols();
+     const octave_idx_type N = L/a;
+
+     dim_vector dims_out(M,N,W);  
+     dims_out.chop_trailing_singletons();
+
+     MArray<LTFAT_COMPLEX> cout(dims_out); 
+	 
+	 fwd_dgt_shear(f.data(),g.data(),L,W,a,M,s0,s1,br,cout.fortran_vec());
+	 
+     return octave_value(cout);
+}
diff --git a/oct/comp_nonsepwin2multi.cc b/oct/comp_nonsepwin2multi.cc
new file mode 100644
index 0000000..c5195ff
--- /dev/null
+++ b/oct/comp_nonsepwin2multi.cc
@@ -0,0 +1,59 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_nonsepwin2multi // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                    c=comp_nonsepwin2multi(g,a,M,lt,L);\n"
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+
+static inline void
+fwd_nonsepwin2multi(const Complex *g,
+                    const octave_idx_type L, const octave_idx_type Lg,
+                    const octave_idx_type a, const octave_idx_type M,
+                    const octave_idx_type lt1, const octave_idx_type lt2,
+                    Complex *mwin)
+{
+    nonsepwin2multi_d(
+        reinterpret_cast<const double _Complex *>(g),
+        L,Lg,a,M,lt1,lt2,
+        reinterpret_cast<double _Complex *>(mwin));
+}
+
+static inline void
+fwd_nonsepwin2multi(const FloatComplex *g,
+                    const octave_idx_type L, const octave_idx_type Lg,
+                    const octave_idx_type a, const octave_idx_type M,
+                    const octave_idx_type lt1, const octave_idx_type lt2,
+                    FloatComplex *mwin)
+{
+    nonsepwin2multi_s(
+        reinterpret_cast<const float _Complex *>(g),
+        L,Lg,a,M,lt1,lt2,
+        reinterpret_cast<float _Complex *>(mwin));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+    DEBUGINFO;
+    MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(0));
+
+    const int    a        = args(1).int_value();
+    const int    M        = args(2).int_value();
+    const Matrix lt       = args(3).matrix_value();
+    const int    L        = args(4).int_value();
+
+    const int Lg = g.rows();
+    const int lt1 = ltfat_round(lt(0));
+    const int lt2 = ltfat_round(lt(1));
+
+    MArray<LTFAT_COMPLEX> mwin(dim_vector(L,lt2));
+
+    fwd_nonsepwin2multi(g.data(),L,Lg,a,M,lt1,lt2,mwin.fortran_vec());
+
+    return octave_value(mwin);
+}
diff --git a/oct/comp_pchirp.cc b/oct/comp_pchirp.cc
new file mode 100644
index 0000000..e313646
--- /dev/null
+++ b/oct/comp_pchirp.cc
@@ -0,0 +1,19 @@
+#include <octave/oct.h>
+#include "ltfat.h"
+
+DEFUN_DLD (comp_pchirp, args, ,
+  "This function calls the C-library\n\
+  c=pchirp(L,n);\n")
+{
+
+   const octave_idx_type L = args(0).int_value();
+   const octave_idx_type n = args(1).int_value();
+
+   ComplexMatrix g(L,1);
+
+   pchirp_d(L, n, reinterpret_cast<double _Complex *>(g.fortran_vec()));
+
+   return octave_value (g);
+
+}
+
diff --git a/oct/comp_pgauss.cc b/oct/comp_pgauss.cc
new file mode 100644
index 0000000..92918ed
--- /dev/null
+++ b/oct/comp_pgauss.cc
@@ -0,0 +1,29 @@
+#include <octave/oct.h>
+#include "ltfat.h"
+
+DEFUN_DLD (comp_pgauss, args, ,
+  "This function calls the C-library\n\
+  c=comp_pgauss(L,w,c_t,c_f);\n")
+{
+
+  const int    L      = args(0).int_value();
+  const double w      = args(1).double_value();
+  const double c_t    = args(2).double_value();
+  const double c_f    = args(3).double_value();
+  
+  if (c_f==0.0)
+  {
+     Matrix g(L,1);
+     pgauss_d(L, w, c_t, g.fortran_vec());
+     
+     return octave_value (g);
+  }
+  else
+  {
+     ComplexMatrix g(L,1);
+     pgauss_cmplx_d(L, w, c_t, c_f, 
+             reinterpret_cast<double _Complex*>(g.fortran_vec()));
+  
+     return octave_value (g);
+  }
+}
diff --git a/oct/comp_sepdgt.cc b/oct/comp_sepdgt.cc
new file mode 100644
index 0000000..f6cf2e5
--- /dev/null
+++ b/oct/comp_sepdgt.cc
@@ -0,0 +1,117 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_sepdgt // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=comp_dgt_fb(f,g,a,M) or comp_dgt_long(f,g,a,M);\n Yeah."
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+/*
+  dgt_fb forwarders
+*/
+
+static inline void fwd_dgt_fb(const Complex *f, const Complex *g,
+                              const octave_idx_type L, const octave_idx_type gl,
+                              const octave_idx_type W, const octave_idx_type a,
+                              const octave_idx_type M, Complex *cout)
+{
+   dgt_fb_cd(reinterpret_cast<const double _Complex*>(f),
+             reinterpret_cast<const double _Complex*>(g),
+             L,gl,W,a,M,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_dgt_fb(const FloatComplex *f, const FloatComplex *g,
+                              const octave_idx_type L, const octave_idx_type gl,
+                              const octave_idx_type W, const octave_idx_type a,
+                              const octave_idx_type M, FloatComplex *cout)
+{
+   dgt_fb_cs(reinterpret_cast<const float _Complex*>(f),
+             reinterpret_cast<const float _Complex*>(g),
+             L,gl,W,a,M,reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void fwd_dgt_fb(const double *f, const double *g,
+                              const octave_idx_type L, const octave_idx_type gl,
+                              const octave_idx_type W, const octave_idx_type a,
+                              const octave_idx_type M, Complex *cout)
+{
+   dgt_fb_d(reinterpret_cast<const double*>(f),
+            reinterpret_cast<const double*>(g),
+            L,gl,W,a,M,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_dgt_fb(const float *f, const float *g,
+                              const octave_idx_type L, const octave_idx_type gl,
+                              const octave_idx_type W, const octave_idx_type a,
+                              const octave_idx_type M, FloatComplex *cout)
+{
+   dgt_fb_s(reinterpret_cast<const float*>(f),
+            reinterpret_cast<const float*>(g),
+            L,gl,W,a,M,reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void fwd_dgt_long(const Complex *f, const Complex *g,
+                                const octave_idx_type L, const octave_idx_type W,
+                                const octave_idx_type a, const octave_idx_type M,
+                                Complex *cout)
+{
+   dgt_long_cd(reinterpret_cast<const double _Complex*>(f),
+              reinterpret_cast<const double _Complex*>(g),
+              L,W,a,M,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_dgt_long(const FloatComplex *f, const FloatComplex *g,
+                                const octave_idx_type L, const octave_idx_type W, 
+                                const octave_idx_type a, const octave_idx_type M,
+                                FloatComplex *cout)
+{
+   dgt_long_cs(reinterpret_cast<const float _Complex*>(f),
+              reinterpret_cast<const float _Complex*>(g),
+              L,W,a,M,reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void fwd_dgt_long(const double *f, const double *g,
+                                const octave_idx_type L, const octave_idx_type W,
+                                const octave_idx_type a, const octave_idx_type M,
+                                Complex *cout)
+{
+   dgt_long_d(f,g,L,W,a,M,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_dgt_long(const float *f, const float *g,
+                                const octave_idx_type L, const octave_idx_type W, 
+                                const octave_idx_type a, const octave_idx_type M,
+                                FloatComplex *cout)
+{
+   dgt_long_s(f,g,L,W,a,M,reinterpret_cast<float _Complex*>(cout));
+}
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   const octave_idx_type a = args(2).int_value();
+   const octave_idx_type M = args(3).int_value();
+         
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+   const octave_idx_type L  = f.rows();
+   const octave_idx_type W  = f.columns();
+   const octave_idx_type gl = g.rows();
+   const octave_idx_type N = L/a;
+         
+   dim_vector dims_out(M,N,W);  
+   dims_out.chop_trailing_singletons();
+
+   MArray<LTFAT_COMPLEX> cout(dims_out); 
+   
+   if(gl<L)
+   {  
+      fwd_dgt_fb(f.data(),g.data(),L,gl,W,a,M,cout.fortran_vec());
+   }
+   else
+   {
+      fwd_dgt_long(f.data(),g.data(),L,W,a,M,cout.fortran_vec());
+   }
+         
+   return octave_value(cout);
+}
diff --git a/oct/comp_sepdgtreal.cc b/oct/comp_sepdgtreal.cc
new file mode 100644
index 0000000..eb67380
--- /dev/null
+++ b/oct/comp_sepdgtreal.cc
@@ -0,0 +1,77 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define REALARGS
+#define OCTFILENAME comp_sepdgtreal // change to filename
+#define OCTFILEHELP "This function calls the C-library\n c=comp_dgtreal_fb(f,g,a,M,boundary);\n Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+/*
+   dgtreal_fb forwarders
+   */
+
+static inline void
+fwd_dgtreal_fb(const double *f, const double *g,
+               const octave_idx_type L, const octave_idx_type gl,
+               const octave_idx_type W, const octave_idx_type a,
+               const octave_idx_type M, Complex *cout)
+{
+   dgtreal_fb_d(f,g,L,gl,W,a,M,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void
+fwd_dgtreal_fb(const float *f, const float *g,
+               const octave_idx_type L, const octave_idx_type gl,
+               const octave_idx_type W, const octave_idx_type a,
+               const octave_idx_type M, FloatComplex *cout)
+{
+   dgtreal_fb_s(f,g,L,gl,W,a,M,reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void
+fwd_dgtreal_long(const double *f, const double *g, const octave_idx_type L,
+                 const octave_idx_type W, const octave_idx_type a,
+                const octave_idx_type M, Complex *cout)
+{
+   dgtreal_long_d(f,g,L,W,a,M,reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void
+fwd_dgtreal_long(const float *f, const float *g, const octave_idx_type L,
+                 const octave_idx_type W, const octave_idx_type a,
+                 const octave_idx_type M, FloatComplex *cout)
+{
+   dgtreal_long_s(f,g,L,W,a,M,reinterpret_cast<float _Complex*>(cout));
+}
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   const octave_idx_type a = args(2).int_value();
+   const octave_idx_type M = args(3).int_value();
+   const octave_idx_type M2 = M/2+1;
+
+   MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+   const octave_idx_type L  = f.rows();
+   const octave_idx_type W  = f.columns();
+   const octave_idx_type gl = g.rows();
+   const octave_idx_type N = L/a;
+
+   dim_vector dims_out(M2,N,W);  
+   dims_out.chop_trailing_singletons();
+
+   MArray<LTFAT_COMPLEX> cout(dims_out); 
+
+   if(gl<L)
+   {
+      fwd_dgtreal_fb(f.data(),g.data(),L,gl,W,a,M,cout.fortran_vec());
+   }
+   else
+   {
+      fwd_dgtreal_long(f.data(),g.data(),L,W,a,M,cout.fortran_vec());
+   }
+
+   return octave_value(cout);
+}
diff --git a/oct/comp_ufilterbank_fft.cc b/oct/comp_ufilterbank_fft.cc
new file mode 100644
index 0000000..002ebb8
--- /dev/null
+++ b/oct/comp_ufilterbank_fft.cc
@@ -0,0 +1,59 @@
+#define TYPEDEPARGS 0, 1
+#define SINGLEARGS
+#define COMPLEXARGS
+#define OCTFILENAME comp_ufilterbank_fft // change to filename
+#define OCTFILEHELP "This function calls the C-library\n\
+                    c=comp_ufilterbank_fft(f,g,a);\n\
+                    Yeah."
+
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type is 32 or 64 bit signed integer
+
+static inline void fwd_ufilterbank_fft( const Complex *f, const Complex *g,
+                               const octave_idx_type L, const octave_idx_type gl,
+							   const octave_idx_type W, const octave_idx_type a,
+							   const octave_idx_type M, Complex *cout)
+{
+   ufilterbank_fft_d(
+           reinterpret_cast<const double _Complex*>(f),
+           reinterpret_cast<const double _Complex*>(g),
+           L,gl,W,a,M,
+		   reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_ufilterbank_fft( const FloatComplex *f, const FloatComplex *g,
+                               const octave_idx_type L, const octave_idx_type gl,
+							   const octave_idx_type W, const octave_idx_type a,
+							   const octave_idx_type M, FloatComplex *cout)
+{
+   ufilterbank_fft_s(
+           reinterpret_cast<const float _Complex*>(f),
+           reinterpret_cast<const float _Complex*>(g),
+           L,gl,W,a,M,
+		   reinterpret_cast<float _Complex*>(cout));
+}
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+     DEBUGINFO;
+	 
+	 MArray<LTFAT_TYPE> f = ltfatOctArray<LTFAT_TYPE>(args(0));
+	 MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(1));
+	 const octave_idx_type a = args(2).int_value();
+     
+     const octave_idx_type L  = f.rows();
+     const octave_idx_type W  = f.columns();
+     const octave_idx_type gl = g.rows();
+     const octave_idx_type M  = g.columns();
+     const octave_idx_type N = L/a;
+
+	 dim_vector dims_out(N,M,W);  
+     dims_out.chop_trailing_singletons();
+     MArray<LTFAT_COMPLEX> cout(dims_out); 
+	 
+	 fwd_ufilterbank_fft(f.data(),g.data(),L,gl,W,a,M,cout.fortran_vec());
+	 
+     return octave_value(cout);
+}
diff --git a/oct/comp_wfac.cc b/oct/comp_wfac.cc
new file mode 100644
index 0000000..645356c
--- /dev/null
+++ b/oct/comp_wfac.cc
@@ -0,0 +1,79 @@
+#define TYPEDEPARGS 0
+#define SINGLEARGS
+#define COMPLEXINDEPENDENT
+#define OCTFILENAME comp_wfac // change to filename
+#define OCTFILEHELP "Computes window factorization.\n\
+Usage: c=comp_wfac(g,a,M);\n\
+Yeah."
+
+#include "ltfat_oct_template_helper.h"
+// octave_idx_type 32 or 64 bit signed integer
+/*
+   dgt_fb forwarders
+   */
+
+static inline void fwd_comp_wfac(const Complex *g,
+   const octave_idx_type L, const octave_idx_type R,
+   const octave_idx_type a, const octave_idx_type M,
+   Complex *cout)
+{
+   wfac_cd(reinterpret_cast<const double _Complex*>(g),
+           L,R,a,M,
+           reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_comp_wfac(const FloatComplex *g,
+   const octave_idx_type L, const octave_idx_type R,
+   const octave_idx_type a, const octave_idx_type M,
+   FloatComplex *cout)
+{
+   wfac_cs(reinterpret_cast<const float _Complex*>(g),
+         L,R,a,M,
+         reinterpret_cast<float _Complex*>(cout));
+}
+
+static inline void fwd_comp_wfac(const double *g,
+   const octave_idx_type L, const octave_idx_type R,
+   const octave_idx_type a, const octave_idx_type M,
+   Complex *cout)
+{
+   wfac_d(reinterpret_cast<const double*>(g),
+         L,R,a,M,
+         reinterpret_cast<double _Complex*>(cout));
+}
+
+static inline void fwd_comp_wfac(const float *g,
+      const octave_idx_type L, const octave_idx_type R,
+      const octave_idx_type a, const octave_idx_type M,
+      FloatComplex *cout)
+{
+   wfac_s(reinterpret_cast<const float*>(g),
+         L,R,a,M,
+         reinterpret_cast<float _Complex*>(cout));
+}
+
+   template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout)
+{
+   DEBUGINFO;
+   MArray<LTFAT_TYPE> g = ltfatOctArray<LTFAT_TYPE>(args(0));
+   const octave_idx_type a = args(1).int_value();
+   const octave_idx_type M = args(2).int_value();
+   const octave_idx_type L = g.rows();
+   const octave_idx_type R = g.columns();
+
+   const octave_idx_type b = L/M;
+
+   ltfatInt h_a, h_m;    
+   const octave_idx_type c=gcd(a, M,&h_a, &h_m);
+   const octave_idx_type p=a/c;
+   const octave_idx_type q=M/c;
+   const octave_idx_type d=b/p;
+
+   MArray<LTFAT_COMPLEX> cout(dim_vector(p*q*R,c*d)); 
+
+   fwd_comp_wfac(g.data(),L,R,a,M,cout.fortran_vec());
+
+   return octave_value(cout);
+}
+
diff --git a/oct/config.h b/oct/config.h
new file mode 100644
index 0000000..b075c90
--- /dev/null
+++ b/oct/config.h
@@ -0,0 +1,13 @@
+/* This file should contain the configuration parameters
+   necessary for the Oct-compilation. */
+
+#ifndef CONFIG_H
+#define CONFIG_H 1
+
+#define FFTW_OPTITYPE FFTW_ESTIMATE
+
+/* Define to a macro mangling the given C identifier (in lower and upper
+   case), which must not contain underscores, for linking with Fortran. */
+#define F77_FUNC(name,NAME) name ## _
+
+#endif /* CONFIG_H */
diff --git a/oct/ltfat_oct_template_helper.h b/oct/ltfat_oct_template_helper.h
new file mode 100644
index 0000000..726c925
--- /dev/null
+++ b/oct/ltfat_oct_template_helper.h
@@ -0,0 +1,348 @@
+#if defined(OCTFILENAME) && defined(OCTFILEHELP)
+#ifndef _LTFAT_OCT_TEMPLATE_HELPER_H
+#define _LTFAT_OCT_TEMPLATE_HELPER_H
+#include "ltfat.h"
+#include <octave/oct.h>
+
+
+#ifdef _DEBUG
+#define DEBUGINFO  octave_stdout << __PRETTY_FUNCTION__ << "\n"
+#else
+#define DEBUGINFO
+#endif
+
+bool checkIsSingle(const octave_value& ov);
+octave_value recastToSingle(const octave_value& ov);
+
+bool checkIsComplex(const octave_value& ov);
+octave_value recastToComplex(const octave_value& ov);
+
+template <class LTFAT_TYPE, class LTFAT_REAL, class LTFAT_COMPLEX>
+octave_value_list octFunction(const octave_value_list& args, int nargout);
+
+template <class LTFAT_TYPE>
+MArray<LTFAT_TYPE> ltfatOctArray(const octave_value& ov);
+
+template <class LTFAT_TYPE>
+MArray<LTFAT_TYPE> ltfatOctArray(const octave_value& ov)
+{
+   error("Casting to unknown type. Everything should be handled in the specialized functions.",__PRETTY_FUNCTION__);
+   return MArray<LTFAT_TYPE>();
+}
+
+template <>
+MArray<double> ltfatOctArray(const octave_value& ov)
+{
+    if(ov.is_double_type())
+    {
+       return (ov.array_value());
+    }
+    else
+    {
+       error("Unsupported data type..");
+    }
+    return MArray<double>();
+}
+
+template <>
+MArray<float> ltfatOctArray(const octave_value& ov)
+{
+    if(ov.is_float_type())
+    {
+       return (ov.float_array_value());
+    }
+    else
+    {
+       error("Unsupported data type..");
+    }
+    return MArray<float>();
+}
+
+template <>
+MArray<Complex> ltfatOctArray(const octave_value& ov)
+{
+    if(ov.is_double_type())
+    {
+       return (ov.complex_array_value());
+    }
+    else
+    {
+       error("Unsupported data type..");
+    }
+    return MArray<Complex>();
+}
+
+template <>
+MArray<FloatComplex> ltfatOctArray(const octave_value& ov)
+{
+    if(ov.is_float_type())
+    {
+       return (ov.float_complex_array_value());
+    }
+    else
+    {
+       error("Unsupported data type..");
+    }
+    return MArray<FloatComplex>();
+}
+
+bool checkIsSingle(const octave_value& ov)
+{
+   if(ov.is_cell())
+   {
+      Cell ov_cell = ov.cell_value();
+      for(int jj=0;jj<ov_cell.numel();jj++)
+      {
+         if(!checkIsSingle(ov_cell.elem(jj)))
+            return false;
+      }
+      return true;
+   }
+   return ov.is_single_type();
+}
+
+bool checkIsComplex(const octave_value& ov)
+{
+   if(ov.is_cell())
+   {
+      Cell ov_cell = ov.cell_value();
+      for(int jj=0;jj<ov_cell.numel();jj++)
+      {
+         if(!checkIsComplex(ov_cell.elem(jj)))
+            return false;
+      }
+      return true;
+   }
+   return ov.is_complex_type();
+}
+
+octave_value recastToSingle(const octave_value& ov)
+{
+   if(ov.is_single_type())
+   {
+      return ov;
+   }
+
+   if(ov.is_cell())
+   {
+      Cell ov_cell = ov.cell_value();
+      Cell ovtmp_cell(ov.dims());
+      for(int jj=0;jj<ovtmp_cell.nelem();jj++)
+      {
+         ovtmp_cell(jj) = recastToSingle(ov_cell.elem(jj));
+      }
+      return ovtmp_cell;
+   }
+   /*
+   TODO: ov is struct
+   */
+   // just copy pointer if the element is not numeric
+   if(!ov.is_numeric_type())
+   {
+      return ov;
+   }
+
+   if(ov.is_complex_type())
+   {
+      return ltfatOctArray<FloatComplex>(ov);
+   }
+   else
+   {
+      return ltfatOctArray<float>(ov);
+   }
+}
+
+octave_value recastToComplex(const octave_value& ov)
+{
+   if(ov.is_complex_type())
+   {
+      return ov;
+   }
+
+   if(ov.is_cell())
+   {
+      Cell ov_cell = ov.cell_value();
+      Cell ovtmp_cell(ov.dims());
+      for(int jj=0;jj<ovtmp_cell.nelem();jj++)
+      {
+         ovtmp_cell(jj) = recastToComplex(ov_cell.elem(jj));
+      }
+      return ovtmp_cell;
+   }
+   /*
+   TODO: ov is struct
+   */
+   // just copy pointer if the element is not numeric
+   if(!ov.is_numeric_type())
+   {
+      return ov;
+   }
+
+   if(ov.is_single_type())
+   {
+      return ltfatOctArray<FloatComplex>(ov);
+   }
+   else
+   {
+      return ltfatOctArray<Complex>(ov);
+   }
+}
+
+
+DEFUN_DLD (OCTFILENAME, args, nargout, OCTFILEHELP)
+{
+octave_value_list argsCopy(args);
+
+#define ENSURESINGLE                                               \
+    for(int ii=0;ii<tdArgsIfSingle.length();ii++)                  \
+        tdArgsIfSingle(ii) = octave_value(recastToSingle(tdArgsIfSingle(ii)));
+
+#define ENSURECOMPLEX                                               \
+for(int ii=0;ii<tdArgsIfComplex.length();ii++)                      \
+    tdArgsIfComplex(ii) = octave_value(recastToComplex(tdArgsIfComplex(ii)));
+
+
+bool isAnySingle = false;
+bool isAnyComplex = false;
+#ifndef TYPEDEPARGS
+return octFunction<double,double,Complex>(argsCopy,nargout);
+#else
+// Arguments, which will be matched by complexity
+// If at least one is complex, the others are cast to complex
+int prhsToCheckIfComplex[] = { TYPEDEPARGS };
+int prhsToCheckIfComplexLen = sizeof(prhsToCheckIfComplex)/sizeof(*prhsToCheckIfComplex);
+
+// Arguments, which will be matchd by data type
+// If at least one is single, the others are cast to single
+#ifndef MATCHEDARGS
+   int prhsToCheckIfSingle[] = { TYPEDEPARGS };
+#else
+   int prhsToCheckIfSingle[] = { TYPEDEPARGS, MATCHEDARGS };
+#endif
+int prhsToCheckIfSingleLen = sizeof(prhsToCheckIfSingle)/sizeof(*prhsToCheckIfSingle);
+
+// WORKAROUND Incorrect detection of the single data type of complex diag. matrices
+for(int ii=0;ii<prhsToCheckIfSingleLen;ii++)
+    if(argsCopy(prhsToCheckIfSingle[ii]).is_diag_matrix())
+       argsCopy(prhsToCheckIfSingle[ii])= argsCopy(prhsToCheckIfSingle[ii]).full_value();
+
+
+// Reference arrays holding arguments to be checked
+octave_value_list tdArgsIfComplex;
+octave_value_list tdArgsIfSingle;
+
+// copy refenrences
+for(int ii=0;ii<prhsToCheckIfComplexLen;ii++)
+   tdArgsIfComplex.append(argsCopy(prhsToCheckIfComplex[ii]));
+
+for(int ii=0;ii<prhsToCheckIfComplexLen;ii++)
+   tdArgsIfSingle.append(argsCopy(prhsToCheckIfSingle[ii]));
+
+// Check if any of the parameters is single
+for(int ii=0;ii<tdArgsIfSingle.length();ii++)
+    if((isAnySingle=checkIsSingle(tdArgsIfSingle(ii)))) break;
+
+// Check if any of the parameters is complex
+for(int ii=0;ii<tdArgsIfComplex.length();ii++)
+    if((isAnyComplex=checkIsComplex(tdArgsIfComplex(ii)))) break;
+
+#if defined(REALARGS)&& !(defined(COMPLEXARGS) || defined(COMPLEXINDEPENDENT))
+if(isAnyComplex)
+{
+   error("Only real inputs are accepted.");
+   return octave_value_list();
+}
+#endif
+
+#ifndef SINGLEARGS
+if(isAnySingle)
+{
+   error("Only double inputs are accepted.");
+   return octave_value_list();
+}
+#endif
+
+
+/****************** HANDLING COMPLEXINDEPENDENT *************************/
+#if defined(COMPLEXINDEPENDENT) || (defined(COMPLEXARGS)&&defined(REALARGS))
+if(isAnyComplex) ENSURECOMPLEX
+#  ifndef SINGLEARGS
+if(isAnyComplex)
+{
+   return octFunction<Complex,double,Complex>(argsCopy,nargout);
+}
+else
+{
+   return octFunction<double,double,Complex>(argsCopy,nargout);
+}
+#  else
+if(isAnySingle) ENSURESINGLE
+
+if(isAnyComplex&&isAnySingle)
+{
+    return octFunction<FloatComplex,float,FloatComplex>(argsCopy,nargout);
+}
+else if(!isAnyComplex&&isAnySingle)
+{
+    return octFunction<float,float,FloatComplex>(argsCopy,nargout);
+}
+else if(isAnyComplex&&!isAnySingle)
+{
+    return octFunction<Complex,double,Complex>(argsCopy,nargout);
+}
+else
+{
+    return octFunction<double,double,Complex>(argsCopy,nargout);
+}
+#  endif
+/****************** HANDLING ONLY COMPLEX *************************/
+#elif defined(COMPLEXARGS) && !defined(REALARGS)
+ENSURECOMPLEX
+#  ifndef SINGLEARGS
+   return octFunction<Complex,double,Complex>(argsCopy,nargout);
+#  else
+if(isAnySingle)
+{
+   ENSURESINGLE
+   return octFunction<FloatComplex,float,FloatComplex>(argsCopy,nargout);
+}
+else
+{
+   return octFunction<Complex,double,Complex>(argsCopy,nargout);
+}
+#  endif
+/****************** HANDLING ONLY REAL *************************/
+#elif !defined(COMPLEXARGS) && defined(REALARGS)
+#  ifndef SINGLEARGS
+   return octFunction<double,double,Complex>(argsCopy,nargout);
+#  else
+if(isAnySingle)
+{
+   ENSURESINGLE
+   return octFunction<float,float,FloatComplex>(argsCopy,nargout);
+}
+else
+{
+   return octFunction<double,double,Complex>(argsCopy,nargout);
+}
+#  endif
+#else
+error("Something wrong in the template system. My bad....\n");
+#endif
+
+
+
+#endif // TYPEDEPARGS
+
+
+error("Something fishy is going on in...\n");
+
+#undef ENSURESINGLE
+#undef ENSURECOMPLEX
+
+return octave_value_list();
+}
+
+
+#endif // _LTFAT_OCT_TEMPLATE_HELPER_H
+#endif // defined(OCTFILENAME) && defined(OCTFILEHELP)
diff --git a/oct/oct-memalloc.c b/oct/oct-memalloc.c
new file mode 100644
index 0000000..cc3c08c
--- /dev/null
+++ b/oct/oct-memalloc.c
@@ -0,0 +1,46 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "stddef.h"
+#include "fftw3.h"
+
+void* ltfat_malloc (size_t n)
+{
+  void *outp;
+  outp = fftw_malloc(n);
+  if (outp == NULL)
+  {
+     puts("ltfat_malloc failed.");
+     exit(1);
+  }
+  return outp;
+}
+
+void* ltfat_realloc (void *ptr, size_t n)
+{
+  void *outp;
+  outp = realloc(ptr, n);
+  if (outp == NULL)
+  {
+     puts("ltfat_realloc failed.");
+     exit(1);
+  }
+  return outp;
+}
+
+void* ltfat_calloc (size_t nmemb, size_t size)
+{
+  void *outp;
+  outp = calloc(nmemb, size);
+  if (outp == NULL)
+  {
+     puts("ltfat_calloc failed.");
+     exit(1);
+  }
+  return outp;
+}
+
+void ltfat_free(void *ptr)
+{
+  fftw_free(ptr);
+}
+
diff --git a/oct/octinit.m b/oct/octinit.m
new file mode 100644
index 0000000..a614827
--- /dev/null
+++ b/oct/octinit.m
@@ -0,0 +1,31 @@
+if isoctave
+  status=2;
+else
+  status=0;
+end;
+
+
+
+%-*- texinfo -*-
+%@deftypefn {Function} octinit
+%@verbatim
+%@end verbatim
+%@strong{Url}: @url{http://ltfat.sourceforge.net/doc/oct/octinit.php}
+%@end deftypefn
+
+% Copyright (C) 2005-2014 Peter L. Soendergaard <soender at users.sourceforge.net>.
+% This file is part of LTFAT version 1.4.4
+%
+% 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 3 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, see <http://www.gnu.org/licenses/>.
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..1de2fba
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,19 @@
+targets = oct
+
+ifeq (@have_libportaudio@,1)
+   targets += playrec 
+endif
+
+
+all: $(targets)
+
+
+oct:
+	$(MAKE) -f Makefile_unix
+	$(MAKE) -C ../oct -f Makefile_unix
+	mv ../oct/*.oct .
+	ls -1 *.oct | cut -d . -f 1 | xargs -i rm -f ../inst/comp/{}.m
+
+playrec:
+	$(MAKE) -C ../thirdparty/Playrec -f Makefile_unixoct
+	mv ../thirdparty/Playrec/playrec.mex .
diff --git a/src/Makefile_mac b/src/Makefile_mac
new file mode 100644
index 0000000..eaf824c
--- /dev/null
+++ b/src/Makefile_mac
@@ -0,0 +1 @@
+include Makefile_unix
diff --git a/src/Makefile_mingw b/src/Makefile_mingw
new file mode 100644
index 0000000..97fe9b4
--- /dev/null
+++ b/src/Makefile_mingw
@@ -0,0 +1,100 @@
+# Use MinGW Make to process this file. Y must provide your sytem system specific MATLABROOT
+# variable on the command line e.g.:
+#
+# make -f Makefile_mingw64 MATLABROOT="C:\Program Files\MATLAB\R2011b" ARCH=win64
+#
+# REMARK: When compiling dll, all dependencies need to be resolved
+# This is not the case when compiled as a static lib.
+
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default MATLABROOT="C:\Program Files\MATLAB\R2011b" )
+  MATLABROOT=C:\Program Files\MATLAB\R2011b
+endif
+
+ifndef ARCH
+  $(warning ARCH variable is udefined. Using default ARCH=win64 )
+  ARCH=win64
+endif
+
+ifndef DFFTW
+   DFFTW=-lfftw3-3
+endif
+
+ifndef SFFTW
+   SFFTW=-lfftw3f-3
+endif
+
+MATLABLINKFLAGS=-L"$(MATLABROOT)\bin\$(ARCH)" $(MATLABLIBS) -lmwlapack -lmwblas
+
+
+CFLAGS=-O3 -s -std=c99 -I./thirdparty -I./
+DIRECTIVES=-DMATLABFORTRAN -DDLL_EXPORT_SYMBOLS 
+
+include filedefs.mk
+include ostools.mk
+
+DFILES = $(addprefix d,$(files)) $(files_notypechange)
+DFILES_BLASLAPACK = $(addprefix d,$(files_blaslapack))
+SFILES = $(addprefix s,$(files)) 
+SFILES_BLASLAPACK = $(addprefix s,$(files_blaslapack))
+
+all: shared
+
+shared: double_shared single_shared
+
+static: double_static single_static
+
+double_shared: $(DFILES) $(DFILES_BLASLAPACK) Makefile_mingw
+	$(CC) -shared -Wl,--dll $(DFILES) $(DFILES_BLASLAPACK)  \
+	-o ../lib/ltfat.dll -static-libgcc -L../mex $(DFFTW) $(MATLABLINKFLAGS)
+	$(RM) *.o *.a
+	$(CP) ..\lib\ltfat.dll ..\mex\
+  
+single_shared: $(SFILES) $(SFILES_BLASLAPACK) Makefile_mingw  
+	$(CC) -shared -Wl,--dll $(SFILES) $(SFILES_BLASLAPACK)  \
+	-o ../lib/ltfatf.dll -static-libgcc -L../mex $(DFFTW) $(SFFTW) -lltfat $(MATLABLINKFLAGS)
+	$(RM) *.o *.a
+	$(CP) ..\lib\ltfatf.dll ..\mex\
+	
+double_shared_noblaslapack: $(DFILES) Makefile_mingw
+	$(CC) -shared -Wl,--dll $(DFILES) \
+	-o ../lib/ltfat.dll -static-libgcc -L../mex $(DFFTW)
+	$(RM) *.o *.a
+	$(CP) ..\lib\ltfat.dll ..\mex\
+  
+single_shared_noblaslapack: $(SFILES) Makefile_mingw  
+	$(CC) -shared -Wl,--dll $(SFILES) \
+	-o ../lib/ltfatf.dll -static-libgcc -L../mex $(DFFTW) $(SFFTW) -lltfat
+	$(RM) *.o *.a
+	$(CP) ..\lib\ltfatf.dll ..\mex\
+	
+double_static: $(DFILES) $(DFILES_BLASLAPACK) Makefile_mingw
+	ar rvu libltfat.a $(DFILES) $(DFILES_BLASLAPACK)
+	ranlib libltfat.a
+	$(CP) libltfat.a ..\lib
+	$(RM) *.o *.a	
+	
+single_static: $(SFILES) $(SFILES_BLASLAPACK) Makefile_mingw
+	ar rvu libltfatf.a $(SFILES) $(SFILES_BLASLAPACK)
+	ranlib libltfatf.a
+	$(CP) libltfatf.a ..\lib
+	$(RM) *.o *.a	
+
+s%.o: %.c config.h
+	$(CC) $(CFLAGS) $(DIRECTIVES) -DLTFAT_SINGLE  -c $< -o s$*.o
+
+d%.o: %.c config.h
+	$(CC) $(CFLAGS) $(DIRECTIVES) -DLTFAT_DOUBLE  -c $< -o d$*.o
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(DIRECTIVES) -DLTFAT_DOUBLE  -c $<
+
+clean:
+	$(RM) ..\lib\ltfat.dll
+	$(RM) ..\lib\ltfatf.dll
+	$(RM) ..\lib\libltfat.a
+	$(RM) ..\lib\libltfatf.a
+	$(RM) ..\mex\ltfat.dll
+	$(RM) ..\mex\ltfatf.dll
+	$(RM) *.o *.a
+
diff --git a/src/Makefile_mingwoct b/src/Makefile_mingwoct
new file mode 100644
index 0000000..8af5e9a
--- /dev/null
+++ b/src/Makefile_mingwoct
@@ -0,0 +1,73 @@
+# Use MinGW Make to process this file
+# make -f Makefile_mingwoct
+#
+#
+
+
+
+include filedefs.mk
+include ostools.mk
+
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default (probably wrong) MATLABROOT="c:\Octave\Octave3.6.4_gcc4.6.2")
+  MATLABROOT=c:\Octave\Octave3.6.4_gcc4.6.2
+endif
+OCTAVELIBS=-lfftw3 -lfftw3f -lblas -llapack
+OCTAVELINKFLAGS=-L$(MATLABROOT)\lib $(OCTAVELIBS)
+
+#CC = i686-pc-mingw32-gcc 
+CC=gcc
+
+CFLAGS=-O3 -s -Wall -std=c99 -m32 -I../src/thirdparty -I./
+DIRECTIVES=
+
+
+DFILES = $(addprefix d,$(files)) $(addprefix d,$(files_blaslapack)) $(files_notypechange)
+SFILES = $(addprefix s,$(files)) $(addprefix s,$(files_blaslapack))
+
+all: static
+
+static: double_static single_static
+
+shared: double_shared single_shared
+
+double_shared: $(DFILES) Makefile_mingwoct
+	$(CC) -m32 -shared -Wl,--dll $(DFILES) \
+	-o ../lib/ltfat.dll ltfat_notdllexport.def -static-libgcc $(OCTAVELINKFLAGS) 
+	$(RM) *.o *.a
+	$(CP) ..\lib\ltfat.dll ..\oct
+  
+single_shared: $(SFILES) Makefile_mingwoct  
+	$(CC) -m32 -shared -Wl,--dll $(SFILES) \
+	-o ../lib/ltfatf.dll -static-libgcc -L../oct -lltfat $(OCTAVELINKFLAGS)
+	$(RM) *.o *.a
+	$(CP) ..\lib\ltfatf.dll ..\oct
+
+double_static: $(DFILES) Makefile_mingwoct
+	ar rvu libltfat.a $(DFILES) 
+	ranlib libltfat.a
+	$(CP) libltfat.a ..\lib
+	$(RM) *.o *.a	
+	
+single_static: $(SFILES) Makefile_mingwoct
+	ar rvu libltfatf.a $(SFILES) 
+	ranlib libltfatf.a
+	$(CP) libltfatf.a ..\lib
+	$(RM) *.o *.a	
+
+s%.o: %.c config.h
+	$(CC) $(CFLAGS) $(DIRECTIVES) -DLTFAT_SINGLE  -c $< -o s$*.o
+
+d%.o: %.c config.h
+	$(CC) $(CFLAGS) $(DIRECTIVES) -DLTFAT_DOUBLE  -c $< -o d$*.o
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(DIRECTIVES) -c $<
+
+clean:
+	$(RM) ..\lib\ltfat.dll
+	$(RM) ..\lib\ltfatf.dll
+	$(RM) ..\lib\libltfat.a
+	$(RM) ..\lib\libltfatf.a
+	$(RM) *.o *.a
+
diff --git a/src/Makefile_unix b/src/Makefile_unix
new file mode 100644
index 0000000..c6edf09
--- /dev/null
+++ b/src/Makefile_unix
@@ -0,0 +1,75 @@
+# To run this makefile, you must provide the ARCH and MATLABROOT
+# variables on the command line, i.e. as in
+#
+# make -f Makefile_unix MATLABROOT=/usr/local/MATLAB/R2011a ARCH=glnxa64
+
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default MATLABROOT="/usr/local/MATLAB/R2011a/")
+  MATLABROOT=/usr/local/MATLAB/R2011a/
+endif
+
+ifndef ARCH
+  $(warning ARCH variable is udefined. Using default ARCH=glnxa64 )
+  ARCH=glnxa64
+endif
+
+ifndef DFFTW
+   DFFTW=-lfftw3
+endif
+
+ifndef SFFTW
+   SFFTW=-lfftw3f
+endif
+
+
+CFLAGS=-O3 -fPIC -std=c99 -Ithirdparty 
+SHARED_FLAGS=-shared -Wl,--no-undefined -lc -lm -L"$(MATLABROOT)/bin/$(ARCH)" \
+			 -lmwblas -lmwlapack $(DFFTW) $(SFFTW)
+
+include filedefs.mk
+
+toCompile = $(files) $(files_blaslapack)
+
+DFILES = $(addprefix d,$(toCompile)) $(files_notypechange)
+SFILES = $(addprefix s,$(toCompile))
+
+
+all: static
+
+static: double_static single_static
+
+shared: double_shared single_shared
+
+double_static: $(DFILES) Makefile_unix
+	ar rvu libltfat.a $(DFILES) 
+	ranlib libltfat.a
+	cp -f libltfat.a ../lib
+
+single_static: $(SFILES) Makefile_unix
+	ar rvu libltfatf.a $(SFILES) 
+	ranlib libltfatf.a
+	cp -f libltfatf.a ../lib
+
+double_shared: $(DFILES) Makefile_unix
+	$(CC) $(SHARED_FLAGS) $(DFILES) -o ../lib/libltfat.so
+
+single_shared: $(SFILES) Makefile_unix
+	$(CC) $(SHARED_FLAGS) $(SFILES) -o ../lib/libltfatf.so
+
+sltfat_blaslapack_matlab.o: ltfat_blaslapack.c config.h
+	$(CC) $(CFLAGS) -DLTFAT_SINGLE -DMATLABFORTRAN -c $< -o $*.o
+
+dltfat_blaslapack_matlab.o: ltfat_blaslapack.c config.h
+	$(CC) $(CFLAGS) -DLTFAT_DOUBLE -DMATLABFORTRAN -c $< -o $*.o
+
+s%.o: %.c config.h
+	$(CC) $(CFLAGS) -DLTFAT_SINGLE  -c $< -o s$*.o
+
+d%.o: %.c config.h
+	$(CC) $(CFLAGS) -DLTFAT_DOUBLE  -c $< -o d$*.o
+
+%.o: %.c Makefile config.h
+	$(CC) $(CFLAGS) -c $<
+
+clean:
+	-rm *.o *.a
diff --git a/src/README b/src/README
new file mode 100644
index 0000000..46e7161
--- /dev/null
+++ b/src/README
@@ -0,0 +1,10 @@
+This directory contains the source for the C-library.
+
+On Unix, type
+
+  make
+
+to compile the C-library. The library is called libltfat.a
+
+
+
diff --git a/src/autom4te.cache/output.0 b/src/autom4te.cache/output.0
new file mode 100644
index 0000000..6a7ae9b
--- /dev/null
+++ b/src/autom4te.cache/output.0
@@ -0,0 +1,4490 @@
+@%:@! /bin/sh
+@%:@ Guess values for system-dependent variables and create Makefiles.
+@%:@ Generated by GNU Autoconf 2.69 for LTFAT 1.4.4.
+@%:@
+@%:@ Report bugs to <http://ltfat.sourceforge.net/contact.php>.
+@%:@ 
+@%:@ 
+@%:@ Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+@%:@ 
+@%:@ 
+@%:@ This configure script is free software; the Free Software Foundation
+@%:@ gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in @%:@(
+  *posix*) :
+    set -o posix ;; @%:@(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in @%:@(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in @%:@((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in @%:@ ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in @%:@(
+  *posix*) :
+    set -o posix ;; @%:@(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+  
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+  
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in @%:@(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in @%:@ ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: http://ltfat.sourceforge.net/contact.php about your
+$0: system, including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+@%:@ as_fn_unset VAR
+@%:@ ---------------
+@%:@ Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+@%:@ as_fn_set_status STATUS
+@%:@ -----------------------
+@%:@ Set @S|@? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} @%:@ as_fn_set_status
+
+@%:@ as_fn_exit STATUS
+@%:@ -----------------
+@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} @%:@ as_fn_exit
+
+@%:@ as_fn_mkdir_p
+@%:@ -------------
+@%:@ Create "@S|@as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} @%:@ as_fn_mkdir_p
+
+@%:@ as_fn_executable_p FILE
+@%:@ -----------------------
+@%:@ Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} @%:@ as_fn_executable_p
+@%:@ as_fn_append VAR VALUE
+@%:@ ----------------------
+@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take
+@%:@ advantage of any shell optimizations that allow amortized linear growth over
+@%:@ repeated appends, instead of the typical quadratic growth present in naive
+@%:@ implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+@%:@ as_fn_arith ARG...
+@%:@ ------------------
+@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the
+@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments
+@%:@ must be portable across @S|@(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD]
+@%:@ ----------------------------------------
+@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+@%:@ script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} @%:@ as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in @%:@(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIB@&t at OBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='LTFAT'
+PACKAGE_TARNAME='ltfat'
+PACKAGE_VERSION='1.4.4'
+PACKAGE_STRING='LTFAT 1.4.4'
+PACKAGE_BUGREPORT='http://ltfat.sourceforge.net/contact.php'
+PACKAGE_URL=''
+
+ac_subst_vars='LTLIBOBJS
+LIB@&t at OBJS
+have_libportaudio
+MKOCTFILE_CHECK
+ac_ct_CXX
+CXXFLAGS
+CXX
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures LTFAT 1.4.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          @<:@@S|@ac_default_prefix@:>@
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          @<:@PREFIX@:>@
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root @<:@DATAROOTDIR/doc/ltfat@:>@
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of LTFAT 1.4.4:";;
+   esac
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://ltfat.sourceforge.net/contact.php>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+LTFAT configure 1.4.4
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+@%:@ ac_fn_c_try_compile LINENO
+@%:@ --------------------------
+@%:@ Try to compile conftest. at S|@ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_try_compile
+
+@%:@ ac_fn_cxx_try_compile LINENO
+@%:@ ----------------------------
+@%:@ Try to compile conftest. at S|@ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_cxx_try_compile
+
+@%:@ ac_fn_c_try_link LINENO
+@%:@ -----------------------
+@%:@ Try to link conftest. at S|@ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by LTFAT $as_me 1.4.4, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in @%:@((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $@%:@ != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+@%:@include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+  
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+  your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str;
+  int number;
+  float fnumber;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case 's': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case 'd': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case 'f': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+}
+
+int
+main ()
+{
+
+  // Check bool.
+  _Bool success = false;
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  test_varargs ("s, d' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+	  || dynamic_array[ni.number - 1] != 543);
+
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c99"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+  
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+#AC_CONFIG_MACRO_DIR([m4/])
+# ===========================================================================
+#          http://www.gnu.org/software/autoconf-archive/ax_blas.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the BLAS linear-algebra
+#   interface (see http://www.netlib.org/blas/). On success, it sets the
+#   BLAS_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with BLAS, you should link with:
+#
+#     $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   Many libraries are searched for, from ATLAS to CXML to ESSL. The user
+#   may also use --with-blas=<lib> in order to use some specific BLAS
+#   library <lib>. In order to link successfully, however, be aware that you
+#   will probably need to use the same Fortran compiler (which can be set
+#   via the F77 env. var.) as was used to compile the BLAS library.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a BLAS library is
+#   found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is
+#   not found. If ACTION-IF-FOUND is not specified, the default action will
+#   define HAVE_BLAS.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 11
+
+# This is what autoupdate's m4 run will expand.  It fires
+# the warning (with _au_warn_XXX), outputs it into the
+# updated configure.ac (with AC_DIAGNOSE), and then outputs
+# the replacement expansion.
+
+
+# This is an auxiliary macro that is also run when
+# autoupdate runs m4.  It simply calls m4_warning, but
+# we need a wrapper so that each warning is emitted only
+# once.  We break the quoting in m4_warning's argument in
+# order to expand this macro's arguments, not AU_DEFUN's.
+
+
+# Finally, this is the expansion that is picked up by
+# autoconf.  It tells the user to run autoupdate, and
+# then outputs the replacement expansion.  We do not care
+# about autoupdate's warning because that contains
+# information on what to do *after* running autoupdate.
+
+
+# ===========================================================================
+#         http://www.gnu.org/software/autoconf-archive/ax_lapack.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_LAPACK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the LAPACK linear-algebra
+#   interface (see http://www.netlib.org/lapack/). On success, it sets the
+#   LAPACK_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with LAPACK, you should link with:
+#
+#     $LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. BLAS_LIBS is the output variable of the AX_BLAS macro,
+#   called automatically. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   The user may also use --with-lapack=<lib> in order to use some specific
+#   LAPACK library <lib>. In order to link successfully, however, be aware
+#   that you will probably need to use the same Fortran compiler (which can
+#   be set via the F77 env. var.) as was used to compile the LAPACK and BLAS
+#   libraries.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a LAPACK library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_LAPACK.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+# This is what autoupdate's m4 run will expand.  It fires
+# the warning (with _au_warn_XXX), outputs it into the
+# updated configure.ac (with AC_DIAGNOSE), and then outputs
+# the replacement expansion.
+
+
+# This is an auxiliary macro that is also run when
+# autoupdate runs m4.  It simply calls m4_warning, but
+# we need a wrapper so that each warning is emitted only
+# once.  We break the quoting in m4_warning's argument in
+# order to expand this macro's arguments, not AU_DEFUN's.
+
+
+# Finally, this is the expansion that is picked up by
+# autoconf.  It tells the user to run autoupdate, and
+# then outputs the replacement expansion.  We do not care
+# about autoupdate's warning because that contains
+# information on what to do *after* running autoupdate.
+
+
+
+# The checks for BLAS and Lapack have been disabled because they
+# provoke an error about a missing install-sh
+
+#dnl Check for BLAS libraries
+#sinclude(ax_blas.m4)
+#AX_BLAS
+#if test "$ax_blas_ok" = "no"; then
+#   AC_MSG_ERROR([Cannot find BLAS libraries])
+#fi
+
+#dnl Check for LAPACK libraries
+#sinclude(ax_lapack.m4)
+#AX_LAPACK
+#if test "$ax_lapack_ok" = "no"; then
+#   AC_MSG_ERROR([Cannot find LAPACK libraries])
+#fi
+
+# Extract the first word of "mkoctfile", so it can be a program name with args.
+set dummy mkoctfile; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MKOCTFILE_CHECK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MKOCTFILE_CHECK"; then
+  ac_cv_prog_MKOCTFILE_CHECK="$MKOCTFILE_CHECK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MKOCTFILE_CHECK=""yes""
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MKOCTFILE_CHECK=$ac_cv_prog_MKOCTFILE_CHECK
+if test -n "$MKOCTFILE_CHECK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKOCTFILE_CHECK" >&5
+$as_echo "$MKOCTFILE_CHECK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$MKOCTFILE_CHECK" != "yes" ; then
+    as_fn_error $? "Please install mkoctfile." "$LINENO" 5
+fi
+
+#AC_CHECK_HEADERS([fftw3.h],[],[AC_MSG_ERROR([fftw was not found])])
+# Checking for portaudio, we pack portaudio.h with LTFAT
+# AC_CHECK_HEADER(portaudio.h)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Pa_GetHostApiCount in -lportaudio" >&5
+$as_echo_n "checking for Pa_GetHostApiCount in -lportaudio... " >&6; }
+if ${ac_cv_lib_portaudio_Pa_GetHostApiCount+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lportaudio  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char Pa_GetHostApiCount ();
+int
+main ()
+{
+return Pa_GetHostApiCount ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_portaudio_Pa_GetHostApiCount=yes
+else
+  ac_cv_lib_portaudio_Pa_GetHostApiCount=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_portaudio_Pa_GetHostApiCount" >&5
+$as_echo "$ac_cv_lib_portaudio_Pa_GetHostApiCount" >&6; }
+if test "x$ac_cv_lib_portaudio_Pa_GetHostApiCount" = xyes; then :
+  have_libportaudio=1
+else
+  echo "Portaudio lib not found. Disabling support of the block processing framework." 
+ have_libportaudio=0
+ 
+fi
+
+
+
+
+ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIB@&t at OBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIB@&t at OBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in @%:@(
+  *posix*) :
+    set -o posix ;; @%:@(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in @%:@(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in @%:@((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD]
+@%:@ ----------------------------------------
+@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+@%:@ script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} @%:@ as_fn_error
+
+
+@%:@ as_fn_set_status STATUS
+@%:@ -----------------------
+@%:@ Set @S|@? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} @%:@ as_fn_set_status
+
+@%:@ as_fn_exit STATUS
+@%:@ -----------------
+@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} @%:@ as_fn_exit
+
+@%:@ as_fn_unset VAR
+@%:@ ---------------
+@%:@ Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+@%:@ as_fn_append VAR VALUE
+@%:@ ----------------------
+@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take
+@%:@ advantage of any shell optimizations that allow amortized linear growth over
+@%:@ repeated appends, instead of the typical quadratic growth present in naive
+@%:@ implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+@%:@ as_fn_arith ARG...
+@%:@ ------------------
+@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the
+@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments
+@%:@ must be portable across @S|@(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in @%:@(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+@%:@ as_fn_mkdir_p
+@%:@ -------------
+@%:@ Create "@S|@as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} @%:@ as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+@%:@ as_fn_executable_p FILE
+@%:@ -----------------------
+@%:@ Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} @%:@ as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by LTFAT $as_me 1.4.4, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE] 
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <http://ltfat.sourceforge.net/contact.php>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+LTFAT config.status 1.4.4
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX
+@%:@@%:@ Running $as_me. @%:@@%:@
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  
+  
+  
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/src/autom4te.cache/requests b/src/autom4te.cache/requests
new file mode 100644
index 0000000..b797aa3
--- /dev/null
+++ b/src/autom4te.cache/requests
@@ -0,0 +1,77 @@
+# This file was generated by Autom4te Wed Aug 21 09:31:00 UTC 2013.
+# It contains the lists of macros which have been traced.
+# It can be safely removed.
+
+ at request = (
+             bless( [
+                      '0',
+                      1,
+                      [
+                        '/usr/share/autoconf'
+                      ],
+                      [
+                        '/usr/share/autoconf/autoconf/autoconf.m4f',
+                        'configure.ac'
+                      ],
+                      {
+                        'AM_PROG_F77_C_O' => 1,
+                        '_LT_AC_TAGCONFIG' => 1,
+                        'm4_pattern_forbid' => 1,
+                        'AC_INIT' => 1,
+                        'AC_CANONICAL_TARGET' => 1,
+                        '_AM_COND_IF' => 1,
+                        'AC_CONFIG_LIBOBJ_DIR' => 1,
+                        'AC_SUBST' => 1,
+                        'AC_CANONICAL_HOST' => 1,
+                        'AC_FC_SRCEXT' => 1,
+                        'AC_PROG_LIBTOOL' => 1,
+                        'AM_INIT_AUTOMAKE' => 1,
+                        'AC_CONFIG_SUBDIRS' => 1,
+                        'AM_PATH_GUILE' => 1,
+                        'AM_AUTOMAKE_VERSION' => 1,
+                        'LT_CONFIG_LTDL_DIR' => 1,
+                        'AC_CONFIG_LINKS' => 1,
+                        'AC_REQUIRE_AUX_FILE' => 1,
+                        'LT_SUPPORTED_TAG' => 1,
+                        'm4_sinclude' => 1,
+                        'AM_MAINTAINER_MODE' => 1,
+                        'AM_NLS' => 1,
+                        'AC_FC_PP_DEFINE' => 1,
+                        'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
+                        '_m4_warn' => 1,
+                        'AM_MAKEFILE_INCLUDE' => 1,
+                        'AM_PROG_CXX_C_O' => 1,
+                        '_AM_MAKEFILE_INCLUDE' => 1,
+                        '_AM_COND_ENDIF' => 1,
+                        'AM_ENABLE_MULTILIB' => 1,
+                        'AM_SILENT_RULES' => 1,
+                        'AM_PROG_MOC' => 1,
+                        'AC_CONFIG_FILES' => 1,
+                        'LT_INIT' => 1,
+                        'include' => 1,
+                        'AM_GNU_GETTEXT' => 1,
+                        'AM_PROG_AR' => 1,
+                        'AC_LIBSOURCE' => 1,
+                        'AC_CANONICAL_BUILD' => 1,
+                        'AM_PROG_FC_C_O' => 1,
+                        'AC_FC_FREEFORM' => 1,
+                        'AC_FC_PP_SRCEXT' => 1,
+                        'AH_OUTPUT' => 1,
+                        'AC_CONFIG_AUX_DIR' => 1,
+                        '_AM_SUBST_NOTMAKE' => 1,
+                        'm4_pattern_allow' => 1,
+                        'AM_PROG_CC_C_O' => 1,
+                        'sinclude' => 1,
+                        'AM_CONDITIONAL' => 1,
+                        'AC_CANONICAL_SYSTEM' => 1,
+                        'AM_XGETTEXT_OPTION' => 1,
+                        'AC_CONFIG_HEADERS' => 1,
+                        'AC_DEFINE_TRACE_LITERAL' => 1,
+                        'AM_POT_TOOLS' => 1,
+                        'm4_include' => 1,
+                        '_AM_COND_ELSE' => 1,
+                        'AC_SUBST_TRACE' => 1
+                      }
+                    ], 'Autom4te::Request' )
+           );
+
diff --git a/src/autom4te.cache/traces.0 b/src/autom4te.cache/traces.0
new file mode 100644
index 0000000..ee1437e
--- /dev/null
+++ b/src/autom4te.cache/traces.0
@@ -0,0 +1,231 @@
+m4trace:configure.ac:2: -1- AC_INIT([LTFAT], [1.4.4], [http://ltfat.sourceforge.net/contact.php], [ltfat])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?A[CHUM]_])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([_AC_])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^AS_FLAGS$])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?m4_])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^dnl$])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?AS_])
+m4trace:configure.ac:2: -1- AC_SUBST([SHELL])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([SHELL])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^SHELL$])
+m4trace:configure.ac:2: -1- AC_SUBST([PATH_SEPARATOR])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PATH_SEPARATOR])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PATH_SEPARATOR$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME],      ['AC_PACKAGE_NAME'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_NAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_NAME$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME],   ['AC_PACKAGE_TARNAME'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_TARNAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION],   ['AC_PACKAGE_VERSION'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_VERSION])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_VERSION$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING],    ['AC_PACKAGE_STRING'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_STRING])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_STRING$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_URL], [m4_ifdef([AC_PACKAGE_URL],       ['AC_PACKAGE_URL'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_URL])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_URL$])
+m4trace:configure.ac:2: -1- AC_SUBST([exec_prefix], [NONE])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([exec_prefix])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^exec_prefix$])
+m4trace:configure.ac:2: -1- AC_SUBST([prefix], [NONE])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([prefix])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^prefix$])
+m4trace:configure.ac:2: -1- AC_SUBST([program_transform_name], [s,x,x,])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([program_transform_name])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^program_transform_name$])
+m4trace:configure.ac:2: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([bindir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^bindir$])
+m4trace:configure.ac:2: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sbindir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^sbindir$])
+m4trace:configure.ac:2: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([libexecdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^libexecdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([datarootdir], ['${prefix}/share'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([datarootdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^datarootdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([datadir], ['${datarootdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([datadir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^datadir$])
+m4trace:configure.ac:2: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sysconfdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^sysconfdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sharedstatedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^sharedstatedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([localstatedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^localstatedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([includedir], ['${prefix}/include'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([includedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^includedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([oldincludedir], ['/usr/include'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([oldincludedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^oldincludedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME],
+				     ['${datarootdir}/doc/${PACKAGE_TARNAME}'],
+				     ['${datarootdir}/doc/${PACKAGE}'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([docdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^docdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([infodir], ['${datarootdir}/info'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([infodir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^infodir$])
+m4trace:configure.ac:2: -1- AC_SUBST([htmldir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([htmldir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^htmldir$])
+m4trace:configure.ac:2: -1- AC_SUBST([dvidir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([dvidir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^dvidir$])
+m4trace:configure.ac:2: -1- AC_SUBST([pdfdir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([pdfdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^pdfdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([psdir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([psdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^psdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([libdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^libdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([localedir], ['${datarootdir}/locale'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([localedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^localedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([mandir], ['${datarootdir}/man'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([mandir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^mandir$])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_NAME$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
+@%:@undef PACKAGE_NAME])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
+@%:@undef PACKAGE_TARNAME])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_VERSION$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
+@%:@undef PACKAGE_VERSION])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_STRING$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
+@%:@undef PACKAGE_STRING])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
+@%:@undef PACKAGE_BUGREPORT])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_URL])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_URL$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_URL], [/* Define to the home page for this package. */
+@%:@undef PACKAGE_URL])
+m4trace:configure.ac:2: -1- AC_SUBST([DEFS])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([DEFS])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^DEFS$])
+m4trace:configure.ac:2: -1- AC_SUBST([ECHO_C])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_C])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_C$])
+m4trace:configure.ac:2: -1- AC_SUBST([ECHO_N])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_N])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_N$])
+m4trace:configure.ac:2: -1- AC_SUBST([ECHO_T])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_T])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_T$])
+m4trace:configure.ac:2: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:2: -1- AC_SUBST([build_alias])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([build_alias])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^build_alias$])
+m4trace:configure.ac:2: -1- AC_SUBST([host_alias])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([host_alias])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^host_alias$])
+m4trace:configure.ac:2: -1- AC_SUBST([target_alias])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([target_alias])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^target_alias$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CFLAGS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CFLAGS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CFLAGS$])
+m4trace:configure.ac:4: -1- AC_SUBST([LDFLAGS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([LDFLAGS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^LDFLAGS$])
+m4trace:configure.ac:4: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:4: -1- AC_SUBST([CPPFLAGS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CPPFLAGS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CPPFLAGS$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([ac_ct_CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([ac_ct_CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^ac_ct_CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([EXEEXT])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^EXEEXT$])
+m4trace:configure.ac:4: -1- AC_SUBST([OBJEXT], [$ac_cv_objext])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([OBJEXT])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^OBJEXT$])
+m4trace:configure.ac:5: -1- AC_SUBST([CXX])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CXX])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CXX$])
+m4trace:configure.ac:5: -1- AC_SUBST([CXXFLAGS])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CXXFLAGS])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CXXFLAGS$])
+m4trace:configure.ac:5: -1- AC_SUBST([LDFLAGS])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([LDFLAGS])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^LDFLAGS$])
+m4trace:configure.ac:5: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:5: -1- AC_SUBST([CPPFLAGS])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CPPFLAGS])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CPPFLAGS$])
+m4trace:configure.ac:5: -1- AC_SUBST([CXX])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CXX])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CXX$])
+m4trace:configure.ac:5: -1- AC_SUBST([ac_ct_CXX])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([ac_ct_CXX])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^ac_ct_CXX$])
+m4trace:configure.ac:8: -1- m4_include([m4/ax_blas.m4])
+m4trace:configure.ac:9: -1- m4_include([m4/ax_lapack.m4])
+m4trace:configure.ac:29: -1- AC_SUBST([MKOCTFILE_CHECK])
+m4trace:configure.ac:29: -1- AC_SUBST_TRACE([MKOCTFILE_CHECK])
+m4trace:configure.ac:29: -1- m4_pattern_allow([^MKOCTFILE_CHECK$])
+m4trace:configure.ac:44: -1- AC_SUBST([have_libportaudio])
+m4trace:configure.ac:44: -1- AC_SUBST_TRACE([have_libportaudio])
+m4trace:configure.ac:44: -1- m4_pattern_allow([^have_libportaudio$])
+m4trace:configure.ac:45: -1- AC_CONFIG_FILES([Makefile])
+m4trace:configure.ac:45: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments.
+You should run autoupdate.], [])
+m4trace:configure.ac:45: -1- AC_SUBST([LIB@&t at OBJS], [$ac_libobjs])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([LIB@&t at OBJS])
+m4trace:configure.ac:45: -1- m4_pattern_allow([^LIB@&t at OBJS$])
+m4trace:configure.ac:45: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([LTLIBOBJS])
+m4trace:configure.ac:45: -1- m4_pattern_allow([^LTLIBOBJS$])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([top_builddir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([top_build_prefix])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([srcdir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([abs_srcdir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([top_srcdir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([abs_top_srcdir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([builddir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([abs_builddir])
+m4trace:configure.ac:45: -1- AC_SUBST_TRACE([abs_top_builddir])
diff --git a/src/bootstrap b/src/bootstrap
new file mode 100755
index 0000000..4066e97
--- /dev/null
+++ b/src/bootstrap
@@ -0,0 +1,2 @@
+#!/bin/sh
+autoconf
diff --git a/src/c-safe-memalloc.c b/src/c-safe-memalloc.c
new file mode 100644
index 0000000..843747b
--- /dev/null
+++ b/src/c-safe-memalloc.c
@@ -0,0 +1,97 @@
+#include "ltfat.h"
+
+
+
+LTFAT_EXTERN_TOO
+void* ltfat_malloc (size_t n)
+{
+    void *outp;
+    outp = fftw_malloc(n);
+    if (outp == NULL)
+    {
+        puts("ltfat_malloc failed.");
+        exit(1);
+    }
+
+    return outp;
+}
+
+LTFAT_EXTERN_TOO
+void* ltfat_realloc (void *ptr, size_t n)
+{
+    void *outp;
+    // DOES NOT PRODUCE MEMORY ALIGNED POINTER
+    // outp = realloc(ptr, n);
+    outp = fftw_malloc(n);
+
+    if (outp == NULL)
+    {
+        puts("ltfat_realloc failed.");
+        exit(1);
+    }
+
+    if(ptr!=NULL)
+    {
+        ltfat_free(ptr);
+    }
+
+    return outp;
+}
+
+void* ltfat_realloc_and_copy (void *ptr, size_t nold, size_t nnew)
+{
+    if (ptr == NULL)
+    {
+        puts("Null pointer.");
+        exit(1);
+    }
+
+    void *outp;
+
+    outp = fftw_malloc(nnew);
+
+    if (outp == NULL)
+    {
+        puts("ltfat_realloc_and_copy failed.");
+        exit(1);
+    }
+
+    memcpy(outp,ptr,nold<nnew?nold:nnew);
+
+    ltfat_free(ptr);
+
+    return outp;
+}
+
+LTFAT_EXTERN_TOO
+void* ltfat_calloc (size_t nmemb, size_t size)
+{
+    void *outp;
+    // DOES NOT PRODUCE MEMORY ALIGNED POINTER
+    // outp = calloc(nmemb, size);
+
+    // workaround
+    outp = fftw_malloc(nmemb*size);
+
+    if (outp == NULL)
+    {
+        puts("ltfat_calloc failed.");
+        exit(1);
+    }
+    // workaround
+    memset(outp,0,nmemb*size);
+
+    return outp;
+}
+
+LTFAT_EXTERN_TOO
+void ltfat_free(const void *ptr)
+{
+    fftw_free((void*)ptr);
+}
+
+void ltfat_safefree(const void *ptr)
+{
+    if(ptr!=NULL)
+        ltfat_free((void *)ptr);
+}
diff --git a/src/ciutils.c b/src/ciutils.c
new file mode 100644
index 0000000..3af25b1
--- /dev/null
+++ b/src/ciutils.c
@@ -0,0 +1,134 @@
+/* NOT PROCESSED DIRECTLY, see ltfat_complexindependent.c */
+#ifdef LTFAT_TYPE
+
+LTFAT_EXTERN
+void LTFAT_NAME(circshift)(LTFAT_TYPE *in, LTFAT_TYPE *out, const ltfatInt L, const ltfatInt shift)
+{
+    ltfatInt shiftMod = shift%L;
+
+    if(in==out)
+    {
+
+        if(1)
+        {
+            LTFAT_TYPE *inTmp = (LTFAT_TYPE *)ltfat_malloc(L*sizeof(LTFAT_TYPE));
+            memcpy(inTmp,in,L*sizeof(LTFAT_TYPE));
+            LTFAT_NAME(circshift)(inTmp,out,L,shift);
+            ltfat_free(inTmp);
+        }
+        else
+        {
+            ltfatInt m,count,ii,jj;
+            for(m=0,count=0; count!=L; m++)
+            {
+                LTFAT_TYPE t = in[m];
+                for(ii=m,jj=m+shiftMod;
+                        jj!=m;
+                        ii=jj,jj=jj+shiftMod<L?jj+shiftMod:jj+shiftMod-L,count++)
+                {
+                    in[ii]=in[jj];
+                }
+                in[ii]=t;
+                count++;
+            }
+        }
+
+
+
+        return;
+    }
+
+
+
+    if(shiftMod<0)
+    {
+        memcpy(out,in-shiftMod,(L+shiftMod)*sizeof*out);
+        memcpy(out+(L+shiftMod),in,-shiftMod*sizeof*out);
+    }
+    else if(shiftMod>0)
+    {
+        memcpy(out+shiftMod,in,(L-shiftMod)*sizeof*out);
+        memcpy(out,in+L-shiftMod,shiftMod*sizeof*out);
+    }
+    else
+    {
+        memcpy(out,in,L*sizeof*out);
+    }
+}
+
+LTFAT_EXTERN
+void LTFAT_NAME(reverse_array)(LTFAT_TYPE *in, LTFAT_TYPE *out,const ltfatInt L)
+{
+
+    if(in==out)
+    {
+        LTFAT_TYPE tmpVar = (LTFAT_TYPE) 0.0;
+        for(ltfatInt ii=0; ii<L/2; ii++)
+        {
+            tmpVar = in[L-1-ii];
+            in[L-1-ii] = in[ii];
+            in[ii] = tmpVar;
+        }
+    }
+    else
+    {
+        for(ltfatInt ii=0; ii<L; ii++)
+        {
+            out[ii] = in[L-1-ii];
+        }
+    }
+}
+
+LTFAT_EXTERN
+void LTFAT_NAME(conjugate_array)(LTFAT_TYPE *in, LTFAT_TYPE *out,const ltfatInt L)
+{
+#ifdef LTFAT_COMPLEXTYPE
+    for(ltfatInt ii=0; ii<L; ii++)
+    {
+        out[ii] = LTFAT_COMPLEXH(conj)(in[ii]);
+    }
+#else
+    if(in==out)
+    {
+        return;
+    }
+    else
+    {
+        memcpy(out,in,L*sizeof(LTFAT_TYPE));
+    }
+#endif
+
+}
+
+
+LTFAT_EXTERN
+void LTFAT_NAME(array2complex)(LTFAT_TYPE *in, LTFAT_COMPLEX *out, const ltfatInt L)
+{
+#ifdef LTFAT_COMPLEXTYPE
+    if(in==(LTFAT_TYPE*)out)
+    {
+        return;
+    }
+    else
+    {
+        memcpy(out,in,L*sizeof(LTFAT_COMPLEX));
+    }
+#else
+    if(in==(LTFAT_TYPE*)out)
+    {
+        // This should produce an error
+    }
+    else
+    {
+        LTFAT_REAL (*outTmp)[2] = (LTFAT_REAL(*)[2])  out;
+        for(ltfatInt ii=0; ii<L; ii++)
+        {
+            outTmp[ii][0] = in[ii];
+            outTmp[ii][1] = (LTFAT_TYPE) 0.0;
+        }
+    }
+#endif
+}
+
+
+#endif // LTFAT_TYPE
diff --git a/src/ciutils.h b/src/ciutils.h
new file mode 100644
index 0000000..3b59fff
--- /dev/null
+++ b/src/ciutils.h
@@ -0,0 +1,16 @@
+/*
+Inplace friendly functions.
+in==out is possibe.
+*/
+
+LTFAT_EXTERN
+void LTFAT_NAME(circshift)(LTFAT_TYPE *in, LTFAT_TYPE *out, const ltfatInt L, const ltfatInt shift);
+
+LTFAT_EXTERN
+void LTFAT_NAME(reverse_array)(LTFAT_TYPE *in, LTFAT_TYPE *out, const ltfatInt L);
+
+LTFAT_EXTERN
+void LTFAT_NAME(conjugate_array)(LTFAT_TYPE *in, LTFAT_TYPE *out, const ltfatInt L);
+
+LTFAT_EXTERN
+void LTFAT_NAME(array2complex)(LTFAT_TYPE *in, LTFAT_COMPLEX *out, const ltfatInt L);
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..cff7bc1
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,75 @@
+#ifndef CONFIG_H
+#define CONFIG_H 1
+/**
+* Include files
+* Constants
+* Macros, not changing
+*/
+
+#include <complex.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <math.h>
+#include "fftw3.h"
+#include "cblas.h"
+
+#define HAVE_BLAS 1
+#define HAVE_LAPACK 1
+
+
+#ifndef PI
+#define PI 3.1415926535897932384626433832795
+#endif /* defined(PI) */
+
+// "Vectorizes" a function call
+#define LTFAT_APPLYFN(type,fn,...) do{ \
+   const type list[] = {(const type)0,__VA_ARGS__}; \
+   size_t len = sizeof(list)/sizeof(*list) - 1; \
+   for(size_t ii=0;ii<len;ii++) \
+      fn((const type)list[ii+1]); \
+}while(0)
+
+// Vectorized free
+#define LTFAT_SAFEFREEALL(...) LTFAT_APPLYFN(void*,ltfat_safefree,__VA_ARGS__)
+
+
+#define LTFAT_MAKENAME(name,type,comp) name ## _ ## comp ## type
+#define LTFAT_NAME_DOUBLE(name) LTFAT_MAKENAME(name,d,)
+#define LTFAT_NAME_SINGLE(name) LTFAT_MAKENAME(name,s,)
+#define LTFAT_NAME_COMPLEXDOUBLE(name) LTFAT_MAKENAME(name,d,c)
+#define LTFAT_NAME_COMPLEXSINGLE(name) LTFAT_MAKENAME(name,s,c)
+
+
+/* Define to a macro mangling the given C identifier (in lower and upper
+   case), which must not contain underscores, for linking with Fortran. */
+
+#ifdef MATLABFORTRAN
+#define F77_FUNC(name,NAME) NAME
+#else
+#define F77_FUNC(name,NAME) name ## _
+#endif
+
+
+/* Handle Windows DLL files */
+/* defined by Makefile when compiling LTFAT */
+#if defined(DLL_EXPORT_SYMBOLS) && ((defined(_WIN32) || defined(__WIN32__)))
+#  define LTFAT_EXTERN extern __declspec(dllexport)
+#  if defined(LTFAT_DOUBLE)
+#     define LTFAT_EXTERN_TOO LTFAT_EXTERN
+#  else
+#     define LTFAT_EXTERN_TOO
+#  endif
+#else
+#  define LTFAT_EXTERN extern
+#  define LTFAT_EXTERN_TOO LTFAT_EXTERN
+#endif
+
+
+
+/* On WinXP, gcc defines __WIN32__ */
+/* On Linux, gcc defines __linux__ */
+
+#endif /* CONFIG_H */
diff --git a/src/configure b/src/configure
new file mode 100755
index 0000000..cc42743
--- /dev/null
+++ b/src/configure
@@ -0,0 +1,4490 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for LTFAT 1.4.4.
+#
+# Report bugs to <http://ltfat.sourceforge.net/contact.php>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: http://ltfat.sourceforge.net/contact.php about your
+$0: system, including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='LTFAT'
+PACKAGE_TARNAME='ltfat'
+PACKAGE_VERSION='1.4.4'
+PACKAGE_STRING='LTFAT 1.4.4'
+PACKAGE_BUGREPORT='http://ltfat.sourceforge.net/contact.php'
+PACKAGE_URL=''
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+have_libportaudio
+MKOCTFILE_CHECK
+ac_ct_CXX
+CXXFLAGS
+CXX
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures LTFAT 1.4.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/ltfat]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of LTFAT 1.4.4:";;
+   esac
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://ltfat.sourceforge.net/contact.php>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+LTFAT configure 1.4.4
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by LTFAT $as_me 1.4.4, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+  your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str;
+  int number;
+  float fnumber;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case 's': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case 'd': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case 'f': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+}
+
+int
+main ()
+{
+
+  // Check bool.
+  _Bool success = false;
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  test_varargs ("s, d' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+	  || dynamic_array[ni.number - 1] != 543);
+
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c99"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+#AC_CONFIG_MACRO_DIR([m4/])
+# ===========================================================================
+#          http://www.gnu.org/software/autoconf-archive/ax_blas.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the BLAS linear-algebra
+#   interface (see http://www.netlib.org/blas/). On success, it sets the
+#   BLAS_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with BLAS, you should link with:
+#
+#     $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   Many libraries are searched for, from ATLAS to CXML to ESSL. The user
+#   may also use --with-blas=<lib> in order to use some specific BLAS
+#   library <lib>. In order to link successfully, however, be aware that you
+#   will probably need to use the same Fortran compiler (which can be set
+#   via the F77 env. var.) as was used to compile the BLAS library.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a BLAS library is
+#   found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is
+#   not found. If ACTION-IF-FOUND is not specified, the default action will
+#   define HAVE_BLAS.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 11
+
+# This is what autoupdate's m4 run will expand.  It fires
+# the warning (with _au_warn_XXX), outputs it into the
+# updated configure.ac (with AC_DIAGNOSE), and then outputs
+# the replacement expansion.
+
+
+# This is an auxiliary macro that is also run when
+# autoupdate runs m4.  It simply calls m4_warning, but
+# we need a wrapper so that each warning is emitted only
+# once.  We break the quoting in m4_warning's argument in
+# order to expand this macro's arguments, not AU_DEFUN's.
+
+
+# Finally, this is the expansion that is picked up by
+# autoconf.  It tells the user to run autoupdate, and
+# then outputs the replacement expansion.  We do not care
+# about autoupdate's warning because that contains
+# information on what to do *after* running autoupdate.
+
+
+# ===========================================================================
+#         http://www.gnu.org/software/autoconf-archive/ax_lapack.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_LAPACK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the LAPACK linear-algebra
+#   interface (see http://www.netlib.org/lapack/). On success, it sets the
+#   LAPACK_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with LAPACK, you should link with:
+#
+#     $LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. BLAS_LIBS is the output variable of the AX_BLAS macro,
+#   called automatically. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   The user may also use --with-lapack=<lib> in order to use some specific
+#   LAPACK library <lib>. In order to link successfully, however, be aware
+#   that you will probably need to use the same Fortran compiler (which can
+#   be set via the F77 env. var.) as was used to compile the LAPACK and BLAS
+#   libraries.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a LAPACK library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_LAPACK.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+# This is what autoupdate's m4 run will expand.  It fires
+# the warning (with _au_warn_XXX), outputs it into the
+# updated configure.ac (with AC_DIAGNOSE), and then outputs
+# the replacement expansion.
+
+
+# This is an auxiliary macro that is also run when
+# autoupdate runs m4.  It simply calls m4_warning, but
+# we need a wrapper so that each warning is emitted only
+# once.  We break the quoting in m4_warning's argument in
+# order to expand this macro's arguments, not AU_DEFUN's.
+
+
+# Finally, this is the expansion that is picked up by
+# autoconf.  It tells the user to run autoupdate, and
+# then outputs the replacement expansion.  We do not care
+# about autoupdate's warning because that contains
+# information on what to do *after* running autoupdate.
+
+
+
+# The checks for BLAS and Lapack have been disabled because they
+# provoke an error about a missing install-sh
+
+#dnl Check for BLAS libraries
+#sinclude(ax_blas.m4)
+#AX_BLAS
+#if test "$ax_blas_ok" = "no"; then
+#   AC_MSG_ERROR([Cannot find BLAS libraries])
+#fi
+
+#dnl Check for LAPACK libraries
+#sinclude(ax_lapack.m4)
+#AX_LAPACK
+#if test "$ax_lapack_ok" = "no"; then
+#   AC_MSG_ERROR([Cannot find LAPACK libraries])
+#fi
+
+# Extract the first word of "mkoctfile", so it can be a program name with args.
+set dummy mkoctfile; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MKOCTFILE_CHECK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MKOCTFILE_CHECK"; then
+  ac_cv_prog_MKOCTFILE_CHECK="$MKOCTFILE_CHECK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MKOCTFILE_CHECK=""yes""
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MKOCTFILE_CHECK=$ac_cv_prog_MKOCTFILE_CHECK
+if test -n "$MKOCTFILE_CHECK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKOCTFILE_CHECK" >&5
+$as_echo "$MKOCTFILE_CHECK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$MKOCTFILE_CHECK" != "yes" ; then
+    as_fn_error $? "Please install mkoctfile." "$LINENO" 5
+fi
+
+#AC_CHECK_HEADERS([fftw3.h],[],[AC_MSG_ERROR([fftw was not found])])
+# Checking for portaudio, we pack portaudio.h with LTFAT
+# AC_CHECK_HEADER(portaudio.h)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Pa_GetHostApiCount in -lportaudio" >&5
+$as_echo_n "checking for Pa_GetHostApiCount in -lportaudio... " >&6; }
+if ${ac_cv_lib_portaudio_Pa_GetHostApiCount+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lportaudio  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char Pa_GetHostApiCount ();
+int
+main ()
+{
+return Pa_GetHostApiCount ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_portaudio_Pa_GetHostApiCount=yes
+else
+  ac_cv_lib_portaudio_Pa_GetHostApiCount=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_portaudio_Pa_GetHostApiCount" >&5
+$as_echo "$ac_cv_lib_portaudio_Pa_GetHostApiCount" >&6; }
+if test "x$ac_cv_lib_portaudio_Pa_GetHostApiCount" = xyes; then :
+  have_libportaudio=1
+else
+  echo "Portaudio lib not found. Disabling support of the block processing framework."
+ have_libportaudio=0
+
+fi
+
+
+
+
+ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by LTFAT $as_me 1.4.4, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <http://ltfat.sourceforge.net/contact.php>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+LTFAT config.status 1.4.4
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/src/configure.ac b/src/configure.ac
new file mode 100644
index 0000000..6228239
--- /dev/null
+++ b/src/configure.ac
@@ -0,0 +1,45 @@
+AC_PREREQ([2.62])
+AC_INIT([LTFAT], [1.4.4], [http://ltfat.sourceforge.net/contact.php], [ltfat])
+
+AC_PROG_CC_C99
+AC_PROG_CXX
+
+#AC_CONFIG_MACRO_DIR([m4/])
+m4_include([m4/ax_blas.m4])
+m4_include([m4/ax_lapack.m4])
+
+# The checks for BLAS and Lapack have been disabled because they
+# provoke an error about a missing install-sh
+
+#dnl Check for BLAS libraries
+#sinclude(ax_blas.m4)
+#AX_BLAS
+#if test "$ax_blas_ok" = "no"; then
+#   AC_MSG_ERROR([Cannot find BLAS libraries])
+#fi
+
+#dnl Check for LAPACK libraries
+#sinclude(ax_lapack.m4)
+#AX_LAPACK
+#if test "$ax_lapack_ok" = "no"; then
+#   AC_MSG_ERROR([Cannot find LAPACK libraries])
+#fi
+
+dnl Check for MKOCTFILE
+AC_CHECK_PROG(MKOCTFILE_CHECK,mkoctfile,"yes")
+if test "$MKOCTFILE_CHECK" != "yes" ; then
+    AC_MSG_ERROR([Please install mkoctfile.])
+fi
+
+#AC_CHECK_HEADERS([fftw3.h],[],[AC_MSG_ERROR([fftw was not found])])
+# Checking for portaudio, we pack portaudio.h with LTFAT
+# AC_CHECK_HEADER(portaudio.h)
+AC_CHECK_LIB(portaudio,Pa_GetHostApiCount,
+[have_libportaudio=1],
+[echo "Portaudio lib not found. Disabling support of the block processing framework." 
+ have_libportaudio=0
+ ])
+
+
+AC_SUBST(have_libportaudio)
+AC_OUTPUT(Makefile)
diff --git a/src/dct.c b/src/dct.c
new file mode 100644
index 0000000..1aaae2e
--- /dev/null
+++ b/src/dct.c
@@ -0,0 +1,128 @@
+/* NOT PROCESSED DIRECTLY, dct_ci.c */
+#ifdef LTFAT_TYPE
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(dct_init)( const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
+                      const dct_kind kind)
+{
+    LTFAT_FFTW(iodim) dims, howmanydims;
+    LTFAT_FFTW(plan) p;
+
+#ifdef LTFAT_COMPLEXTYPE
+    dims.n = L;
+    dims.is = 2;
+    dims.os = 2;
+
+    howmanydims.n = W;
+    howmanydims.is = 2*L;
+    howmanydims.os = 2*L;
+
+    // We want to use the plan for the unaligned imaginary part of the array
+    unsigned flag = FFTW_ESTIMATE | FFTW_UNALIGNED;
+#else
+    dims.n = L;
+    dims.is = 1;
+    dims.os = 1;
+
+    howmanydims.n = W;
+    howmanydims.is = L;
+    howmanydims.os = L;
+
+    unsigned flag = FFTW_ESTIMATE;
+#endif
+
+    LTFAT_FFTW(r2r_kind) kindFftw = kind;
+    p = LTFAT_FFTW(plan_guru_r2r)(1, &dims,
+                                  1, &howmanydims,
+                                  (LTFAT_REAL*)cout, (LTFAT_REAL*)cout,
+                                  &kindFftw, flag);
+
+    return p;
+}
+
+
+// f and cout cannot be equal, because creating plan can tamper with the array
+LTFAT_EXTERN void
+LTFAT_NAME(dct)(const LTFAT_TYPE *f, const ltfatInt L, const ltfatInt W,
+                LTFAT_TYPE *cout, const dct_kind kind)
+{
+    LTFAT_FFTW(plan) p = LTFAT_NAME(dct_init)( L, W, cout, kind);
+
+    LTFAT_NAME(dct_execute)(p, f,  L,  W,  cout, kind);
+
+    LTFAT_FFTW(destroy_plan)(p);
+}
+
+// f and cout can be equal, provided plan was already created
+LTFAT_EXTERN
+void LTFAT_NAME(dct_execute)(const LTFAT_FFTW(plan) p, const LTFAT_TYPE *f,
+                             const ltfatInt L, const ltfatInt W,
+                             LTFAT_TYPE *cout, const dct_kind kind)
+{
+    // Copy input to the output
+    if(cout!=f)
+        memcpy(cout,f,L*W*sizeof*f);
+
+    if(L==1)
+        return;
+
+    ltfatInt N = 2*L;
+    LTFAT_REAL sqrt2 = (LTFAT_REAL) sqrt(2.0);
+    LTFAT_REAL postScale = (LTFAT_REAL) 1.0/sqrt2;
+    LTFAT_REAL scale = (LTFAT_REAL) sqrt2*(1.0/(double)N)*sqrt((double)L);
+
+    if(kind==DCTI || kind==DCTIII)
+    {
+        for(ltfatInt ii=0; ii<W; ii++)
+        {
+            cout[ii*L]*=sqrt2;
+        }
+    }
+
+    if(kind==DCTI)
+    {
+        N -= 2;
+        for(ltfatInt ii=0; ii<W; ii++)
+        {
+            cout[(ii+1)*L-1] *= sqrt2;
+        }
+
+        scale = (LTFAT_REAL) sqrt2*(1.0/((double)N))*sqrt((double)L-1);
+    }
+
+    LTFAT_REAL* c_r = (LTFAT_REAL*)cout;
+
+    LTFAT_FFTW(execute_r2r)(p,c_r,c_r);
+#ifdef LTFAT_COMPLEXTYPE
+    LTFAT_REAL* c_i = c_r+1;
+    LTFAT_FFTW(execute_r2r)(p,c_i,c_i);
+#endif
+
+    // Post-scaling
+    for(ltfatInt ii=0; ii<L*W; ii++)
+    {
+        cout[ii] *= scale;
+    }
+
+    if(kind==DCTI || kind==DCTII)
+    {
+        // Scale DC component(s)
+        for(ltfatInt ii=0; ii<W; ii++)
+        {
+            cout[ii*L] *= postScale;
+        }
+    }
+
+    if(kind==DCTI)
+    {
+        // Scale AC component
+        for(ltfatInt ii=0; ii<W; ii++)
+        {
+            cout[(ii+1)*L-1] *= postScale;
+        }
+    }
+}
+
+#endif
diff --git a/src/dct_ci.c b/src/dct_ci.c
new file mode 100644
index 0000000..409b753
--- /dev/null
+++ b/src/dct_ci.c
@@ -0,0 +1,11 @@
+#ifdef LTFAT_COMPLEXTYPE
+#  undef LTFAT_COMPLEXTYPE
+#endif // LTFAT_COMPLEXTYPE
+
+#include "ltfat_types.h"
+#include "dct.c"
+
+#define LTFAT_COMPLEXTYPE
+#include "ltfat_types.h"
+#include "dct.c"
+#undef LTFAT_COMPLEXTYPE
diff --git a/src/dgt.c b/src/dgt.c
new file mode 100644
index 0000000..7664f8a
--- /dev/null
+++ b/src/dgt.c
@@ -0,0 +1,112 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN
+void LTFAT_NAME_COMPLEX(dgt_long)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                                  const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                                  const ltfatInt M, LTFAT_COMPLEX *cout)
+{
+    LTFAT_NAME(dgt_long_plan) plan =
+        LTFAT_NAME(dgt_long_init)(f, g, L, W, a, M, cout, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_long_execute)(plan);
+
+    LTFAT_NAME(dgt_long_done)(plan);
+}
+
+LTFAT_EXTERN
+void LTFAT_NAME(dgt_long)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                          const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                          const ltfatInt M, LTFAT_COMPLEX *cout)
+{
+    LTFAT_COMPLEX* gf = (LTFAT_COMPLEX*) ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_NAME_REAL(wfac)(g, L, 1, a, M,gf);
+
+    LTFAT_NAME(dgt_fac_r)(f, (const LTFAT_COMPLEX*)gf,L,W, a,M, cout);
+
+
+    ltfat_free(gf);
+}
+
+
+LTFAT_EXTERN
+void LTFAT_NAME(dgtreal_long)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                              const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                              const ltfatInt M, LTFAT_COMPLEX *cout)
+{
+
+    LTFAT_NAME(dgtreal_long_plan) plan =
+        LTFAT_NAME(dgtreal_long_init)(f, g, L, W, a, M, cout, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgtreal_long_execute)(plan);
+
+    LTFAT_NAME(dgtreal_long_done)(plan);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dgt_fb)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                           const ltfatInt L, const ltfatInt gl,
+                           const ltfatInt W,  const ltfatInt a, const ltfatInt M,
+                           LTFAT_COMPLEX *cout)
+{
+
+    LTFAT_NAME(dgt_fb_plan) plan =
+        LTFAT_NAME(dgt_fb_init)(g, gl, a, M, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_fb_execute)(plan, f, L, W, cout);
+
+    LTFAT_NAME(dgt_fb_done)(plan);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_fb)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                       const ltfatInt L, const ltfatInt gl,
+                       const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                       LTFAT_COMPLEX *cout)
+{
+
+    LTFAT_NAME(dgtreal_fb_plan) plan =
+        LTFAT_NAME(dgtreal_fb_init)(g, gl, a, M, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgtreal_fb_execute)(plan, f, L, W, cout);
+
+    LTFAT_NAME(dgtreal_fb_done)(plan);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_ola)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                    const ltfatInt L, const ltfatInt gl,
+                    const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                    LTFAT_COMPLEX *cout)
+{
+    LTFAT_NAME(dgt_ola_plan) plan =
+        LTFAT_NAME(dgt_ola_init)(g, gl, W, a, M, bl, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_ola_execute)(plan, f, L, cout);
+
+    LTFAT_NAME(dgt_ola_done)(plan);
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_ola)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                        const ltfatInt L, const ltfatInt gl,
+                        const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                        LTFAT_COMPLEX *cout)
+{
+    LTFAT_NAME(dgtreal_ola_plan) plan =
+        LTFAT_NAME(dgtreal_ola_init)(g, gl, W, a, M, bl, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgtreal_ola_execute)(plan, f, L, cout);
+
+    LTFAT_NAME(dgtreal_ola_done)(plan);
+
+}
+
+
diff --git a/src/dgt_fac.c b/src/dgt_fac.c
new file mode 100644
index 0000000..1bed1d8
--- /dev/null
+++ b/src/dgt_fac.c
@@ -0,0 +1,120 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_long_plan)
+LTFAT_NAME(dgt_long_init)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                          const ltfatInt L, const ltfatInt W,
+                          const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *cout,
+                          unsigned flags)
+{
+
+    LTFAT_NAME(dgt_long_plan) plan;
+    ltfatInt h_m;
+
+    plan.a=a;
+    plan.M=M;
+    plan.L=L;
+    plan.W=W;
+    const ltfatInt N=L/a;
+    const ltfatInt b=L/M;
+
+    plan.c=gcd(a, M,&plan.h_a, &h_m);
+    const ltfatInt p=a/plan.c;
+    const ltfatInt q=M/plan.c;
+    const ltfatInt d=b/p;
+    plan.h_a=-plan.h_a;
+
+    plan.sbuf = ltfat_malloc(2*d*sizeof(LTFAT_REAL));
+    plan.cout = cout;
+    plan.f    = f;
+
+    plan.gf   = ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+
+    plan.ff = ltfat_malloc(2*d*p*q*W*sizeof(LTFAT_REAL));
+    plan.cf = ltfat_malloc(2*d*q*q*W*sizeof(LTFAT_REAL));
+
+    /* Get factorization of window */
+    LTFAT_NAME_COMPLEX(wfac)(g, L, 1, a, M, plan.gf);
+
+    // Downcasting to ints
+    int Mint = (int) M;
+
+    /* Create plans. In-place. */
+    plan.p_veryend =
+        LTFAT_FFTW(plan_many_dft)(1, &Mint, N*W,
+                                  plan.cout, NULL,
+                                  1, Mint,
+                                  plan.cout, NULL,
+                                  1, Mint,
+                                  FFTW_FORWARD, flags);
+
+    plan.p_before =
+        LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)plan.sbuf,
+                                (LTFAT_COMPLEX*)plan.sbuf,
+                                FFTW_FORWARD, flags);
+
+    plan.p_after  =
+        LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)plan.sbuf,
+                                (LTFAT_COMPLEX*)plan.sbuf,
+                                FFTW_BACKWARD, flags);
+
+    return plan;
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_long_execute)(const LTFAT_NAME(dgt_long_plan) plan)
+{
+
+    LTFAT_NAME(dgt_walnut_plan)(plan);
+
+    /* FFT to modulate the coefficients. */
+    LTFAT_FFTW(execute)(plan.p_veryend);
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_long_done)(LTFAT_NAME(dgt_long_plan) plan)
+{
+    LTFAT_FFTW(destroy_plan)(plan.p_veryend);
+    LTFAT_FFTW(destroy_plan)(plan.p_before);
+    LTFAT_FFTW(destroy_plan)(plan.p_after);
+    LTFAT_SAFEFREEALL(plan.sbuf,plan.gf,plan.ff,plan.cf);
+}
+
+
+
+
+
+/* -------------- Real valued signal ------------------------ */
+
+LTFAT_EXTERN
+void LTFAT_NAME(dgt_fac_r)(const LTFAT_REAL *f, const LTFAT_COMPLEX *gf,
+                           const ltfatInt L,
+                           const ltfatInt W, const ltfatInt a,
+                           const ltfatInt M, LTFAT_COMPLEX *cout)
+{
+
+    const ltfatInt N=L/a;
+    // Downcasting to int
+    int Mint = (int) M;
+
+    /* Create plan. In-place. */
+    LTFAT_FFTW(plan) p_veryend =
+        LTFAT_FFTW(plan_many_dft)(1, &Mint, N*W,
+                                  cout, NULL,
+                                  1, Mint,
+                                  cout, NULL,
+                                  1, Mint,
+                                  FFTW_FORWARD, FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_walnut_r)(f,gf,L,W,a,M,cout);
+
+    /* FFT to modulate the coefficients. */
+    LTFAT_FFTW(execute)(p_veryend);
+
+    LTFAT_FFTW(destroy_plan)(p_veryend);
+
+}
diff --git a/src/dgt_fb.c b/src/dgt_fb.c
new file mode 100644
index 0000000..9e25811
--- /dev/null
+++ b/src/dgt_fb.c
@@ -0,0 +1,529 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#define CH(name) LTFAT_COMPLEXH(name)
+
+/* The following macro adds the coefficients together performing the
+ * last part of the Poisson summation, executes the FFT on the summed
+ * coefficients, and places the coefficients in the output array.
+ *
+ * The first summation is done in that peculiar way to obtain the
+ * correct phase for a frequency invariant Gabor transform. Summing
+ * them directly would lead to a time invariant (phase-locked) Gabor
+ * transform.
+ *
+ * The macro is called in three different places in the dgt_fb function.
+ */
+
+
+#define THE_SUM { \
+for (ltfatInt m=0;m<M;m++) \
+{ \
+   rem = 2*positiverem(m+(n*a-glh), M); \
+   sbuf[rem]=0.0; \
+   sbuf[rem+1]=0.0; \
+   fbd=fw+2*m; \
+   for (ltfatInt k=0;k<gl/M;k++) \
+   { \
+      sbuf[rem]  += fbd[0]; \
+      sbuf[rem+1]+= fbd[1]; \
+      fbd+=2*M; \
+   } \
+} \
+\
+ LTFAT_FFTW(execute)(plan.p_small);			\
+\
+coefsum=(LTFAT_REAL*)cout+2*(n*M+w*M*N); \
+for (ltfatInt m=0;m<M;m++) \
+{ \
+   coefsum[2*m] = sbuf[2*m]; \
+   coefsum[2*m+1] = sbuf[2*m+1]; \
+}}
+
+#define THE_SUM_REAL { \
+for (ltfatInt m=0;m<M;m++) \
+{ \
+   rem = positiverem(m+(n*a-glh), M); \
+   sbuf[rem]=0.0; \
+   fbd=fw+m; \
+   for (ltfatInt k=0;k<gl/M;k++) \
+   { \
+     sbuf[rem]+=(*fbd);			\
+      fbd+=M; \
+   } \
+} \
+\
+ LTFAT_FFTW(execute)(plan.p_small);			\
+\
+coefsum=(LTFAT_REAL*)cout+2*(n*M2+w*M2*N); \
+for (ltfatInt m=0;m<M2;m++) \
+{ \
+   coefsum[2*m]   = CH(creal)(cbuf[m]); \
+   coefsum[2*m+1] = CH(cimag)(cbuf[m]); \
+}}
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_fb_plan)
+LTFAT_NAME(dgt_fb_init)(const LTFAT_COMPLEX *g,
+                        const ltfatInt gl, const ltfatInt a, const ltfatInt M,
+                        unsigned flags)
+{
+    LTFAT_NAME(dgt_fb_plan) plan;
+
+    plan.a=a;
+    plan.M=M;
+    plan.gl=gl;
+
+    plan.gw  = (LTFAT_COMPLEX*)ltfat_malloc(gl*sizeof(LTFAT_COMPLEX));
+
+    plan.fw  = (LTFAT_REAL*)ltfat_malloc(2*gl*sizeof(LTFAT_REAL));
+
+    plan.sbuf = (LTFAT_REAL*)ltfat_malloc(M*sizeof(LTFAT_COMPLEX));
+
+    plan.p_small = LTFAT_FFTW(plan_dft_1d)(M, (LTFAT_COMPLEX*)plan.sbuf, (LTFAT_COMPLEX*)plan.sbuf,
+                                           FFTW_FORWARD, flags);
+
+    /* This is a floor operation. */
+    const ltfatInt glh=gl/2;
+
+
+    /* Do the fftshift of g to place the center in the middle and
+     * conjugate it.
+     */
+
+    for (ltfatInt l=0; l<glh; l++)
+    {
+        plan.gw[l]=CH(conj)(g[l+(gl-glh)]);
+    }
+    for (ltfatInt l=glh; l<gl; l++)
+    {
+        plan.gw[l]=CH(conj)(g[l-glh]);
+    }
+
+    return (plan);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fb_done)(LTFAT_NAME(dgt_fb_plan) plan)
+{
+    LTFAT_SAFEFREEALL(plan.sbuf,plan.gw,plan.fw);
+    LTFAT_FFTW(destroy_plan)(plan.p_small);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fb_execute)(LTFAT_NAME(dgt_fb_plan) plan, const LTFAT_COMPLEX *f,
+                           const ltfatInt L, const ltfatInt W,  LTFAT_COMPLEX *cout)
+{
+    /*  --------- initial declarations -------------- */
+
+    const ltfatInt a=plan.a;
+    const ltfatInt M=plan.M;
+    const ltfatInt N=L/a;
+
+    const ltfatInt gl=plan.gl;
+    LTFAT_REAL *sbuf=plan.sbuf;
+    LTFAT_REAL *fw=plan.fw;
+
+    /* This is a floor operation. */
+    const ltfatInt glh=plan.gl/2;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+
+    ltfatInt rem;
+
+    LTFAT_COMPLEX *gb;
+    LTFAT_REAL *coefsum, *fbd;
+
+
+    /*  ---------- main body ----------- */
+
+    /*----- Handle the first boundary using periodic boundary conditions.*/
+    for (ltfatInt n=0; n<glh_d_a; n++)
+    {
+        gb=plan.gw;
+        for (ltfatInt w=0; w<W; w++)
+        {
+
+            fbd=(LTFAT_REAL*)f+2*(L-(glh-n*a)+L*w);
+            for (ltfatInt l=0; l<glh-n*a; l++)
+            {
+                fw[2*l]  =fbd[2*l]*CH(creal)(gb[l])-fbd[2*l+1]*CH(cimag)(gb[l]);
+                fw[2*l+1]=fbd[2*l+1]*CH(creal)(gb[l])+fbd[2*l]*CH(cimag)(gb[l]);
+            }
+            fbd=(LTFAT_REAL*)f-2*(glh-n*a)+2*L*w;
+            for (ltfatInt l=glh-n*a; l<gl; l++)
+            {
+                fw[2*l]  =fbd[2*l]*CH(creal)(gb[l])-fbd[2*l+1]*CH(cimag)(gb[l]);
+                fw[2*l+1]=fbd[2*l+1]*CH(creal)(gb[l])+fbd[2*l]*CH(cimag)(gb[l]);
+            }
+
+            THE_SUM
+
+        }
+    }
+
+    /* ----- Handle the middle case. --------------------- */
+    for (ltfatInt n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+    {
+        gb=plan.gw;
+        for (ltfatInt w=0; w<W; w++)
+        {
+            fbd=(LTFAT_REAL*)f+2*(n*a-glh+L*w);
+            for (ltfatInt l=0; l<gl; l++)
+            {
+                fw[2*l]  =fbd[2*l]*CH(creal)(gb[l])-fbd[2*l+1]*CH(cimag)(gb[l]);
+                fw[2*l+1]=fbd[2*l+1]*CH(creal)(gb[l])+fbd[2*l]*CH(cimag)(gb[l]);
+            }
+
+            THE_SUM
+        }
+
+    }
+
+    /* Handle the last boundary using periodic boundary conditions. */
+    for (ltfatInt n=(L-(gl+1)/2)/a+1; n<N; n++)
+    {
+        gb=plan.gw;
+        for (ltfatInt w=0; w<W; w++)
+        {
+            fbd=(LTFAT_REAL*)f+2*(n*a-glh+L*w);
+            for (ltfatInt l=0; l<L-n*a+glh; l++)
+            {
+                fw[2*l]  =fbd[2*l]*CH(creal)(gb[l])-fbd[2*l+1]*CH(cimag)(gb[l]);
+                fw[2*l+1]=fbd[2*l+1]*CH(creal)(gb[l])+fbd[2*l]*CH(cimag)(gb[l]);
+            }
+            fbd=(LTFAT_REAL*)f-2*(L-n*a+glh)+2*L*w;
+            for (ltfatInt l=L-n*a+glh; l<gl; l++)
+            {
+                fw[2*l]  =fbd[2*l]*CH(creal)(gb[l])-fbd[2*l+1]*CH(cimag)(gb[l]);
+                fw[2*l+1]=fbd[2*l+1]*CH(creal)(gb[l])+fbd[2*l]*CH(cimag)(gb[l]);
+            }
+
+            THE_SUM
+        }
+    }
+
+}
+
+/* See the comments on the macro THE_SUM. This macro uses real valued
+ * inputs, but produces complex valued output and uses a regular FFT.
+ */
+#define THE_SUM_R {for (ltfatInt m=0;m<M;m++) \
+{ \
+   rem = 2*positiverem(m+(n*a-glh), M); \
+   sbuf[rem]=0.0; \
+   sbuf[rem+1]=0.0; \
+   fbd=fw+m; \
+   for (ltfatInt k=0;k<gl/M;k++) \
+   { \
+      sbuf[rem]  += (*fbd); \
+      fbd+=M; \
+   } \
+}   \
+\
+    LTFAT_FFTW(execute)(p_small);		\
+\
+coefsum=(LTFAT_REAL*)cout+2*(n*M+r*M*N+w*M*N*R); \
+for (ltfatInt m=0;m<M;m++) \
+{ \
+   coefsum[2*m]   = sbuf[2*m]; \
+   coefsum[2*m+1] = sbuf[2*m+1]; \
+}}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fb)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                   const ltfatInt L, const ltfatInt gl,
+                   const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                   LTFAT_COMPLEX *cout)
+{
+    /*  --------- initial declarations -------------- */
+
+    ltfatInt r, rem;
+
+    LTFAT_REAL *gw;
+
+    LTFAT_FFTW(plan) p_small;
+
+    LTFAT_REAL *gb;
+    LTFAT_REAL *sbuf,*coefsum, *fw;
+
+    const LTFAT_REAL *fbd;
+
+
+    const ltfatInt R = 1;
+
+    /*  ----------- calculation of parameters and plans -------- */
+
+    const ltfatInt N=L/a;
+
+    /* This is a floor operation. */
+    const ltfatInt glh=gl/2;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+
+    gw   = (LTFAT_REAL*)ltfat_malloc(gl*R*sizeof(LTFAT_REAL));
+    fw   = (LTFAT_REAL*)ltfat_malloc(gl*sizeof(LTFAT_REAL));
+    sbuf = (LTFAT_REAL*)ltfat_malloc(2*M*sizeof(LTFAT_REAL));
+
+    /* Create plan. In-place. */
+    p_small = LTFAT_FFTW(plan_dft_1d)(M, (LTFAT_COMPLEX*)sbuf,
+                                      (LTFAT_COMPLEX*)sbuf,
+                                      FFTW_FORWARD, FFTW_MEASURE);
+
+    /*  ---------- main body ----------- */
+
+    /* Do the fftshift of g to place the center in the middle and
+     * conjugate it.
+     */
+
+    for (r=0; r<R; r++)
+    {
+        for (ltfatInt l=0; l<glh; l++)
+        {
+            gw[l+gl*r]=g[l+(gl-glh)+gl*r];
+        }
+        for (ltfatInt l=glh; l<gl; l++)
+        {
+            gw[l+gl*r]=g[l-glh+gl*r];
+        }
+    }
+
+    /*----- Handle the first boundary using periodic boundary conditions.*/
+    for (ltfatInt n=0; n<glh_d_a; n++)
+    {
+        for (ltfatInt r=0; r<R; r++)
+        {
+            gb=gw+r*gl;
+            for (ltfatInt w=0; w<W; w++)
+            {
+
+                fbd=f+L-(glh-n*a)+L*w;
+                for (ltfatInt l=0; l<glh-n*a; l++)
+                {
+                    fw[l]  =fbd[l]*gb[l];
+                }
+                fbd=f-(glh-n*a)+L*w;
+                for (ltfatInt l=glh-n*a; l<gl; l++)
+                {
+                    fw[l]  =fbd[l]*gb[l];
+                }
+
+                THE_SUM_R
+
+            }
+
+        }
+    }
+
+    /* ----- Handle the middle case. --------------------- */
+    for (ltfatInt n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+    {
+
+        for (ltfatInt r=0; r<R; r++)
+        {
+            gb=gw+r*gl;
+            for (ltfatInt w=0; w<W; w++)
+            {
+                fbd=f+(n*a-glh+L*w);
+                for (ltfatInt l=0; l<gl; l++)
+                {
+                    fw[l]  =fbd[l]*gb[l];
+                }
+
+                THE_SUM_R
+            }
+
+        }
+
+    }
+
+    /* Handle the last boundary using periodic boundary conditions. */
+    for (ltfatInt n=(L-(gl+1)/2)/a+1; n<N; n++)
+    {
+        for (ltfatInt r=0; r<R; r++)
+        {
+            gb=gw+r*gl;
+            for (ltfatInt w=0; w<W; w++)
+            {
+                fbd=f+(n*a-glh+L*w);
+                for (ltfatInt l=0; l<L-n*a+glh; l++)
+                {
+                    fw[l]  =fbd[l]*gb[l];
+                }
+                fbd=f-(L-n*a+glh)+L*w;
+                for (ltfatInt l=L-n*a+glh; l<gl; l++)
+                {
+                    fw[l]  =fbd[l]*gb[l];
+                }
+
+                THE_SUM_R
+            }
+        }
+    }
+
+    /* -----------  Clean up ----------------- */
+    LTFAT_SAFEFREEALL(sbuf,gw,fw);
+    LTFAT_FFTW(destroy_plan)(p_small);
+}
+
+
+
+
+
+
+
+
+LTFAT_EXTERN LTFAT_NAME(dgtreal_fb_plan)
+LTFAT_NAME(dgtreal_fb_init)(const LTFAT_REAL *g,
+                            const ltfatInt gl, const ltfatInt a, const ltfatInt M,
+                            unsigned flags)
+{
+    LTFAT_NAME(dgtreal_fb_plan) plan;
+
+    plan.a=a;
+    plan.M=M;
+    const ltfatInt M2=M/2+1;
+    plan.gl=gl;
+
+
+
+    plan.gw   = ltfat_malloc(gl*sizeof*plan.gw);
+
+    plan.fw   = ltfat_malloc(gl*sizeof*plan.fw);
+
+    plan.sbuf = ltfat_malloc(M*sizeof*plan.sbuf);
+
+    plan.cbuf = ltfat_malloc(M2*sizeof*plan.cbuf);
+
+    plan.p_small = LTFAT_FFTW(plan_dft_r2c_1d)(M, plan.sbuf, plan.cbuf, flags);
+
+    /* This is a floor operation. */
+    const ltfatInt glh=gl/2;
+
+
+    /* Do the fftshift of g to place the center in the middle and
+     * conjugate it.
+     */
+
+    for (ltfatInt l=0; l<glh; l++)
+    {
+        plan.gw[l]=g[l+(gl-glh)];
+    }
+    for (ltfatInt l=glh; l<gl; l++)
+    {
+        plan.gw[l]=g[l-glh];
+    }
+
+    return (plan);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_fb_done)(LTFAT_NAME(dgtreal_fb_plan) plan)
+{
+    LTFAT_SAFEFREEALL(plan.sbuf,plan.cbuf,plan.gw,plan.fw);
+    LTFAT_FFTW(destroy_plan)(plan.p_small);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_fb_execute)(const LTFAT_NAME(dgtreal_fb_plan) plan, const LTFAT_REAL *f,
+                               const ltfatInt L, const ltfatInt W,
+                               LTFAT_COMPLEX *cout)
+{
+    /*  --------- initial declarations -------------- */
+
+    const ltfatInt a=plan.a;
+    const ltfatInt M=plan.M;
+    const ltfatInt N=L/a;
+
+    const ltfatInt gl=plan.gl;
+    LTFAT_REAL    *sbuf=plan.sbuf;
+    LTFAT_COMPLEX *cbuf=plan.cbuf;
+    LTFAT_REAL *fw=plan.fw;
+
+    /* These are floor operations. */
+    const ltfatInt glh=plan.gl/2;
+    const ltfatInt M2=M/2+1;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+
+    ltfatInt rem;
+
+    LTFAT_REAL *gb;
+    LTFAT_REAL *coefsum;
+
+    const LTFAT_REAL *fbd;
+
+    /*  ---------- main body ----------- */
+
+    /*----- Handle the first boundary using periodic boundary conditions.*/
+    for (ltfatInt n=0; n<glh_d_a; n++)
+    {
+        gb=plan.gw;
+        for (ltfatInt w=0; w<W; w++)
+        {
+
+            fbd=f+L-(glh-n*a)+L*w;
+            for (ltfatInt l=0; l<glh-n*a; l++)
+            {
+                fw[l]  =fbd[l]*gb[l];
+            }
+            fbd=f-(glh-n*a)+L*w;
+            for (ltfatInt l=glh-n*a; l<gl; l++)
+            {
+                fw[l]  =fbd[l]*gb[l];
+            }
+
+            THE_SUM_REAL
+
+        }
+    }
+
+    /* ----- Handle the middle case. --------------------- */
+    for (ltfatInt n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+    {
+
+        gb=plan.gw;
+        for (ltfatInt w=0; w<W; w++)
+        {
+            fbd=f+(n*a-glh+L*w);
+            for (ltfatInt l=0; l<gl; l++)
+            {
+                fw[l]  =fbd[l]*gb[l];
+            }
+
+            THE_SUM_REAL
+        }
+
+    }
+
+    /* Handle the last boundary using periodic boundary conditions. */
+    for (ltfatInt n=(L-(gl+1)/2)/a+1; n<N; n++)
+    {
+        gb=plan.gw;
+        for (ltfatInt w=0; w<W; w++)
+        {
+            fbd=f+(n*a-glh+L*w);
+            for (ltfatInt l=0; l<L-n*a+glh; l++)
+            {
+                fw[l]  =fbd[l]*gb[l];
+            }
+            fbd=f-(L-n*a+glh)+L*w;
+            for (ltfatInt l=L-n*a+glh; l<gl; l++)
+            {
+                fw[l]  =fbd[l]*gb[l];
+            }
+
+            THE_SUM_REAL
+        }
+    }
+
+}
+
+#undef THE_SUM
+#undef CH
diff --git a/src/dgt_long.h b/src/dgt_long.h
new file mode 100644
index 0000000..a581400
--- /dev/null
+++ b/src/dgt_long.h
@@ -0,0 +1,47 @@
+typedef struct
+{
+    ltfatInt a;
+    ltfatInt M;
+    ltfatInt L;
+    ltfatInt W;
+    ltfatInt c;
+    ltfatInt h_a;
+    LTFAT_FFTW(plan) p_before;
+    LTFAT_FFTW(plan) p_after;
+    LTFAT_FFTW(plan) p_veryend;
+    LTFAT_REAL *sbuf;
+    const LTFAT_COMPLEX *f;
+    LTFAT_COMPLEX *gf;
+    LTFAT_COMPLEX *cout;
+    LTFAT_REAL *ff, *cf;
+
+} LTFAT_NAME(dgt_long_plan);
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dgt_long)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                             const ltfatInt L, const ltfatInt W,  const ltfatInt a,
+                             const ltfatInt M, LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_long)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                     const ltfatInt L, const ltfatInt W,  const ltfatInt a,
+                     const ltfatInt M, LTFAT_COMPLEX *cout);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_long_plan)
+LTFAT_NAME(dgt_long_init)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                          const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                          const ltfatInt M, LTFAT_COMPLEX *cout,
+                          unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_long_execute)(const LTFAT_NAME(dgt_long_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_long_done)(LTFAT_NAME(dgt_long_plan) plan);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_walnut_plan)(LTFAT_NAME(dgt_long_plan) plan);
diff --git a/src/dgt_multi.c b/src/dgt_multi.c
new file mode 100644
index 0000000..988cafd
--- /dev/null
+++ b/src/dgt_multi.c
@@ -0,0 +1,132 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(nonsepwin2multi)(const LTFAT_COMPLEX *g,
+                            const ltfatInt L, const ltfatInt Lg, const ltfatInt a, const ltfatInt M,
+                            const ltfatInt lt1, const ltfatInt lt2,
+                            LTFAT_COMPLEX *mwin)
+{
+    const ltfatInt b=L/M;
+
+    const LTFAT_REAL scal = 2*PI/L;
+
+    LTFAT_COMPLEX *gwork = (LTFAT_COMPLEX *)ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+    LTFAT_NAME(fir2long_c)((const LTFAT_COMPLEX*)g,Lg,L,(LTFAT_COMPLEX*)gwork);
+
+    for (ltfatInt w=0; w<lt2; w++)
+    {
+        const ltfatInt wavenum=((w*lt1)%lt2)*b/lt2;
+        for (ltfatInt l=0; l<L; l++)
+        {
+            mwin[l+w*L]=cexp(I*scal*l*wavenum)*gwork[positiverem(l-w*a,L)];
+        }
+    }
+
+    ltfat_free(gwork);
+}
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_multi_plan)
+LTFAT_NAME(dgt_multi_init)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                           const ltfatInt L, const ltfatInt Lg, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                           const ltfatInt lt1, const ltfatInt lt2,
+                           LTFAT_COMPLEX *cout,unsigned flags)
+{
+
+    LTFAT_NAME(dgt_multi_plan) plan;
+
+    plan.a=a;
+    plan.M=M;
+    plan.L=L;
+    plan.Lg=Lg;
+    plan.W=W;
+
+    plan.lt1=lt1;
+    plan.lt2=lt2;
+
+    plan.f     = (LTFAT_COMPLEX *)f;
+    plan.cout  = cout;
+
+    const ltfatInt N   = L/a;
+    const ltfatInt Ns  = N/lt2;
+
+    plan.mwin = (LTFAT_COMPLEX *)ltfat_malloc(L*lt2*sizeof(LTFAT_COMPLEX));
+    plan.c_scratch = (LTFAT_COMPLEX *)ltfat_malloc(M*Ns*W*sizeof(LTFAT_COMPLEX));
+
+
+    LTFAT_NAME(nonsepwin2multi)(g,L,Lg,a,M,lt1,lt2,plan.mwin);
+
+    plan.rect_plan_array = (LTFAT_NAME(dgt_long_plan)*) ltfat_malloc(lt2*sizeof(LTFAT_NAME(dgt_long_plan)));
+
+    for (ltfatInt win=0; win<lt2; win++)
+    {
+        plan.rect_plan_array[win]=LTFAT_NAME(dgt_long_init)((const LTFAT_COMPLEX*)plan.f,(const LTFAT_COMPLEX*)(plan.mwin+L*win),L,W,a*lt2,M,
+                                  (LTFAT_COMPLEX*)plan.c_scratch,flags);
+    }
+
+    plan.mod = (LTFAT_COMPLEX*) ltfat_malloc(N*sizeof(LTFAT_COMPLEX));
+
+    for (ltfatInt win=0; win<plan.lt2; win++)
+    {
+        for (ltfatInt n=0; n<Ns; n++)
+        {
+            plan.mod[win+n*lt2] = cexp(-2*PI*I*(a*n*((win*lt1)%lt2))/M);
+        }
+    }
+
+    return plan;
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_multi_execute)(const LTFAT_NAME(dgt_multi_plan) plan)
+{
+    const ltfatInt N   = plan.L/plan.a;
+    const ltfatInt Ns  = N/plan.lt2;
+
+    const ltfatInt M=plan.M;
+    const ltfatInt W=plan.W;
+    const ltfatInt lt2=plan.lt2;
+
+    for (ltfatInt win=0; win<plan.lt2; win++)
+    {
+        LTFAT_NAME(dgt_long_execute)(plan.rect_plan_array[win]);
+        for (ltfatInt w=0; w<W; w++)
+        {
+            for (ltfatInt n=0; n<Ns; n++)
+            {
+                for (ltfatInt m=0; m<M; m++)
+                {
+                    plan.cout[m+win*M+n*lt2*M+w*M*N] = plan.mod[win+n*lt2]*plan.c_scratch[m+n*M+w*M*Ns];
+                }
+            }
+        }
+    }
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_multi_done)(LTFAT_NAME(dgt_multi_plan) plan)
+{
+    for (ltfatInt ii=0; ii<plan.lt2; ii++)
+    {
+        LTFAT_NAME(dgt_long_done)(plan.rect_plan_array[ii]);
+    }
+    LTFAT_SAFEFREEALL(plan.mod,plan.rect_plan_array,plan.c_scratch,plan.mwin);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_multi)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                      const ltfatInt L, const ltfatInt Lg, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                      const ltfatInt lt1, const ltfatInt lt2,
+                      LTFAT_COMPLEX *cout)
+{
+
+    LTFAT_NAME(dgt_multi_plan) plan = LTFAT_NAME(dgt_multi_init)(
+                                          f,g,L,Lg,W,a,M,lt1,lt2,cout,FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_multi_execute)(plan);
+
+    LTFAT_NAME(dgt_multi_done)(plan);
+
+}
diff --git a/src/dgt_multi.h b/src/dgt_multi.h
new file mode 100644
index 0000000..26cb0c9
--- /dev/null
+++ b/src/dgt_multi.h
@@ -0,0 +1,50 @@
+
+
+typedef struct
+{
+    ltfatInt a;
+    ltfatInt M;
+    ltfatInt L;
+    ltfatInt Lg;
+    ltfatInt W;
+    ltfatInt lt1;
+    ltfatInt lt2;
+
+    LTFAT_COMPLEX *f;
+    LTFAT_COMPLEX *c_scratch;
+    LTFAT_COMPLEX *cout;
+
+    LTFAT_COMPLEX *mwin;
+    LTFAT_COMPLEX *c_rect;
+
+    LTFAT_COMPLEX *mod;
+
+    LTFAT_NAME(dgt_long_plan) *rect_plan_array;
+
+} LTFAT_NAME(dgt_multi_plan);
+
+LTFAT_EXTERN LTFAT_NAME(dgt_multi_plan)
+LTFAT_NAME(dgt_multi_init)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                           const ltfatInt L, const ltfatInt Lg, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                           const ltfatInt lt1, const ltfatInt lt2,
+                           LTFAT_COMPLEX *c,unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_multi_execute)(const LTFAT_NAME(dgt_multi_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_multi_done)(LTFAT_NAME(dgt_multi_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(nonsepwin2multi)(const LTFAT_COMPLEX *g,
+                            const ltfatInt L, const ltfatInt Lg, const ltfatInt a, const ltfatInt M,
+                            const ltfatInt lt1, const ltfatInt lt2,
+                            LTFAT_COMPLEX *mwin);
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_multi)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                      const ltfatInt L, const ltfatInt Lg, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                      const ltfatInt lt1, const ltfatInt lt2,
+                      LTFAT_COMPLEX *c);
diff --git a/src/dgt_ola.c b/src/dgt_ola.c
new file mode 100644
index 0000000..001636c
--- /dev/null
+++ b/src/dgt_ola.c
@@ -0,0 +1,280 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_ola_plan)
+LTFAT_NAME(dgt_ola_init)(const LTFAT_COMPLEX *g, const ltfatInt gl,
+                         const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                         unsigned flags)
+{
+
+    LTFAT_NAME(dgt_ola_plan) plan;
+
+    plan.bl = bl;
+    plan.gl = gl;
+    plan.W  = W;
+
+    const ltfatInt Lext    = bl+gl;
+    const ltfatInt Nblocke = Lext/a;
+
+    plan.buf  = ltfat_malloc(Lext*W*sizeof*plan.buf);
+    plan.gext = ltfat_malloc(Lext*sizeof*plan.gext);
+    plan.cbuf = ltfat_malloc(M*Nblocke*W*sizeof*plan.cbuf);
+
+    LTFAT_NAME(fir2long_c)(g, gl, Lext, plan.gext);
+
+    /* Zero the last part of the buffer, it will always be zero. */
+    for (ltfatInt w=0; w<W; w++)
+    {
+        for (ltfatInt jj=bl; jj<Lext; jj++)
+        {
+            plan.buf[jj+w*Lext] = (LTFAT_COMPLEX) 0.0;
+        }
+    }
+
+    plan.plan =
+        LTFAT_NAME(dgt_long_init)((const LTFAT_COMPLEX*)plan.buf,
+                                  (const LTFAT_COMPLEX*)plan.gext,
+                                  Lext, W, a, M,
+                                  plan.cbuf, flags);
+
+    return (plan);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_ola_execute)(const LTFAT_NAME(dgt_ola_plan) plan,
+                            const LTFAT_COMPLEX *f, const ltfatInt L,
+                            LTFAT_COMPLEX *cout)
+
+{
+    const ltfatInt bl      = plan.bl;
+    const ltfatInt gl      = plan.gl;
+    const ltfatInt a       = plan.plan.a;
+    const ltfatInt M       = plan.plan.M;
+    const ltfatInt N       = L/a;
+    const ltfatInt Lext    = bl+gl;
+    const ltfatInt Nb      = L/bl;
+    const ltfatInt b2      = gl/a/2;
+    const ltfatInt Nblock  = bl/a;
+    const ltfatInt Nblocke = Lext/a;
+    const ltfatInt W       = plan.W;
+
+
+    /* Zero the output array, as we will be adding to it */
+    for (ltfatInt ii=0; ii<M*N*W; ii++)
+    {
+        cout[ii] = (LTFAT_COMPLEX) 0.0;
+    }
+
+    for (ltfatInt ii=0; ii<Nb; ii++)
+    {
+        ltfatInt s_ii;
+
+        /* Copy to working buffer. */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            memcpy(plan.buf+Lext*w,f+ii*bl+w*L,sizeof(LTFAT_COMPLEX)*bl);
+        }
+
+        /* Execute the short DGT */
+        LTFAT_NAME(dgt_long_execute)(plan.plan);
+
+        /* Place the results */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            LTFAT_COMPLEX *cout_p;
+            LTFAT_COMPLEX *cbuf_p;
+
+            /* Place large block */
+            cout_p = cout + ii*M*Nblock+w*M*N ;
+            cbuf_p = plan.cbuf +             w*M*Nblocke;
+            for (ltfatInt m=0; m<M; m++)
+            {
+                for (ltfatInt n=0; n<Nblock; n++)
+                {
+                    cout_p[m+n*M] += cbuf_p[m+n*M];
+                }
+            }
+
+            /* Small block + */
+            s_ii=positiverem(ii+1,Nb);
+            cout_p = cout + s_ii*M*Nblock+w*M*N ;
+            cbuf_p = plan.cbuf +      M*Nblock+w*M*Nblocke;
+            for (ltfatInt m=0; m<M; m++)
+            {
+                for (ltfatInt n=0; n<b2; n++)
+                {
+                    cout_p[m+n*M] += cbuf_p[m+n*M];
+                }
+            }
+
+
+            /* Small block - */
+            s_ii=positiverem(ii-1,Nb)+1;
+            cout_p = cout + M*(s_ii*Nblock-b2)+w*M*N ;
+            cbuf_p = plan.cbuf + M*(Nblock+b2)     +w*M*Nblocke;
+            for (ltfatInt m=0; m<M; m++)
+            {
+                for (ltfatInt n=0; n<b2; n++)
+                {
+                    cout_p[m+n*M] += cbuf_p[m+n*M];
+                }
+            }
+
+        }
+
+    }
+
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_ola_done)(LTFAT_NAME(dgt_ola_plan) plan)
+{
+    LTFAT_NAME(dgt_long_done)(plan.plan);
+    LTFAT_SAFEFREEALL(plan.cbuf,plan.gext,plan.buf);
+}
+
+
+
+LTFAT_EXTERN LTFAT_NAME(dgtreal_ola_plan)
+LTFAT_NAME(dgtreal_ola_init)(const LTFAT_REAL *g, const ltfatInt gl,
+                             const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                             unsigned flags)
+{
+
+    LTFAT_NAME(dgtreal_ola_plan) plan;
+
+    plan.bl = bl;
+    plan.gl = gl;
+    plan.W  = W;
+    const ltfatInt M2=M/2+1;
+
+    const ltfatInt Lext    = bl+gl;
+    const ltfatInt Nblocke = Lext/a;
+
+    plan.buf  = (LTFAT_REAL*) ltfat_malloc(Lext*W*sizeof(LTFAT_REAL));
+    plan.gext = (LTFAT_REAL*) ltfat_malloc(Lext*sizeof(LTFAT_REAL));
+    plan.cbuf = (LTFAT_COMPLEX*) ltfat_malloc(M2*Nblocke*W*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_NAME(fir2long_r)(g, gl, Lext, plan.gext);
+
+    /* Zero the last part of the buffer, it will always be zero. */
+    for (ltfatInt w=0; w<W; w++)
+    {
+        for (ltfatInt jj=bl; jj<Lext; jj++)
+        {
+            plan.buf[jj+w*Lext]=0.0;
+        }
+    }
+
+    plan.plan =
+        LTFAT_NAME(dgtreal_long_init)((const LTFAT_REAL*)plan.buf,
+                                      (const LTFAT_REAL*)plan.gext,
+                                      Lext, W, a, M,
+                                      plan.cbuf, flags);
+
+    return (plan);
+
+}
+
+
+
+
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_ola_execute)(const LTFAT_NAME(dgtreal_ola_plan) plan,
+                                const LTFAT_REAL *f, const ltfatInt L,
+                                LTFAT_COMPLEX *cout)
+
+{
+    const ltfatInt bl      = plan.bl;
+    const ltfatInt gl      = plan.gl;
+    const ltfatInt a       = plan.plan.a;
+    const ltfatInt M       = plan.plan.M;
+    const ltfatInt N       = L/a;
+    const ltfatInt Lext    = bl+gl;
+    const ltfatInt Nb      = L/bl;
+    const ltfatInt b2      = gl/a/2;
+    const ltfatInt Nblock  = bl/a;
+    const ltfatInt Nblocke = Lext/a;
+    const ltfatInt W       = plan.W;
+    const ltfatInt M2      = M/2+1;
+
+    /* Zero the output array, as we will be adding to it */
+    for (ltfatInt ii=0; ii<M2*N*W; ii++)
+    {
+        cout[ii] = (LTFAT_COMPLEX) 0.0;
+    }
+
+
+    for (ltfatInt ii=0; ii<Nb; ii++)
+    {
+        ltfatInt s_ii;
+
+        /* Copy to working buffer. */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            memcpy(plan.buf+Lext*w,f+ii*bl+w*L,sizeof(LTFAT_REAL)*bl);
+        }
+
+        /* Execute the short DGTREAL */
+        LTFAT_NAME(dgtreal_long_execute)(plan.plan);
+
+        /* Place the results */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            LTFAT_COMPLEX *cout_p;
+            LTFAT_COMPLEX *cbuf_p;
+
+            /* Place large block */
+            cout_p = cout + ii*M2*Nblock+w*M2*N ;
+            cbuf_p = plan.cbuf +             w*M2*Nblocke;
+            for (ltfatInt m=0; m<M2; m++)
+            {
+                for (ltfatInt n=0; n<Nblock; n++)
+                {
+                    cout_p[m+n*M2] += cbuf_p[m+n*M2];
+                }
+            }
+
+            /* Small block + */
+            s_ii=positiverem(ii+1,Nb);
+            cout_p = cout + s_ii*M2*Nblock+w*M2*N ;
+            cbuf_p = plan.cbuf +      M2*Nblock+w*M2*Nblocke;
+            for (ltfatInt m=0; m<M2; m++)
+            {
+                for (ltfatInt n=0; n<b2; n++)
+                {
+                    cout_p[m+n*M2] += cbuf_p[m+n*M2];
+                }
+            }
+
+
+            /* Small block - */
+            s_ii=positiverem(ii-1,Nb)+1;
+            cout_p = cout + M2*(s_ii*Nblock-b2)+w*M2*N ;
+            cbuf_p = plan.cbuf + M2*(     Nblock+b2)+w*M2*Nblocke;
+            for (ltfatInt m=0; m<M2; m++)
+            {
+                for (ltfatInt n=0; n<b2; n++)
+                {
+                    cout_p[m+n*M2] += cbuf_p[m+n*M2];
+                }
+            }
+
+        }
+
+    }
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_ola_done)(LTFAT_NAME(dgtreal_ola_plan) plan)
+{
+    LTFAT_NAME(dgtreal_long_done)(plan.plan);
+    LTFAT_SAFEFREEALL(plan.cbuf,plan.gext,plan.buf);
+}
diff --git a/src/dgt_shear.c b/src/dgt_shear.c
new file mode 100644
index 0000000..5ce0366
--- /dev/null
+++ b/src/dgt_shear.c
@@ -0,0 +1,297 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+
+// long is only "at least 32 bit"
+static inline long long positiverem_long(long long a,long long b)
+{
+    const long long c = a%b;
+    return(c<0 ? c+b : c);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(pchirp)(const long long L, const long long n, LTFAT_COMPLEX *g)
+{
+
+    const long long LL=2*L;
+    const long long Lponen=positiverem_long((L+1)*n,LL);
+
+    for (long long m=0; m<L; m++)
+    {
+        const long long idx = positiverem_long(
+                             positiverem_long(Lponen*m,LL)*m,LL);
+
+        g[m] = cexp(1.0*I*PI*idx/L);
+    }
+
+
+    /* const LTFAT_REAL LL=2.0*L; */
+    /* const LTFAT_REAL Lpone=L+1; */
+
+    /* for (ltfatInt m=0;m<L;m++) */
+    /* { */
+    /*    //g[m] = cexp(I*PI*fmod(Lpone*n*m*m,LL)/L); */
+    /*    g[m] = cexp(I*PI*fmod(fmod(fmod(Lpone*n,LL)*m,LL)*m,LL)/L); */
+    /* } */
+
+}
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_shear_plan)
+LTFAT_NAME(dgt_shear_init)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                           const ltfatInt L, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                           const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
+                           LTFAT_COMPLEX *cout,
+                           unsigned flags)
+{
+    LTFAT_NAME(dgt_shear_plan) plan;
+
+    plan.a=a;
+    plan.M=M;
+    plan.L=L;
+    plan.W=W;
+
+    plan.s0=s0;
+    plan.s1=s1;
+    plan.br=br;
+
+    const ltfatInt b=L/M;
+    const ltfatInt N=L/a;
+
+    const ltfatInt ar = a*b/br;
+    const ltfatInt Mr = L/br;
+    const ltfatInt Nr = L/ar;
+
+    plan.f     = (LTFAT_COMPLEX *)f;
+    plan.fwork = (LTFAT_COMPLEX *)f;
+    plan.gwork = (LTFAT_COMPLEX *)g;
+    plan.cout  = cout;
+
+    plan.c_rect = ltfat_malloc(M*N*W*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_COMPLEX *f_before_fft = (LTFAT_COMPLEX *)f;
+    LTFAT_COMPLEX *g_before_fft = (LTFAT_COMPLEX *)g;
+
+    if ((s0!=0) || (s1!=0))
+    {
+        plan.fwork = ltfat_malloc(L*W*sizeof(LTFAT_COMPLEX));
+        plan.gwork = ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+    }
+
+
+    if (s1)
+    {
+        plan.p1 = ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+
+        LTFAT_NAME(pchirp)(L,s1,plan.p1);
+
+        for (ltfatInt l=0; l<L; l++)
+        {
+            plan.gwork[l] = g[l]*plan.p1[l];
+        }
+
+        f_before_fft=plan.fwork;
+        g_before_fft=plan.gwork;
+
+    }
+
+    if (s0==0)
+    {
+
+        /* Call the rectangular computation in the time domain */
+        /* LTFAT_NAME(dgt_long)(plan.fwork,plan.gwork,L,W,ar,Mr,plan.c_rect); */
+
+        plan.rect_plan = LTFAT_NAME(dgt_long_init)(plan.fwork, plan.gwork,
+                         L, W, ar, Mr, plan.c_rect, flags);
+    }
+    else
+    {
+
+        /* Allocate memory and compute the pchirp */
+        plan.p0 = ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+        LTFAT_NAME(pchirp)(L,-s0,plan.p0);
+
+        /* if data has already been copied to the working arrays, use
+         * inline FFTs. Otherwise, if this is the first time they are
+         * being used, do the copying using the fft. */
+
+        // Downcasting to int
+        int Lint = (int) L;
+        plan.f_plan = LTFAT_FFTW(plan_many_dft)(1, &Lint, W,
+                                                f_before_fft, NULL, 1, L,
+                                                plan.fwork, NULL, 1, L,
+                                                FFTW_FORWARD, flags);
+
+        plan.g_plan = LTFAT_FFTW(plan_dft_1d)(L, g_before_fft, plan.gwork, FFTW_FORWARD, flags);
+
+        /* Execute the FFTs */
+        LTFAT_FFTW(execute)(plan.g_plan);
+
+        /* Multiply g by the chirp and scale by 1/L */
+        for (ltfatInt l=0; l<L; l++)
+        {
+            plan.gwork[l] = plan.gwork[l]*plan.p0[l]/L;
+        }
+
+        /* Call the rectangular computation in the frequency domain*/
+        /* LTFAT_NAME(dgt_long)(plan.fwork,plan.gwork,L,W,br,Nr,plan.c_rect); */
+        /* Call the rectangular computation in the frequency domain*/
+        plan.rect_plan = LTFAT_NAME(dgt_long_init)(plan.fwork, plan.gwork, L, W, br, Nr, plan.c_rect, flags);
+
+    }
+
+    plan.finalmod = ltfat_malloc(2*N*sizeof(LTFAT_COMPLEX));
+
+    for (ltfatInt n=0; n<2*N; n++)
+    {
+        plan.finalmod[n]=cexp(PI*I*n/N);
+    }
+
+    return plan;
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shear_execute)(const LTFAT_NAME(dgt_shear_plan) plan)
+{
+
+    const ltfatInt a=plan.a;
+    const ltfatInt M=plan.M;
+    const ltfatInt L=plan.L;
+
+    const ltfatInt b=plan.L/plan.M;
+    const ltfatInt N=plan.L/plan.a;
+    const long s0 = plan.s0;
+    const long s1 = plan.s1;
+
+    const ltfatInt ar = plan.a*b/plan.br;
+    const ltfatInt Mr = plan.L/plan.br;
+    const ltfatInt Nr = plan.L/ar;
+
+
+    if (s1)
+    {
+        for (ltfatInt w=0; w<plan.W; w++)
+        {
+            for (ltfatInt l=0; l<plan.L; l++)
+            {
+                plan.fwork[l+w*plan.L] = plan.f[l+w*plan.L]*plan.p1[l];
+            }
+        }
+
+    }
+
+
+    if (s0==0)
+    {
+
+        const ltfatInt twoN=2*N;
+
+        /* In this case, cc1=1 */
+
+        const long cc3 = positiverem_long(s1*(L+1),twoN);
+
+        const long tmp1=positiverem_long(cc3*a,twoN);
+
+        LTFAT_NAME(dgt_long_execute)(plan.rect_plan);
+
+        for (ltfatInt k=0; k<N; k++)
+        {
+            const ltfatInt phsidx= positiverem_long((tmp1*k)%twoN*k,twoN);
+            const long part1= positiverem_long(-s1*k*a,L);
+            for (ltfatInt m=0; m<M; m++)
+            {
+                /* The line below has a hidden floor operation when dividing with the last b */
+                const ltfatInt idx2 = ((part1+b*m)%L)/b;
+
+                const ltfatInt inidx  =    m+k*M;
+                const ltfatInt outidx = idx2+k*M;
+                for (ltfatInt w=0; w<plan.W; w++)
+                {
+                    plan.cout[outidx+w*M*N] = plan.c_rect[inidx+w*M*N]*plan.finalmod[phsidx];
+                }
+            }
+        }
+
+
+    }
+    else
+    {
+
+        const ltfatInt twoN=2*N;
+        const long cc1=ar/a;
+        const long cc2=positiverem_long(-s0*plan.br/a,twoN);
+        const long cc3=positiverem_long(a*s1*(L+1),twoN);
+        const long cc4=positiverem_long(cc2*plan.br*(L+1),twoN);
+        const long cc5=positiverem_long(2*cc1*plan.br,twoN);
+        const long cc6=positiverem_long((s0*s1+1)*plan.br,L);
+
+        LTFAT_FFTW(execute)(plan.f_plan);
+
+        for (ltfatInt w=0; w<plan.W; w++)
+        {
+            for (ltfatInt l=0; l<plan.L; l++)
+            {
+
+                plan.fwork[l+w*plan.L] = plan.fwork[l+w*plan.L]*plan.p0[l];
+            }
+        }
+
+        LTFAT_NAME(dgt_long_execute)(plan.rect_plan);
+
+        for (ltfatInt k=0; k<Nr; k++)
+        {
+            const long part1 = positiverem_long(-s1*k*ar,L);
+            for (ltfatInt m=0; m<Mr; m++)
+            {
+                const long sq1 = k*cc1+cc2*m;
+
+                const ltfatInt phsidx = positiverem_long(
+                                       (cc3*sq1*sq1)%twoN-(m*(cc4*m+k*cc5))%twoN,twoN);
+
+                /* The line below has a hidden floor operation when dividing with the last b */
+                const ltfatInt idx2 = ((part1+cc6*m)%L)/b;
+
+                const ltfatInt inidx  = positiverem(-k,Nr)+m*Nr;
+                const ltfatInt outidx = idx2+(sq1%N)*M;
+                for (ltfatInt w=0; w<plan.W; w++)
+                {
+                    plan.cout[outidx+w*M*N] = plan.c_rect[inidx+w*M*N]*plan.finalmod[phsidx];
+
+                }
+            }
+        }
+
+    }
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shear_done)(LTFAT_NAME(dgt_shear_plan) plan)
+{
+    LTFAT_NAME(dgt_long_done)(plan.rect_plan);
+    LTFAT_SAFEFREEALL(plan.finalmod,plan.c_rect,plan.fwork,plan.gwork,plan.p0,plan.p1);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shear)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                      const ltfatInt L, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                      const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
+                      LTFAT_COMPLEX *cout)
+{
+
+    LTFAT_NAME(dgt_shear_plan) plan = LTFAT_NAME(dgt_shear_init)(
+                                          f,g,L,W,a,M,s0,s1,br,cout,FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_shear_execute)(plan);
+
+    LTFAT_NAME(dgt_shear_done)(plan);
+
+}
+
+
+
+
diff --git a/src/dgt_shear.h b/src/dgt_shear.h
new file mode 100644
index 0000000..eb7e9e8
--- /dev/null
+++ b/src/dgt_shear.h
@@ -0,0 +1,53 @@
+typedef struct
+{
+    ltfatInt a;
+    ltfatInt M;
+    ltfatInt L;
+    ltfatInt W;
+    ltfatInt s0;
+    ltfatInt s1;
+    ltfatInt br;
+
+    LTFAT_COMPLEX *p0;
+    LTFAT_COMPLEX *p1;
+
+    LTFAT_COMPLEX *fwork;
+    LTFAT_COMPLEX *gwork;
+    LTFAT_COMPLEX *c_rect;
+
+    LTFAT_COMPLEX *finalmod;
+
+    LTFAT_FFTW(plan) f_plan;
+    LTFAT_FFTW(plan) g_plan;
+
+
+    LTFAT_NAME(dgt_long_plan) rect_plan;
+
+    const LTFAT_COMPLEX *f;
+    LTFAT_COMPLEX *cout;
+
+} LTFAT_NAME(dgt_shear_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_shear_plan)
+LTFAT_NAME(dgt_shear_init)(
+    const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+    const ltfatInt L, const ltfatInt W, const ltfatInt a,
+    const ltfatInt M, const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
+    LTFAT_COMPLEX *cout,
+    unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shear_execute)(const LTFAT_NAME(dgt_shear_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shear_done)(LTFAT_NAME(dgt_shear_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shear)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                      const ltfatInt L, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                      const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
+                      LTFAT_COMPLEX *c);
+
+LTFAT_EXTERN void
+LTFAT_NAME(pchirp)(const long long L, const long long n, LTFAT_COMPLEX *g);
diff --git a/src/dgt_shearola.c b/src/dgt_shearola.c
new file mode 100644
index 0000000..5cfc515
--- /dev/null
+++ b/src/dgt_shearola.c
@@ -0,0 +1,157 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_shearola_plan)
+LTFAT_NAME(dgt_shearola_init)(const LTFAT_COMPLEX *g, const ltfatInt gl,
+                              const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                              const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
+                              const ltfatInt bl,
+                              unsigned flags)
+{
+
+    LTFAT_NAME(dgt_shearola_plan) plan;
+
+    plan.bl = bl;
+    plan.gl = gl;
+    plan.W  = W;
+
+    const ltfatInt Lext    = bl+gl;
+    const ltfatInt Nblocke = Lext/a;
+
+    plan.buf  = ltfat_malloc(Lext*W*sizeof(LTFAT_COMPLEX));
+    plan.gext = ltfat_malloc(Lext*sizeof(LTFAT_COMPLEX));
+    plan.cbuf = ltfat_malloc(M*Nblocke*W*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_NAME(fir2long_c)(g, gl, Lext, plan.gext);
+
+    /* Zero the last part of the buffer, it will always be zero. */
+    for (ltfatInt w=0; w<W; w++)
+    {
+        for (ltfatInt jj=bl; jj<Lext; jj++)
+        {
+            plan.buf[jj+w*Lext] = (LTFAT_COMPLEX) 0.0;
+        }
+    }
+
+    plan.plan =
+        LTFAT_NAME(dgt_shear_init)((const LTFAT_COMPLEX*)plan.buf,
+                                   (const LTFAT_COMPLEX*)plan.gext,
+                                   Lext, W, a, M,
+                                   s0, s1, br,
+                                   plan.cbuf, flags);
+
+    return (plan);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shearola_execute)(const LTFAT_NAME(dgt_shearola_plan) plan,
+                                 const LTFAT_COMPLEX *f, const ltfatInt L,
+                                 LTFAT_COMPLEX *cout)
+
+{
+    const ltfatInt bl      = plan.bl;
+    const ltfatInt gl      = plan.gl;
+    const ltfatInt a       = plan.plan.a;
+    const ltfatInt M       = plan.plan.M;
+    const ltfatInt N       = L/a;
+    const ltfatInt Lext    = bl+gl;
+    const ltfatInt Nb      = L/bl;
+    const ltfatInt b2      = gl/a/2;
+    const ltfatInt Nblock  = bl/a;
+    const ltfatInt Nblocke = Lext/a;
+    const ltfatInt W       = plan.W;
+
+
+    /* Zero the output array, as we will be adding to it */
+    for (ltfatInt ii=0; ii<M*N*W; ii++)
+    {
+        cout[ii] = (LTFAT_COMPLEX) 0.0;
+    }
+
+    for (ltfatInt ii=0; ii<Nb; ii++)
+    {
+        ltfatInt s_ii;
+
+        /* Copy to working buffer. */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            memcpy(plan.buf+Lext*w,f+ii*bl+w*L,sizeof(LTFAT_COMPLEX)*bl);
+        }
+
+        /* Execute the short DGT */
+        LTFAT_NAME(dgt_shear_execute)(plan.plan);
+
+        /* Place the results */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            /* Place large block */
+            LTFAT_COMPLEX *cout_p = cout +      ii*M*Nblock+w*M*N ;
+            LTFAT_COMPLEX *cbuf_p = plan.cbuf +  w*M*Nblocke;
+            for (ltfatInt m=0; m<M; m++)
+            {
+                for (ltfatInt n=0; n<Nblock; n++)
+                {
+                    cout_p[m+n*M] += cbuf_p[m+n*M];
+                }
+            }
+
+            /* Small block + */
+            s_ii=positiverem(ii+1,Nb);
+            cout_p = cout + s_ii*M*Nblock+w*M*N ;
+            cbuf_p = plan.cbuf +      M*Nblock+w*M*Nblocke;
+            for (ltfatInt m=0; m<M; m++)
+            {
+                for (ltfatInt n=0; n<b2; n++)
+                {
+                    cout_p[m+n*M] += cbuf_p[m+n*M];
+                }
+            }
+
+
+            /* Small block - */
+            s_ii=positiverem(ii-1,Nb)+1;
+            cout_p = cout + M*(s_ii*Nblock-b2)+w*M*N ;
+            cbuf_p = plan.cbuf + M*(Nblock+b2)     +w*M*Nblocke;
+            for (ltfatInt m=0; m<M; m++)
+            {
+                for (ltfatInt n=0; n<b2; n++)
+                {
+                    cout_p[m+n*M] += cbuf_p[m+n*M];
+                }
+            }
+
+        }
+
+    }
+
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shearola_done)(LTFAT_NAME(dgt_shearola_plan) plan)
+{
+    LTFAT_NAME(dgt_shear_done)(plan.plan);
+
+    /* ltfat_free(plan.cbuf); */
+
+    LTFAT_SAFEFREEALL(plan.gext,plan.buf);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shearola)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                         const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                         const ltfatInt s0, const ltfatInt s1, const ltfatInt br, const ltfatInt bl,
+                         LTFAT_COMPLEX *cout)
+{
+
+    LTFAT_NAME(dgt_shearola_plan) plan = LTFAT_NAME(dgt_shearola_init)(
+            g,gl,W,a,M,s0,s1,br,bl,FFTW_ESTIMATE);
+
+    LTFAT_NAME(dgt_shearola_execute)(plan,f,L,cout);
+
+    LTFAT_NAME(dgt_shearola_done)(plan);
+
+}
diff --git a/src/dgt_walnut.c b/src/dgt_walnut.c
new file mode 100644
index 0000000..79b57b3
--- /dev/null
+++ b/src/dgt_walnut.c
@@ -0,0 +1,672 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+/*  This routine computes the DGT factorization using strided FFTs so
+    the memory layout is optimized for the matrix product. Compared to
+    dgt_fac_1, it moves the r-loop to be the outermost loop to
+    conserve memory and hopefully use the cache hierachy better
+
+    The routine uses a very small buffer to do the DFTs.
+
+    Integer indexing is optimized.
+
+    Special code for integer oversampling.
+
+    Code works on LTFAT_REAL's instead on LTFAT_COMPLEX
+*/
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_walnut_plan)(LTFAT_NAME(dgt_long_plan) plan)
+{
+
+    /*  --------- initial declarations -------------- */
+
+    LTFAT_REAL *gbase, *fbase, *cbase;
+
+    ltfatInt rem;
+
+    LTFAT_REAL *ffp, *fp, *cfp;
+
+    /*  ----------- calculation of parameters and plans -------- */
+
+    const ltfatInt a=plan.a;
+    const ltfatInt M=plan.M;
+    const ltfatInt L=plan.L;
+    const ltfatInt W=plan.W;
+    const ltfatInt N=L/a;
+    const ltfatInt c=plan.c;
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=N/q;
+
+    const LTFAT_COMPLEX *f = plan.f;
+    const LTFAT_COMPLEX *gf = (const LTFAT_COMPLEX *)plan.gf;
+
+    const ltfatInt h_a=plan.h_a;
+
+    LTFAT_REAL *sbuf=plan.sbuf;
+    LTFAT_COMPLEX *cout=plan.cout;
+
+    /* Scaling constant needed because of FFTWs normalization. */
+    const LTFAT_REAL scalconst=1.0/((LTFAT_REAL)d*sqrt((LTFAT_REAL)M));
+
+    /* Leading dimensions of the 4dim array. */
+    const ltfatInt ld2a=2*p*q*W;
+
+    /* Leading dimensions of cf */
+    const ltfatInt ld3b=2*q*q*W;
+    const ltfatInt ld5c=M*N;
+
+    /* --------- main loop begins here ------------------- */
+    for (ltfatInt r=0; r<c; r++)
+    {
+
+
+        /*  ---------- compute signal factorization ----------- */
+        ffp=plan.ff;
+        fp=(LTFAT_REAL*)f+2*r;
+        if (p==1)
+        {
+            /* Integer oversampling case */
+
+            for (ltfatInt w=0; w<W; w++)
+            {
+                for (ltfatInt l=0; l<q; l++)
+                {
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        rem = 2*((s*M+l*a)%L);
+                        sbuf[2*s]   = fp[rem];
+                        sbuf[2*s+1] = fp[rem+1];
+                    }
+
+                    LTFAT_FFTW(execute)(plan.p_before);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        ffp[s*ld2a]   = sbuf[2*s]*scalconst;
+                        ffp[s*ld2a+1] = sbuf[2*s+1]*scalconst;
+                    }
+                    ffp+=2;
+                }
+                fp+=2*L;
+            }
+            fp-=2*L*W;
+
+            /* Do the Matmul */
+            for (ltfatInt s=0; s<d; s++)
+            {
+                gbase=(LTFAT_REAL*)gf+2*(r+s*c)*q;
+                fbase=plan.ff+2*s*q*W;
+                cbase=plan.cf+2*s*q*q*W;
+
+                for (ltfatInt nm=0; nm<q*W; nm++)
+                {
+                    for (ltfatInt mm=0; mm<q; mm++)
+                    {
+                        cbase[0]=gbase[0]*fbase[0]+gbase[1]*fbase[1];
+                        cbase[1]=gbase[0]*fbase[1]-gbase[1]*fbase[0];
+                        gbase+=2;
+                        cbase+=2;
+                    }
+                    gbase-=2*q;
+                    fbase+=2;
+                }
+                cbase-=2*q*q*W;
+            }
+
+
+        }
+        else
+        {
+            /* rational sampling case */
+
+            for (ltfatInt w=0; w<W; w++)
+            {
+                for (ltfatInt l=0; l<q; l++)
+                {
+                    for (ltfatInt k=0; k<p; k++)
+                    {
+                        for (ltfatInt s=0; s<d; s++)
+                        {
+                            rem = 2*positiverem(k*M+s*p*M-l*h_a*a, L);
+                            sbuf[2*s]   = fp[rem];
+                            sbuf[2*s+1] = fp[rem+1];
+                        }
+
+                        LTFAT_FFTW(execute)(plan.p_before);
+
+                        for (ltfatInt s=0; s<d; s++)
+                        {
+                            ffp[s*ld2a]   = sbuf[2*s]*scalconst;
+                            ffp[s*ld2a+1] = sbuf[2*s+1]*scalconst;
+                        }
+                        ffp+=2;
+                    }
+                }
+                fp+=2*L;
+            }
+            fp-=2*L*W;
+
+            for (ltfatInt s=0; s<d; s++)
+            {
+                gbase=(LTFAT_REAL*)gf+2*(r+s*c)*p*q;
+                fbase=plan.ff+2*s*p*q*W;
+                cbase=plan.cf+2*s*q*q*W;
+
+                for (ltfatInt nm=0; nm<q*W; nm++)
+                {
+                    for (ltfatInt mm=0; mm<q; mm++)
+                    {
+                        cbase[0]=0.0;
+                        cbase[1]=0.0;
+                        for (ltfatInt km=0; km<p; km++)
+                        {
+                            cbase[0]+=gbase[0]*fbase[0]+gbase[1]*fbase[1];
+                            cbase[1]+=gbase[0]*fbase[1]-gbase[1]*fbase[0];
+                            gbase+=2;
+                            fbase+=2;
+                        }
+                        fbase-=2*p;
+                        cbase+=2;
+                    }
+                    gbase-=2*q*p;
+                    fbase+=2*p;
+                }
+                cbase-=2*q*q*W;
+                fbase-=2*p*q*W;
+            }
+
+        } /* end of if p==1 */
+
+        /*  -------  compute inverse coefficient factorization ------- */
+        cfp=plan.cf;
+
+        /* Cover both integer and rational sampling case */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            /* Complete inverse fac of coefficients */
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt u=0; u<q; u++)
+                {
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        sbuf[2*s]   = cfp[s*ld3b];
+                        sbuf[2*s+1] = cfp[s*ld3b+1];
+                    }
+                    cfp+=2;
+
+                    /* Do inverse fft of length d */
+                    LTFAT_FFTW(execute)(plan.p_after);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        rem= r+l*c+positiverem(u+s*q-l*h_a,N)*M+w*ld5c;
+                        LTFAT_REAL* coutTmp = (LTFAT_REAL*) &cout[rem];
+                        coutTmp[0]=sbuf[2*s];
+                        coutTmp[1]=sbuf[2*s+1];
+                    }
+                }
+            }
+        }
+
+
+        /* ----------- Main loop ends here ------------------------ */
+    }
+
+}
+
+
+
+
+/* -------------- Real valued signal ------------------------ */
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_walnut_r)(const LTFAT_REAL *f, const LTFAT_COMPLEX *gf,
+                         const ltfatInt L,
+                         const ltfatInt W, const ltfatInt a,
+                         const ltfatInt M, LTFAT_COMPLEX *cout)
+{
+
+    /*  --------- initial declarations -------------- */
+
+    ltfatInt b, N, c, d, p, q, h_a, h_m;
+
+    LTFAT_REAL *gbase, *fbase, *cbase;
+
+    ltfatInt l, k, r, s, u, w, nm, mm, km;
+    ltfatInt ld2a, ld3b;
+    ltfatInt rem;
+
+    LTFAT_FFTW(plan) p_before, p_after;
+    LTFAT_REAL *ff, *cf, *ffp, *sbuf, *cfp;
+
+    const LTFAT_REAL *fp;
+
+
+
+    LTFAT_REAL scalconst;
+
+    /*  ----------- calculation of parameters and plans -------- */
+
+    b=L/M;
+    N=L/a;
+
+    c=gcd(a, M,&h_a, &h_m);
+    p=a/c;
+    q=M/c;
+    d=b/p;
+
+    h_a=-h_a;
+
+    /* Scaling constant needed because of FFTWs normalization. */
+    scalconst=1.0/((LTFAT_REAL)d*sqrt((LTFAT_REAL)M));
+
+    ff = (LTFAT_REAL*)ltfat_malloc(2*d*p*q*W*sizeof(LTFAT_REAL));
+    cf = (LTFAT_REAL*)ltfat_malloc(2*d*q*q*W*sizeof(LTFAT_REAL));
+    sbuf = (LTFAT_REAL*)ltfat_malloc(2*d*sizeof(LTFAT_REAL));
+
+    /* Create plans. In-place. */
+
+    p_before = LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)sbuf, (LTFAT_COMPLEX*)sbuf,
+                                       FFTW_FORWARD, FFTW_ESTIMATE);
+
+    p_after  = LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)sbuf, (LTFAT_COMPLEX*)sbuf,
+                                       FFTW_BACKWARD, FFTW_ESTIMATE);
+
+    /* Leading dimensions of the 4dim array. */
+    ld2a=2*p*q*W;
+
+    /* Leading dimensions of cf */
+    ld3b=2*q*q*W;
+
+    /* --------- main loop begins here ------------------- */
+    for (r=0; r<c; r++)
+    {
+        /*  ---------- compute signal factorization ----------- */
+        ffp=ff;
+        fp=f+r;
+        if (p==1)
+        {
+            /* Integer oversampling case */
+            for (w=0; w<W; w++)
+            {
+                for (l=0; l<q; l++)
+                {
+                    for (s=0; s<d; s++)
+                    {
+                        rem = (s*M+l*a)%L;
+                        sbuf[2*s]   = fp[rem];
+                        sbuf[2*s+1] = 0.0;
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (s=0; s<d; s++)
+                    {
+                        ffp[s*ld2a]   = sbuf[2*s]*scalconst;
+                        ffp[s*ld2a+1] = sbuf[2*s+1]*scalconst;
+                    }
+                    ffp+=2;
+                }
+                fp+=L;
+            }
+            fp-=2*L*W;
+        }
+        else
+        {
+            /* rational sampling case */
+
+            for (w=0; w<W; w++)
+            {
+                for (l=0; l<q; l++)
+                {
+                    for (k=0; k<p; k++)
+                    {
+                        for (s=0; s<d; s++)
+                        {
+                            rem = positiverem(k*M+s*p*M-l*h_a*a, L);
+                            sbuf[2*s]   = fp[rem];
+                            sbuf[2*s+1] = 0.0;
+                        }
+
+                        LTFAT_FFTW(execute)(p_before);
+
+                        for (s=0; s<d; s++)
+                        {
+                            ffp[s*ld2a]   = sbuf[2*s]*scalconst;
+                            ffp[s*ld2a+1] = sbuf[2*s+1]*scalconst;
+                        }
+                        ffp+=2;
+                    }
+                }
+                fp+=L;
+            }
+            fp-=2*L*W;
+        }
+
+        /* ----------- compute matrix multiplication ----------- */
+
+        /* Do the matmul  */
+        if (p==1)
+        {
+            /* Integer oversampling case */
+
+
+            /* Rational oversampling case */
+            for (s=0; s<d; s++)
+            {
+                gbase=(LTFAT_REAL*)gf+2*(r+s*c)*q;
+                fbase=ff+2*s*q*W;
+                cbase=cf+2*s*q*q*W;
+
+                for (nm=0; nm<q*W; nm++)
+                {
+                    for (mm=0; mm<q; mm++)
+                    {
+                        cbase[0]=gbase[0]*fbase[0]+gbase[1]*fbase[1];
+                        cbase[1]=gbase[0]*fbase[1]-gbase[1]*fbase[0];
+                        gbase+=2;
+                        cbase+=2;
+                    }
+                    gbase-=2*q;
+                    fbase+=2;
+                }
+                cbase-=2*q*q*W;
+            }
+
+        }
+        else
+        {
+
+            /* Rational oversampling case */
+            for (s=0; s<d; s++)
+            {
+                gbase=(LTFAT_REAL*)gf+2*(r+s*c)*p*q;
+                fbase=ff+2*s*p*q*W;
+                cbase=cf+2*s*q*q*W;
+
+                for (nm=0; nm<q*W; nm++)
+                {
+                    for (mm=0; mm<q; mm++)
+                    {
+                        cbase[0]=0.0;
+                        cbase[1]=0.0;
+                        for (km=0; km<p; km++)
+                        {
+                            cbase[0]+=gbase[0]*fbase[0]+gbase[1]*fbase[1];
+                            cbase[1]+=gbase[0]*fbase[1]-gbase[1]*fbase[0];
+                            gbase+=2;
+                            fbase+=2;
+                        }
+                        fbase-=2*p;
+                        cbase+=2;
+                    }
+                    gbase-=2*q*p;
+                    fbase+=2*p;
+                }
+                cbase-=2*q*q*W;
+                fbase-=2*p*q*W;
+            }
+        }
+
+
+
+        /*  -------  compute inverse coefficient factorization ------- */
+        cfp=cf;
+        const ltfatInt ld5c=M*N;
+
+        /* Cover both integer and rational sampling case */
+        for (w=0; w<W; w++)
+        {
+            /* Complete inverse fac of coefficients */
+            for (l=0; l<q; l++)
+            {
+                for (u=0; u<q; u++)
+                {
+                    for (s=0; s<d; s++)
+                    {
+                        sbuf[2*s]   = cfp[s*ld3b];
+                        sbuf[2*s+1] = cfp[s*ld3b+1];
+                    }
+                    cfp+=2;
+
+                    /* Do inverse fft of length d */
+                    LTFAT_FFTW(execute)(p_after);
+
+                    for (s=0; s<d; s++)
+                    {
+                        rem= r+l*c+positiverem(u+s*q-l*h_a,N)*M+w*ld5c;
+                        LTFAT_REAL* coutTmp = (LTFAT_REAL*) &cout[rem];
+                        coutTmp[0]=sbuf[2*s];
+                        coutTmp[1]=sbuf[2*s+1];
+
+                    }
+                }
+            }
+        }
+
+
+        /* ----------- Main loop ends here ------------------------ */
+    }
+
+    /* -----------  Clean up ----------------- */
+    LTFAT_FFTW(destroy_plan)(p_before);
+    LTFAT_FFTW(destroy_plan)(p_after);
+
+    LTFAT_SAFEFREEALL(sbuf,ff,cf);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_walnut_plan)(LTFAT_NAME(dgtreal_long_plan) plan)
+{
+    /*  --------- initial declarations -------------- */
+
+    const ltfatInt a=plan.a;
+    const ltfatInt M=plan.M;
+    const ltfatInt L=plan.L;
+    const ltfatInt W=plan.W;
+    const ltfatInt N=L/a;
+    const ltfatInt c=plan.c;
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=N/q;
+
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    const LTFAT_REAL *f = plan.f;
+    const LTFAT_COMPLEX *gf = (const LTFAT_COMPLEX *)plan.gf;
+
+    const ltfatInt h_a=plan.h_a;
+
+    LTFAT_REAL *sbuf=plan.sbuf;
+    LTFAT_COMPLEX *cbuf=plan.cbuf;
+
+    LTFAT_REAL *cout=plan.cwork;
+
+
+    LTFAT_REAL *gbase, *fbase, *cbase;
+
+    LTFAT_REAL *ffp;
+
+    const LTFAT_REAL *fp;
+
+    /* Scaling constant needed because of FFTWs normalization. */
+    const LTFAT_REAL scalconst=1.0/((LTFAT_REAL)d*sqrt((LTFAT_REAL)M));
+
+    /* Leading dimensions of the 4dim array. */
+    const ltfatInt ld2a=2*p*q*W;
+
+    /* Leading dimensions of cf */
+    const ltfatInt ld3b=2*q*q*W;
+
+    /* --------- main loop begins here ------------------- */
+    for (ltfatInt r=0; r<c; r++)
+    {
+        /*  ---------- compute signal factorization ----------- */
+        ffp=plan.ff;
+        fp=f+r;
+        if (p==1)
+        {
+            /* Integer oversampling case */
+            for (ltfatInt w=0; w<W; w++)
+            {
+                for (ltfatInt l=0; l<q; l++)
+                {
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        sbuf[s]   = fp[(s*M+l*a)%L];
+                    }
+
+                    LTFAT_FFTW(execute)(plan.p_before);
+
+                    for (ltfatInt s=0; s<d2; s++)
+                    {
+                        ffp[s*ld2a]   = LTFAT_COMPLEXH(creal)(cbuf[s])*scalconst;
+                        ffp[s*ld2a+1] = LTFAT_COMPLEXH(cimag)(cbuf[s])*scalconst;
+                    }
+                    ffp+=2;
+                }
+                fp+=L;
+            }
+            fp-=2*L*W;
+        }
+        else
+        {
+            /* rational sampling case */
+
+            for (ltfatInt w=0; w<W; w++)
+            {
+                for (ltfatInt l=0; l<q; l++)
+                {
+                    for (ltfatInt k=0; k<p; k++)
+                    {
+                        for (ltfatInt s=0; s<d; s++)
+                        {
+                            sbuf[s]   = fp[ positiverem(k*M+s*p*M-l*h_a*a, L) ];
+                        }
+
+                        LTFAT_FFTW(execute)(plan.p_before);
+
+                        for (ltfatInt s=0; s<d2; s++)
+                        {
+                            ffp[s*ld2a]   = LTFAT_COMPLEXH(creal)(cbuf[s])*scalconst;
+                            ffp[s*ld2a+1] = LTFAT_COMPLEXH(cimag)(cbuf[s])*scalconst;
+                        }
+                        ffp+=2;
+                    }
+                }
+                fp+=L;
+            }
+            fp-=2*L*W;
+        }
+
+        /* ----------- compute matrix multiplication ----------- */
+
+        /* Do the matmul  */
+        if (p==1)
+        {
+            /* Integer oversampling case */
+
+
+            /* Rational oversampling case */
+            for (ltfatInt s=0; s<d2; s++)
+            {
+                gbase=(LTFAT_REAL*)gf+2*(r+s*c)*q;
+                fbase=plan.ff+2*s*q*W;
+                cbase=plan.cf+2*s*q*q*W;
+
+                for (ltfatInt nm=0; nm<q*W; nm++)
+                {
+                    for (ltfatInt mm=0; mm<q; mm++)
+                    {
+                        cbase[0]=gbase[0]*fbase[0]+gbase[1]*fbase[1];
+                        cbase[1]=gbase[0]*fbase[1]-gbase[1]*fbase[0];
+                        gbase+=2;
+                        cbase+=2;
+                    }
+                    gbase-=2*q;
+                    fbase+=2;
+                }
+                cbase-=2*q*q*W;
+            }
+
+        }
+        else
+        {
+
+            /* Rational oversampling case */
+            for (ltfatInt s=0; s<d2; s++)
+            {
+                gbase=(LTFAT_REAL*)gf+2*(r+s*c)*p*q;
+                fbase=plan.ff+2*s*p*q*W;
+                cbase=plan.cf+2*s*q*q*W;
+
+                for (ltfatInt nm=0; nm<q*W; nm++)
+                {
+                    for (ltfatInt mm=0; mm<q; mm++)
+                    {
+                        cbase[0]=0.0;
+                        cbase[1]=0.0;
+                        for (ltfatInt km=0; km<p; km++)
+                        {
+                            cbase[0]+=gbase[0]*fbase[0]+gbase[1]*fbase[1];
+                            cbase[1]+=gbase[0]*fbase[1]-gbase[1]*fbase[0];
+                            gbase+=2;
+                            fbase+=2;
+                        }
+                        fbase-=2*p;
+                        cbase+=2;
+                    }
+                    gbase-=2*q*p;
+                    fbase+=2*p;
+                }
+                cbase-=2*q*q*W;
+                fbase-=2*p*q*W;
+            }
+        }
+
+
+
+        /*  -------  compute inverse coefficient factorization ------- */
+        LTFAT_REAL *cfp=plan.cf;
+        const ltfatInt ld5c=M*N;
+
+        /* Cover both integer and rational sampling case */
+        for (ltfatInt w=0; w<W; w++)
+        {
+            /* Complete inverse fac of coefficients */
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt u=0; u<q; u++)
+                {
+                    for (ltfatInt s=0; s<d2; s++)
+                    {
+                        LTFAT_REAL* cbufTmp = (LTFAT_REAL*) &cbuf[s];
+                        cbufTmp[0] = cfp[s*ld3b];
+                        cbufTmp[1] = cfp[s*ld3b+1];
+                    }
+                    cfp+=2;
+
+                    /* Do inverse fft of length d */
+                    LTFAT_FFTW(execute)(plan.p_after);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        cout[ r+l*c+positiverem(u+s*q-l*h_a,N)*M+w*ld5c ]=sbuf[s];
+                    }
+                }
+            }
+        }
+
+
+        /* ----------- Main loop ends here ------------------------ */
+    }
+
+}
diff --git a/src/dgtreal_fac.c b/src/dgtreal_fac.c
new file mode 100644
index 0000000..61ba61f
--- /dev/null
+++ b/src/dgtreal_fac.c
@@ -0,0 +1,92 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN LTFAT_NAME(dgtreal_long_plan)
+LTFAT_NAME(dgtreal_long_init)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                              const ltfatInt L, const ltfatInt W,
+                              const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *cout,
+                              unsigned flags)
+{
+
+    LTFAT_NAME(dgtreal_long_plan) plan;
+    ltfatInt h_m;
+
+    plan.a=a;
+    plan.M=M;
+    plan.L=L;
+    plan.W=W;
+    const ltfatInt N=L/a;
+
+
+    plan.c=gcd(a, M,&plan.h_a, &h_m);
+    const ltfatInt b=L/M;
+    const ltfatInt p=a/plan.c;
+    const ltfatInt q=M/plan.c;
+    const ltfatInt d=b/p;
+    plan.h_a=-plan.h_a;
+
+    const ltfatInt M2=M/2+1;
+    const ltfatInt d2=d/2+1;
+
+    plan.sbuf = ltfat_malloc( d*sizeof(LTFAT_REAL));
+    plan.cbuf = ltfat_malloc(d2*sizeof(LTFAT_COMPLEX));
+    plan.cout = cout;
+    plan.f    = f;
+
+    plan.ff = ltfat_malloc(2*d2*p*q*W*sizeof(LTFAT_REAL));
+    plan.cf = ltfat_malloc(2*d2*q*q*W*sizeof(LTFAT_REAL));
+
+    const ltfatInt wfs = wfacreal_size(L,a,M);
+
+    plan.gf   = (LTFAT_COMPLEX*)ltfat_malloc(wfs*sizeof(LTFAT_COMPLEX));
+
+    plan.cwork = (LTFAT_REAL*)ltfat_malloc(M*N*W*sizeof(LTFAT_REAL));
+
+    /* Get factorization of window */
+    LTFAT_NAME(wfacreal)(g, L, 1, a, M, plan.gf);
+
+    /* Create plans. In-place. */
+    // Downcast to int
+    int Mint = (int) plan.M;
+
+    plan.p_veryend =
+        LTFAT_FFTW(plan_many_dft_r2c)(1, &Mint, N*W,
+                                      plan.cwork, NULL,
+                                      1, M,
+                                      cout, NULL,
+                                      1, M2,
+                                      flags);
+
+    plan.p_before =
+        LTFAT_FFTW(plan_dft_r2c_1d)(d, plan.sbuf, plan.cbuf, flags);
+
+    plan.p_after  =
+        LTFAT_FFTW(plan_dft_c2r_1d)(d, plan.cbuf, plan.sbuf, flags);
+
+    return plan;
+}
+
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_long_execute)(const LTFAT_NAME(dgtreal_long_plan) plan)
+{
+
+    LTFAT_NAME(dgtreal_walnut_plan)(plan);
+
+    /* FFT to modulate the coefficients. */
+    LTFAT_FFTW(execute)(plan.p_veryend);
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_long_done)(LTFAT_NAME(dgtreal_long_plan) plan)
+{
+    LTFAT_FFTW(destroy_plan)(plan.p_veryend);
+    LTFAT_FFTW(destroy_plan)(plan.p_before);
+    LTFAT_FFTW(destroy_plan)(plan.p_after);
+    LTFAT_SAFEFREEALL(plan.sbuf,plan.cbuf,plan.cwork,plan.gf,plan.ff,plan.cf);
+}
diff --git a/src/drivers.c b/src/drivers.c
new file mode 100644
index 0000000..eeb6abd
--- /dev/null
+++ b/src/drivers.c
@@ -0,0 +1,78 @@
+#include "config.h"
+#include "ltfat.h"
+#include "winmanip.h"
+
+/* Compute canonical dual/tight window. This last parameter
+ * indicates the type: 0 = dual, 1 = tight.
+ */
+void fircanon_r(const double *g, const ltfatInt Lg, const ltfatInt L, const ltfatInt a,
+		const ltfatInt M, double *gdual, const ltfatInt Ldual, const ltfatInt symm,
+		const ltfatInt wintype)
+{
+   
+   double *tmp_fir, *tmp_iir;
+   
+   tmp_fir = (double*)ltfat_malloc(Lg*sizeof(double));
+   tmp_iir = (double*)ltfat_malloc(L*sizeof(double));
+
+   /* Move center of window from the middle of the vector to the beginning. */
+   ifftshift_r(g, Lg, tmp_fir);
+   
+   /* Extend the FIR window to an IIR window. */
+   fir2iir_r(tmp_fir, Lg, L, tmp_iir);
+         
+   if (wintype==0)
+   {
+     gabdualreal_long(g, L, 1, a, M, tmp_iir);
+   }
+   else
+   {
+     gabtightreal_long(g, L, 1, a, M, tmp_iir);
+   }
+      
+   /* Cut dual IIR window to a FIR window. */
+   iir2fir_r(tmp_iir, L, Ldual, symm, tmp_fir);
+   
+   /* Move center of window to the middle of the vector. */
+   fftshift_r(tmp_fir, Ldual, gdual);
+   
+   ltfat_free(gdualf);
+   ltfat_free(gf);
+   ltfat_free(tmp_iir);
+   ltfat_free(tmp_fir);
+
+}
+
+
+/* Driver routine to calculate dual of FIR window. This routine
+ * Input:
+ *          g     : pointer to FIR window
+ *          Lg    : Length of g
+ *          L     : Length of system for which g and gdual should be
+ *                  dual windows.
+ *          a     : Length of time step (hop size)
+ *          M     : Number of channels.
+ *          gdual : pointer to dual window
+ *          Ldual : Length of dual window
+ *          symm  : Symmetry of input window, see the help for iir2fir
+ *
+ */ 
+void firdual_r(const double *g, const ltfatInt Lg, const ltfatInt L, const ltfatInt a,
+		const ltfatInt M, double *gdual, const ltfatInt Ldual, const ltfatInt symm)
+{
+   /* The final 0 indicates that we want the dual window.*/
+   fircanon_r(g, Lg, L, a, M, gdual, Ldual,  symm, 0);
+}
+
+
+/* Driver routine to calculate tight window of FIR window. Same input/output
+ * parameters as firdual_r
+ */
+void firtight_r(const double *g, const ltfatInt Lg, const ltfatInt L, const ltfatInt a,
+		const ltfatInt M, double *gdual, const ltfatInt Ldual, const ltfatInt symm)
+{
+   /* The final 1 indicates that we want the tight window.*/
+   fircanon_r(g, Lg, L, a, M, gdual, Ldual,  symm, 1);
+}
+
+
diff --git a/src/dst.c b/src/dst.c
new file mode 100644
index 0000000..839d49c
--- /dev/null
+++ b/src/dst.c
@@ -0,0 +1,114 @@
+/* NOT PROCESSED DIRECTLY, dst_ci.c */
+#ifdef LTFAT_TYPE
+
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(dst_init)( const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
+                      const dst_kind kind)
+{
+    LTFAT_FFTW(iodim) dims, howmanydims;
+    LTFAT_FFTW(plan) p;
+
+#ifdef LTFAT_COMPLEXTYPE
+    dims.n = L;
+    dims.is = 2;
+    dims.os = 2;
+
+    howmanydims.n = W;
+    howmanydims.is = 2*L;
+    howmanydims.os = 2*L;
+
+    unsigned flag = FFTW_ESTIMATE | FFTW_UNALIGNED;
+#else
+    dims.n = L;
+    dims.is = 1;
+    dims.os = 1;
+
+    howmanydims.n = W;
+    howmanydims.is = L;
+    howmanydims.os = L;
+
+    unsigned flag = FFTW_ESTIMATE;
+#endif
+
+    LTFAT_FFTW(r2r_kind) kindFftw = kind;
+    p = LTFAT_FFTW(plan_guru_r2r)(1, &dims,
+                                  1, &howmanydims,
+                                  (LTFAT_REAL*)cout, (LTFAT_REAL*)cout,
+                                  &kindFftw, flag);
+
+    return p;
+}
+
+
+// f and cout cannot be equal, because creating plan can tamper with the array
+LTFAT_EXTERN void
+LTFAT_NAME(dst)(const LTFAT_TYPE *f, const ltfatInt L, const ltfatInt W,
+                LTFAT_TYPE *cout, const dst_kind kind)
+{
+    LTFAT_FFTW(plan) p = LTFAT_NAME(dst_init)( L, W, cout, kind);
+
+    LTFAT_NAME(dst_execute)(p, f,  L,  W, cout, kind);
+
+    LTFAT_FFTW(destroy_plan)(p);
+}
+
+// f and cout can be equal, provided plan was already created
+LTFAT_EXTERN void
+LTFAT_NAME(dst_execute)(LTFAT_FFTW(plan) p, const LTFAT_TYPE *f,
+                        const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
+                        const dst_kind kind)
+{
+    // Copy input to the output
+    if(cout!=f)
+        memcpy(cout,f,L*W*sizeof*f);
+
+    if(L==1)
+        return;
+
+    ltfatInt N = 2*L;
+    LTFAT_REAL sqrt2 = (LTFAT_REAL) sqrt(2.0);
+    LTFAT_REAL postScale = (LTFAT_REAL) 1.0/sqrt2;
+    LTFAT_REAL scale = (LTFAT_REAL) sqrt2*(1.0/(double)N)*sqrt((double)L);
+
+    if(kind==DSTIII)
+    {
+        for(ltfatInt ii=0; ii<W; ii++)
+        {
+            cout[(ii+1)*L-1] *= sqrt2;
+        }
+    }
+
+    if(kind==DSTI)
+    {
+        N += 2;
+        scale = (LTFAT_REAL) sqrt2*(1.0/((double)N))*sqrt((double)L+1);
+    }
+
+    LTFAT_REAL* c_r = (LTFAT_REAL*)cout;
+
+    LTFAT_FFTW(execute_r2r)(p,c_r,c_r);
+#ifdef LTFAT_COMPLEXTYPE
+    LTFAT_REAL* c_i = c_r+1;
+    LTFAT_FFTW(execute_r2r)(p,c_i,c_i);
+#endif
+
+    // Post-scaling
+    for(ltfatInt ii=0; ii<L*W; ii++)
+    {
+        cout[ii] *= scale;
+    }
+
+    if(kind==DSTII)
+    {
+        // Scale AC component
+        for(ltfatInt ii=0; ii<W; ii++)
+        {
+            cout[(ii+1)*L-1] *= postScale;
+        }
+    }
+}
+
+#endif
diff --git a/src/dst_ci.c b/src/dst_ci.c
new file mode 100644
index 0000000..f3d365b
--- /dev/null
+++ b/src/dst_ci.c
@@ -0,0 +1,11 @@
+#ifdef LTFAT_COMPLEXTYPE
+#  undef LTFAT_COMPLEXTYPE
+#endif // LTFAT_COMPLEXTYPE
+
+#include "ltfat_types.h"
+#include "dst.c"
+
+#define LTFAT_COMPLEXTYPE
+#include "ltfat_types.h"
+#include "dst.c"
+#undef LTFAT_COMPLEXTYPE
diff --git a/src/dwilt.c b/src/dwilt.c
new file mode 100644
index 0000000..5a40b56
--- /dev/null
+++ b/src/dwilt.c
@@ -0,0 +1,152 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#define CH(name) LTFAT_COMPLEXH(name)
+
+#define POSTPROC_REAL \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     pcoef[0]=CH(creal)(pcoef2[0]); \
+\
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+       pcoef[m]=-scalconst*CH(cimag)(pcoef2[m]); \
+       pcoef[m+M]=scalconst*CH(creal)(pcoef2[m+coef2_ld]); \
+     } \
+ \
+     for (ltfatInt m=2;m<M;m+=2) \
+     { \
+       pcoef[m]=scalconst*CH(creal)(pcoef2[m]); \
+       pcoef[m+M]=-scalconst*CH(cimag)(pcoef2[m+coef2_ld]); \
+     } \
+ \
+     pcoef[M]=CH(creal)(pcoef2[M+nyquestadd]); \
+     pcoef+=2*M; \
+     pcoef2+=2*coef2_ld; \
+  }
+
+#define POSTPROC_COMPLEX \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     pcoef[0] = pcoef2[0]; \
+ \
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+       pcoef[m] = scalconst*I*(pcoef2[m]-pcoef2[M2-m]); \
+       pcoef[m+M]=scalconst*(pcoef2[m+M2]+pcoef2[M4-m]); \
+     } \
+ \
+     for (ltfatInt m=2;m<M;m+=2) \
+     { \
+         pcoef[m] = scalconst*(pcoef2[m]+pcoef2[M2-m]); \
+         pcoef[m+M] = scalconst*I*(pcoef2[m+M2]-pcoef2[M4-m]); \
+     } \
+ \
+     pcoef[M]=pcoef2[M+nyquestadd]; \
+     pcoef+=M2; \
+     pcoef2+=M4; \
+  }
+
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dwilt_long)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                               const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                               LTFAT_COMPLEX *cout)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2);
+
+    /* coef2=comp_dgt(f,g,a,2*M,L); */
+    LTFAT_NAME_COMPLEX(dgt_long)(f, g, L, W, M, 2*M, coef2);
+
+    const ltfatInt nyquestadd = (M%2)*M2;
+
+    LTFAT_COMPLEX *pcoef  = cout;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    POSTPROC_COMPLEX
+
+    ltfat_free(coef2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(dwilt_long)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                            const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                            LTFAT_REAL *cout)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt coef2_ld = M+1;
+    const LTFAT_REAL scalconst = sqrt(2.0);
+    const ltfatInt nyquestadd = (M%2)*coef2_ld;
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc((M+1)*N*W*sizeof*coef2);
+
+    /* coef2=comp_dgt(f,g,a,2*M,L); */
+    LTFAT_NAME(dgtreal_long)(f, g, L, W, M, 2*M, coef2);
+
+
+    LTFAT_REAL *pcoef  = cout;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    POSTPROC_REAL
+
+    ltfat_free(coef2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dwilt_fb)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                             const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                             LTFAT_COMPLEX *cout)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2);
+
+    /* coef2=comp_dgt(f,g,a,2*M,L); */
+    LTFAT_NAME_COMPLEX(dgt_fb)(f, g, L, gl, W, M, 2*M, coef2);
+
+    const ltfatInt nyquestadd = (M%2)*M2;
+
+    LTFAT_COMPLEX *pcoef  = cout;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    POSTPROC_COMPLEX
+
+    ltfat_free(coef2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(dwilt_fb)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                          const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                          LTFAT_REAL *cout)
+{
+    const ltfatInt N = L/M;
+    const ltfatInt coef2_ld = M + 1;
+    const ltfatInt nyquestadd = (M%2)*coef2_ld;
+    const LTFAT_REAL scalconst = (LTFAT_REAL) sqrt(2.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc((M+1)*N*W*sizeof*coef2);
+    LTFAT_NAME(dgtreal_fb)(f, g, L, gl, W, M, 2*M, coef2);
+
+    LTFAT_REAL* pcoef  = cout;
+    LTFAT_COMPLEX* pcoef2 = coef2;
+
+    POSTPROC_REAL
+
+    ltfat_free(coef2);
+}
+
+#undef CH
+#undef POSTPROC_REAL
+#undef POSTPROC_COMPLEX
+
diff --git a/src/fftreal.c b/src/fftreal.c
new file mode 100644
index 0000000..6ea6f46
--- /dev/null
+++ b/src/fftreal.c
@@ -0,0 +1,88 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+/**
+* FFreal routines
+*/
+
+LTFAT_EXTERN void
+LTFAT_NAME(fftreal)(LTFAT_REAL *f, const ltfatInt L, const ltfatInt W,
+                    LTFAT_COMPLEX *cout)
+{
+    LTFAT_FFTW(plan) p = LTFAT_NAME(fftreal_init)(f, L, W, cout, FFTW_ESTIMATE);
+    LTFAT_NAME(fftreal_execute)(p,f,cout);
+    LTFAT_FFTW(destroy_plan)(p);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(fftreal_execute)(const LTFAT_FFTW(plan) p, LTFAT_REAL *f,
+                            LTFAT_COMPLEX *cout)
+{
+    LTFAT_FFTW(execute_dft_r2c)(p,f,cout);
+}
+
+
+/*
+* IF anything else than FFTW_ESTIMATE is used for a flag, the planning overwrites input array !
+*/
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(fftreal_init)(LTFAT_REAL *f, const ltfatInt L, const ltfatInt W,
+                         LTFAT_COMPLEX *cout, unsigned flag)
+{
+    ltfatInt L2 = (L/2)+1;
+    int ltfatInt = (int) L;
+    LTFAT_FFTW(plan) p = LTFAT_FFTW(plan_many_dft_r2c)(1, &ltfatInt, W,
+                         f, NULL,
+                         1, L,
+                         cout, NULL,
+                         1, L2,
+                         flag);
+
+    return p;
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifftreal)(LTFAT_COMPLEX *c, const ltfatInt L, const ltfatInt W,
+                     LTFAT_REAL *f)
+{
+    LTFAT_FFTW(plan) p = LTFAT_NAME(ifftreal_init)(c, L, W, f, FFTW_ESTIMATE);
+    LTFAT_NAME(ifftreal_execute)(p,c,L,W,f);
+    LTFAT_FFTW(destroy_plan)(p);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifftreal_execute)(const LTFAT_FFTW(plan) p, LTFAT_COMPLEX *c,
+                             const ltfatInt L, const ltfatInt W,
+                             LTFAT_REAL *f)
+{
+    LTFAT_FFTW(execute_dft_c2r)(p,c,f);
+
+    LTFAT_REAL s  = (LTFAT_REAL) (1.0/L);
+    for (ltfatInt ii=0; ii<L*W; ii++)
+    {
+        f[ii] *=s;
+    }
+}
+
+
+/*
+* IF anything else than FFTW_ESTIMATE is used for a flag, the planning overwrites input array !
+*/
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(ifftreal_init)(LTFAT_COMPLEX *c, const ltfatInt L, const ltfatInt W,
+                          LTFAT_REAL *f, unsigned flag)
+{
+    ltfatInt L2 = (L/2)+1;
+    int ltfatInt = (int) L;
+    LTFAT_FFTW(plan) p = LTFAT_FFTW(plan_many_dft_c2r)(1, &ltfatInt, W,
+                         c, NULL,
+                         1, L2,
+                         f, NULL,
+                         1, L,
+                         flag);
+
+    return p;
+}
+
+
diff --git a/src/filedefs.mk b/src/filedefs.mk
new file mode 100644
index 0000000..19944f0
--- /dev/null
+++ b/src/filedefs.mk
@@ -0,0 +1,12 @@
+files = dgt.o dgt_fac.o dgt_fb.o dgt_multi.o dgt_ola.o dgt_shear.o	\
+  dgt_walnut.o dgtreal_fac.o dwilt.o idwilt.o wmdct.o iwmdct.o filterbank.o ifilterbank.o heapint.o		\
+  idgt.o idgt_fac.o idgt_fb.o iwfac.o pfilt.o reassign.o	\
+  spread.o wfac.o windows.o winmanip.o ltfat_complexindependent.o \
+  dgt_shearola.o dct_ci.o dst_ci.o fftreal.o 
+
+files_blaslapack = \
+	ltfat_blaslapack.o gabdual_fac.o gabtight_fac.o ltfat_complexindependent_bl.o
+
+
+files_notypechange = c-safe-memalloc.o integer_manip.o
+
diff --git a/src/filterbank.c b/src/filterbank.c
new file mode 100644
index 0000000..41f984e
--- /dev/null
+++ b/src/filterbank.c
@@ -0,0 +1,396 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+/**
+* FFT filterbank routines
+*/
+
+struct LTFAT_NAME(convsub_fft_plan_struct)
+{
+    const ltfatInt L;
+    const ltfatInt W;
+    const ltfatInt a;
+    const LTFAT_FFTW(plan) p_c;
+};
+
+struct LTFAT_NAME(convsub_fftbl_plan_struct)
+{
+    const ltfatInt L;
+    const ltfatInt Gl;
+    const ltfatInt W;
+    const double a;
+    const LTFAT_FFTW(plan) p_c;
+    LTFAT_COMPLEX* buf;
+    const ltfatInt bufLen;
+};
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fft)(const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G[],
+                           const ltfatInt L, const ltfatInt W, const ltfatInt a[], const ltfatInt M,
+                           LTFAT_COMPLEX *cout[])
+{
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(convsub_fft)(F,G[m],L,W,a[m],cout[m]);
+    }
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fft_execute)(LTFAT_NAME(convsub_fft_plan) p[],
+                                   const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G[],
+                                   const ltfatInt M, LTFAT_COMPLEX *cout[])
+{
+
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(convsub_fft_execute)(p[m],F,G[m],cout[m]);
+    }
+}
+
+
+LTFAT_EXTERN LTFAT_NAME(convsub_fft_plan)
+LTFAT_NAME(convsub_fft_init)(const ltfatInt L, const ltfatInt W,
+                             const ltfatInt a, const LTFAT_COMPLEX *cout)
+{
+    const ltfatInt N = L/a;
+
+    int Nint = (int) N;
+
+    const LTFAT_FFTW(iodim) dims = {.n = Nint, .is = 1, .os = 1};
+    const LTFAT_FFTW(iodim) howmany_dims = {.n = W,.is = Nint, .os = Nint};
+
+    LTFAT_COMPLEX* coutNc = (LTFAT_COMPLEX*) cout;
+    LTFAT_FFTW(plan) p_many =
+        LTFAT_FFTW(plan_guru_dft)(1, &dims, 1, &howmany_dims,
+                                  coutNc, coutNc,
+                                  FFTW_BACKWARD, FFTW_ESTIMATE);
+
+
+    struct LTFAT_NAME(convsub_fft_plan_struct) p_struct =
+    { .L = L, .a = a, .W = W, .p_c = p_many };
+
+    LTFAT_NAME(convsub_fft_plan) p = ltfat_malloc(sizeof*p);
+    memcpy(p,&p_struct,sizeof*p);
+    return p;
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fft_done)(LTFAT_NAME(convsub_fft_plan) p)
+{
+    LTFAT_FFTW(destroy_plan)(p->p_c);
+    ltfat_free(p);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fft_execute)(const LTFAT_NAME(convsub_fft_plan) p,
+                                const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G,
+                                LTFAT_COMPLEX *cout)
+{
+    const ltfatInt L = p->L;
+    const ltfatInt W = p->W;
+    const ltfatInt a = p->a;
+    const ltfatInt N = L/a;
+    const LTFAT_REAL scalconst = (LTFAT_REAL) (1.0/L);
+
+    memset(cout,0,W*N*sizeof*cout);
+
+    for(ltfatInt w=0; w<W; w++)
+    {
+        LTFAT_COMPLEX* GPtrTmp = (LTFAT_COMPLEX*) G;
+        LTFAT_COMPLEX* FPtrTmp = (LTFAT_COMPLEX*) (F + w*L);
+        for(ltfatInt jj=0; jj<a; jj++)
+        {
+            for(ltfatInt n=0; n<N; n++)
+            {
+                cout[w*N+n] += *GPtrTmp++**FPtrTmp++;
+            }
+        }
+    }
+
+    for(ltfatInt ii=0; ii<N*W; ii++)
+    {
+        cout[ii] *= scalconst;
+    }
+
+    LTFAT_FFTW(execute_dft)(p->p_c,cout,cout);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fft)(const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G,
+                        const ltfatInt L, const ltfatInt W,
+                        const ltfatInt a, LTFAT_COMPLEX *cout)
+{
+    LTFAT_NAME(convsub_fft_plan) p = LTFAT_NAME(convsub_fft_init)(L,W,a,cout);
+    LTFAT_NAME(convsub_fft_execute)(p,F,G,cout);
+    LTFAT_NAME(convsub_fft_done)(p);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fftbl)(const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G[],
+                             const ltfatInt L, const ltfatInt Gl[],
+                             const ltfatInt W, const double a[], const ltfatInt M,
+                             const ltfatInt foff[], const int realonly[],
+                             LTFAT_COMPLEX *cout[])
+{
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(convsub_fftbl)(F,G[m],L,Gl[m],W,a[m],
+                                  foff[m],realonly[m],cout[m]);
+    }
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fftbl_execute)(LTFAT_NAME(convsub_fftbl_plan) p[],
+                                     const LTFAT_COMPLEX *F,
+                                     const LTFAT_COMPLEX *G[],
+                                     const ltfatInt M, const ltfatInt foff[],
+                                     const int realonly[], LTFAT_COMPLEX *cout[])
+{
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(convsub_fftbl_execute)(p[m],F,G[m],foff[m],realonly[m],cout[m]);
+    }
+
+}
+
+
+LTFAT_EXTERN LTFAT_NAME(convsub_fftbl_plan)
+LTFAT_NAME(convsub_fftbl_init)( const ltfatInt L, const ltfatInt Gl,
+                                const ltfatInt W, const double a,
+                                const LTFAT_COMPLEX *cout)
+{
+    const ltfatInt N = (ltfatInt) floor(L/a + 0.5);
+
+    int Nint = (int) N;
+
+    const LTFAT_FFTW(iodim) dims = {.n = Nint, .is = 1, .os = 1};
+    const LTFAT_FFTW(iodim) howmany_dims = {.n = W,.is = Nint, .os = Nint};
+
+   LTFAT_COMPLEX *coutNc = (LTFAT_COMPLEX *) cout;
+    LTFAT_FFTW(plan) p_many =
+        LTFAT_FFTW(plan_guru_dft)(1, &dims, 1, &howmany_dims,
+                                  coutNc, coutNc,
+                                  FFTW_BACKWARD, FFTW_ESTIMATE);
+
+    const ltfatInt bufLen = (ltfatInt) ceil(Gl/((double)N))*N;
+    LTFAT_COMPLEX *buf = ltfat_malloc(bufLen*sizeof*buf);
+
+    struct LTFAT_NAME(convsub_fftbl_plan_struct) p_struct =
+    {
+        .L = L, .Gl = Gl, .a = a, .W = W, .p_c = p_many , .bufLen = bufLen,
+        .buf = buf
+    };
+
+    LTFAT_NAME(convsub_fftbl_plan) p = ltfat_malloc(sizeof*p);
+    memcpy(p,&p_struct,sizeof*p);
+    return p;
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fftbl_done)( LTFAT_NAME(convsub_fftbl_plan) p)
+{
+    LTFAT_FFTW(destroy_plan)(p->p_c);
+    ltfat_free(p->buf);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fftbl_execute)(const LTFAT_NAME(convsub_fftbl_plan) p,
+                                  const LTFAT_COMPLEX *F,
+                                  const LTFAT_COMPLEX *G,
+                                  const ltfatInt foff,
+                                  const int realonly,
+                                  LTFAT_COMPLEX *cout)
+{
+    const ltfatInt L = p->L;
+    const ltfatInt Gl = p->Gl;
+    const ltfatInt W = p->W;
+    const double a = p->a;
+    LTFAT_COMPLEX* tmp = p->buf;
+    const ltfatInt tmpLen = p->bufLen;
+    // Output length
+    const ltfatInt N = (ltfatInt) floor(L/a + 0.5);
+    //const ltfatInt tmpLen = (ltfatInt) ceil(Gl/((double)N))*N;
+    const LTFAT_REAL scalconst = (LTFAT_REAL) 1.0/(L);
+    // LTFAT_COMPLEX *tmp = ltfat_calloc(tmpLen,sizeof*tmp);
+
+    for(ltfatInt w=0; w<W; w++)
+    {
+        // First Gl elements of tmp is copied from F so,
+        // zero only the part which wont be written to.
+        memset(tmp+Gl,0,(tmpLen-Gl)*sizeof*tmp);
+        LTFAT_COMPLEX *tmpPtr = tmp;
+        ltfatInt foffTmp = foff;
+        ltfatInt tmpLg = Gl;
+
+        // Copy samples of F according to range of G
+        if(foffTmp<0)
+        {
+            ltfatInt toCopy = imin(-foffTmp,tmpLg);
+            memcpy(tmpPtr,F+(w+1)*L+foffTmp,toCopy*sizeof*F);
+            tmpPtr+=toCopy;
+            tmpLg-=toCopy;
+            foffTmp = 0;
+        }
+
+        if(foffTmp+tmpLg>L)
+        {
+            ltfatInt over = foffTmp+tmpLg - L;
+            memcpy(tmpPtr+Gl-over,F+w*L,over*sizeof*F);
+            tmpLg -=over;
+        }
+
+        memcpy(tmpPtr,F+w*L+foffTmp,tmpLg*sizeof*F);
+
+        // Do the filtering
+        for(ltfatInt ii=0; ii<Gl; ii++)
+        {
+            tmp[ii] *= G[ii];
+        }
+
+        // Do the folding
+        for(ltfatInt jj=1; jj<tmpLen/N; jj++)
+        {
+            for(ltfatInt ii=0; ii<N; ii++)
+            {
+                tmp[ii] += tmp[jj*N+ii];
+            }
+        }
+
+        // Do the circshift
+         LTFAT_NAME_COMPLEX(circshift)(tmp,cout+w*N,N,foff);
+        //LTFAT_NAME_COMPLEX(circshift)(tmp,cout+w*N,N,-Gl/2);
+        // memcpy(cout+w*N,tmp,N*sizeof*cout);
+    }
+
+    for(ltfatInt ii=0; ii<W*N; ii++)
+    {
+        cout[ii] *= scalconst;
+    }
+
+    // ifft
+    LTFAT_FFTW(execute_dft)(p->p_c,cout,cout);
+
+
+    if(realonly)
+    {
+        // Involute the filter and call the function again
+        const ltfatInt foffconj = positiverem(L-foff-Gl,L)+1;
+        LTFAT_COMPLEX *Gconj = ltfat_malloc(Gl*sizeof*Gconj);
+        LTFAT_COMPLEX *cout2 = ltfat_malloc(W*N*sizeof*cout2);
+        for(ltfatInt ii=0; ii<Gl; ii++)
+        {
+            Gconj[ii] = (LTFAT_COMPLEX) conj((double _Complex)G[Gl-1-ii]);
+        }
+
+        LTFAT_NAME(convsub_fftbl_execute)(p, F, Gconj, foffconj, false, cout2);
+
+        // Scale
+        for(ltfatInt ii=0; ii<W*N; ii++)
+        {
+            cout[ii] = (cout[ii] + cout2[ii])/2.0;
+        }
+        ltfat_free(Gconj);
+        ltfat_free(cout2);
+    }
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fftbl)(const LTFAT_COMPLEX *F,  const LTFAT_COMPLEX *G,
+                          const ltfatInt L, const ltfatInt Gl, const ltfatInt W,
+                          const double a, const ltfatInt foff,
+                          const int realonly, LTFAT_COMPLEX *cout)
+{
+    LTFAT_NAME(convsub_fftbl_plan) p =
+        LTFAT_NAME(convsub_fftbl_init)( L, Gl, W, a, cout);
+
+    LTFAT_NAME(convsub_fftbl_execute)(p, F, G, foff, realonly, cout);
+
+    LTFAT_NAME(convsub_fftbl_done)(p);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(ufilterbank_fft)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                            const ltfatInt L, const ltfatInt Gl,
+                            const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                            LTFAT_COMPLEX *cout)
+{
+
+    /* ----- Initialization ------------ */
+
+    const ltfatInt N=L/a;
+
+    /* Downcasting to ints */
+    int Lint = (int) L;
+    int Nint = (int) N;
+
+    LTFAT_COMPLEX *gwork = (LTFAT_COMPLEX*)ltfat_malloc(L*M*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_COMPLEX *work = (LTFAT_COMPLEX*)ltfat_malloc(L*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_FFTW(plan) plan_g =
+        LTFAT_FFTW(plan_many_dft)(1, &Lint, M,
+                                  gwork, NULL,
+                                  1, Lint,
+                                  gwork, NULL,
+                                  1, Lint,
+                                  FFTW_FORWARD, FFTW_ESTIMATE);
+
+    LTFAT_FFTW(plan_dft_1d)(L, gwork, gwork,
+                            FFTW_FORWARD, FFTW_ESTIMATE);
+
+    LTFAT_FFTW(plan) plan_w =
+        LTFAT_FFTW(plan_dft_1d)(L, work, work,
+                                FFTW_FORWARD, FFTW_ESTIMATE);
+
+    LTFAT_FFTW(plan) plan_c =
+        LTFAT_FFTW(plan_many_dft)(1, &Nint, M*W,
+                                  cout, NULL,
+                                  1, Nint,
+                                  cout, NULL,
+                                  1, Nint,
+                                  FFTW_BACKWARD, FFTW_ESTIMATE);
+
+    const LTFAT_REAL scalconst = 1.0/L;
+
+    /* ----- Main -------------------------- */
+
+    /* Extend g and copy to work buffer */
+    for (ltfatInt m=0; m<M; m++)
+    {
+        LTFAT_NAME(fir2long_c)(g+m*Gl, Gl, L, gwork+m*L);
+    }
+
+    LTFAT_FFTW(execute)(plan_g);
+
+    for (ltfatInt w=0; w<W; w++)
+    {
+        memcpy(work,f+L*w,sizeof(LTFAT_COMPLEX)*L);
+        LTFAT_FFTW(execute)(plan_w);
+
+        for (ltfatInt m=0; m<M; m++)
+        {
+            for (ltfatInt n=0; n<N; n++)
+            {
+                cout[n+m*N+w*N*M]=(LTFAT_COMPLEX) 0.0;
+
+                for (ltfatInt k=0; k<a; k++)
+                {
+                    const ltfatInt l=n+k*N;
+                    cout[n+m*N+w*N*M] += work[l]*gwork[l+m*L]*scalconst;
+                }
+            }
+        }
+    }
+
+
+    LTFAT_FFTW(execute)(plan_c);
+
+
+    LTFAT_SAFEFREEALL(work,gwork);
+}
diff --git a/src/gabdual.c b/src/gabdual.c
new file mode 100644
index 0000000..d254dfb
--- /dev/null
+++ b/src/gabdual.c
@@ -0,0 +1,36 @@
+/* NOT PROCESSED DIRECTLY, see ltfat_complexindependent.c */
+#ifdef LTFAT_TYPE
+
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabdual_long)(const LTFAT_TYPE *g,
+                         const ltfatInt L, const ltfatInt R, const ltfatInt a,
+                         const ltfatInt M, LTFAT_TYPE *gd)
+{
+
+    const ltfatInt wfs = L;
+
+
+    LTFAT_COMPLEX *gf = ltfat_malloc(wfs*R*sizeof(LTFAT_COMPLEX));
+    LTFAT_COMPLEX *gdf = ltfat_malloc(wfs*R*sizeof(LTFAT_COMPLEX));
+
+#ifdef LTFAT_COMPLEXTYPE
+
+    LTFAT_NAME(wfac)(g, L, R, a, M, gf);
+    LTFAT_NAME_REAL(gabdual_fac)((const LTFAT_COMPLEX *)gf,L,R,a,M,gdf);
+    LTFAT_NAME(iwfac)((const LTFAT_COMPLEX *)gdf,L,R,a,M,gd);
+
+#else
+
+    LTFAT_NAME_REAL(wfacreal)(g, L, R, a, M, gf);
+    LTFAT_NAME_REAL(gabdualreal_fac)((const LTFAT_COMPLEX *)gf,L,R,a,M,gdf);
+    LTFAT_NAME_REAL(iwfacreal)((const LTFAT_COMPLEX *)gdf,L,R,a,M,gd);
+
+#endif
+
+    LTFAT_SAFEFREEALL(gdf,gf);
+}
+
+#endif
diff --git a/src/gabdual_fac.c b/src/gabdual_fac.c
new file mode 100644
index 0000000..f5d4ff1
--- /dev/null
+++ b/src/gabdual_fac.c
@@ -0,0 +1,99 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabdual_fac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                        const ltfatInt a, const ltfatInt M,
+                        LTFAT_COMPLEX *gdualf)
+{
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_COMPLEX *Sf;
+
+    const LTFAT_COMPLEX zzero = (LTFAT_COMPLEX) 0.0;//{0.0, 0.0 };
+    const LTFAT_COMPLEX alpha = (LTFAT_COMPLEX) (1.0+0.0*I);//{1.0, 0.0 };
+
+    const ltfatInt N=L/a;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=N/q;
+
+    Sf = (LTFAT_COMPLEX*)ltfat_malloc(p*p*sizeof(LTFAT_COMPLEX));
+
+    /* Copy the contents of gf to gdualf because LAPACK overwrites it input
+     * argument
+     */
+    memcpy(gdualf,gf,sizeof(LTFAT_COMPLEX)*L*R);
+
+    for (ltfatInt rs=0; rs<c*d; rs++)
+    {
+        LTFAT_NAME(ltfat_gemm)(CblasNoTrans,CblasConjTrans,p,p,q*R,
+                               &alpha,
+                               gf+rs*p*q*R,p,
+                               gf+rs*p*q*R,p,
+                               &zzero,Sf,p);
+
+        LTFAT_NAME(ltfat_posv)(p, q*R, Sf, p,
+                               gdualf+rs*p*q*R, p);
+
+    }
+
+    /* Clear the work-array. */
+    ltfat_free(Sf);
+
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabdualreal_fac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                            const ltfatInt a, const ltfatInt M,
+                            LTFAT_COMPLEX *gdualf)
+{
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_COMPLEX *Sf;
+
+    const LTFAT_COMPLEX zzero = (LTFAT_COMPLEX)0.0;
+    const LTFAT_COMPLEX alpha = (LTFAT_COMPLEX)(1.0 + 0.0*I);//{1.0, 0.0 };
+
+    const ltfatInt N=L/a;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=N/q;
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    Sf = (LTFAT_COMPLEX*)ltfat_malloc(p*p*sizeof(LTFAT_COMPLEX));
+
+    /* Copy the contents of gf to gdualf because LAPACK overwrites it input
+     * argument
+     */
+    memcpy(gdualf,gf,sizeof(LTFAT_COMPLEX)*L*R);
+
+    for (ltfatInt rs=0; rs<c*d2; rs++)
+    {
+        LTFAT_NAME(ltfat_gemm)(CblasNoTrans,CblasConjTrans,p,p,q*R,
+                               &alpha,
+                               gf+rs*p*q*R,p,
+                               gf+rs*p*q*R,p,
+                               &zzero,Sf,p);
+
+        LTFAT_NAME(ltfat_posv)(p, q*R, Sf, p,
+                               gdualf+rs*p*q*R, p);
+
+    }
+
+    /* Clear the work-array. */
+    ltfat_free(Sf);
+
+
+}
+
diff --git a/src/gabtight.c b/src/gabtight.c
new file mode 100644
index 0000000..0bcf1aa
--- /dev/null
+++ b/src/gabtight.c
@@ -0,0 +1,36 @@
+/* NOT PROCESSED DIRECTLY, see ltfat_complexindependent.c */
+#ifdef LTFAT_TYPE
+
+#include "ltfat.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabtight_long)(const LTFAT_TYPE *g,
+                          const ltfatInt L, const ltfatInt R, const ltfatInt a,
+                          const ltfatInt M, LTFAT_TYPE *gd)
+{
+
+#ifdef LTFAT_COMPLEXTYPE
+
+    LTFAT_COMPLEX *gf = ltfat_malloc(L*R*sizeof(LTFAT_COMPLEX));
+    LTFAT_COMPLEX *gdf = ltfat_malloc(L*R*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_NAME(wfac)(g, L, R, a, M, gf);
+    LTFAT_NAME_REAL(gabtight_fac)((const LTFAT_COMPLEX *)gf,L,R,a,M,gdf);
+    LTFAT_NAME(iwfac)((const LTFAT_COMPLEX *)gdf,L,R,a,M,gd);
+
+#else
+
+    const ltfatInt wfs = L; /* wfacreal_size(L,a,M); */
+
+    LTFAT_COMPLEX *gf = ltfat_malloc(wfs*R*sizeof(LTFAT_COMPLEX));
+    LTFAT_COMPLEX *gdf = ltfat_malloc(wfs*R*sizeof(LTFAT_COMPLEX));
+
+    LTFAT_NAME_REAL(wfacreal)(g, L, R, a, M, gf);
+    LTFAT_NAME_REAL(gabtightreal_fac)((const LTFAT_COMPLEX *)gf,L,R,a,M,gdf);
+    LTFAT_NAME_REAL(iwfacreal)((const LTFAT_COMPLEX *)gdf,L,R,a,M,gd);
+
+#endif
+
+    LTFAT_SAFEFREEALL(gdf,gf);
+}
+#endif
diff --git a/src/gabtight_fac.c b/src/gabtight_fac.c
new file mode 100644
index 0000000..07d2ca7
--- /dev/null
+++ b/src/gabtight_fac.c
@@ -0,0 +1,106 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabtight_fac)(const LTFAT_COMPLEX *gf, const ltfatInt L,const ltfatInt R,
+                         const ltfatInt a, const ltfatInt M,
+                         LTFAT_COMPLEX *gtightf)
+{
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_COMPLEX *Sf, *U, *VT, *gfwork;
+    LTFAT_REAL *S;
+
+    const LTFAT_COMPLEX zzero = (LTFAT_COMPLEX) 0.0;//{0.0, 0.0 };
+    const LTFAT_COMPLEX alpha = (LTFAT_COMPLEX) (1.0+0.0*I);//{1.0, 0.0 };
+
+    const ltfatInt N=L/a;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=N/q;
+
+    S  = ltfat_malloc(p*sizeof*S);
+    Sf = ltfat_malloc(p*p*sizeof*Sf);
+    U  = ltfat_malloc(p*p*sizeof*U);
+    VT = ltfat_malloc(p*q*R*sizeof*VT);
+    gfwork = ltfat_malloc(L*R*sizeof*gfwork);
+
+    /* Copy the contents of gf to gfwork because LAPACK overwrites
+     * the input.
+     */
+    memcpy(gfwork,gf,L*R*sizeof*gfwork);
+
+    for (ltfatInt rs=0; rs<c*d; rs++)
+    {
+        /* Compute the thin SVD */
+        LTFAT_NAME(ltfat_gesvd)(p, q*R, gfwork+rs*p*q*R, p,
+                                S, U, p, VT, p);
+
+        /* Combine U and V. */
+        LTFAT_NAME(ltfat_gemm)(CblasNoTrans,CblasNoTrans,p,q*R,p,
+                               &alpha,(const LTFAT_COMPLEX*)U,p,
+                               (const LTFAT_COMPLEX*)VT,p,
+                               &zzero,gtightf+rs*p*q*R, p);
+
+
+    }
+
+    LTFAT_SAFEFREEALL(gfwork,Sf,S,U,VT);
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabtightreal_fac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                             const ltfatInt a, const ltfatInt M,
+                             LTFAT_COMPLEX *gtightf)
+{
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_COMPLEX *Sf, *U, *VT, *gfwork;
+    LTFAT_REAL *S;
+
+    const LTFAT_COMPLEX zzero = (LTFAT_COMPLEX) 0.0;
+    const LTFAT_COMPLEX alpha = (LTFAT_COMPLEX) 1.0+0.0*I;//{1.0, 0.0 };
+
+    const ltfatInt N=L/a;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=N/q;
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    S  = ltfat_malloc(p*sizeof*S);
+    Sf = ltfat_malloc(p*p*sizeof*Sf);
+    U  = ltfat_malloc(p*p*sizeof*U);
+    VT = ltfat_malloc(p*q*R*sizeof*VT);
+    gfwork = ltfat_malloc(L*R*sizeof*gfwork);
+
+    /* Copy the contents of gf to gfwork because LAPACK overwrites
+     * the input.
+     */
+    memcpy(gfwork,gf,L*R*sizeof*gfwork);
+
+    for (ltfatInt rs=0; rs<c*d2; rs++)
+    {
+        /* Compute the thin SVD */
+        LTFAT_NAME(ltfat_gesvd)(p, q*R, gfwork+rs*p*q*R, p,
+                                S, U, p, VT, p);
+
+        /* Combine U and V. */
+        LTFAT_NAME(ltfat_gemm)(CblasNoTrans,CblasNoTrans,p,q*R,p,
+                               &alpha,(const LTFAT_COMPLEX*)U,p,
+                               (const LTFAT_COMPLEX*)VT,p,
+                               &zzero,gtightf+rs*p*q*R, p);
+    }
+
+    LTFAT_SAFEFREEALL(gfwork,Sf,S,U,VT);
+}
+
diff --git a/src/goertzel.c b/src/goertzel.c
new file mode 100644
index 0000000..85882bf
--- /dev/null
+++ b/src/goertzel.c
@@ -0,0 +1,543 @@
+/* NOT PROCESSED DIRECTLY, see ltfat_complexindependent.c */
+#ifdef LTFAT_TYPE
+
+#ifndef GGA_UNROLL
+#   define GGA_UNROLL 8
+#endif
+
+struct LTFAT_NAME(gga_plan_struct)
+{
+    const LTFAT_REAL* cos_term;
+    const LTFAT_COMPLEX* cc_term;
+    const LTFAT_COMPLEX* cc2_term;
+    const ltfatInt M;
+    const ltfatInt L;
+};
+
+struct LTFAT_NAME(chzt_plan_struct)
+{
+    LTFAT_COMPLEX* fbuffer;
+    LTFAT_COMPLEX* W2;
+    LTFAT_COMPLEX* Wo;
+    LTFAT_COMPLEX* chirpF;
+    const LTFAT_FFTW(plan) plan;
+    const LTFAT_FFTW(plan) plan2;
+    const ltfatInt L;
+    const ltfatInt K;
+    const ltfatInt Lfft;
+};
+
+
+LTFAT_EXTERN LTFAT_NAME(gga_plan)
+LTFAT_NAME(gga_init)(const LTFAT_REAL *indVecPtr, const ltfatInt M, const ltfatInt L)
+{
+    LTFAT_REAL* cos_term = ltfat_malloc(M*sizeof*cos_term);
+    LTFAT_COMPLEX* cc_term = ltfat_malloc(M*sizeof*cc_term);
+    LTFAT_COMPLEX* cc2_term = ltfat_malloc(M*sizeof*cc2_term);
+
+    LTFAT_REAL pik_term_pre = (LTFAT_REAL) (2.0*PI/((double) L));
+    LTFAT_REAL _Complex cc2_pre = (-1.0*_Complex_I*((double)(L-1)));
+    LTFAT_REAL _Complex cc_pre =  (-1.0*_Complex_I*((double)(L)));
+
+    for(ltfatInt m=0; m<M; m++)
+    {
+        LTFAT_REAL pik_term = pik_term_pre*indVecPtr[m];
+        cos_term[m] = (LTFAT_REAL) cos(pik_term)*2.0;
+        cc_term[m] = (LTFAT_COMPLEX) cexp(cc_pre*pik_term);
+        cc2_term[m] = (LTFAT_COMPLEX) cexp(cc2_pre*pik_term);
+    }
+
+    // This is workaround for defining constant elements of the struct.
+    struct LTFAT_NAME(gga_plan_struct) plan_tmp =
+    {.cos_term=cos_term,.cc_term=cc_term,.cc2_term=cc2_term,.M=M,.L=L};
+
+    LTFAT_NAME(gga_plan) plan = ltfat_malloc(sizeof*plan);
+    memcpy(plan,&plan_tmp,sizeof*plan);
+
+    return plan;
+}
+
+LTFAT_EXTERN
+void LTFAT_NAME(gga_done)(LTFAT_NAME(gga_plan) plan)
+{
+    LTFAT_SAFEFREEALL((void*)plan->cos_term,
+                      (void*)plan->cc_term,
+                      (void*)plan->cc2_term);
+    ltfat_free(plan);
+}
+
+
+LTFAT_EXTERN
+void LTFAT_NAME(gga_execute)(LTFAT_NAME(gga_plan) p,
+                             const LTFAT_TYPE *fPtr,
+                             const ltfatInt W,
+                             LTFAT_COMPLEX *cPtr)
+{
+#ifndef GGA_UNROLL
+
+    for(ltfatInt w=0; w<W; w++)
+    {
+        LTFAT_COMPLEX *cPtrTmp = (LTFAT_COMPLEX*) cPtr+w*p.M;
+
+        for(ltfatInt m=0; m<p.M; m++)
+        {
+            LTFAT_TYPE s0 =  0.0;
+            LTFAT_TYPE s1 =  0.0;
+            LTFAT_TYPE s2 =  0.0;
+            LTFAT_TYPE *fPtrTmp = (LTFAT_TYPE*) fPtr+w*p.L;
+
+            for(ltfatInt ii=0; ii<p.L-1; ii++)
+            {
+                s0 = *fPtrTmp++ + p.cos_term[m]*s1 - s2;
+                s2=s1;
+                s1=s0;
+            }
+            s0 = *fPtrTmp + p.cos_term[m]*s1 - s2;
+
+            *cPtrTmp++ = (s0*p.cc2_term[m] - s1*p.cc_term[m]);
+        }
+    }
+#else
+    for(ltfatInt w=0; w<W; w++)
+    {
+        LTFAT_COMPLEX *cPtrTmp = (LTFAT_COMPLEX*) cPtr+w*p->M;
+        ltfatInt unrollRem = p->M%GGA_UNROLL;
+
+        const LTFAT_REAL* cos_term = p->cos_term;
+        const LTFAT_COMPLEX* cc_term = p->cc_term;
+        const LTFAT_COMPLEX* cc2_term = p->cc2_term;
+//#pragma omp parallel for
+        for(ltfatInt m=0; m<p->M-unrollRem; m+=GGA_UNROLL)
+        {
+            LTFAT_TYPE s0[GGA_UNROLL];
+            LTFAT_TYPE s1[GGA_UNROLL];
+            LTFAT_TYPE s2[GGA_UNROLL];
+
+            for(ltfatInt un=0; un<GGA_UNROLL; un++)
+            {
+                s0[un] = 0.0;
+                s1[un] = 0.0;
+                s2[un] = 0.0;
+            }
+
+            LTFAT_TYPE *fPtrTmp = (LTFAT_TYPE*) fPtr+w*p->L;
+
+            for(ltfatInt ii=0; ii<p->L-1; ii++)
+            {
+                for(ltfatInt un=0; un<GGA_UNROLL; un++)
+                {
+                    s0[un] = *fPtrTmp + cos_term[un]*s1[un] - s2[un];
+                    s2[un]=s1[un];
+                    s1[un]=s0[un];
+                }
+                fPtrTmp++;
+            }
+            for(ltfatInt un=0; un<GGA_UNROLL; un++)
+            {
+                s0[un] = *fPtrTmp + cos_term[un]*s1[un] - s2[un];
+                cPtrTmp[m+un] = (s0[un]*cc2_term[un] - s1[un]*cc_term[un]);
+            }
+            cos_term+=GGA_UNROLL;
+            cc_term+=GGA_UNROLL;
+            cc2_term+=GGA_UNROLL;
+        }
+
+        ltfatInt m= p->M-unrollRem;
+
+
+        LTFAT_TYPE s0[GGA_UNROLL];
+        LTFAT_TYPE s1[GGA_UNROLL];
+        LTFAT_TYPE s2[GGA_UNROLL];
+
+        for(ltfatInt un=0; un<unrollRem; un++)
+        {
+            s0[un] = 0.0;
+            s1[un] = 0.0;
+            s2[un] = 0.0;
+        }
+
+        LTFAT_TYPE *fPtrTmp = (LTFAT_TYPE*) fPtr+w*p->L;
+
+        for(ltfatInt ii=0; ii<p->L-1; ii++)
+        {
+            for(ltfatInt un=0; un<unrollRem; un++)
+            {
+                s0[un] = *fPtrTmp + cos_term[un]*s1[un] - s2[un];
+                s2[un]=s1[un];
+                s1[un]=s0[un];
+            }
+            fPtrTmp++;
+        }
+
+        for(ltfatInt un=0; un<unrollRem; un++)
+        {
+            s0[un] = *fPtrTmp + cos_term[un]*s1[un] - s2[un];
+            cPtrTmp[m+un] = (s0[un]*cc2_term[un] - s1[un]*cc_term[un]);
+        }
+
+    }
+#endif
+}
+
+
+
+LTFAT_EXTERN
+void LTFAT_NAME(gga)(const LTFAT_TYPE *fPtr, const LTFAT_REAL *indVecPtr,
+                     const ltfatInt L, const ltfatInt W, const ltfatInt M, LTFAT_COMPLEX *cPtr)
+{
+    LTFAT_NAME(gga_plan) p = LTFAT_NAME(gga_init)(indVecPtr, M, L);
+    LTFAT_NAME(gga_execute)(p,fPtr,W,cPtr);
+    LTFAT_NAME(gga_done)(p);
+}
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt)(const LTFAT_TYPE *fPtr, const ltfatInt L, const ltfatInt W,
+                 const ltfatInt K, const LTFAT_REAL deltao, const LTFAT_REAL o,
+                 LTFAT_COMPLEX *cPtr)
+{
+    LTFAT_NAME(chzt_plan) p = LTFAT_NAME(chzt_init)(K,L,deltao, o,
+                              FFTW_ESTIMATE,
+                              CZT_NEXTFASTFFT);
+
+    LTFAT_NAME(chzt_execute)(p, fPtr, W, cPtr);
+
+    LTFAT_NAME(chzt_done)(p);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt_execute)(LTFAT_NAME(chzt_plan) p, const LTFAT_TYPE *fPtr,
+                         const ltfatInt W, LTFAT_COMPLEX *cPtr)
+{
+
+    ltfatInt L = p->L;
+    ltfatInt K = p->K;
+    ltfatInt Lfft = p->Lfft;
+    LTFAT_COMPLEX* fbuffer = p->fbuffer;
+    LTFAT_FFTW(plan) plan_f = p->plan;
+    LTFAT_FFTW(plan) plan_fi = p->plan2;
+    LTFAT_COMPLEX* W2 = p->W2;
+    LTFAT_COMPLEX* Wo = p->Wo;
+    LTFAT_COMPLEX* chirpF = p->chirpF;
+
+    for(ltfatInt w = 0; w<W; w++)
+    {
+        memset(fbuffer,0,Lfft*sizeof*fbuffer);
+        LTFAT_NAME(array2complex)((LTFAT_TYPE *)(fPtr+w*L),fbuffer,L);
+
+        //1) Premultiply by a chirp
+
+        for(ltfatInt ii=0; ii<L; ii++)
+        {
+            fbuffer[ii]*=Wo[ii];
+        }
+
+        // 2) FFT of input
+        LTFAT_FFTW(execute)(plan_f);
+
+        // Frequency domain filtering
+        for(ltfatInt ii=0; ii<Lfft; ii++)
+        {
+            fbuffer[ii]*=chirpF[ii];
+        }
+
+
+        // Inverse FFT
+        LTFAT_COMPLEX *fPtrTmp = fbuffer;
+        LTFAT_FFTW(execute)(plan_fi);
+
+        // Final chirp multiplication and normalization
+        LTFAT_COMPLEX *cPtrTmp = cPtr + w*K;
+        for(ltfatInt ii=0; ii<K; ii++)
+        {
+            cPtrTmp[ii]=fPtrTmp[ii]*W2[ii];
+        }
+
+    }
+
+}
+
+LTFAT_EXTERN LTFAT_NAME(chzt_plan)
+LTFAT_NAME(chzt_init)(const ltfatInt K, ltfatInt L, const LTFAT_REAL deltao,
+                      const LTFAT_REAL o, const unsigned fftw_flags,
+                      czt_ffthint hint)
+{
+    ltfatInt Lfft = L+K-1;
+
+    if(hint == CZT_NEXTPOW2)
+        Lfft = nextPow2(Lfft);
+    else
+        Lfft = nextfastfft(Lfft);
+
+    LTFAT_COMPLEX* fbuffer = ltfat_malloc(Lfft*sizeof*fbuffer);
+    LTFAT_FFTW(plan) plan_f =  LTFAT_FFTW(plan_dft_1d)(Lfft, fbuffer, fbuffer,
+                               FFTW_FORWARD, fftw_flags);
+    LTFAT_FFTW(plan) plan_fi =  LTFAT_FFTW(plan_dft_1d)(Lfft, fbuffer, fbuffer,
+                                FFTW_BACKWARD, fftw_flags);
+
+    // Pre and post chirp
+    ltfatInt N = L>K?L:K;
+    LTFAT_COMPLEX* W2 = ltfat_malloc(Lfft*sizeof*W2);
+    LTFAT_COMPLEX* chirpF = ltfat_malloc(Lfft*sizeof*chirpF);
+    LTFAT_COMPLEX* Wo = ltfat_malloc(L*sizeof*Wo);
+
+
+    for(ltfatInt ii=0; ii<N; ii++)
+    {
+        W2[ii] = (LTFAT_COMPLEX) cexp(-1.0*I*deltao*ii*ii/2.0);
+    }
+
+    for(ltfatInt ii=0; ii<L; ii++)
+    {
+        Wo[ii] = (LTFAT_COMPLEX) cexp(-1.0*I*o*ii)*W2[ii];
+    }
+    // Set the rest to zero
+    memset(W2+N,0,(Lfft-N)*sizeof*W2);
+
+    LTFAT_NAME_COMPLEX(conjugate_array)(W2,chirpF,K);
+    LTFAT_NAME_COMPLEX(conjugate_array)(W2+1,chirpF+Lfft-L+1,L-1);
+    LTFAT_NAME_COMPLEX(reverse_array)(chirpF+Lfft-L+1,chirpF+Lfft-L+1,L-1);
+    memset(chirpF+K,0,(Lfft-(L+K-1))*sizeof*chirpF);
+
+    LTFAT_FFTW(execute_dft)(plan_f,chirpF,chirpF);
+
+
+    for(ltfatInt ii=0; ii<K; ii++)
+    {
+        W2[ii] = (LTFAT_COMPLEX) cexp(-1.0*I*deltao*ii*ii/2.0)/((LTFAT_REAL) Lfft);
+    }
+
+
+
+    /*
+    We could have shrinked the W2 to length K here.
+    */
+    struct LTFAT_NAME(chzt_plan_struct) p_struct =
+    {
+        .fbuffer = fbuffer, .plan=plan_f,.plan2=plan_fi,.L=L, .K=K, .W2 = W2,
+        .Wo=Wo,.chirpF=chirpF,.Lfft=Lfft
+    };
+
+    LTFAT_NAME(chzt_plan) p = ltfat_malloc(sizeof*p);
+    memcpy(p,&p_struct,sizeof*p);
+
+    return  p;
+}
+
+LTFAT_EXTERN
+void LTFAT_NAME(chzt_done)(LTFAT_NAME(chzt_plan) p)
+{
+    LTFAT_SAFEFREEALL(p->fbuffer,p->W2,p->Wo,p->chirpF);
+    LTFAT_FFTW(destroy_plan)(p->plan);
+    LTFAT_FFTW(destroy_plan)(p->plan2);
+    ltfat_free(p);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt_fac)(const LTFAT_TYPE *fPtr, const ltfatInt L,
+                     const ltfatInt W, const ltfatInt K, const LTFAT_REAL deltao,
+                     const LTFAT_REAL o, LTFAT_COMPLEX *cPtr)
+{
+    LTFAT_NAME(chzt_plan) p = LTFAT_NAME(chzt_fac_init)(K,L,deltao, o,FFTW_ESTIMATE, CZT_NEXTFASTFFT);
+
+    LTFAT_NAME(chzt_fac_execute)(p, fPtr, W, cPtr);
+
+    LTFAT_NAME(chzt_done)(p);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt_fac_execute)(LTFAT_NAME(chzt_plan) p, const LTFAT_TYPE *fPtr,
+                             const ltfatInt W, LTFAT_COMPLEX *cPtr)
+{
+    ltfatInt L = p->L;
+    ltfatInt K = p->K;
+    ltfatInt Lfft = p->Lfft;
+    LTFAT_COMPLEX* fbuffer = p->fbuffer;
+    LTFAT_FFTW(plan) plan_f = p->plan;
+    LTFAT_FFTW(plan) plan_fi = p->plan2;
+    LTFAT_COMPLEX* W2 = p->W2;
+    LTFAT_COMPLEX* Wo = p->Wo;
+    LTFAT_COMPLEX* chirpF = p->chirpF;
+
+    LTFAT_COMPLEX* fBufTmp;
+    ltfatInt q = (ltfatInt) ceil(((double)L)/((double)K));
+
+    ltfatInt lastK = (L/q);
+
+    for(ltfatInt w = 0; w<W; w++)
+    {
+        // *********************************
+        // 1) Read and reorganize input data
+        // *********************************
+        memset(fbuffer,0,q*Lfft*sizeof*fbuffer);
+        LTFAT_TYPE* fPtrTmp = ((LTFAT_TYPE *)fPtr) + w*L;
+
+        for(ltfatInt k=0; k<lastK; k++)
+        {
+            LTFAT_TYPE* fTmp = fPtrTmp + k*q;
+            fBufTmp = fbuffer + k;
+            for(ltfatInt jj=0; jj<q; jj++)
+            {
+                *fBufTmp = (LTFAT_COMPLEX) fTmp[jj];
+                fBufTmp+=Lfft;
+            }
+        }
+
+        LTFAT_TYPE* fTmp = fPtrTmp + lastK*q;
+        fBufTmp = fbuffer + lastK;
+        for(ltfatInt jj=0; jj<L-lastK*q; jj++)
+        {
+            *fBufTmp = (LTFAT_COMPLEX) fTmp[jj];
+            fBufTmp+=Lfft;
+        }
+
+        // *********************************
+        // 2) Premultiply
+        // *********************************
+
+        fBufTmp = fbuffer;
+        for(ltfatInt jj=0; jj<q; jj++)
+        {
+            for(ltfatInt k=0; k<K; k++)
+            {
+                fBufTmp[k]*=W2[k];
+            }
+            fBufTmp+=Lfft;
+        }
+
+        // *********************************
+        // 3) q ffts of length Lfft
+        // *********************************
+        LTFAT_FFTW(execute)(plan_f);
+
+        // *********************************
+        // 4) Filter
+        // *********************************
+        fBufTmp = fbuffer;
+        // Frequency domain filtering
+        for(ltfatInt jj=0; jj<q; jj++)
+        {
+            for(ltfatInt ii=0; ii<Lfft; ii++)
+            {
+                fBufTmp[ii]*=chirpF[ii];
+            }
+            fBufTmp+=Lfft;
+        }
+
+        // *********************************
+        // 5) q iffts of length Lfft
+        // *********************************
+        LTFAT_FFTW(execute)(plan_fi);
+
+
+        // *********************************
+        // 6) Postmultiply
+        // *********************************
+        fBufTmp = fbuffer;
+        LTFAT_COMPLEX* Wotmp = Wo;
+        for(ltfatInt jj=0; jj<q; jj++)
+        {
+            for(ltfatInt k=0; k<K; k++)
+            {
+                fBufTmp[k]*=Wotmp[k];
+            }
+            fBufTmp+=Lfft;
+            Wotmp+=K;
+        }
+
+        // *********************************
+        // 7) Sum cols
+        // *********************************
+        LTFAT_COMPLEX *cPtrTmp = cPtr + w*K;
+        for(ltfatInt k=0; k<K; k++)
+        {
+            fBufTmp = fbuffer + k;
+            cPtrTmp[k] = (LTFAT_COMPLEX) 0.0;
+            for(ltfatInt jj=0; jj<q; jj++)
+            {
+                cPtrTmp[k]+= *fBufTmp;
+                fBufTmp+=Lfft;
+            }
+        }
+
+    }
+}
+
+LTFAT_EXTERN LTFAT_NAME(chzt_plan)
+LTFAT_NAME(chzt_fac_init)(const ltfatInt K, const ltfatInt L,
+                          const LTFAT_REAL deltao, const LTFAT_REAL o,
+                          const unsigned fftw_flags, czt_ffthint hint)
+{
+
+    ltfatInt Lfft=2*K-1;
+    if(hint == CZT_NEXTPOW2)
+        Lfft = nextPow2(Lfft);
+    else
+        Lfft = nextfastfft(Lfft);
+
+    ltfatInt q = (ltfatInt) ceil(((double)L)/((double)K));
+
+    LTFAT_COMPLEX* fbuffer = ltfat_malloc(q*Lfft*sizeof*fbuffer);
+
+    const LTFAT_FFTW(iodim) dims = {.n = Lfft, .is = 1, .os = 1};
+    const LTFAT_FFTW(iodim) howmany_dims = {.n = q,.is = Lfft, .os = Lfft};
+    LTFAT_FFTW(plan) plan_f =  LTFAT_FFTW(plan_guru_dft)(1, &dims, 1, &howmany_dims,
+                               (LTFAT_COMPLEX*)fbuffer, (LTFAT_COMPLEX*) fbuffer,
+                               FFTW_FORWARD, fftw_flags);
+
+    LTFAT_FFTW(plan) plan_fi =  LTFAT_FFTW(plan_guru_dft)(1, &dims, 1, &howmany_dims,
+                                (LTFAT_COMPLEX*)fbuffer, (LTFAT_COMPLEX*) fbuffer,
+                                FFTW_BACKWARD, fftw_flags);
+
+    LTFAT_COMPLEX* W2 = ltfat_malloc(K*sizeof*W2);
+    LTFAT_COMPLEX* chirpF = ltfat_malloc(Lfft*sizeof*chirpF);
+    LTFAT_COMPLEX* Wo = ltfat_malloc(q*K*sizeof*Wo);
+
+    LTFAT_FFTW(plan) plan_chirpF =  LTFAT_FFTW(plan_dft_1d)(Lfft, (LTFAT_COMPLEX*)chirpF, (LTFAT_COMPLEX*) chirpF,
+                                    FFTW_FORWARD, fftw_flags);
+
+    for(ltfatInt k=0; k<K; k++)
+    {
+        W2[k] = (LTFAT_COMPLEX) cexp(-1.0*q*I*deltao*k*k/2.0);
+    }
+
+    LTFAT_NAME_COMPLEX(conjugate_array)(W2,chirpF,K);
+    LTFAT_NAME_COMPLEX(conjugate_array)(W2+1,chirpF+Lfft-K+1,K-1);
+    LTFAT_NAME_COMPLEX(reverse_array)(chirpF+Lfft-K+1,chirpF+Lfft-K+1,K-1);
+    memset(chirpF+K,0,(Lfft-(2*K-1))*sizeof*chirpF);
+    LTFAT_FFTW(execute)(plan_chirpF);
+    LTFAT_FFTW(destroy_plan)(plan_chirpF);
+
+    LTFAT_REAL oneoverLfft = 1.0/((LTFAT_REAL) Lfft);
+
+    for(ltfatInt jj=0; jj<q; jj++)
+    {
+        LTFAT_COMPLEX* Wotmp = Wo + jj*K;
+        for(ltfatInt k=0; k<K; k++)
+        {
+            Wotmp[k] = (LTFAT_COMPLEX) cexp(-1.0*I*jj*(k*deltao+o))*W2[k]*oneoverLfft;
+        }
+    }
+
+    for(ltfatInt k=0; k<K; k++)
+    {
+        W2[k] *= (LTFAT_COMPLEX) cexp(-1.0*I*k*q*o);
+    }
+
+
+    struct LTFAT_NAME(chzt_plan_struct) p_struct =
+    {.fbuffer = fbuffer, .plan=plan_f, .plan2=plan_fi,.L=L,.K=K, .W2 = W2,
+     .Wo=Wo,.chirpF=chirpF,.Lfft=Lfft};
+
+   LTFAT_NAME(chzt_plan) p = ltfat_malloc(sizeof*p);
+   memcpy(p,&p_struct,sizeof*p);
+   return  p;
+}
+
+
+
+#endif // LTFAT_TYPE
+
diff --git a/src/goertzel.h b/src/goertzel.h
new file mode 100644
index 0000000..568aa49
--- /dev/null
+++ b/src/goertzel.h
@@ -0,0 +1,67 @@
+/*
+Goertzel algorithm
+*/
+// This is opaque pointer
+typedef struct LTFAT_NAME(gga_plan_struct) *LTFAT_NAME(gga_plan);
+
+LTFAT_EXTERN LTFAT_NAME(gga_plan)
+LTFAT_NAME(gga_init)(const LTFAT_REAL *indVecPtr,
+                     const ltfatInt M, const ltfatInt L);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gga_done)(LTFAT_NAME(gga_plan) plan);
+
+
+LTFAT_EXTERN
+void LTFAT_NAME(gga)(const LTFAT_TYPE *fPtr, const LTFAT_REAL *indVecPtr,
+                     const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                     LTFAT_COMPLEX *cPtr);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gga_execute)(LTFAT_NAME(gga_plan) p,
+                        const LTFAT_TYPE *fPtr,
+                        const ltfatInt W,
+                        LTFAT_COMPLEX *cPtr);
+
+
+/*
+Chirped Z transform
+*/
+// This is opaque pointer
+typedef struct LTFAT_NAME(chzt_plan_struct) *LTFAT_NAME(chzt_plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt)(const LTFAT_TYPE *fPtr, const ltfatInt L,
+                      const ltfatInt W, const ltfatInt K,
+                      const LTFAT_REAL deltao, const LTFAT_REAL o,
+                      LTFAT_COMPLEX *cPtr);
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt_execute)(LTFAT_NAME(chzt_plan) p, const LTFAT_TYPE *fPtr,
+                         const ltfatInt W, LTFAT_COMPLEX *cPtr);
+
+LTFAT_EXTERN LTFAT_NAME(chzt_plan)
+LTFAT_NAME(chzt_init)(const ltfatInt K, const ltfatInt L,
+                      const LTFAT_REAL deltao, const LTFAT_REAL o,
+                      const unsigned fftw_flags, czt_ffthint hint);
+
+LTFAT_EXTERN
+void LTFAT_NAME(chzt_done)(LTFAT_NAME(chzt_plan) p);
+
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt_fac)(const LTFAT_TYPE *fPtr, const ltfatInt L,
+                     const ltfatInt W, const ltfatInt K,
+                     const LTFAT_REAL deltao, const LTFAT_REAL o,
+                     LTFAT_COMPLEX *cPtr);
+
+LTFAT_EXTERN void
+LTFAT_NAME(chzt_fac_execute)(LTFAT_NAME(chzt_plan) p, const LTFAT_TYPE *fPtr,
+                             const ltfatInt W, LTFAT_COMPLEX *cPtr);
+
+LTFAT_EXTERN LTFAT_NAME(chzt_plan)
+LTFAT_NAME(chzt_fac_init)(const ltfatInt K, const ltfatInt L,
+                          const LTFAT_REAL deltao, const LTFAT_REAL o,
+                          const unsigned fftw_flags, czt_ffthint hint);
diff --git a/src/heapint.c b/src/heapint.c
new file mode 100644
index 0000000..78bc8ec
--- /dev/null
+++ b/src/heapint.c
@@ -0,0 +1,305 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+typedef struct
+{
+    ltfatInt *h;
+    ltfatInt heapsize;
+    ltfatInt totalheapsize;
+    const LTFAT_REAL *s;
+}
+LTFAT_NAME(heap);
+
+LTFAT_EXTERN
+void LTFAT_NAME(heap_insert)(LTFAT_NAME(heap) *h, const ltfatInt key)
+{
+    ltfatInt pos,pos2, swap;
+
+    /*printf("Grow heap: heapsize %i, totalheapsize %i\n",h->heapsize,h->totalheapsize);*/
+
+    /* Grow heap if necessary */
+    if (h->totalheapsize==h->heapsize)
+    {
+        (h->totalheapsize)*=2;
+        h->h = (ltfatInt*)realloc(h->h,h->totalheapsize*sizeof(ltfatInt));
+    }
+
+    pos=h->heapsize;
+    h->heapsize++;
+
+    /*printf("heap: heapsize %i, pos %i\n",h->heapsize,pos);*/
+
+    h->h[h->heapsize-1]=key;
+
+    /* printf("before heapint main loop\n"); */
+
+    while (pos>0)
+    {
+        /* printf("pos %i\n",pos); */
+        pos2=(pos-pos%2)/2;
+        if (h->s[h->h[pos2]] < h->s[h->h[pos]] )
+        {
+            swap=h->h[pos2];
+            h->h[pos2]=h->h[pos];
+            h->h[pos]=swap;
+            pos=pos2;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    /* { */
+    /*       printf("C INSERT heapsize: %i\n",h->heapsize); */
+    /*       for (ii=0; ii<h->heapsize; ii++) */
+    /* 	 printf("    %i\n",h->h[ii]); */
+    /*    } */
+
+}
+LTFAT_EXTERN
+ltfatInt LTFAT_NAME(heap_delete)(LTFAT_NAME(heap) *h)
+{
+
+    ltfatInt pos, maxchildpos, swap, key;
+    LTFAT_REAL maxchildkey;
+
+    /* Extract first element */
+    key=h->h[0];
+
+    /* Put last element on first elements place, and make the heap smaller. */
+    h->h[0]=h->h[h->heapsize-1];
+    h->heapsize--;
+
+    /* Fix the just introduced problem. */
+    pos=0;
+
+    /*  %%%%%%%%%%%%%%
+     * %
+     * %  Is maxchildpos 0 or 1 indexed!
+     * %
+     * %
+     * %%%%%%%%%%%%%
+     */
+
+
+    while (2*pos+1<h->heapsize)
+    {
+        if (2*pos+3>h->heapsize)
+        {
+            maxchildkey=h->s[h->h[2*pos+1]];
+            maxchildpos=1;
+        }
+        else
+        {
+            if (h->s[h->h[2*pos+1]]>=h->s[h->h[2*pos+2]])
+            {
+                maxchildkey=h->s[h->h[2*pos+1]];
+                maxchildpos=1;
+            }
+            else
+            {
+                maxchildkey=h->s[h->h[2*pos+2]];
+                maxchildpos=2;
+            }
+        }
+
+        if (maxchildkey>h->s[h->h[pos]])
+        {
+            swap=h->h[2*pos+maxchildpos];
+            h->h[2*pos+maxchildpos]=h->h[pos];
+            h->h[pos]=swap;
+            pos=2*pos+maxchildpos;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    /*    { */
+    /*       printf("C DELETE heapsize: %i\n",h->heapsize); */
+    /*       for (ii=0; ii<h->heapsize; ii++) */
+    /* 	 printf("    %i %f\n",h->h[ii],h->s[h->h[ii]]); */
+    /*    }    */
+
+
+    return key;
+}
+
+
+LTFAT_EXTERN
+void LTFAT_NAME(heapint)(const LTFAT_REAL *s,
+                         const LTFAT_REAL *tgrad,
+                         const LTFAT_REAL *fgrad,
+                         const ltfatInt a, const ltfatInt M, const ltfatInt L, const ltfatInt W,
+                         LTFAT_REAL tol, LTFAT_REAL *phase)
+{
+
+    /* Declarations */
+    ltfatInt b, N, ii, jj, Imax, domainloop;
+    ltfatInt w, w_E, w_W, w_N, w_S;
+    LTFAT_REAL maxs;
+    ltfatInt *donemask;
+    LTFAT_NAME(heap) h;
+
+    N=L/a;
+    b=L/M;
+
+    /* Main body */
+    /* printf("Main body a: %i, M: %i, N, %i, L: %i, W: %i\n",a,M,N,L,W); */
+
+
+    h.totalheapsize  =(ltfatInt)(M*log((LTFAT_REAL)M));
+    h.h              = (ltfatInt*)ltfat_malloc(h.totalheapsize*sizeof(ltfatInt));
+    h.s              = s;
+    h.heapsize       = 0;
+
+    donemask = (ltfatInt*)ltfat_malloc(M*N*W*sizeof(ltfatInt));
+
+    LTFAT_REAL *tgradw = (LTFAT_REAL*)ltfat_malloc(M*N*sizeof(LTFAT_REAL));
+    LTFAT_REAL *fgradw = (LTFAT_REAL*)ltfat_malloc(M*N*sizeof(LTFAT_REAL));
+
+    /* Set the phase to zero initially */
+    for (ii=0; ii<M*N*W; ii++)
+    {
+        phase[ii]=0.0;
+    }
+
+    /* Rescale the partial derivatives to a torus of length L. We copy
+       to work arrays because the input is const. */
+    for (jj=0; jj<N; jj++)
+    {
+        for (ii=0; ii<M; ii++)
+        {
+            tgradw[ii+jj*M] = tgrad[ii+jj*M]*2*PI*a/L;
+            fgradw[ii+jj*M] = fgrad[ii+jj*M]*2*PI*b/L+2*PI*jj*a*b/L;
+        }
+    }
+
+    maxs=-1e99;
+    Imax=0; /* This is just included to avoid a warning from the C++ compiler */
+    for (ii=0; ii<M*N; ii++)
+    {
+        if (s[ii]>maxs)
+        {
+            maxs=s[ii];
+            Imax=ii;
+        }
+    }
+
+    /*   printf("Mark\n"); */
+
+    /* Mark all the small elements as done, they get a zero phase.
+     * Code 5
+     */
+    for (ii=0; ii<M*N*W; ii++)
+    {
+        if (s[ii]<tol*maxs)
+            donemask[ii]=5;
+        else
+            donemask[ii]=0;
+    }
+
+
+    domainloop=1;
+
+
+    while (domainloop)
+    {
+        /* printf("Main loop, Imax: %i\n",Imax); */
+
+        h.heapsize=0;
+
+        /* Put maximal element onto the heap and mark that it is done. It
+         * will get zero phase.
+         */
+        LTFAT_NAME(heap_insert)(&h,Imax);
+
+        /* printf("after heap_insert, Imax %i, h.heapize %i\n", Imax,h.heapsize); */
+
+        donemask[Imax]=6;
+
+        /*      printf("after donemask\n",h.heapsize); */
+
+        while (h.heapsize>0)
+        {
+
+            /* printf("Inner loop, heapsize: %i\n",h.heapsize); */
+            /* Extract largest element from heap and delete it. */
+
+            w = LTFAT_NAME(heap_delete)(&h);
+
+            /* Try and put the four neighbours onto the heap.
+             * Integration by trapezoidal rule */
+
+            /* North */
+            w_N=(w-1+M)%M+w-w%M;
+            if (!donemask[w_N])
+            {
+                /*   printf("C North: %i %i\n",w,w_N); */
+                phase[w_N] = phase[w]+(fgradw[w]+fgradw[w_N])/2;
+                donemask[w_N]=1;
+                LTFAT_NAME(heap_insert)(&h,w_N);
+            }
+
+            /* South */
+            w_S=((w+1)%M)+w-w%M;
+            if (!donemask[w_S])
+            {
+                /* 	   printf("C South: %i %i\n",w,w_S); */
+                phase[w_S] = phase[w]-(fgradw[w]+fgradw[w_S])/2;
+                donemask[w_S]=2;
+                LTFAT_NAME(heap_insert)(&h,w_S);
+            }
+
+            /* East */
+            w_E = (w+M)%(M*N);
+            if (!donemask[w_E])
+            {
+                /* 	   printf("C East:%i %i\n",w,w_E); */
+                phase[w_E]=phase[w]+(tgradw[w]+tgradw[w_E])/2;
+                donemask[w_E]=3;
+                LTFAT_NAME(heap_insert)(&h,w_E);
+            }
+
+            /* West */
+            w_W = (w-M+M*N)%(M*N);
+            if (!donemask[w_W])
+            {
+                /* 	   printf("C West: %i %i\n",w,w_W); */
+                phase[w_W]=phase[w]-(tgradw[w]+tgradw[w_W])/2;
+                donemask[w_W]=4;
+                LTFAT_NAME(heap_insert)(&h,w_W);
+            }
+
+        }
+
+        /* Find the new maximal element
+         *
+         * This code is currently missing
+         *
+         */
+
+        maxs=-1e99;
+        domainloop=0;
+        for (ii=0; ii<M*N; ii++)
+        {
+            if (!donemask[ii] && s[ii]>maxs)
+            {
+                maxs=s[ii];
+                Imax=ii;
+                domainloop=1;
+            }
+        }
+
+
+    }
+
+    ltfat_free(tgradw);
+    ltfat_free(fgradw);
+    ltfat_free(donemask);
+    ltfat_free(h.h);
+
+}
+
diff --git a/src/idgt.c b/src/idgt.c
new file mode 100644
index 0000000..7cd9ab2
--- /dev/null
+++ b/src/idgt.c
@@ -0,0 +1,37 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_long)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *g,
+                      const ltfatInt L, const ltfatInt W,
+                      const ltfatInt a, const ltfatInt M,
+                      LTFAT_COMPLEX *f)
+{
+    LTFAT_COMPLEX *gf = ltfat_malloc(L*sizeof*gf);
+    LTFAT_NAME_COMPLEX(wfac)(g, L, 1, a, M, gf);
+
+    LTFAT_NAME(idgt_fac)(cin, (const LTFAT_COMPLEX*) gf, L, W,a, M, f);
+
+    ltfat_free(gf);
+}
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgtreal_long)(const LTFAT_COMPLEX *cin, const LTFAT_REAL *g,
+                          const ltfatInt L, const ltfatInt W,
+                          const ltfatInt a, const ltfatInt M,
+                          LTFAT_REAL *f)
+{
+// TO DO: Is it possible to use wfacreal? wfacreal_size(L,a,M)
+
+    LTFAT_COMPLEX *gf = ltfat_malloc(L*sizeof*gf);
+    LTFAT_NAME(wfac)(g, L, 1, a, M, gf);
+
+    LTFAT_NAME(idgtreal_fac)(cin, (const LTFAT_COMPLEX*) gf, L, W,a, M, f);
+
+    ltfat_free(gf);
+}
diff --git a/src/idgt_fac.c b/src/idgt_fac.c
new file mode 100644
index 0000000..7f51fe1
--- /dev/null
+++ b/src/idgt_fac.c
@@ -0,0 +1,376 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_fac)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *gf,
+                     const ltfatInt L, const ltfatInt W,
+                     const ltfatInt a, const ltfatInt M,
+                     LTFAT_COMPLEX *f)
+{
+
+    /*  --------- initial declarations -------------- */
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_FFTW(plan) p_before, p_after, p_veryend;
+    LTFAT_COMPLEX *ff, *cf, *cwork, *cbuf;
+
+    /*  ----------- calculation of parameters and plans -------- */
+
+    const ltfatInt b=L/M;
+    const ltfatInt N=L/a;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    h_a=-h_a;
+
+    ff    = ltfat_malloc(d*p*q*W*sizeof*ff);
+    cf    = ltfat_malloc(d*q*q*W*sizeof*cf);
+    cwork = ltfat_malloc(M*N*W*sizeof*cwork);
+    cbuf  = ltfat_malloc(d*sizeof*cbuf);
+
+    /* Scaling constant needed because of FFTWs normalization. */
+    const LTFAT_REAL scalconst = 1.0/((LTFAT_REAL)d*sqrt((LTFAT_REAL)M));
+
+    /* Create plans. In-place. */
+
+    p_after  = LTFAT_FFTW(plan_dft_1d)(d, cbuf, cbuf,
+                                       FFTW_FORWARD, FFTW_ESTIMATE);
+
+    p_before = LTFAT_FFTW(plan_dft_1d)(d, cbuf, cbuf,
+                                       FFTW_BACKWARD, FFTW_ESTIMATE);
+
+    /* Create plan. Copy data so we do not overwrite input. Therefore
+       it is ok to cast away the constness of cin.*/
+
+    // Downcast to int
+    int Mint = (int) M;
+
+    p_veryend = LTFAT_FFTW(plan_many_dft)(1, &Mint, N*W,
+                                          (LTFAT_COMPLEX *)cin, NULL,
+                                          1, Mint,
+                                          cwork, NULL,
+                                          1, Mint,
+                                          FFTW_BACKWARD, FFTW_ESTIMATE);
+
+    /* -------- Execute initial IFFT ------------------------ */
+    LTFAT_FFTW(execute)(p_veryend);
+
+
+    /* -------- Main loop ----------------------------------- */
+
+    const ltfatInt ld4c=M*N;
+
+    /* Leading dimensions of cf */
+    const ltfatInt ld3b=q*q*W;
+
+    /* Leading dimensions of the 4dim array. */
+    const ltfatInt ld2ff=p*q*W;
+
+    for (ltfatInt r=0; r<c; r++)
+    {
+
+
+        LTFAT_COMPLEX *cfp=cf;
+
+        for (ltfatInt w=0; w<W; w++)
+        {
+            /* Complete inverse fac of coefficients */
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt u=0; u<q; u++)
+                {
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        const ltfatInt rem = r+l*c+positiverem(u+s*q-l*h_a,N)*M+w*ld4c;
+                        cbuf[s] = cwork[rem];
+                    }
+
+                    /* Do inverse fft of length d */
+                    LTFAT_FFTW(execute)(p_after);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        cfp[s*ld3b] =  cbuf[s];
+                    }
+                    /* Advance the cf pointer. This is only done in this
+                    * one place, because the loops are placed such that
+                    * this pointer will advance linearly through
+                    * memory. Reordering the loops will break this. */
+                    cfp++;
+                }
+            }
+        }
+
+
+
+        /* -------- compute matrix multiplication ---------- */
+
+
+        /* Do the matmul  */
+        for (ltfatInt s=0; s<d; s++)
+        {
+
+            const LTFAT_COMPLEX *gbase = gf+(r+s*c)*p*q;
+            LTFAT_COMPLEX       *fbase = ff+s*p*q*W;
+            const LTFAT_COMPLEX *cbase = (const LTFAT_COMPLEX *)cf+s*q*q*W;
+
+            for (ltfatInt nm=0; nm<q*W; nm++)
+            {
+                for (ltfatInt km=0; km<p; km++)
+                {
+
+                    fbase[km+nm*p]=0.0;
+                    for (ltfatInt mm=0; mm<q; mm++)
+                    {
+                        fbase[km+nm*p]+=gbase[km+mm*p]*cbase[mm+nm*q];
+                    }
+                    /* Scale because of FFTWs normalization. */
+                    fbase[km+nm*p]=fbase[km+nm*p]*scalconst;
+                }
+            }
+        }
+
+
+
+
+        /* ----------- compute inverse signal factorization ---------- */
+
+
+        LTFAT_COMPLEX *ffp = ff;
+        LTFAT_COMPLEX *fp  = f+r;
+
+        for (ltfatInt w=0; w<W; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        cbuf[s] = ffp[s*ld2ff];
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        const ltfatInt rem = positiverem(k*M+s*p*M-l*h_a*a, L);
+                        fp[rem] = cbuf[s];
+                    }
+
+                    /* Advance the ff pointer. This is only done in this
+                    * one place, because the loops are placed such that
+                    * this pointer will advance linearly through
+                    * memory. Reordering the loops will break this. */
+                    ffp++;
+                }
+            }
+            fp+=L;
+        }
+        fp-=L*W;
+
+        /* ----- Main loop ends here ------------- */
+    }
+
+    /* -----------  Clean up ----------------- */
+
+    LTFAT_FFTW(destroy_plan)(p_veryend);
+    LTFAT_FFTW(destroy_plan)(p_after);
+    LTFAT_FFTW(destroy_plan)(p_before);
+
+    LTFAT_SAFEFREEALL(cwork,ff,cf,cbuf);
+}
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgtreal_fac)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *gf,
+                         const ltfatInt L, const ltfatInt W,
+                         const ltfatInt a, const ltfatInt M,
+                         LTFAT_REAL *f)
+{
+
+    /*  --------- initial declarations -------------- */
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_FFTW(plan) p_before, p_after, p_veryend;
+    LTFAT_COMPLEX *ff, *cf, *cbuf;
+    LTFAT_REAL *cwork, *sbuf;
+
+    /* This is a floor operation. */
+    const ltfatInt M2= M/2+1;
+
+    /*  ----------- calculation of parameters and plans -------- */
+
+    const ltfatInt b=L/M;
+    const ltfatInt N=L/a;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    h_a=-h_a;
+
+    ff    = ltfat_malloc(d2*p*q*W*sizeof*ff);
+    cf    = ltfat_malloc(d2*q*q*W*sizeof*cf);
+    cwork = ltfat_malloc(M*N*W*sizeof*cwork);
+    cbuf  = ltfat_malloc(d2*sizeof*cbuf);
+    sbuf  = ltfat_malloc(d*sizeof*sbuf);
+
+    /* Scaling constant needed because of FFTWs normalization. */
+    const LTFAT_REAL scalconst = 1.0/((LTFAT_REAL)d*sqrt((LTFAT_REAL)M));
+
+    /* Create plans. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_c2r_1d)(d, cbuf, sbuf, FFTW_ESTIMATE);
+
+    p_after  = LTFAT_FFTW(plan_dft_r2c_1d)(d, sbuf, cbuf, FFTW_ESTIMATE);
+
+    /* Create plan. Copy data so we do not overwrite input. Therefore
+       it is ok to cast away the constness of cin. This transform
+       destroys its input by default, but the extra flag should prevent
+       this. */
+
+    // Downcast to int
+    int Mint = (int) M;
+    p_veryend = LTFAT_FFTW(plan_many_dft_c2r)(1, &Mint, N*W,
+                (LTFAT_COMPLEX *)cin, NULL,
+                1, M2,
+                cwork, NULL,
+                1, M,
+                FFTW_ESTIMATE+FFTW_PRESERVE_INPUT);
+
+
+    /* -------- Execute initial IFFT ------------------------ */
+    LTFAT_FFTW(execute)(p_veryend);
+
+
+
+    const ltfatInt ld4c=M*N;
+
+    /* Leading dimensions of cf */
+    const ltfatInt ld3b=q*q*W;
+
+    /* Leading dimensions of the 4dim array. */
+    const ltfatInt ld2ff=p*q*W;
+
+    /* -------- Main loop ----------------------------------- */
+    for (ltfatInt r=0; r<c; r++)
+    {
+
+        /* -------- compute coefficient factorization ----------- */
+
+        LTFAT_COMPLEX *cfp=cf;
+
+        for (ltfatInt w=0; w<W; w++)
+        {
+            /* Complete inverse fac of coefficients */
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt u=0; u<q; u++)
+                {
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        sbuf[s] = cwork[r+l*c+positiverem(u+s*q-l*h_a,N)*M+w*ld4c];
+                    }
+
+                    /* Do inverse fft of length d */
+                    LTFAT_FFTW(execute)(p_after);
+
+                    for (ltfatInt s=0; s<d2; s++)
+                    {
+                        cfp[s*ld3b] = cbuf[s];
+                    }
+                    /* Advance the cf pointer. This is only done in this
+                    * one place, because the loops are placed such that
+                    * this pointer will advance linearly through
+                    * memory. Reordering the loops will break this. */
+                    cfp++;
+                }
+            }
+        }
+
+
+        /* -------- compute matrix multiplication ---------- */
+
+
+        /* Do the matmul  */
+        for (ltfatInt s=0; s<d2; s++)
+        {
+            const LTFAT_COMPLEX *gbase = gf+(r+s*c)*p*q;
+            LTFAT_COMPLEX       *fbase = ff+s*p*q*W;
+            const LTFAT_COMPLEX *cbase = (const LTFAT_COMPLEX *)cf+s*q*q*W;
+
+            for (ltfatInt nm=0; nm<q*W; nm++)
+            {
+                for (ltfatInt km=0; km<p; km++)
+                {
+                    fbase[km+nm*p]=0.0;
+                    for (ltfatInt mm=0; mm<q; mm++)
+                    {
+                        fbase[km+nm*p]+=gbase[km+mm*p]*cbase[mm+nm*q];
+                    }
+                    /* Scale because of FFTWs normalization. */
+                    fbase[km+nm*p]=fbase[km+nm*p]*scalconst;
+                }
+            }
+        }
+
+
+        /* ----------- compute inverse signal factorization ---------- */
+
+        LTFAT_COMPLEX *ffp = ff;
+        LTFAT_REAL    *fp  = f+r;
+
+        for (ltfatInt w=0; w<W; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    for (ltfatInt s=0; s<d2; s++)
+                    {
+                        cbuf[s] = ffp[s*ld2ff];
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        fp[positiverem(k*M+s*p*M-l*h_a*a, L)] = sbuf[s];
+                    }
+
+                    /* Advance the ff pointer. This is only done in this
+                    * one place, because the loops are placed such that
+                    * this pointer will advance linearly through
+                    * memory. Reordering the loops will break this. */
+                    ffp++;
+                }
+            }
+            fp+=L;
+        }
+        fp-=L*W;
+
+
+        /*  ------- main loop ends -------- */
+    }
+
+    /* -----------  Clean up ----------------- */
+
+    LTFAT_FFTW(destroy_plan)(p_veryend);
+    LTFAT_FFTW(destroy_plan)(p_after);
+    LTFAT_FFTW(destroy_plan)(p_before);
+
+    LTFAT_SAFEFREEALL(cwork,ff,cf,cbuf,sbuf);
+}
diff --git a/src/idgt_fb.c b/src/idgt_fb.c
new file mode 100644
index 0000000..ee0d2da
--- /dev/null
+++ b/src/idgt_fb.c
@@ -0,0 +1,406 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#define THE_SUM { \
+	 /* Copy to c-buffer and ifft it */ \
+	 for (ltfatInt m=0; m<M; m++) \
+	 { \
+	    cbuf[m]=cin[m+n*M+w*M*N]; \
+	 } \
+	 LTFAT_FFTW(execute)(p_small); \
+\
+	 const ltfatInt rem = positiverem(-n*a+glh, M); \
+	 for (ltfatInt ii=0; ii<gl/M; ii++) \
+	 { \
+	    for (ltfatInt m=0; m<rem; m++) \
+	    { \
+	       ff[m+ii*M]=cbuf[M-rem+m]*gw[m+ii*M]; \
+	    } \
+	    for (ltfatInt m=0; m<M-rem; m++) \
+	    { \
+	       ff[m+ii*M+rem] = cbuf[m]*gw[m+rem+ii*M]; \
+	    } \
+	 } \
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_fb)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *g,
+                    const ltfatInt L, const ltfatInt gl, const ltfatInt W,
+                    const ltfatInt a, const ltfatInt M,
+                    LTFAT_COMPLEX *f)
+
+{
+    /*  --------- initial declarations -------------- */
+
+    const ltfatInt N=L/a;
+
+    ltfatInt ep, sp;
+
+    /* This is a floor operation. */
+    const ltfatInt glh=gl/2;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+    LTFAT_COMPLEX *fw;
+
+    LTFAT_COMPLEX *cbuf = ltfat_malloc(M*sizeof*cbuf);
+
+    /* Create plan. In-place. */
+    LTFAT_FFTW(plan) p_small = LTFAT_FFTW(plan_dft_1d)(M, cbuf, cbuf, FFTW_BACKWARD, FFTW_MEASURE);
+
+    /* % The fftshift actually makes some things easier. */
+    LTFAT_COMPLEX *gw  = ltfat_malloc(gl*sizeof*gw);
+    for (ltfatInt l=0; l<glh; l++)
+    {
+        gw[l] = g[l+(gl-glh)];
+    }
+    for (ltfatInt l=glh; l<gl; l++)
+    {
+        gw[l] = g[l-glh];
+    }
+
+    LTFAT_COMPLEX *ff  = ltfat_malloc(gl*sizeof*ff);
+
+    for (ltfatInt w=0; w<W; w++)
+    {
+        fw=f+w*L;
+        for (ltfatInt l=0; l<L; l++)
+        {
+            fw[l] = (LTFAT_COMPLEX) 0.0;
+        }
+        /* ----- Handle the first boundary using periodic boundary conditions. --- */
+        for (ltfatInt n=0; n<glh_d_a; n++)
+        {
+
+            THE_SUM;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* % Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<L-sp; ii++)
+            {
+                fw[sp+ii]+=ff[ii];
+            }
+            for (ltfatInt ii=0; ii<ep+1; ii++)
+            {
+                fw[ii] +=ff[L-sp+ii];
+            }
+        }
+
+
+        /* ----- Handle the middle case. --------------------- */
+        for (ltfatInt n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+        {
+
+            THE_SUM;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<ep-sp+1; ii++)
+            {
+                fw[ii+sp] += ff[ii];
+            }
+        }
+
+        /* Handle the last boundary using periodic boundary conditions. */
+        for (ltfatInt n=(L-(gl+1)/2)/a+1; n<N; n++)
+        {
+
+            THE_SUM;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<L-sp; ii++)
+            {
+                fw[sp+ii]+=ff[ii];
+            }
+            for (ltfatInt ii=0; ii<ep+1; ii++)
+            {
+                fw[ii] +=ff[L-sp+ii];
+            }
+
+        }
+    }
+
+    LTFAT_SAFEFREEALL(cbuf,ff,gw);
+    LTFAT_FFTW(destroy_plan)(p_small);
+
+}
+
+/* ------------------- IDGT_FB_R --------------------- */
+
+
+#define THE_SUM_R { \
+     \
+	 for (ltfatInt m=0; m<M; m++) \
+	 { \
+	    cbuf[m]=cin[m+n*M+w*M*N]; \
+	 } \
+	 LTFAT_FFTW(execute)(p_small); \
+\
+	 const ltfatInt rem = positiverem(-n*a+glh, M); \
+	 for (ltfatInt ii=0; ii<gl/M; ii++) \
+	 { \
+	    for (ltfatInt m=0; m<rem; m++) \
+	    { \
+	       ff[m+ii*M] = cbuf[M-rem+m]*gw[m+ii*M]; \
+	    } \
+	    for (ltfatInt m=0; m<M-rem; m++) \
+	    { \
+	       ff[m+ii*M+rem] = cbuf[m]*gw[m+rem+ii*M]; \
+	    } \
+	 } \
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_fb_r)(const LTFAT_COMPLEX *cin, const LTFAT_REAL *g,
+                      const ltfatInt L, const ltfatInt gl, const ltfatInt W,
+                      const ltfatInt a, const ltfatInt M,
+                      LTFAT_COMPLEX *f)
+
+{
+    /*  --------- initial declarations -------------- */
+
+    const ltfatInt N=L/a;
+
+    ltfatInt ep, sp;
+
+    /* This is a floor operation. */
+    const ltfatInt glh=gl/2;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+    LTFAT_COMPLEX *fw;
+
+    LTFAT_COMPLEX *cbuf = (LTFAT_COMPLEX*)ltfat_malloc(M*sizeof(LTFAT_COMPLEX));
+
+    /* Create plan. In-place. */
+    LTFAT_FFTW(plan) p_small = LTFAT_FFTW(plan_dft_1d)(M, cbuf, cbuf, FFTW_BACKWARD, FFTW_MEASURE);
+
+    /* % The fftshift actually makes some things easier. */
+    LTFAT_REAL *gw  = (LTFAT_REAL*)ltfat_malloc(gl*sizeof(LTFAT_REAL));
+    for (ltfatInt l=0; l<glh; l++)
+    {
+        gw[l] = g[l+(gl-glh)];
+    }
+    for (ltfatInt l=glh; l<gl; l++)
+    {
+        gw[l] = g[l-glh];
+    }
+
+    LTFAT_COMPLEX *ff  = (LTFAT_COMPLEX*)ltfat_malloc(gl*sizeof(LTFAT_COMPLEX));
+
+    for (ltfatInt w=0; w<W; w++)
+    {
+        fw=f+w*L;
+        for (ltfatInt l=0; l<L; l++)
+        {
+            fw[l]=(LTFAT_COMPLEX)0.0;
+        }
+        /* ----- Handle the first boundary using periodic boundary conditions. --- */
+        for (ltfatInt n=0; n<glh_d_a; n++)
+        {
+
+            THE_SUM_R;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* % Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<L-sp; ii++)
+            {
+                fw[sp+ii]+=ff[ii];
+            }
+            for (ltfatInt ii=0; ii<ep+1; ii++)
+            {
+                fw[ii] +=ff[L-sp+ii];
+            }
+        }
+
+
+        /* ----- Handle the middle case. --------------------- */
+        for (ltfatInt n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+        {
+
+            THE_SUM_R;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<ep-sp+1; ii++)
+            {
+                fw[ii+sp] += ff[ii];
+            }
+        }
+
+        /* Handle the last boundary using periodic boundary conditions. */
+        for (ltfatInt n=(L-(gl+1)/2)/a+1; n<N; n++)
+        {
+
+            THE_SUM_R;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<L-sp; ii++)
+            {
+                fw[sp+ii]+=ff[ii];
+            }
+            for (ltfatInt ii=0; ii<ep+1; ii++)
+            {
+                fw[ii] +=ff[L-sp+ii];
+            }
+
+        }
+    }
+
+    LTFAT_SAFEFREEALL(cbuf,ff,gw);
+    LTFAT_FFTW(destroy_plan)(p_small);
+
+}
+
+
+
+
+/* ------------------- IDGTREAL ---------------------- */
+
+#define THE_SUM_REAL { \
+	 for (ltfatInt m=0; m<M2; m++) \
+	 { \
+	    cbuf[m]=cin[m+n*M2+w*M2*N]; \
+	 } \
+	 LTFAT_FFTW(execute)(p_small); \
+\
+	 const ltfatInt rem = positiverem(-n*a+glh, M); \
+	 for (ltfatInt ii=0; ii<gl/M; ii++) \
+	 { \
+	    for (ltfatInt m=0; m<rem; m++) \
+	    { \
+	       ff[m+ii*M] = crbuf[M-rem+m]*gw[m+ii*M]; \
+	    } \
+	    for (ltfatInt m=0; m<M-rem; m++) \
+	    { \
+	       ff[m+ii*M+rem] = crbuf[m]*gw[m+rem+ii*M]; \
+	    } \
+	 } \
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgtreal_fb)(const LTFAT_COMPLEX *cin, const LTFAT_REAL *g,
+                        const ltfatInt L, const ltfatInt gl, const ltfatInt W,
+                        const ltfatInt a, const ltfatInt M,
+                        LTFAT_REAL *f)
+
+{
+    /*  --------- initial declarations -------------- */
+
+    const ltfatInt N=L/a;
+
+    /* This is a floor operation. */
+    const ltfatInt M2= M/2+1;
+
+    ltfatInt ep, sp;
+
+    /* This is a floor operation. */
+    const ltfatInt glh=gl/2;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+    LTFAT_REAL *fw;
+
+    LTFAT_COMPLEX *cbuf  = ltfat_malloc(M2*sizeof*cbuf);
+    LTFAT_REAL    *crbuf = ltfat_malloc( M*sizeof*crbuf);
+
+    /* Create plan. In-place. */
+    LTFAT_FFTW(plan) p_small = LTFAT_FFTW(plan_dft_c2r_1d)(M, cbuf, crbuf, FFTW_MEASURE);
+
+    /* % The fftshift actually makes some things easier. */
+    LTFAT_REAL *gw  = ltfat_malloc(gl*sizeof*gw);
+    for (ltfatInt l=0; l<glh; l++)
+    {
+        gw[l] = g[l+(gl-glh)];
+    }
+    for (ltfatInt l=glh; l<gl; l++)
+    {
+        gw[l] = g[l-glh];
+    }
+
+    LTFAT_REAL *ff  = ltfat_malloc(gl*sizeof*ff);
+
+    for (ltfatInt w=0; w<W; w++)
+    {
+        fw=f+w*L;
+        for (ltfatInt l=0; l<L; l++)
+        {
+            fw[l]=0.0;
+        }
+        /* ----- Handle the first boundary using periodic boundary conditions. --- */
+        for (ltfatInt n=0; n<glh_d_a; n++)
+        {
+
+            THE_SUM_REAL;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* % Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<L-sp; ii++)
+            {
+                fw[sp+ii]+=ff[ii];
+            }
+            for (ltfatInt ii=0; ii<ep+1; ii++)
+            {
+                fw[ii] +=ff[L-sp+ii];
+            }
+        }
+
+
+        /* ----- Handle the middle case. --------------------- */
+        for (ltfatInt n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+        {
+
+            THE_SUM_REAL;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<ep-sp+1; ii++)
+            {
+                fw[ii+sp] += ff[ii];
+            }
+        }
+
+        /* Handle the last boundary using periodic boundary conditions. */
+        for (ltfatInt n=(L-(gl+1)/2)/a+1; n<N; n++)
+        {
+
+            THE_SUM_REAL;
+
+            sp=positiverem(n*a-glh,L);
+            ep=positiverem(n*a-glh+gl-1,L);
+
+            /* Add the ff vector to f at position sp. */
+            for (ltfatInt ii=0; ii<L-sp; ii++)
+            {
+                fw[sp+ii]+=ff[ii];
+            }
+            for (ltfatInt ii=0; ii<ep+1; ii++)
+            {
+                fw[ii] +=ff[L-sp+ii];
+            }
+
+        }
+    }
+
+    LTFAT_SAFEFREEALL(cbuf,crbuf,ff,gw);
+    LTFAT_FFTW(destroy_plan)(p_small);
+
+}
diff --git a/src/idwilt.c b/src/idwilt.c
new file mode 100644
index 0000000..8ff5366
--- /dev/null
+++ b/src/idwilt.c
@@ -0,0 +1,153 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#define CH(name) LTFAT_COMPLEXH(name)
+
+#define PREPROC_REAL \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     pcoef2[0]=pcoef[0]; \
+\
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+        pcoef2[m] = -I*scalconst*(pcoef[m]); \
+        pcoef2[m+coef2_ld] = scalconst*(pcoef[m+M]); \
+     } \
+ \
+     for (ltfatInt m=2;m<M;m+=2) \
+     { \
+        pcoef2[m] = scalconst*(pcoef[m]); \
+        pcoef2[m+coef2_ld] = -I*scalconst*(pcoef[m+M]); \
+     } \
+ \
+     pcoef2[M+nyquestadd] = pcoef[M]; \
+     pcoef+=2*M; \
+     pcoef2+=2*coef2_ld; \
+  }
+
+#define PREPROC_COMPLEX \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     pcoef2[0] = pcoef[0]; \
+ \
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+        pcoef2[m] = -I*scalconst*pcoef[m]; \
+        pcoef2[M2-m] = I*scalconst*pcoef[m]; \
+        pcoef2[M2+m] =  scalconst*pcoef[m+M]; \
+        pcoef2[M4-m] = scalconst*pcoef[m+M]; \
+     } \
+ \
+     for (ltfatInt m=2;m<M;m+=2) \
+     { \
+        pcoef2[m] = scalconst*pcoef[m]; \
+        pcoef2[M2-m] = scalconst*pcoef[m]; \
+        pcoef2[M2+m] =  -I*scalconst*pcoef[m+M]; \
+        pcoef2[M4-m] = I*scalconst*pcoef[m+M]; \
+     } \
+ \
+     pcoef2[M+nyquestadd] = pcoef[M]; \
+     pcoef+=M2; \
+     pcoef2+=M4; \
+  }
+
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(idwilt_long)(const LTFAT_COMPLEX *c, const LTFAT_COMPLEX *g,
+                                const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                                LTFAT_COMPLEX *f)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc(2*M*N*W,sizeof*coef2);
+
+    const ltfatInt nyquestadd = (M%2)*M2;
+
+    const LTFAT_COMPLEX *pcoef  = c;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    PREPROC_COMPLEX
+
+    LTFAT_NAME(idgt_long)(coef2, g, L, W, M, 2*M, f);
+
+    ltfat_free(coef2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(idwilt_long)(const LTFAT_REAL *c, const LTFAT_REAL *g,
+                             const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                             LTFAT_REAL *f)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt coef2_ld = M+1;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const ltfatInt nyquestadd = (M%2)*coef2_ld;
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc((M+1)*N*W,sizeof*coef2);
+
+    const LTFAT_REAL *pcoef  = c;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    PREPROC_REAL
+
+    LTFAT_NAME(idgtreal_long)(coef2, g, L, W, M, 2*M, f);
+
+    ltfat_free(coef2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(idwilt_fb)(const LTFAT_COMPLEX *c, const LTFAT_COMPLEX *g,
+                              const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                              LTFAT_COMPLEX *f)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc(2*M*N*W,sizeof*coef2);
+
+    const ltfatInt nyquestadd = (M%2)*M2;
+
+    const LTFAT_COMPLEX *pcoef  = c;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    PREPROC_COMPLEX
+
+    LTFAT_NAME(idgt_fb)(coef2, g, L, gl, W, M, 2*M, f);
+
+    ltfat_free(coef2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(idwilt_fb)(const LTFAT_REAL *c, const LTFAT_REAL *g,
+                           const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                           LTFAT_REAL *f)
+{
+    const ltfatInt N = L/M;
+    const ltfatInt coef2_ld = M + 1;
+    const ltfatInt nyquestadd = (M%2)*coef2_ld;
+    const LTFAT_REAL scalconst = (LTFAT_REAL) 1.0/sqrt(2.0);
+
+    LTFAT_COMPLEX *coef2 = (LTFAT_COMPLEX*)ltfat_calloc((M+1)*N*W,sizeof(LTFAT_COMPLEX));
+
+    const LTFAT_REAL* pcoef  = c;
+    LTFAT_COMPLEX* pcoef2 = coef2;
+
+    PREPROC_REAL
+
+    LTFAT_NAME(idgtreal_fb)(coef2, g, L, gl, W, M, 2*M, f);
+
+    ltfat_free(coef2);
+}
+
+#undef CH
+#undef PREPROC_REAL
+#undef PREPROC_COMPLEX
+
diff --git a/src/ifilterbank.c b/src/ifilterbank.c
new file mode 100644
index 0000000..acdbfe9
--- /dev/null
+++ b/src/ifilterbank.c
@@ -0,0 +1,301 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+struct LTFAT_NAME(upconv_fft_plan_struct)
+{
+    const ltfatInt L;
+    const ltfatInt W;
+    const ltfatInt a;
+    const LTFAT_FFTW(plan) p_c;
+    LTFAT_COMPLEX* buf;
+    const ltfatInt bufLen;
+};
+
+struct LTFAT_NAME(upconv_fftbl_plan_struct)
+{
+    const ltfatInt L;
+    const ltfatInt Gl;
+    const ltfatInt W;
+    const double a;
+    const LTFAT_FFTW(plan) p_c;
+    LTFAT_COMPLEX* buf;
+    const ltfatInt bufLen;
+};
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fft)(const LTFAT_COMPLEX *cin[], const LTFAT_COMPLEX *G[],
+                            const ltfatInt L, const ltfatInt W, const ltfatInt a[], const ltfatInt M,
+                            LTFAT_COMPLEX *F)
+{
+    // This is necessary since F us used as an accumulator
+    memset(F,0,L*W*sizeof*F);
+
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(upconv_fft)(cin[m],G[m],L,W,a[m],F);
+    }
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fft_execute)(LTFAT_NAME(upconv_fft_plan) p[],
+                                    const LTFAT_COMPLEX *cin[],
+                                    const LTFAT_COMPLEX *G[],
+                                    const ltfatInt M,
+                                    LTFAT_COMPLEX *F )
+{
+    ltfatInt L = p[0]->L;
+    ltfatInt W = p[0]->W;
+    // This is necessary since F us used as an accumulator
+    memset(F,0,W*L*sizeof*F);
+
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(upconv_fft_execute)(p[m], cin[m], G[m], F);
+    }
+}
+
+
+// Inverse
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fft)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                       const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                       LTFAT_COMPLEX *F)
+{
+    LTFAT_NAME(upconv_fft_plan) p =
+        LTFAT_NAME(upconv_fft_init)(L,W, a);
+
+    LTFAT_NAME(upconv_fft_execute)(p,cin, G, F);
+
+    LTFAT_NAME(upconv_fft_done)(p);
+}
+
+LTFAT_EXTERN LTFAT_NAME(upconv_fft_plan)
+LTFAT_NAME(upconv_fft_init)(const ltfatInt L, const ltfatInt W, const ltfatInt a)
+{
+    ltfatInt N = L/a;
+    int Nint = (int) N;
+
+    const LTFAT_FFTW(iodim) dims = {.n = Nint, .is = 1, .os = 1};
+    const LTFAT_FFTW(iodim) howmany_dims = {.n = W,.is = Nint, .os = Nint};
+
+    LTFAT_COMPLEX* buf = ltfat_malloc(W*N*sizeof*buf);
+    LTFAT_FFTW(plan) p_many =
+        LTFAT_FFTW(plan_guru_dft)(1, &dims, 1, &howmany_dims,
+                                  buf, buf,
+                                  FFTW_FORWARD, FFTW_ESTIMATE);
+
+    struct LTFAT_NAME(upconv_fft_plan_struct) p_struct =
+    { .L = L, .a = a, .W = W, .p_c = p_many, .buf=buf, .bufLen=W*N };
+
+    LTFAT_NAME(upconv_fft_plan) p = ltfat_malloc(sizeof*p);
+    memcpy(p,&p_struct,sizeof*p);
+    return p;
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fft_execute)(LTFAT_NAME(upconv_fft_plan) p,
+                               const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                               LTFAT_COMPLEX *F)
+{
+    const ltfatInt L = p->L;
+    const ltfatInt a = p->a;
+    const ltfatInt W = p->W;
+    LTFAT_COMPLEX* buf = p->buf;
+    ltfatInt N = L/a;
+    memcpy(buf,cin,W*N*sizeof*cin);
+
+
+    // New array execution, inplace
+    LTFAT_FFTW(execute_dft)(p->p_c,buf,buf);
+
+    for(ltfatInt w=0; w<W; w++)
+    {
+        LTFAT_COMPLEX *FPtr = F + w*L;
+        LTFAT_COMPLEX *GPtr = (LTFAT_COMPLEX *) G;
+        for(ltfatInt jj=0; jj<a; jj++)
+        {
+            for(ltfatInt ii=0; ii<N; ii++)
+            {
+                // Really readable ;)
+                *FPtr++ += LTFAT_COMPLEXH(conj)(*GPtr++)*buf[ii+N*w];
+            }
+        }
+    }
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fft_done)(LTFAT_NAME(upconv_fft_plan) p)
+{
+    LTFAT_FFTW(destroy_plan)(p->p_c);
+    ltfat_free(p->buf);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fftbl)(const LTFAT_COMPLEX *cin[], const LTFAT_COMPLEX *G[],
+                              const ltfatInt L, const ltfatInt Gl[],
+                              const ltfatInt W, const double a[], const ltfatInt M,
+                              const ltfatInt foff[], const int realonly[],
+                              LTFAT_COMPLEX *F)
+{
+    // This is necessary since F us used as an accumulator
+    memset(F,0,W*L*sizeof*F);
+
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(upconv_fftbl)(cin[m],G[m],L,Gl[m],W,a[m],foff[m],realonly[m],F);
+    }
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fftbl_execute)(LTFAT_NAME(upconv_fftbl_plan) p[],
+                                      const LTFAT_COMPLEX *cin[],
+                                      const LTFAT_COMPLEX *G[],
+                                      const ltfatInt M, const ltfatInt foff[],
+                                      const int realonly[],
+                                      LTFAT_COMPLEX *F)
+{
+    ltfatInt L = p[0]->L;
+    ltfatInt W = p[0]->W;
+    // This is necessary since F us used as an accumulator
+    memset(F,0,W*L*sizeof*F);
+
+    for(ltfatInt m =0; m<M; m++)
+    {
+        LTFAT_NAME(upconv_fftbl_execute)(p[m],cin[m],G[m],foff[m],realonly[m],F);
+    }
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fftbl)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                         const ltfatInt L, const ltfatInt Gl, const ltfatInt W,
+                         const double a,
+                         const ltfatInt foff, const int realonly,
+                         LTFAT_COMPLEX *F)
+{
+    LTFAT_NAME(upconv_fftbl_plan) p =
+        LTFAT_NAME(upconv_fftbl_init)( L, Gl, W, a);
+
+    LTFAT_NAME(upconv_fftbl_execute)(p,cin,G,foff,realonly,F);
+
+    LTFAT_NAME(upconv_fftbl_done)( p);
+}
+
+LTFAT_EXTERN LTFAT_NAME(upconv_fftbl_plan)
+LTFAT_NAME(upconv_fftbl_init)( const ltfatInt L, const ltfatInt Gl,
+                               const ltfatInt W, const double a)
+{
+    ltfatInt N = (ltfatInt) floor(L/a + 0.5);
+    int Nint = (int) N;
+
+    const LTFAT_FFTW(iodim) dims = {.n = Nint, .is = 1, .os = 1};
+    const LTFAT_FFTW(iodim) howmany_dims = {.n = W,.is = Nint, .os = Nint};
+
+    LTFAT_COMPLEX* buf = ltfat_malloc(N*W*sizeof*buf);
+    LTFAT_FFTW(plan) p_many =
+        LTFAT_FFTW(plan_guru_dft)(1, &dims, 1, &howmany_dims,
+                                  buf, buf,
+                                  FFTW_FORWARD, FFTW_ESTIMATE);
+
+
+    struct LTFAT_NAME(upconv_fftbl_plan_struct) p_struct =
+    {
+        .L = L, .Gl = Gl, .a = a, .W = W,
+        .p_c = p_many, .buf = buf, .bufLen = N*W
+    };
+
+    LTFAT_NAME(upconv_fftbl_plan) p = ltfat_malloc(sizeof*p);
+    memcpy(p,&p_struct,sizeof*p);
+    return p;
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fftbl_execute)(const LTFAT_NAME(upconv_fftbl_plan) p,
+                                 const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                                 const ltfatInt foff,
+                                 const int realonly, LTFAT_COMPLEX *F)
+{
+    const ltfatInt L = p->L;
+    const ltfatInt W = p->W;
+    const ltfatInt Gl = p->Gl;
+    const double a = p->a;
+    LTFAT_COMPLEX* cbuf = p->buf;
+
+    ltfatInt N = (ltfatInt) floor(L/a + 0.5);
+    memcpy(cbuf,cin,N*W*sizeof*cin);
+    LTFAT_FFTW(execute_dft)(p->p_c,cbuf,cbuf);
+
+    for(ltfatInt w=0; w<W; w++)
+    {
+
+        LTFAT_NAME_COMPLEX(circshift)(cbuf+w*N,cbuf+w*N,N,-foff);
+        //LTFAT_NAME_COMPLEX(circshift)(cbuf+w*N,cbuf+w*N,N,Gl/2);
+
+        const LTFAT_COMPLEX* GPtrTmp = G;
+        LTFAT_COMPLEX* FPtrTmp = F+w*L;
+        LTFAT_COMPLEX* CPtrTmp = cbuf+w*N;
+
+        // Determine range of G
+        ltfatInt foffTmp = foff;
+        ltfatInt tmpLg = N<Gl?N:Gl;
+        ltfatInt over = 0;
+        if(foffTmp+tmpLg>(ltfatInt)L)
+        {
+            over = foffTmp+tmpLg - (ltfatInt)L;
+        }
+
+
+        if(foffTmp<0)
+        {
+            ltfatInt toCopy = (-foffTmp)<tmpLg?-foffTmp:tmpLg;
+            FPtrTmp = F+(w+1)*L+foffTmp;
+            for(ltfatInt ii=0; ii<toCopy; ii++)
+            {
+                LTFAT_COMPLEX tmp = *CPtrTmp++ * LTFAT_COMPLEXH(conj)(*GPtrTmp++);
+                FPtrTmp[ii]+= tmp;
+            }
+
+            tmpLg-=toCopy;
+            foffTmp = 0;
+        }
+
+        FPtrTmp = F+w*L+foffTmp;
+        for(ltfatInt ii=0; ii<tmpLg-over; ii++)
+        {
+            LTFAT_COMPLEX tmp = *CPtrTmp++ * LTFAT_COMPLEXH(conj)(*GPtrTmp++);
+            FPtrTmp[ii]+=tmp;
+        }
+
+        FPtrTmp = F+w*L;
+        for(ltfatInt ii=0; ii<over; ii++)
+        {
+            LTFAT_COMPLEX tmp = (*CPtrTmp++ * LTFAT_COMPLEXH(conj)(*GPtrTmp++));
+            FPtrTmp[ii]+= tmp;
+        }
+    }
+
+
+    if(realonly)
+    {
+        const ltfatInt foffconj = positiverem(L-foff-Gl,L)+1;
+        LTFAT_COMPLEX *Gconj = ltfat_malloc(Gl*sizeof*Gconj);
+        LTFAT_NAME_COMPLEX(reverse_array)((LTFAT_COMPLEX *)G,Gconj,Gl);
+        LTFAT_NAME_COMPLEX(conjugate_array)(Gconj,Gconj,Gl);
+
+        LTFAT_NAME(upconv_fftbl_execute)(p,cin, Gconj, foffconj, false, F);
+        ltfat_free(Gconj);
+    }
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fftbl_done)(LTFAT_NAME(upconv_fftbl_plan) p)
+{
+    LTFAT_FFTW(destroy_plan)(p->p_c);
+    ltfat_free(p->buf);
+}
diff --git a/src/integer_manip.c b/src/integer_manip.c
new file mode 100644
index 0000000..767be27
--- /dev/null
+++ b/src/integer_manip.c
@@ -0,0 +1,279 @@
+#include "ltfat.h"
+
+
+LTFAT_EXTERN_TOO void
+fftindex(const ltfatInt N, ltfatInt *indexout)
+{
+    ltfatInt ii;
+
+    if (N%2==0)
+    {
+        for (ii=0; ii<N/2+1; ii++)
+        {
+            indexout[ii]=ii;
+        }
+        for (ii=N/2; ii<N-1; ii++)
+        {
+            indexout[ii+1]=-N+ii+1;
+        }
+    }
+    else
+    {
+        for (ii=0; ii<(N-1)/2+1; ii++)
+        {
+            indexout[ii]=ii;
+        }
+        for (ii=(N-1)/2; ii<N-1; ii++)
+        {
+            indexout[ii+1]=-N+ii+1;
+        }
+    }
+
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+imax(const ltfatInt a, const ltfatInt b)
+{
+   return (a > b ? a : b);
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+imin(const ltfatInt a, const ltfatInt b)
+{
+   return (a < b ? a : b);
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+makelarger(const ltfatInt L, const ltfatInt K)
+{
+    /* This is a floor operation */
+    ltfatInt o = (L/K)*K;
+
+    /* Make it a ceil */
+    if (L%K>0)
+    {
+        o += K;
+    }
+
+    return o;
+}
+
+/* Extended Euclid algorithm. */
+LTFAT_EXTERN_TOO ltfatInt
+gcd (const ltfatInt a, const ltfatInt b, ltfatInt *r, ltfatInt *s )
+{
+    ltfatInt a1 = a;
+    ltfatInt b1 = b;
+    ltfatInt a2 = 1;
+    ltfatInt b2 = 0;
+    ltfatInt a3 = 0;
+    ltfatInt b3 = 1;
+    ltfatInt c, d;
+    while ( b1 != 0 )
+    {
+        d=a1/b1;
+        c = a1;
+        a1 = b1;
+        b1 = c-d*b1;
+
+        c = a2;
+        a2 = b2;
+        b2 = c-d*b2;
+
+        c = a3;
+        a3 = b3;
+        b3 = c-d*b3;
+
+    }
+
+    *r=a2;
+    *s=a3;
+    return a1;
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+lcm(const ltfatInt a, const ltfatInt b)
+{
+    ltfatInt junk_r, junk_s;
+
+    ltfatInt c = gcd(a, b, &junk_r, &junk_s);
+
+    return (a*b/c);
+}
+
+
+LTFAT_EXTERN_TOO void
+gabimagepars(const ltfatInt Ls, const ltfatInt x, const ltfatInt y,
+             ltfatInt *a, ltfatInt *M, ltfatInt *L, ltfatInt *N, ltfatInt *Ngood)
+{
+
+
+    *M = imin(y,Ls);
+    *N = imax(x,Ls);
+
+    /* Determine the minimum transform size. */
+    ltfatInt K = lcm(*M,*N);
+
+    /* This L is good, but is it not the same as DGT will choose. */
+    ltfatInt Llong = makelarger(Ls,K);
+
+    /* Fix a from the long L */
+    *a=Llong/(*N);
+
+    /* Now we have fixed a and M, so we can use the standard method of choosing L. */
+    ltfatInt Lsmallest=lcm(*a,*M);
+    *L = makelarger(Ls, Lsmallest);
+
+    /* We did not get N as desired. */
+    *N=*L/(*a);
+
+    /* Number of columns to display */
+    *Ngood=(Ls/(*a));
+}
+
+/* Determine the size of the output array of wfacreal and iwfacreal */
+LTFAT_EXTERN_TOO ltfatInt
+wfacreal_size(const ltfatInt L, const ltfatInt a, const ltfatInt M)
+{
+
+    ltfatInt h_a, h_m;
+
+    const ltfatInt b=L/M;
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt d=b/p;
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    return d2*p*M;
+
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+nextPow2(const ltfatInt y)
+{
+    ltfatInt x = (ltfatInt) y;
+    ltfatInt bits = sizeof(x)*8;
+
+    if(x==0)
+        return 1;
+
+    x--;
+    (x) = ((x)>>1)  | (x);
+    (x) = ((x)>>2)  | (x);
+    (x) = ((x)>>4)  | (x);
+    (x) = ((x)>>8)  | (x);
+    (x) = ((x)>>16) | (x);
+    if(bits>32)
+        (x) = ((x)>>32) | (x);
+
+    (x)++;
+    return x;
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+nextfastfft(const ltfatInt x)
+{
+   ltfatInt xtmp = x;
+    while (1)
+    {
+        ltfatInt m = xtmp;
+
+        while ((m % 2) == 0)
+            m /= 2;
+        while ((m % 3) == 0)
+            m /= 3;
+        while ((m % 5) == 0)
+            m /= 5;
+        if (m <= 1)
+            break;                    /* n is completely factorable by twos, threes, and fives */
+        xtmp++;
+    }
+    return xtmp;
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+pow2(const ltfatInt x)
+{
+    return ((1)<<(x));
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+modPow2(const ltfatInt x, const ltfatInt pow2var)
+{
+    return ((x)&(pow2var-1));
+}
+
+LTFAT_EXTERN_TOO int
+isPow2(const ltfatInt x)
+{
+    return x==nextPow2(x);
+}
+
+LTFAT_EXTERN_TOO int
+ilog2(const ltfatInt x)
+{
+    ltfatInt tmp = 0;
+    ltfatInt xtmp = x;
+     while (xtmp >>= 1) ++tmp;
+    return tmp;
+}
+
+// integer power by squaring
+LTFAT_EXTERN_TOO ltfatInt
+ipow(const ltfatInt base, const ltfatInt exp)
+{
+    ltfatInt baseTmp = (ltfatInt) base;
+    ltfatInt expTmp = (ltfatInt) exp;
+    ltfatInt result = 1;
+
+    while (expTmp)
+    {
+        if (expTmp & 1)
+            result *= baseTmp;
+        expTmp >>= 1;
+        baseTmp *= baseTmp;
+    }
+
+    return result;
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+filterbank_td_size(const ltfatInt L, const ltfatInt a, const ltfatInt gl,
+                   const ltfatInt offset, const ltfatExtType ext)
+{
+    ltfatInt Lc = 0;
+    if(ext==PER)
+    {
+        Lc = (ltfatInt) ceil( L/((double)a) );
+    }
+    else if(ext==VALID)
+    {
+        Lc = (ltfatInt) ceil( (L-(gl-1))/((double)a) );
+
+    }
+    else
+    {
+        Lc = (ltfatInt) ceil( (L + gl - 1 + offset )/((double)a) );
+    }
+    return Lc;
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+ltfat_round(const double x)
+{
+    if (x < 0.0)
+        return (ltfatInt)(x - 0.5);
+    else
+        return (ltfatInt)(x + 0.5);
+}
+
+LTFAT_EXTERN_TOO ltfatInt
+positiverem(const ltfatInt a,const ltfatInt b)
+{
+    const ltfatInt c = a%b;
+    return(c<0 ? c+b : c);
+}
+
+
diff --git a/src/iwfac.c b/src/iwfac.c
new file mode 100644
index 0000000..57e340e
--- /dev/null
+++ b/src/iwfac.c
@@ -0,0 +1,206 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(iwfac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                          const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *g)
+{
+
+    ltfatInt h_a, h_m;
+
+    ltfatInt rem, negrem;
+
+    LTFAT_REAL scaling, *sbuf, *gfp;
+
+    LTFAT_FFTW(plan) p_before;
+
+    const ltfatInt b=L/M;
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    /* division by d is because of the way FFTW normalizes the transform. */
+    scaling=1.0/sqrt(M)/d;
+
+    sbuf = ltfat_malloc(2*d*sizeof*sbuf);
+
+    /* Create plan. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)sbuf, (LTFAT_COMPLEX*)sbuf,
+                                       FFTW_BACKWARD, FFTW_MEASURE);
+
+
+
+    const ltfatInt ld3=c*p*q*R;
+    gfp=(LTFAT_REAL*)gf;
+
+    for (ltfatInt r=0; r<c; r++)
+    {
+        for (ltfatInt w=0; w<R; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    negrem=positiverem(k*M-l*a,L);
+                    for (ltfatInt s=0; s<2*d; s+=2)
+                    {
+                        sbuf[s]   = gfp[s*ld3]*scaling;
+                        sbuf[s+1] = gfp[s*ld3+1]*scaling;
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        rem = (negrem+s*p*M)%L;
+                        LTFAT_REAL* gTmp = (LTFAT_REAL*) &(g[r+rem+L*w]);
+                        gTmp[0] = sbuf[2*s];
+                        gTmp[1] = sbuf[2*s+1];
+                    }
+                    gfp+=2;
+                }
+            }
+        }
+    }
+
+    /* Clear the work-array. */
+    ltfat_free(sbuf);
+    LTFAT_FFTW(destroy_plan)(p_before);
+}
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(iwfac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                       const ltfatInt a, const ltfatInt M, LTFAT_REAL *g)
+{
+
+    ltfatInt h_a, h_m;
+
+    ltfatInt rem, negrem;
+
+    LTFAT_REAL scaling, *sbuf, *gfp;
+
+    LTFAT_FFTW(plan) p_before;
+
+    const ltfatInt b=L/M;
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    /* division by d is because of the way FFTW normalizes the transform. */
+    scaling=1.0/sqrt(M)/d;
+
+    sbuf = ltfat_malloc(2*d*sizeof*sbuf);
+
+    /* Create plan. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)sbuf, (LTFAT_COMPLEX*)sbuf,
+                                       FFTW_BACKWARD, FFTW_MEASURE);
+
+
+
+    const ltfatInt ld3=c*p*q*R;
+    gfp=(LTFAT_REAL*)gf;
+
+    for (ltfatInt r=0; r<c; r++)
+    {
+        for (ltfatInt w=0; w<R; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    negrem=positiverem(k*M-l*a,L);
+                    for (ltfatInt s=0; s<2*d; s+=2)
+                    {
+                        sbuf[s]   = gfp[s*ld3]*scaling;
+                        sbuf[s+1] = gfp[s*ld3+1]*scaling;
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        rem = (negrem+s*p*M)%L;
+                        g[r+rem+L*w] = sbuf[2*s];
+                    }
+                    gfp+=2;
+                }
+            }
+        }
+    }
+
+    /* Clear the work-array. */
+    ltfat_free(sbuf);
+    LTFAT_FFTW(destroy_plan)(p_before);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(iwfacreal)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                      const ltfatInt a, const ltfatInt M, LTFAT_REAL *g)
+{
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_FFTW(plan) p_before;
+
+    const ltfatInt b=L/M;
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    /* division by d is because of the way FFTW normalizes the transform. */
+    const LTFAT_REAL scaling=1.0/sqrt(M)/d;
+
+    LTFAT_REAL    *sbuf = ltfat_malloc( d*sizeof*sbuf);
+    LTFAT_COMPLEX *cbuf = ltfat_malloc(d2*sizeof*cbuf);
+
+    /* Create plan. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_c2r_1d)(d, cbuf, sbuf, FFTW_MEASURE);
+
+    const ltfatInt ld3=c*p*q*R;
+
+    /* Advancing pointer: Runs through array pointing out the base for the strided operations. */
+    const LTFAT_COMPLEX *gfp = gf;
+
+    for (ltfatInt r=0; r<c; r++)
+    {
+        for (ltfatInt w=0; w<R; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    const ltfatInt negrem=positiverem(k*M-l*a,L);
+                    for (ltfatInt s=0; s<d2; s++)
+                    {
+                        cbuf[s] = gfp[s*ld3]*scaling;
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (ltfatInt s=0; s<d; s++)
+                    {
+                        g[r+(negrem+s*p*M)%L+L*w] = sbuf[s];
+                    }
+                    gfp++;
+                }
+            }
+        }
+    }
+
+    /* Clear the work-arrays. */
+    LTFAT_SAFEFREEALL(cbuf,sbuf);
+
+    LTFAT_FFTW(destroy_plan)(p_before);
+}
+
+
+
diff --git a/src/iwmdct.c b/src/iwmdct.c
new file mode 100644
index 0000000..8408055
--- /dev/null
+++ b/src/iwmdct.c
@@ -0,0 +1,163 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#define CH(name) LTFAT_COMPLEXH(name)
+
+#define PREPROC_COMPLEX \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     for (ltfatInt m=0;m<M;m+=2) \
+     { \
+        pcoef2[m] = eipi4*pcoef[m]; \
+        pcoef2[M2-1-m] = emipi4*pcoef[m]; \
+        pcoef2[m+M2] = emipi4*pcoef[m+M]; \
+        pcoef2[M4-1-m] = eipi4*pcoef[m+M]; \
+     } \
+ \
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+        pcoef2[m] = emipi4*pcoef[m]; \
+        pcoef2[M2-1-m] = eipi4*pcoef[m]; \
+        pcoef2[m+M2] = eipi4*pcoef[m+M];  \
+        pcoef2[M4-1-m] = emipi4*pcoef[m+M]; \
+     } \
+ \
+     pcoef+=M2; \
+     pcoef2+=M4; \
+  }
+
+#define POSTPROC_REAL \
+   for(ltfatInt w=0;w<W;w++) \
+      for(ltfatInt n=0;n<L;n++) \
+         f[n+w*L] = scalconst*CH(creal)(f2[n+w*L]*CH(cexp)(I*PI*n/(2.0*M)));
+
+#define POSTPROC_COMPLEX \
+   for(ltfatInt w=0;w<W;w++) \
+      for(ltfatInt n=0;n<L;n++) \
+         f[n+w*L] = scalconst*f2[n+w*L]*CH(cexp)(I*PI*n/(2.0*M));
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(idwiltiii_long)(const LTFAT_COMPLEX *c, const LTFAT_COMPLEX *g,
+                                   const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                                   LTFAT_COMPLEX *f)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0);
+    const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc(2*M*N*W,sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+
+
+    const LTFAT_COMPLEX *pcoef  = c;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    PREPROC_COMPLEX
+
+    LTFAT_NAME(idgt_long)(coef2, g, L, W, M, 2*M, f2);
+
+    POSTPROC_COMPLEX
+
+    LTFAT_SAFEFREEALL(coef2,f2);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(idwiltiii_long)(const LTFAT_REAL *c, const LTFAT_REAL *g,
+                                const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                                LTFAT_REAL *f)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2 = 2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0);
+    const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc(2*M*N*W,sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+    LTFAT_COMPLEX *g2 = ltfat_malloc(L*sizeof*g2);
+    for(ltfatInt ii=0; ii<L; ii++)
+        g2[ii]=g[ii];
+
+
+    const LTFAT_REAL *pcoef  = c;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    PREPROC_COMPLEX
+
+    LTFAT_NAME(idgt_long)(coef2, g2, L, W, M, 2*M, f2);
+
+    POSTPROC_REAL
+
+    LTFAT_SAFEFREEALL(coef2,f2,g2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(idwiltiii_fb)(const LTFAT_COMPLEX *c, const LTFAT_COMPLEX *g,
+                                 const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                                 LTFAT_COMPLEX *f)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0);
+    const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc(2*M*N*W,sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+
+
+    const LTFAT_COMPLEX *pcoef  = c;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    PREPROC_COMPLEX
+
+    LTFAT_NAME(idgt_fb)(coef2, g, L, gl, W, M, 2*M, f2);
+
+    POSTPROC_COMPLEX
+
+    LTFAT_SAFEFREEALL(coef2,f2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(idwiltiii_fb)(const LTFAT_REAL *c, const LTFAT_REAL *g,
+                              const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                              LTFAT_REAL *f)
+{
+    const ltfatInt N = L/M;
+    const ltfatInt M2 = 2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0);
+    const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_calloc(2*M*N*W,sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+    LTFAT_COMPLEX *g2 = ltfat_malloc(gl*sizeof*g2);
+    for(ltfatInt ii=0; ii<gl; ii++)
+        g2[ii]=g[ii];
+
+
+    const LTFAT_REAL* pcoef  = c;
+    LTFAT_COMPLEX* pcoef2 = coef2;
+
+    PREPROC_COMPLEX
+
+    LTFAT_NAME(idgt_fb)(coef2, g2, L, gl, W, M, 2*M, f2);
+
+    POSTPROC_REAL
+
+    LTFAT_SAFEFREEALL(coef2,f2,g2);
+}
+
+#undef CH
+#undef PREPROC_COMPLEX
+#undef POSTPROC_REAL
+#undef POSTPROC_COMPLEX
+
diff --git a/src/ltfat.h b/src/ltfat.h
new file mode 100644
index 0000000..9affd84
--- /dev/null
+++ b/src/ltfat.h
@@ -0,0 +1,181 @@
+#ifndef LTFAT_H
+#define LTFAT_H 1
+#include "config.h"
+
+#ifdef LTFAT_COMPAT32
+typedef int       ltfatInt;
+#else
+typedef ptrdiff_t ltfatInt;
+#endif /* defined(LTFAT_COMPAT32) */
+
+typedef enum
+{
+   ltfatUnspecErr = 1,
+   ltfatNoErr = 0
+} ltfatStatus;
+
+
+typedef enum
+{
+    DCTI=FFTW_REDFT00, DCTIII=FFTW_REDFT01,
+    DCTII=FFTW_REDFT10, DCTIV=FFTW_REDFT11
+} dct_kind;
+
+
+typedef enum
+{
+    DSTI=FFTW_RODFT00, DSTIII=FFTW_RODFT01,
+    DSTII=FFTW_RODFT10, DSTIV=FFTW_RODFT11
+} dst_kind;
+
+typedef enum
+{
+    CZT_NEXTFASTFFT,
+    CZT_NEXTPOW2
+} czt_ffthint;
+
+
+/* BEGIN_C_DECLS */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* -------- Create the single precision routines headers ----- */
+
+#ifndef LTFAT_DOUBLE
+#ifndef LTFAT_SINGLE
+#      define LTFAT_SINGLE_WASNOTDEFINED
+#      define LTFAT_SINGLE
+#endif
+
+#   include "ltfat_types.h"
+#   include "ltfat_typecomplexindependent.h"
+
+#   define LTFAT_COMPLEXTYPE
+#   include "ltfat_types.h"
+#   include "ltfat_typecomplexindependent.h"
+#   undef LTFAT_COMPLEXTYPE
+
+#   include "ltfat_types.h"
+#   include "ltfat_typeindependent.h"
+
+#   ifdef LTFAT_SINGLE_WASNOTDEFINED
+#      undef LTFAT_SINGLE
+#      undef LTFAT_SINGLE_WASNOTDEFINED
+#   endif
+#endif
+
+
+/* -------- Create the single precision routines headers ----- */
+#ifndef LTFAT_SINGLE
+#ifndef LTFAT_DOUBLE
+#   define LTFAT_DOUBLE_WASNOTDEFINED
+#   define LTFAT_DOUBLE
+#endif
+
+#include "ltfat_types.h"
+#include "ltfat_typecomplexindependent.h"
+
+#define LTFAT_COMPLEXTYPE
+#include "ltfat_types.h"
+#include "ltfat_typecomplexindependent.h"
+#undef LTFAT_COMPLEXTYPE
+
+#include "ltfat_types.h"
+#include "ltfat_typeindependent.h"
+
+#   ifdef LTFAT_DOUBLE_WASNOTDEFINED
+#      undef LTFAT_DOUBLE
+#      undef LTFAT_DOUBLE_WASNOTDEFINED
+#   endif
+#endif
+
+
+// Undef all
+#undef LTFAT_COMPLEX
+#undef LTFAT_REAL
+#undef LTFAT_TYPE
+#undef LTFAT_NAME
+#undef LTFAT_NAME_REAL
+#undef LTFAT_NAME_COMPLEX
+#undef LTFAT_FFTW
+#undef LTFAT_MX_CLASSID
+#undef LTFAT_MX_COMPLEXITY
+#undef LTFAT_COMPLEXH
+
+/* -------- Define routines that do not change between single/double-- */
+LTFAT_EXTERN_TOO
+ltfatInt gcd(const ltfatInt a, const ltfatInt b, ltfatInt *r, ltfatInt *s );
+
+LTFAT_EXTERN_TOO
+void* ltfat_malloc (size_t n);
+
+LTFAT_EXTERN_TOO
+void* ltfat_calloc (size_t nmemb, size_t size);
+
+LTFAT_EXTERN_TOO
+void* ltfat_realloc (void *ptr, size_t n);
+
+LTFAT_EXTERN_TOO
+void* ltfat_realloc_and_copy (void *ptr, size_t nold, size_t nnew);
+
+LTFAT_EXTERN_TOO
+void  ltfat_free(const void *ptr);
+
+LTFAT_EXTERN_TOO
+void  ltfat_safefree(const void *ptr);
+
+LTFAT_EXTERN_TOO
+void fftindex(const ltfatInt N, ltfatInt *indexout);
+
+LTFAT_EXTERN_TOO
+ltfatInt makelarger(const ltfatInt L, const ltfatInt K);
+
+LTFAT_EXTERN_TOO
+ltfatInt filterbank_td_size(const ltfatInt L,const ltfatInt a,
+                            const ltfatInt gl,const ltfatInt offset,
+                            const ltfatExtType ext);
+
+LTFAT_EXTERN_TOO
+ltfatInt imax(const ltfatInt a, const ltfatInt b);
+
+LTFAT_EXTERN_TOO
+ltfatInt imin(const ltfatInt a, const ltfatInt b);
+
+LTFAT_EXTERN_TOO
+ltfatInt lcm(const ltfatInt a, const ltfatInt b);
+
+LTFAT_EXTERN_TOO
+void gabimagepars(const ltfatInt Ls, const ltfatInt x, const ltfatInt y,
+                  ltfatInt *a, ltfatInt *M, ltfatInt *L, ltfatInt *N, ltfatInt *Ngood);
+
+LTFAT_EXTERN_TOO
+ltfatInt wfacreal_size(const ltfatInt L, const ltfatInt a, const ltfatInt M);
+
+LTFAT_EXTERN_TOO
+ltfatInt nextPow2(const ltfatInt x);
+
+LTFAT_EXTERN_TOO
+ltfatInt nextfastfft(const ltfatInt x);
+
+LTFAT_EXTERN_TOO
+ltfatInt pow2(const ltfatInt x);
+
+LTFAT_EXTERN_TOO
+ltfatInt modPow2(const ltfatInt x,const ltfatInt pow2var);
+
+LTFAT_EXTERN_TOO
+ltfatInt ltfat_round(const double x);
+
+LTFAT_EXTERN_TOO
+ltfatInt positiverem(const ltfatInt a,const ltfatInt b);
+
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+/* END_C_DECLS */
+
+#endif /* !LTFAT_H */
diff --git a/src/ltfat_blaslapack.c b/src/ltfat_blaslapack.c
new file mode 100644
index 0000000..d0a58ac
--- /dev/null
+++ b/src/ltfat_blaslapack.c
@@ -0,0 +1,225 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#ifdef LTFAT_DOUBLE
+#define LTFAT_POSV F77_FUNC(zposv,ZPOSV)
+#define LTFAT_GESVD F77_FUNC(zgesvd,ZGESVD)
+#define LTFAT_clapack_posv clapack_zposv
+#define LTFAT_GEMM F77_FUNC (zgemm, ZGEMM)
+#define LTFAT_cblas_gemm cblas_zgemm
+#endif
+
+#ifdef LTFAT_SINGLE
+#define LTFAT_POSV F77_FUNC(cposv,CPOSV)
+#define LTFAT_GESVD F77_FUNC(cgesvd,CGESVD)
+#define LTFAT_clapack_posv clapack_cposv
+#define LTFAT_GEMM F77_FUNC (cgemm, CGEMM)
+#define LTFAT_cblas_gemm cblas_cgemm
+#endif
+
+
+/* Use the LAPACK library supplied with ATLAS */
+#ifdef HAVE_ATLASLAPACK
+#include "clapack.h"
+#endif /* end of HAVE_ATLASLAPACK */
+
+/* Call Fortran LAPACK */
+#ifdef HAVE_LAPACK
+#include "f77-fcn.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+F77_RET_T
+LTFAT_POSV (F77_CONST_CHAR_ARG_DECL uplo,
+            const ptrdiff_t *n, const ptrdiff_t *nrhs,
+            const LTFAT_REAL *a, const ptrdiff_t *lda,
+            LTFAT_REAL *b, const ptrdiff_t *ldb,
+            ptrdiff_t *info
+            F77_CHAR_ARG_LEN_DECL);
+
+
+F77_RET_T
+LTFAT_GESVD (F77_CONST_CHAR_ARG_DECL jobu,
+             F77_CONST_CHAR_ARG_DECL jobvt,
+             const ptrdiff_t *M, const ptrdiff_t *N,
+             LTFAT_REAL* A, const ptrdiff_t *lda,
+             LTFAT_REAL *S, LTFAT_REAL* U, const ptrdiff_t *ldu,
+             LTFAT_REAL *VT, const ptrdiff_t *ldvt, LTFAT_REAL *work,
+             const ptrdiff_t *lwork,
+             LTFAT_REAL *rwork, ptrdiff_t *info
+             F77_CHAR_ARG_LEN_DECL
+             F77_CHAR_ARG_LEN_DECL);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of HAVE_LAPACK */
+
+/* Call Fortran BLAS */
+#ifdef HAVE_BLAS
+#include "f77-fcn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+F77_RET_T
+LTFAT_GEMM (F77_CONST_CHAR_ARG_DECL TransA,
+            F77_CONST_CHAR_ARG_DECL TransB,
+            const ptrdiff_t *M, const ptrdiff_t *N,
+            const ptrdiff_t *K,
+            const LTFAT_COMPLEX *alpha,
+            const LTFAT_COMPLEX *a, const ptrdiff_t *lda,
+            const LTFAT_COMPLEX *b, const ptrdiff_t *ldb,
+            const LTFAT_COMPLEX *beta,
+            LTFAT_COMPLEX *c,
+            const ptrdiff_t *ldc
+            F77_CHAR_ARG_LEN_DECL
+            F77_CHAR_ARG_LEN_DECL);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of HAVE_BLAS */
+
+
+
+/* ----- Compute Cholesky factorization  ------------
+ *
+ * For simplification, the interface assumes that we
+ * are using column-major format and storing the upper
+ * triangle
+ */
+ltfatInt LTFAT_NAME(ltfat_posv)(const ptrdiff_t N, const ptrdiff_t NRHS,
+                           LTFAT_COMPLEX *A, const ptrdiff_t lda,
+                           LTFAT_COMPLEX *B, const ptrdiff_t ldb)
+#ifdef HAVE_CBLASLAPACK
+{
+    return LTFAT_clapack_posv(CblasColMajor, CblasUpper, N, NRHS, (LTFAT_REAL*)A, lda,
+                              (LTFAT_REAL*)B, ldb);
+}
+#endif
+#ifdef HAVE_LAPACK
+{
+    ptrdiff_t info;
+    char u;
+
+    u = 'U';
+
+    LTFAT_POSV (F77_CONST_CHAR_ARG2 (&u, 1),
+                &N, &NRHS, (LTFAT_REAL*)A, &lda,
+                (LTFAT_REAL*)B, &ldb,
+                &info
+                F77_CHAR_ARG_LEN (1)
+               );
+
+    return info;
+}
+#endif
+
+/* ----- Compute SVD factorization  ------------ */
+ltfatInt LTFAT_NAME(ltfat_gesvd)(const ptrdiff_t M, const ptrdiff_t N,
+                            LTFAT_COMPLEX *A, const ptrdiff_t lda,
+                            LTFAT_REAL *S, LTFAT_COMPLEX *U, const ptrdiff_t ldu,
+                            LTFAT_COMPLEX *VT, const ptrdiff_t ldvt)
+#ifdef HAVE_LAPACK
+{
+
+    ptrdiff_t lwork, info, maxMN;
+    LTFAT_REAL workquery[2];
+    LTFAT_REAL *rwork, *work;
+
+    char jobu;
+    char jobvt;
+
+    /* Set constants to declare thin SVD */
+    jobu = 'S';
+    jobvt = 'S';
+
+    maxMN = M > N ? M : N;
+
+    /* Allocate workspace */
+    rwork = (LTFAT_REAL*)ltfat_malloc(5*maxMN*sizeof(LTFAT_REAL));
+
+    /* Ask ZGESVD what the dimension of WORK should be. */
+    lwork = -1;
+    LTFAT_GESVD (F77_CONST_CHAR_ARG2 (&jobu, 1),
+                 F77_CONST_CHAR_ARG2 (&jobvt, 1),
+                 &M, &N, (LTFAT_REAL*)A, &lda, S, (LTFAT_REAL*)U,
+                 &ldu, (LTFAT_REAL*)VT,
+                 &ldvt, (LTFAT_REAL*)(&workquery), &lwork,
+                 rwork, &info
+                 F77_CHAR_ARG_LEN (1)
+                 F77_CHAR_ARG_LEN (1));
+
+    /* Get the result from real part of work */
+    lwork = (ptrdiff_t)(workquery[0]);
+
+    /* Allocate more workspace */
+    work = (LTFAT_REAL*)ltfat_malloc(lwork*sizeof(LTFAT_COMPLEX));
+
+    /* Call the function for real this time */
+
+    LTFAT_GESVD (F77_CONST_CHAR_ARG2 (&jobu, 1),
+                 F77_CONST_CHAR_ARG2 (&jobvt, 1),
+                 &M, &N, (LTFAT_REAL*)A, &lda, S,
+                 (LTFAT_REAL*)U, &ldu, (LTFAT_REAL*)VT,
+                 &ldvt, work, &lwork,
+                 rwork, &info
+                 F77_CHAR_ARG_LEN (1)
+                 F77_CHAR_ARG_LEN (1));
+
+
+    /* Free workspace */
+    ltfat_free(rwork);
+    ltfat_free(work);
+
+    return info;
+
+}
+#endif /* End of HAVE_LAPACK */
+
+
+void LTFAT_NAME(ltfat_gemm)(const enum CBLAS_TRANSPOSE TransA,
+                            const enum CBLAS_TRANSPOSE TransB,
+                            const ptrdiff_t M, const ptrdiff_t N, const ptrdiff_t K,
+                            const LTFAT_COMPLEX *alpha,
+                            const LTFAT_COMPLEX *A, const ptrdiff_t lda,
+                            const LTFAT_COMPLEX *B, const ptrdiff_t ldb,
+                            const LTFAT_COMPLEX *beta,
+                            LTFAT_COMPLEX *C, const ptrdiff_t ldc)
+#ifdef HAVE_CBLAS
+{
+
+    LTFAT_cblas_gemm(CblasColMajor, TransA, TransB, M, N, K,
+                     (LTFAT_REAL*)alpha, (LTFAT_REAL*)A, lda, (LTFAT_REAL*)B, ldb,
+                     (LTFAT_REAL*)beta, (LTFAT_REAL*)C, ldc);
+
+}
+#endif
+#ifdef HAVE_BLAS
+{
+    char ca, cb;
+
+    if (TransA == CblasNoTrans)   ca='N';
+    if (TransA == CblasConjTrans) ca='C';
+
+    if (TransB == CblasNoTrans)   cb='N';
+    if (TransB == CblasConjTrans) cb='C';
+
+    LTFAT_GEMM (F77_CONST_CHAR_ARG2 (&ca, 1),
+                F77_CONST_CHAR_ARG2 (&cb, 1),
+                &M, &N, &K,
+                alpha,
+                A, &lda,
+                B, &ldb,
+                beta, C, &ldc
+                F77_CHAR_ARG_LEN (1)
+                F77_CHAR_ARG_LEN (1)
+               );
+
+
+}
+#endif /* end of HAVE_BLAS */
diff --git a/src/ltfat_complexindependent.c b/src/ltfat_complexindependent.c
new file mode 100644
index 0000000..5bb017a
--- /dev/null
+++ b/src/ltfat_complexindependent.c
@@ -0,0 +1,25 @@
+#ifdef LTFAT_COMPLEXTYPE
+#  undef LTFAT_COMPLEXTYPE
+#endif // LTFAT_COMPLEXTYPE
+
+#include "ltfat.h"
+
+#include "ltfat_types.h"
+
+#include "goertzel.c"
+#include "wavelets.c"
+#include "spread.c"
+#include "ciutils.c"
+
+
+#define LTFAT_COMPLEXTYPE
+#include "ltfat_types.h"
+
+#include "wavelets.c"
+#include "goertzel.c"
+#include "spread.c"
+#include "ciutils.c"
+
+#undef LTFAT_COMPLEXTYPE
+
+
diff --git a/src/ltfat_complexindependent_bl.c b/src/ltfat_complexindependent_bl.c
new file mode 100644
index 0000000..78b413c
--- /dev/null
+++ b/src/ltfat_complexindependent_bl.c
@@ -0,0 +1,23 @@
+#ifdef LTFAT_COMPLEXTYPE
+#  undef LTFAT_COMPLEXTYPE
+#endif // LTFAT_COMPLEXTYPE
+
+#include "config.h"
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+#include "gabdual.c"
+#include "gabtight.c"
+
+
+#define LTFAT_COMPLEXTYPE
+#include "ltfat_types.h"
+
+#include "gabdual.c"
+#include "gabtight.c"
+
+
+#undef LTFAT_COMPLEXTYPE
+
+
diff --git a/src/ltfat_typecomplexindependent.h b/src/ltfat_typecomplexindependent.h
new file mode 100644
index 0000000..9c7fda4
--- /dev/null
+++ b/src/ltfat_typecomplexindependent.h
@@ -0,0 +1,101 @@
+#include "wavelets.h"
+#include "goertzel.h"
+#include "ciutils.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(col2diag)(const LTFAT_TYPE *cin, const ltfatInt L,
+                     LTFAT_TYPE *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabdual_long)(const LTFAT_TYPE *g,
+                         const ltfatInt L, const ltfatInt R, const ltfatInt a,
+                         const ltfatInt M, LTFAT_TYPE *gd);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabtight_long)(const LTFAT_TYPE *g,
+                          const ltfatInt L, const ltfatInt R, const ltfatInt a,
+                          const ltfatInt M, LTFAT_TYPE *gd);
+
+
+/* --------- Wilson and WMDCT bases ---------*/
+LTFAT_EXTERN void
+LTFAT_NAME(dwilt_long)(const LTFAT_TYPE *f,
+                       const LTFAT_TYPE *g,
+                       const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                       LTFAT_TYPE *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dwilt_fb)(const LTFAT_TYPE *f, const LTFAT_TYPE *g,
+                     const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                     LTFAT_TYPE *cout);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dwiltiii_long)(const LTFAT_TYPE *f,
+                          const LTFAT_TYPE *g,
+                          const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                          LTFAT_TYPE *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dwiltiii_fb)(const LTFAT_TYPE *f, const LTFAT_TYPE *g,
+                        const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                        LTFAT_TYPE *cout);
+
+
+/* --------- Wilson and WMDCT inverses ---------*/
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idwilt_long)(const LTFAT_TYPE *cin,
+                        const LTFAT_TYPE *g,
+                        const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                        LTFAT_TYPE *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idwilt_fb)(const LTFAT_TYPE *cin, const LTFAT_TYPE *g,
+                      const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                      LTFAT_TYPE *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idwiltiii_long)(const LTFAT_TYPE *cin,
+                           const LTFAT_TYPE *g,
+                           const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                           LTFAT_TYPE *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idwiltiii_fb)(const LTFAT_TYPE *cin, const LTFAT_TYPE *g,
+                         const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                         LTFAT_TYPE *f);
+
+/* --------------- DCT -------------------*/
+
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(dct_init)( const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
+                      const dct_kind kind);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dct)(const LTFAT_TYPE *f, const ltfatInt L, const ltfatInt W,
+                LTFAT_TYPE *cout, const dct_kind kind);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dct_execute)(const LTFAT_FFTW(plan) p, const LTFAT_TYPE *f,
+                        const ltfatInt L, const ltfatInt W,
+                        LTFAT_TYPE *cout, const dct_kind kind);
+
+/* --------------- DST -------------------*/
+
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(dst_init)( const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
+                      const dst_kind kind);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dst)(const LTFAT_TYPE *f, const ltfatInt L, const ltfatInt W,
+                LTFAT_TYPE *cout, const dst_kind kind);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dst_execute)(LTFAT_FFTW(plan) p, const LTFAT_TYPE *f,
+                        const ltfatInt L, const ltfatInt W, LTFAT_TYPE *cout,
+                        const dst_kind kind);
+
+
diff --git a/src/ltfat_typeindependent.h b/src/ltfat_typeindependent.h
new file mode 100644
index 0000000..dd9f5a4
--- /dev/null
+++ b/src/ltfat_typeindependent.h
@@ -0,0 +1,657 @@
+#include "dgt_long.h"
+#include "dgt_multi.h"
+#include "dgt_shear.h"
+
+/*  --------- factorizations --------------- */
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(wfac)(const LTFAT_COMPLEX *g, const ltfatInt L, const ltfatInt R,
+                         const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *gf);
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(wfac)(const LTFAT_REAL *g, const ltfatInt L, const ltfatInt R,
+                      const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *gf);
+
+LTFAT_EXTERN void
+LTFAT_NAME(wfacreal)(const LTFAT_REAL *g, const ltfatInt L, const ltfatInt R,
+                     const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *gf);
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(iwfac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                          const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *g);
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(iwfac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                       const ltfatInt a, const ltfatInt M, LTFAT_REAL *g);
+
+LTFAT_EXTERN void
+LTFAT_NAME(iwfacreal)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                      const ltfatInt a, const ltfatInt M, LTFAT_REAL *g);
+
+/* --------- DGT by factorization ------------ */
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fac)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *gf,
+                    const ltfatInt L, const ltfatInt W,  const ltfatInt a,
+                    const ltfatInt M, LTFAT_COMPLEX *cout);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_long)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                         const ltfatInt L, const ltfatInt W,  const ltfatInt a,
+                         const ltfatInt M, LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fac_r)(const LTFAT_REAL *f, const LTFAT_COMPLEX *gf,
+                      const ltfatInt L,
+                      const ltfatInt W,  const ltfatInt a,
+                      const ltfatInt M, LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN
+void LTFAT_NAME(dgtreal_fac)(const LTFAT_REAL *f, const LTFAT_COMPLEX *gf,
+                             const ltfatInt L,
+                             const ltfatInt W,  const ltfatInt a,
+                             const ltfatInt M, LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_walnut_r)(const LTFAT_REAL *f, const LTFAT_COMPLEX *gf,
+                         const ltfatInt L, const ltfatInt W,
+                         const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *cout);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_fac)(const LTFAT_COMPLEX *c, const LTFAT_COMPLEX *gf,
+                     const ltfatInt L,
+                     const ltfatInt W,const ltfatInt a, const ltfatInt M,
+                     LTFAT_COMPLEX *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgtreal_fac)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *gf,
+                         const ltfatInt L, const ltfatInt W,
+                         const ltfatInt a, const ltfatInt M,
+                         LTFAT_REAL *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_long)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *g,
+                      const ltfatInt L, const ltfatInt W,
+                      const ltfatInt a, const ltfatInt M,
+                      LTFAT_COMPLEX *f);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgtreal_long)(const LTFAT_COMPLEX *cin, const LTFAT_REAL *g,
+                          const ltfatInt L, const ltfatInt W,
+                          const ltfatInt a, const ltfatInt M,
+                          LTFAT_REAL *f);
+
+
+/* --------- dual windows etc. --------------- */
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabdual_fac)(const LTFAT_COMPLEX *g, const ltfatInt L, const ltfatInt R,
+                        const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *gdualf);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabdualreal_fac)(const LTFAT_COMPLEX *g, const ltfatInt L, const ltfatInt R,
+                            const ltfatInt a, const ltfatInt M, LTFAT_COMPLEX *gdualf);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabtight_fac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                         const ltfatInt a, const ltfatInt M,
+                         LTFAT_COMPLEX *gtightf);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabtightreal_fac)(const LTFAT_COMPLEX *gf, const ltfatInt L, const ltfatInt R,
+                             const ltfatInt a, const ltfatInt M,
+                             LTFAT_COMPLEX *gtightf);
+
+
+/* --------- filter bank DGTs ---------------- */
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dgt_fb)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                           const ltfatInt L, const ltfatInt gl,
+                           const ltfatInt W,  const ltfatInt a, const ltfatInt M,
+                           LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fb)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                   const ltfatInt L, const ltfatInt gl,
+                   const ltfatInt W,  const ltfatInt a, const ltfatInt M,
+                   LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_fb)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                       const ltfatInt L, const ltfatInt gl,
+                       const ltfatInt W,  const ltfatInt a, const ltfatInt M,
+                       LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_fb)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *g,
+                    const ltfatInt L, const ltfatInt gl,
+                    const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                    LTFAT_COMPLEX *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgt_fb_r)(const LTFAT_COMPLEX *cin, const LTFAT_REAL *g,
+                      const ltfatInt L, const ltfatInt gl,
+                      const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                      LTFAT_COMPLEX *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(idgtreal_fb)(const LTFAT_COMPLEX *cin, const LTFAT_REAL *g,
+                        const ltfatInt L, const ltfatInt gl, const ltfatInt W,
+                        const ltfatInt a, const ltfatInt M,
+                        LTFAT_REAL *f);
+
+/* ---------- OLA DGTs ------------- */
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_ola)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                    const ltfatInt L, const ltfatInt gl,
+                    const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                    LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_ola)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                        const ltfatInt L, const ltfatInt gl,
+                        const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                        LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shearola)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                         const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                         const ltfatInt s0, const ltfatInt s1, const ltfatInt br, const ltfatInt bl,
+                         LTFAT_COMPLEX *cout);
+
+/* --------- FFT ------------------*/
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(fftreal_init)(LTFAT_REAL *f, const ltfatInt L, const ltfatInt W,
+                         LTFAT_COMPLEX *cout, unsigned flag);
+
+LTFAT_EXTERN void
+LTFAT_NAME(fftreal_execute)(LTFAT_FFTW(plan) p, LTFAT_REAL *f,
+                            LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(fftreal)(LTFAT_REAL *f, const ltfatInt L, const ltfatInt W,
+                    LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN LTFAT_FFTW(plan)
+LTFAT_NAME(ifftreal_init)(LTFAT_COMPLEX *c, const ltfatInt L, const ltfatInt W,
+                          LTFAT_REAL *f, unsigned flag);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifftreal_execute)(LTFAT_FFTW(plan), LTFAT_COMPLEX *c,
+                             const ltfatInt L, const ltfatInt W,
+                             LTFAT_REAL *f);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifftreal)(LTFAT_COMPLEX *c, const ltfatInt L, const ltfatInt W,
+                     LTFAT_REAL *f);
+
+
+/* --------- filterbank codes ------------*/
+
+typedef struct LTFAT_NAME(convsub_fft_plan_struct) *LTFAT_NAME(convsub_fft_plan);
+typedef struct LTFAT_NAME(convsub_fftbl_plan_struct) *LTFAT_NAME(convsub_fftbl_plan);
+
+typedef struct LTFAT_NAME(upconv_fft_plan_struct) *LTFAT_NAME(upconv_fft_plan);
+typedef struct LTFAT_NAME(upconv_fftbl_plan_struct) *LTFAT_NAME(upconv_fftbl_plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ufilterbank_fft)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                            const ltfatInt L, const ltfatInt gl,
+                            const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                            LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fft)(const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G[],
+                           const ltfatInt L, const ltfatInt W, const ltfatInt a[], const ltfatInt M,
+                           LTFAT_COMPLEX *cout[]);
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fft_execute)(LTFAT_NAME(convsub_fft_plan) p[],
+                                   const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G[],
+                                   const ltfatInt M, LTFAT_COMPLEX *cout[]);
+
+
+LTFAT_EXTERN LTFAT_NAME(convsub_fft_plan)
+LTFAT_NAME(convsub_fft_init)(const ltfatInt L, const ltfatInt W,
+                             const ltfatInt a, const LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fft_done)(LTFAT_NAME(convsub_fft_plan) p);
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fft_execute)(const LTFAT_NAME(convsub_fft_plan) p,
+                                const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G,
+                                LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fft)(const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G,
+                        const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                        LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fftbl)(const LTFAT_COMPLEX *F, const LTFAT_COMPLEX *G[],
+                             const ltfatInt L, const ltfatInt Gl[],
+                             const ltfatInt W, const double a[], const ltfatInt M,
+                             const ltfatInt foff[], const int realonly[],
+                             LTFAT_COMPLEX *cout[]);
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_fftbl_execute)(LTFAT_NAME(convsub_fftbl_plan) p[],
+                                     const LTFAT_COMPLEX *F,
+                                     const LTFAT_COMPLEX *G[],
+                                     const ltfatInt M, const ltfatInt foff[],
+                                     const int realonly[], LTFAT_COMPLEX *cout[]);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fft_execute)(LTFAT_NAME(upconv_fft_plan) p[],
+                                    const LTFAT_COMPLEX *cin[],
+                                    const LTFAT_COMPLEX *G[],
+                                    const ltfatInt M,
+                                    LTFAT_COMPLEX *F );
+
+
+LTFAT_EXTERN LTFAT_NAME(convsub_fftbl_plan)
+LTFAT_NAME(convsub_fftbl_init)( const ltfatInt L, const ltfatInt Gl,
+                                const ltfatInt W, const double a,
+                                const LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fftbl_done)( LTFAT_NAME(convsub_fftbl_plan) p);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fftbl_execute)(const LTFAT_NAME(convsub_fftbl_plan) p,
+                                  const LTFAT_COMPLEX *F,
+                                  const LTFAT_COMPLEX *G,
+                                  const ltfatInt foff,
+                                  const int realonly,
+                                  LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_fftbl)(const LTFAT_COMPLEX *F,  const LTFAT_COMPLEX *G,
+                          const ltfatInt L, const ltfatInt Gl, const ltfatInt W,
+                          const double a, const ltfatInt foff,
+                          const int realonly, LTFAT_COMPLEX *cout);
+
+
+
+// Inverse
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fft)(const LTFAT_COMPLEX *cin[], const LTFAT_COMPLEX *G[],
+                            const ltfatInt L, const ltfatInt W, const ltfatInt a[], const ltfatInt M,
+                            LTFAT_COMPLEX *F);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fft_execute)(LTFAT_NAME(upconv_fft_plan) p[],
+                                    const LTFAT_COMPLEX *cin[],
+                                    const LTFAT_COMPLEX *G[],
+                                    const ltfatInt M,
+                                    LTFAT_COMPLEX *F );
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fft)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                       const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                       LTFAT_COMPLEX *F);
+
+LTFAT_EXTERN LTFAT_NAME(upconv_fft_plan)
+LTFAT_NAME(upconv_fft_init)(const ltfatInt L, const ltfatInt W, const ltfatInt a);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fft_execute)(LTFAT_NAME(upconv_fft_plan) p,
+                               const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                               LTFAT_COMPLEX *F);
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fft_done)(LTFAT_NAME(upconv_fft_plan) p);
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fftbl)(const LTFAT_COMPLEX *cin[], const LTFAT_COMPLEX *G[],
+                              const ltfatInt L, const ltfatInt Gl[], const ltfatInt W, const double a[], const ltfatInt M,
+                              const ptrdiff_t foff[], const int realonly[],
+                              LTFAT_COMPLEX *F);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_fftbl_execute)(LTFAT_NAME(upconv_fftbl_plan) p[],
+                                      const LTFAT_COMPLEX *cin[],
+                                      const LTFAT_COMPLEX *G[],
+                                      const ltfatInt M, const ltfatInt foff[],
+                                      const int realonly[],
+                                      LTFAT_COMPLEX *F);
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fftbl)(const LTFAT_COMPLEX *cin, const LTFAT_COMPLEX *G,
+                         const ltfatInt L, const ltfatInt Gl, const ltfatInt W,
+                         const double a, const ptrdiff_t foff,
+                         const int realonly, LTFAT_COMPLEX *F);
+
+LTFAT_EXTERN LTFAT_NAME(upconv_fftbl_plan)
+LTFAT_NAME(upconv_fftbl_init)( const ltfatInt L, const ltfatInt Gl,
+                               const ltfatInt W, const double a);
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fftbl_done)(LTFAT_NAME(upconv_fftbl_plan) p);
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_fftbl_execute)(const LTFAT_NAME(upconv_fftbl_plan) p,
+                                 const LTFAT_COMPLEX *cin,
+                                 const LTFAT_COMPLEX *G,
+                                 const ptrdiff_t foff, const int realonly,
+                                 LTFAT_COMPLEX *F);
+
+
+
+/* -------- windows ------------------------------ */
+
+LTFAT_EXTERN void
+LTFAT_NAME(pgauss)(const ltfatInt L, const double w, const double c_t,
+                   LTFAT_REAL *g);
+
+LTFAT_EXTERN void
+LTFAT_NAME(pgauss_cmplx)(const ltfatInt L, const double w, const double c_t,
+                         const double c_f, LTFAT_COMPLEX *g);
+
+
+/* --------- pfilt and filterbanks ------------- */
+LTFAT_EXTERN void
+LTFAT_NAME(pfilt_fir_rr)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                         const ltfatInt L, const ltfatInt gl,
+                         const ltfatInt W, const ltfatInt a,
+                         LTFAT_REAL *cout);
+
+/* --------- other stuff -------- */
+LTFAT_EXTERN void
+LTFAT_NAME(heapint)(const LTFAT_REAL *s,
+                    const LTFAT_REAL *tgrad,
+                    const LTFAT_REAL *fgrad,
+                    const ltfatInt a, const ltfatInt M, const ltfatInt L, const ltfatInt W,
+                    const LTFAT_REAL tol, LTFAT_REAL *phase);
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabreassign)(const LTFAT_REAL *s, const LTFAT_REAL *tgrad,
+                        const LTFAT_REAL *fgrad, const ltfatInt L, const ltfatInt W,
+                        const ltfatInt a, const ltfatInt M, LTFAT_REAL *sr);
+
+LTFAT_EXTERN void
+LTFAT_NAME(fftshift_r)(const LTFAT_REAL *f, const ltfatInt L, LTFAT_REAL *h);
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifftshift_r)(const LTFAT_REAL *f, const ltfatInt L, LTFAT_REAL *h);
+
+LTFAT_EXTERN void
+LTFAT_NAME(fir2long_r)(const LTFAT_REAL *f, const ltfatInt Lfir, const ltfatInt Llong,
+                       LTFAT_REAL *h);
+
+LTFAT_EXTERN void
+LTFAT_NAME(fir2long_c)(const LTFAT_COMPLEX *f,
+                       const ltfatInt Lfir, const ltfatInt Llong,
+                       LTFAT_COMPLEX *h);
+
+LTFAT_EXTERN void
+LTFAT_NAME(long2fir_r)(const LTFAT_REAL *f, const ltfatInt Llong,
+                       const ltfatInt Lfir, LTFAT_REAL *h);
+
+LTFAT_EXTERN void
+LTFAT_NAME(long2fir_c)(const LTFAT_COMPLEX *f, const ltfatInt Llong,
+                       const ltfatInt Lfir, LTFAT_COMPLEX *h);
+
+ltfatInt
+LTFAT_NAME(complexprod)(LTFAT_COMPLEX *c, const LTFAT_COMPLEX a,
+                        const LTFAT_COMPLEX b);
+
+/* ----- internal routines for calling BLAS and LAPACK ----- */
+
+/*
+// LAPACK overwrites the input argument.
+ltfatInt
+LTFAT_NAME(ltfat_posv)(const ltfatInt N, const ltfatInt NRHS,
+			 LTFAT_COMPLEX *A, const ltfatInt lda,
+			 LTFAT_COMPLEX *B, const ltfatInt ldb);
+
+// LAPACK overwrites the input argument.
+ltfatInt
+LTFAT_NAME(ltfat_gesvd)(const ltfatInt M, const ltfatInt N,
+			  LTFAT_COMPLEX *A, const ltfatInt lda,
+			  LTFAT_REAL *S, LTFAT_COMPLEX *U, const ltfatInt ldu,
+			  LTFAT_COMPLEX *VT, const ltfatInt ldvt);
+
+void
+LTFAT_NAME(ltfat_gemm)(const enum CBLAS_TRANSPOSE TransA,
+			 const enum CBLAS_TRANSPOSE TransB,
+			 const ltfatInt M, const ltfatInt N, const ltfatInt K,
+			 const LTFAT_COMPLEX *alpha,
+			 const LTFAT_COMPLEX *A, const ltfatInt lda,
+			 const LTFAT_COMPLEX *B, const ltfatInt ldb,
+			 const LTFAT_COMPLEX *beta,
+			 LTFAT_COMPLEX *C, const ltfatInt ldc);
+*/
+
+
+// LAPACK overwrites the input argument.
+ltfatInt
+LTFAT_NAME(ltfat_posv)(const ptrdiff_t N, const ptrdiff_t NRHS,
+                       LTFAT_COMPLEX *A, const ptrdiff_t lda,
+                       LTFAT_COMPLEX *B, const ptrdiff_t ldb);
+
+// LAPACK overwrites the input argument.
+ltfatInt
+LTFAT_NAME(ltfat_gesvd)(const ptrdiff_t M, const ptrdiff_t N,
+                        LTFAT_COMPLEX *A, const ptrdiff_t lda,
+                        LTFAT_REAL *S, LTFAT_COMPLEX *U, const ptrdiff_t ldu,
+                        LTFAT_COMPLEX *VT, const ptrdiff_t ldvt);
+
+void
+LTFAT_NAME(ltfat_gemm)(const enum CBLAS_TRANSPOSE TransA,
+                       const enum CBLAS_TRANSPOSE TransB,
+                       const ptrdiff_t M, const ptrdiff_t N, const ptrdiff_t K,
+                       const LTFAT_COMPLEX *alpha,
+                       const LTFAT_COMPLEX *A, const ptrdiff_t lda,
+                       const LTFAT_COMPLEX *B, const ptrdiff_t ldb,
+                       const LTFAT_COMPLEX *beta,
+                       LTFAT_COMPLEX *C, const ptrdiff_t ldc);
+
+/*   --- dgtreal_long class definition  --- */
+typedef struct
+{
+    ltfatInt a;
+    ltfatInt M;
+    ltfatInt L;
+    ltfatInt W;
+    ltfatInt c;
+    ltfatInt h_a;
+    LTFAT_FFTW(plan) p_before;
+    LTFAT_FFTW(plan) p_after;
+    LTFAT_FFTW(plan) p_veryend;
+    LTFAT_REAL *sbuf;
+    LTFAT_COMPLEX *cbuf;
+    const LTFAT_REAL *f;
+    LTFAT_COMPLEX *gf;
+    LTFAT_REAL *cwork;
+    LTFAT_COMPLEX *cout;
+    LTFAT_REAL *ff, *cf;
+} LTFAT_NAME(dgtreal_long_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgtreal_long_plan)
+LTFAT_NAME(dgtreal_long_init)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                              const ltfatInt L, const ltfatInt W, const ltfatInt a,
+                              const ltfatInt M, LTFAT_COMPLEX *cout,
+                              unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_long_execute)(const LTFAT_NAME(dgtreal_long_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_long_done)(LTFAT_NAME(dgtreal_long_plan) plan);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_walnut_plan)(LTFAT_NAME(dgtreal_long_plan) plan);
+
+
+
+
+/*   --- dgt_fb class definition  --- */
+typedef struct
+{
+    ltfatInt a;
+    ltfatInt M;
+    ltfatInt gl;
+
+    LTFAT_FFTW(plan) p_small;
+    LTFAT_REAL *sbuf;
+    LTFAT_REAL *fw;
+    LTFAT_COMPLEX *gw;
+    LTFAT_COMPLEX *cout;
+} LTFAT_NAME(dgt_fb_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_fb_plan)
+LTFAT_NAME(dgt_fb_init)(const LTFAT_COMPLEX *g,
+                        const ltfatInt gl, const ltfatInt a, const ltfatInt M,
+                        unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fb_execute)(const LTFAT_NAME(dgt_fb_plan) plan,
+                           const LTFAT_COMPLEX *f, const ltfatInt L, const ltfatInt W,
+                           LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_fb_done)(LTFAT_NAME(dgt_fb_plan) plan);
+
+
+
+/*   --- dgtreal_fb class definition  --- */
+
+typedef struct
+{
+    ltfatInt a;
+    ltfatInt M;
+    ltfatInt gl;
+
+    LTFAT_FFTW(plan) p_small;
+    LTFAT_REAL    *sbuf;
+    LTFAT_COMPLEX *cbuf;
+    LTFAT_REAL *fw;
+    LTFAT_REAL *gw;
+    LTFAT_COMPLEX *cout;
+} LTFAT_NAME(dgtreal_fb_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgtreal_fb_plan)
+LTFAT_NAME(dgtreal_fb_init)(const LTFAT_REAL *g,
+                            const ltfatInt gl, const ltfatInt a, const ltfatInt M,
+                            unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_fb_execute)(const LTFAT_NAME(dgtreal_fb_plan) plan,
+                               const LTFAT_REAL *f, const ltfatInt L, const ltfatInt W,
+                               LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_fb_done)(LTFAT_NAME(dgtreal_fb_plan) plan);
+
+
+/*   --- dgt_ola class definition  --- */
+typedef struct
+{
+    LTFAT_NAME(dgt_long_plan) plan;
+    ltfatInt bl;
+    ltfatInt gl;
+    ltfatInt W;
+    LTFAT_COMPLEX *buf;
+    LTFAT_COMPLEX *gext;
+    LTFAT_COMPLEX *cbuf;
+
+} LTFAT_NAME(dgt_ola_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_ola_plan)
+LTFAT_NAME(dgt_ola_init)(const LTFAT_COMPLEX *g, const ltfatInt gl,
+                         const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                         unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_ola_execute)(const LTFAT_NAME(dgt_ola_plan) plan,
+                            const LTFAT_COMPLEX *f, const ltfatInt L,
+                            LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_ola_done)(LTFAT_NAME(dgt_ola_plan) plan);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_walnut_plan)(LTFAT_NAME(dgt_long_plan) plan);
+
+
+/*   --- dgtreal_ola class definition  --- */
+typedef struct
+{
+    LTFAT_NAME(dgtreal_long_plan) plan;
+    ltfatInt bl;
+    ltfatInt gl;
+    ltfatInt W;
+    LTFAT_REAL *buf;
+    LTFAT_REAL *gext;
+    LTFAT_COMPLEX *cbuf;
+
+} LTFAT_NAME(dgtreal_ola_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgtreal_ola_plan)
+LTFAT_NAME(dgtreal_ola_init)(const LTFAT_REAL *g, const ltfatInt gl,
+                             const ltfatInt W, const ltfatInt a, const ltfatInt M, const ltfatInt bl,
+                             unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_ola_execute)(const LTFAT_NAME(dgtreal_ola_plan) plan,
+                                const LTFAT_REAL *f, const ltfatInt L,
+                                LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_ola_done)(LTFAT_NAME(dgtreal_ola_plan) plan);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgtreal_walnut_plan)(LTFAT_NAME(dgtreal_long_plan) plan);
+
+/* -----  dgt_shearola class definition ------ */
+
+typedef struct
+{
+    LTFAT_NAME(dgt_shear_plan) plan;
+    ltfatInt bl;
+    ltfatInt gl;
+    ltfatInt W;
+    LTFAT_COMPLEX *buf;
+    LTFAT_COMPLEX *gext;
+    LTFAT_COMPLEX *cbuf;
+
+} LTFAT_NAME(dgt_shearola_plan);
+
+
+LTFAT_EXTERN LTFAT_NAME(dgt_shearola_plan)
+LTFAT_NAME(dgt_shearola_init)(const LTFAT_COMPLEX *g, const ltfatInt gl,
+                              const ltfatInt W, const ltfatInt a, const ltfatInt M,
+                              const ltfatInt s0, const ltfatInt s1, const ltfatInt br,
+                              const ltfatInt bl,
+                              unsigned flags);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shearola_execute)(const LTFAT_NAME(dgt_shearola_plan) plan,
+                                 const LTFAT_COMPLEX *f, const ltfatInt L,
+                                 LTFAT_COMPLEX *cout);
+
+LTFAT_EXTERN void
+LTFAT_NAME(dgt_shearola_done)(LTFAT_NAME(dgt_shearola_plan) plan);
+
+
+
diff --git a/src/ltfat_types.h b/src/ltfat_types.h
new file mode 100644
index 0000000..fb81922
--- /dev/null
+++ b/src/ltfat_types.h
@@ -0,0 +1,81 @@
+/**
+*
+*/
+
+#ifdef LTFAT_COMPLEX
+#undef LTFAT_COMPLEX
+#endif
+#ifdef LTFAT_REAL
+#undef LTFAT_REAL
+#endif
+#ifdef LTFAT_TYPE
+#undef LTFAT_TYPE
+#endif
+#ifdef LTFAT_NAME
+#undef LTFAT_NAME
+#endif
+#ifdef LTFAT_NAME_REAL
+#undef LTFAT_NAME_REAL
+#endif
+#ifdef LTFAT_NAME_COMPLEX
+#undef LTFAT_NAME_COMPLEX
+#endif
+#ifdef LTFAT_FFTW
+#undef LTFAT_FFTW
+#endif
+
+#ifdef LTFAT_MX_CLASSID
+#undef LTFAT_MX_CLASSID
+#endif
+
+#ifdef LTFAT_MX_COMPLEXITY
+#undef LTFAT_MX_COMPLEXITY
+#endif
+
+#ifdef LTFAT_COMPLEXH
+#undef LTFAT_COMPLEXH
+#endif
+
+#ifdef LTFAT_COMPLEXH
+#undef LTFAT_COMPLEXH
+#endif
+
+#ifdef LTFAT_DOUBLE
+#  define LTFAT_REAL double
+#  define LTFAT_COMPLEX double _Complex
+#  define LTFAT_FFTW(name) fftw_ ## name
+#  define LTFAT_NAME_REAL(name) LTFAT_NAME_DOUBLE(name)
+#  define LTFAT_NAME_COMPLEX(name) LTFAT_NAME_COMPLEXDOUBLE(name)
+#  define LTFAT_COMPLEXH(name) name
+#  define LTFAT_MX_CLASSID mxDOUBLE_CLASS
+#  if defined(LTFAT_COMPLEXTYPE)
+#    define LTFAT_TYPE LTFAT_COMPLEX
+#    define LTFAT_NAME(name) LTFAT_NAME_COMPLEXDOUBLE(name)
+#    define LTFAT_MX_COMPLEXITY mxCOMPLEX
+#  else
+#    define LTFAT_TYPE LTFAT_REAL
+#    define LTFAT_NAME(name) LTFAT_NAME_DOUBLE(name)
+#    define LTFAT_MX_COMPLEXITY mxREAL
+#  endif
+#endif
+
+#ifdef LTFAT_SINGLE
+#define LTFAT_REAL float
+#define LTFAT_COMPLEX float _Complex
+#define LTFAT_MX_CLASSID mxSINGLE_CLASS
+#define LTFAT_NAME_REAL(name) LTFAT_NAME_SINGLE(name)
+#define LTFAT_NAME_COMPLEX(name) LTFAT_NAME_COMPLEXSINGLE(name)
+#define LTFAT_FFTW(name) fftwf_ ## name
+#define LTFAT_COMPLEXH(name) name ## f
+#  if defined(LTFAT_COMPLEXTYPE)
+#    define LTFAT_TYPE LTFAT_COMPLEX
+#    define LTFAT_NAME(name) LTFAT_NAME_COMPLEXSINGLE(name)
+#    define LTFAT_MX_COMPLEXITY mxCOMPLEX
+#  else
+#    define LTFAT_TYPE LTFAT_REAL
+#    define LTFAT_NAME(name) LTFAT_NAME_SINGLE(name)
+#    define LTFAT_MX_COMPLEXITY mxREAL
+#  endif
+#endif
+
+
diff --git a/src/m4/ax_blas.m4 b/src/m4/ax_blas.m4
new file mode 100644
index 0000000..e4f96cb
--- /dev/null
+++ b/src/m4/ax_blas.m4
@@ -0,0 +1,201 @@
+# ===========================================================================
+#          http://www.gnu.org/software/autoconf-archive/ax_blas.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the BLAS linear-algebra
+#   interface (see http://www.netlib.org/blas/). On success, it sets the
+#   BLAS_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with BLAS, you should link with:
+#
+#     $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   Many libraries are searched for, from ATLAS to CXML to ESSL. The user
+#   may also use --with-blas=<lib> in order to use some specific BLAS
+#   library <lib>. In order to link successfully, however, be aware that you
+#   will probably need to use the same Fortran compiler (which can be set
+#   via the F77 env. var.) as was used to compile the BLAS library.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a BLAS library is
+#   found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is
+#   not found. If ACTION-IF-FOUND is not specified, the default action will
+#   define HAVE_BLAS.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 11
+
+AU_ALIAS([ACX_BLAS], [AX_BLAS])
+AC_DEFUN([AX_BLAS], [
+AC_PREREQ(2.50)
+AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])
+ax_blas_ok=no
+
+AC_ARG_WITH(blas,
+	[AS_HELP_STRING([--with-blas=<lib>], [use BLAS library <lib>])])
+case $with_blas in
+	yes | "") ;;
+	no) ax_blas_ok=disable ;;
+	-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;;
+	*) BLAS_LIBS="-l$with_blas" ;;
+esac
+
+# Get fortran linker names of BLAS functions to check for.
+AC_F77_FUNC(sgemm)
+AC_F77_FUNC(dgemm)
+
+ax_blas_save_LIBS="$LIBS"
+LIBS="$LIBS $FLIBS"
+
+# First, check BLAS_LIBS environment variable
+if test $ax_blas_ok = no; then
+if test "x$BLAS_LIBS" != x; then
+	save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
+	AC_MSG_CHECKING([for $sgemm in $BLAS_LIBS])
+	AC_TRY_LINK_FUNC($sgemm, [ax_blas_ok=yes], [BLAS_LIBS=""])
+	AC_MSG_RESULT($ax_blas_ok)
+	LIBS="$save_LIBS"
+fi
+fi
+
+# BLAS linked to by default?  (happens on some supercomputers)
+if test $ax_blas_ok = no; then
+	save_LIBS="$LIBS"; LIBS="$LIBS"
+	AC_MSG_CHECKING([if $sgemm is being linked in already])
+	AC_TRY_LINK_FUNC($sgemm, [ax_blas_ok=yes])
+	AC_MSG_RESULT($ax_blas_ok)
+	LIBS="$save_LIBS"
+fi
+
+# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(atlas, ATL_xerbla,
+		[AC_CHECK_LIB(f77blas, $sgemm,
+		[AC_CHECK_LIB(cblas, cblas_dgemm,
+			[ax_blas_ok=yes
+			 BLAS_LIBS="-lcblas -lf77blas -latlas"],
+			[], [-lf77blas -latlas])],
+			[], [-latlas])])
+fi
+
+# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(blas, $sgemm,
+		[AC_CHECK_LIB(dgemm, $dgemm,
+		[AC_CHECK_LIB(sgemm, $sgemm,
+			[ax_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"],
+			[], [-lblas])],
+			[], [-lblas])])
+fi
+
+# BLAS in Intel MKL library?
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(mkl, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lmkl"])
+fi
+
+# BLAS in Apple vecLib library?
+if test $ax_blas_ok = no; then
+	save_LIBS="$LIBS"; LIBS="-framework vecLib $LIBS"
+	AC_MSG_CHECKING([for $sgemm in -framework vecLib])
+	AC_TRY_LINK_FUNC($sgemm, [ax_blas_ok=yes;BLAS_LIBS="-framework vecLib"])
+	AC_MSG_RESULT($ax_blas_ok)
+	LIBS="$save_LIBS"
+fi
+
+# BLAS in Alpha CXML library?
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(cxml, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lcxml"])
+fi
+
+# BLAS in Alpha DXML library? (now called CXML, see above)
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(dxml, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-ldxml"])
+fi
+
+# BLAS in Sun Performance library?
+if test $ax_blas_ok = no; then
+	if test "x$GCC" != xyes; then # only works with Sun CC
+		AC_CHECK_LIB(sunmath, acosp,
+			[AC_CHECK_LIB(sunperf, $sgemm,
+				[BLAS_LIBS="-xlic_lib=sunperf -lsunmath"
+                                 ax_blas_ok=yes],[],[-lsunmath])])
+	fi
+fi
+
+# BLAS in SCSL library?  (SGI/Cray Scientific Library)
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(scs, $sgemm, [ax_blas_ok=yes; BLAS_LIBS="-lscs"])
+fi
+
+# BLAS in SGIMATH library?
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(complib.sgimath, $sgemm,
+		     [ax_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"])
+fi
+
+# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(blas, $sgemm,
+		[AC_CHECK_LIB(essl, $sgemm,
+			[ax_blas_ok=yes; BLAS_LIBS="-lessl -lblas"],
+			[], [-lblas $FLIBS])])
+fi
+
+# Generic BLAS library?
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(blas, $sgemm, [ax_blas_ok=yes; BLAS_LIBS="-lblas"])
+fi
+
+AC_SUBST(BLAS_LIBS)
+
+LIBS="$ax_blas_save_LIBS"
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_blas_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_BLAS,1,[Define if you have a BLAS library.]),[$1])
+        :
+else
+        ax_blas_ok=no
+        $2
+fi
+])dnl AX_BLAS
diff --git a/src/m4/ax_lapack.m4 b/src/m4/ax_lapack.m4
new file mode 100644
index 0000000..6aa16aa
--- /dev/null
+++ b/src/m4/ax_lapack.m4
@@ -0,0 +1,131 @@
+# ===========================================================================
+#         http://www.gnu.org/software/autoconf-archive/ax_lapack.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_LAPACK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro looks for a library that implements the LAPACK linear-algebra
+#   interface (see http://www.netlib.org/lapack/). On success, it sets the
+#   LAPACK_LIBS output variable to hold the requisite library linkages.
+#
+#   To link with LAPACK, you should link with:
+#
+#     $LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS
+#
+#   in that order. BLAS_LIBS is the output variable of the AX_BLAS macro,
+#   called automatically. FLIBS is the output variable of the
+#   AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is
+#   sometimes necessary in order to link with F77 libraries. Users will also
+#   need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same
+#   reason.
+#
+#   The user may also use --with-lapack=<lib> in order to use some specific
+#   LAPACK library <lib>. In order to link successfully, however, be aware
+#   that you will probably need to use the same Fortran compiler (which can
+#   be set via the F77 env. var.) as was used to compile the LAPACK and BLAS
+#   libraries.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a LAPACK library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_LAPACK.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Steven G. Johnson <stevenj at alum.mit.edu>
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AU_ALIAS([ACX_LAPACK], [AX_LAPACK])
+AC_DEFUN([AX_LAPACK], [
+AC_REQUIRE([AX_BLAS])
+ax_lapack_ok=no
+
+AC_ARG_WITH(lapack,
+        [AS_HELP_STRING([--with-lapack=<lib>], [use LAPACK library <lib>])])
+case $with_lapack in
+        yes | "") ;;
+        no) ax_lapack_ok=disable ;;
+        -* | */* | *.a | *.so | *.so.* | *.o) LAPACK_LIBS="$with_lapack" ;;
+        *) LAPACK_LIBS="-l$with_lapack" ;;
+esac
+
+# Get fortran linker name of LAPACK function to check for.
+AC_F77_FUNC(cheev)
+
+# We cannot use LAPACK if BLAS is not found
+if test "x$ax_blas_ok" != xyes; then
+        ax_lapack_ok=noblas
+        LAPACK_LIBS=""
+fi
+
+# First, check LAPACK_LIBS environment variable
+if test "x$LAPACK_LIBS" != x; then
+        save_LIBS="$LIBS"; LIBS="$LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS"
+        AC_MSG_CHECKING([for $cheev in $LAPACK_LIBS])
+        AC_TRY_LINK_FUNC($cheev, [ax_lapack_ok=yes], [LAPACK_LIBS=""])
+        AC_MSG_RESULT($ax_lapack_ok)
+        LIBS="$save_LIBS"
+        if test $ax_lapack_ok = no; then
+                LAPACK_LIBS=""
+        fi
+fi
+
+# LAPACK linked to by default?  (is sometimes included in BLAS lib)
+if test $ax_lapack_ok = no; then
+        save_LIBS="$LIBS"; LIBS="$LIBS $BLAS_LIBS $FLIBS"
+        AC_CHECK_FUNC($cheev, [ax_lapack_ok=yes])
+        LIBS="$save_LIBS"
+fi
+
+# Generic LAPACK library?
+for lapack in lapack lapack_rs6k; do
+        if test $ax_lapack_ok = no; then
+                save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
+                AC_CHECK_LIB($lapack, $cheev,
+                    [ax_lapack_ok=yes; LAPACK_LIBS="-l$lapack"], [], [$FLIBS])
+                LIBS="$save_LIBS"
+        fi
+done
+
+AC_SUBST(LAPACK_LIBS)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_lapack_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_LAPACK,1,[Define if you have LAPACK library.]),[$1])
+        :
+else
+        ax_lapack_ok=no
+        $2
+fi
+])dnl AX_LAPACK
diff --git a/src/ostools.mk b/src/ostools.mk
new file mode 100644
index 0000000..5eb5f3d
--- /dev/null
+++ b/src/ostools.mk
@@ -0,0 +1,26 @@
+#This file produces system and environment dependent tools for working with files
+#It sets the following variables
+#
+#  RM
+#  CP
+
+ifeq ($(OS),Windows_NT) 
+RM = del /Q /F
+CP = copy /Y
+PS2 = \\
+PS = $(strip $(PS2))
+ifdef ComSpec
+SHELL := $(ComSpec)
+endif
+ifdef COMSPEC
+SHELL := $(COMSPEC)
+endif
+CC = gcc
+else
+#If not on Windows
+RM = rm -rf
+CP = cp -f
+PS = /
+endif
+
+#CC=gcc
diff --git a/src/pfilt.c b/src/pfilt.c
new file mode 100644
index 0000000..2136fb8
--- /dev/null
+++ b/src/pfilt.c
@@ -0,0 +1,104 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(pfilt_fir_rr)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                         const ltfatInt L, const ltfatInt gl,
+                         const ltfatInt W, const ltfatInt a,
+                         LTFAT_REAL *cout)
+{
+    /*  --------- initial declarations -------------- */
+
+    ltfatInt l, n, w;
+
+    LTFAT_REAL *gw;
+
+    LTFAT_REAL *gb;
+    LTFAT_REAL fw;
+
+    const LTFAT_REAL *fbd;
+
+    /*  ----------- calculation of parameters and plans -------- */
+
+    const ltfatInt N=L/a;
+
+    /* These are floor operations. */
+    const ltfatInt glh=gl/2;
+
+    /* This is a ceil operation. */
+    const ltfatInt glh_d_a=(ltfatInt)ceil((glh*1.0)/(a));
+
+    gw   = (LTFAT_REAL*)ltfat_malloc(gl*sizeof(LTFAT_REAL));
+
+    /*  ---------- main body ----------- */
+
+    /* Do the fftshift of g to place the center in the middle and
+     * conjugate it.
+     */
+
+    for (l=0; l<glh; l++)
+    {
+        gw[l]=g[l+(gl-glh)];
+    }
+    for (l=glh; l<gl; l++)
+    {
+        gw[l]=g[l-glh];
+    }
+
+    for (w=0; w<W; w++)
+    {
+        /*----- Handle the first boundary using periodic boundary conditions.*/
+        for (n=0; n<glh_d_a; n++)
+        {
+            gb=gw;
+            fbd=f+L-(glh-n*a)+L*w;
+            fw=0.0;
+            for (l=0; l<glh-n*a; l++)
+            {
+                fw +=fbd[l]*gb[l];
+            }
+            fbd=f-(glh-n*a)+L*w;
+            for (l=glh-n*a; l<gl; l++)
+            {
+                fw +=fbd[l]*gb[l];
+            }
+            cout[n+w*N]=fw;
+        }
+
+        /* ----- Handle the middle case. --------------------- */
+        for (n=glh_d_a; n<(L-(gl+1)/2)/a+1; n++)
+        {
+            gb=gw;
+            fbd=f+(n*a-glh+L*w);
+            fw=0;
+            for (l=0; l<gl; l++)
+            {
+                fw +=fbd[l]*gb[l];
+            }
+            cout[n+w*N]=fw;
+        }
+
+        /* Handle the last boundary using periodic boundary conditions. */
+        for (n=(L-(gl+1)/2)/a+1; n<N; n++)
+        {
+            gb=gw;
+            fbd=f+(n*a-glh+L*w);
+            fw=0;
+            for (l=0; l<L-n*a+glh; l++)
+            {
+                fw +=fbd[l]*gb[l];
+            }
+            fbd=f-(L-n*a+glh)+L*w;
+            for (l=L-n*a+glh; l<gl; l++)
+            {
+                fw +=fbd[l]*gb[l];
+            }
+            cout[n+w*N]=fw;
+        }
+    }
+
+    /* -----------  Clean up ----------------- */
+    ltfat_free(gw);
+
+}
diff --git a/src/reassign.c b/src/reassign.c
new file mode 100644
index 0000000..f2f0543
--- /dev/null
+++ b/src/reassign.c
@@ -0,0 +1,45 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(gabreassign)(const LTFAT_REAL *s, const LTFAT_REAL *tgrad,
+                        const LTFAT_REAL *fgrad, const ltfatInt L, const ltfatInt W,
+                        const ltfatInt a, const ltfatInt M, LTFAT_REAL *sr)
+{
+
+    ltfatInt ii, posi, posj;
+
+
+    const ltfatInt N=L/a;
+    const ltfatInt b=L/M;
+
+    ltfatInt *timepos = ltfat_malloc(N*sizeof*timepos);
+    ltfatInt *freqpos = ltfat_malloc(M*sizeof*freqpos);
+
+    fftindex(N,timepos);
+    fftindex(M,freqpos);
+
+    /* Zero the output array. */
+    memset(sr,0,M*N*W*sizeof*sr);
+
+    for (ltfatInt w=0; w<W; w++)
+    {
+        for (ii=0; ii<M; ii++)
+        {
+            for (ltfatInt jj=0; jj<N; jj++)
+            {
+                /* Do a 'round' followed by a 'mod'. 'round' is not
+                 * present in all libraries, so use trunc(x+.5) instead */
+                /*posi=positiverem((ltfatInt)trunc(tgrad[ii+jj*M]/b+freqpos[ii]+.5),M);
+                  posj=positiverem((ltfatInt)trunc(fgrad[ii+jj*M]/a+timepos[jj]+.5),N);*/
+                posi=positiverem(ltfat_round(tgrad[ii+jj*M]/b+freqpos[ii]),M);
+                posj=positiverem(ltfat_round(fgrad[ii+jj*M]/a+timepos[jj]),N);
+
+                sr[posi+posj*M]+=s[ii+jj*M];
+            }
+        }
+    }
+
+    LTFAT_SAFEFREEALL(freqpos,timepos);
+}
diff --git a/src/spread.c b/src/spread.c
new file mode 100644
index 0000000..a0a6e65
--- /dev/null
+++ b/src/spread.c
@@ -0,0 +1,36 @@
+/* NOT PROCESSED DIRECTLY, see ltfat_complexindependent.c */
+#ifdef LTFAT_TYPE
+#include "ltfat.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(col2diag)(const LTFAT_TYPE *cin, const ltfatInt L,
+                     LTFAT_TYPE *cout)
+{
+    ltfatInt ii;
+
+    LTFAT_TYPE *pcout;
+    const LTFAT_TYPE *pcin;
+
+    pcout=cout;
+    const ltfatInt Lp1=L+1;
+    for (ltfatInt jj=0; jj<L; jj++)
+    {
+        pcin=cin+(L-jj)*L;
+        for (ii=0; ii<jj; ii++)
+        {
+            (*pcout) = (*pcin);
+            pcout++;
+            pcin+=Lp1;
+        }
+        pcin-=L*L;
+        for (ii=jj; ii<L; ii++)
+        {
+            (*pcout) = (*pcin);
+            pcout++;
+            pcin+=Lp1;
+        }
+    }
+
+}
+
+#endif
diff --git a/src/thirdparty/cblas.h b/src/thirdparty/cblas.h
new file mode 100644
index 0000000..4087ffb
--- /dev/null
+++ b/src/thirdparty/cblas.h
@@ -0,0 +1,596 @@
+#ifndef CBLAS_H
+
+#ifndef CBLAS_ENUM_DEFINED_H
+   #define CBLAS_ENUM_DEFINED_H
+   enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102 };
+   enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113,
+                         AtlasConj=114};
+   enum CBLAS_UPLO  {CblasUpper=121, CblasLower=122};
+   enum CBLAS_DIAG  {CblasNonUnit=131, CblasUnit=132};
+   enum CBLAS_SIDE  {CblasLeft=141, CblasRight=142};
+#endif
+
+#ifndef CBLAS_ENUM_ONLY
+#define CBLAS_H
+#define CBLAS_INDEX int
+
+int cblas_errprn(int ierr, int info, char *form, ...);
+
+/*
+ * ===========================================================================
+ * Prototypes for level 1 BLAS functions (complex are recast as routines)
+ * ===========================================================================
+ */
+float  cblas_sdsdot(const int N, const float alpha, const float *X,
+                    const int incX, const float *Y, const int incY);
+double cblas_dsdot(const int N, const float *X, const int incX, const float *Y,
+                   const int incY);
+float  cblas_sdot(const int N, const float  *X, const int incX,
+                  const float  *Y, const int incY);
+double cblas_ddot(const int N, const double *X, const int incX,
+                  const double *Y, const int incY);
+/*
+ * Functions having prefixes Z and C only
+ */
+void   cblas_cdotu_sub(const int N, const void *X, const int incX,
+                       const void *Y, const int incY, void *dotu);
+void   cblas_cdotc_sub(const int N, const void *X, const int incX,
+                       const void *Y, const int incY, void *dotc);
+
+void   cblas_zdotu_sub(const int N, const void *X, const int incX,
+                       const void *Y, const int incY, void *dotu);
+void   cblas_zdotc_sub(const int N, const void *X, const int incX,
+                       const void *Y, const int incY, void *dotc);
+
+
+/*
+ * Functions having prefixes S D SC DZ
+ */
+float  cblas_snrm2(const int N, const float *X, const int incX);
+float  cblas_sasum(const int N, const float *X, const int incX);
+
+double cblas_dnrm2(const int N, const double *X, const int incX);
+double cblas_dasum(const int N, const double *X, const int incX);
+
+float  cblas_scnrm2(const int N, const void *X, const int incX);
+float  cblas_scasum(const int N, const void *X, const int incX);
+
+double cblas_dznrm2(const int N, const void *X, const int incX);
+double cblas_dzasum(const int N, const void *X, const int incX);
+
+
+/*
+ * Functions having standard 4 prefixes (S D C Z)
+ */
+CBLAS_INDEX cblas_isamax(const int N, const float  *X, const int incX);
+CBLAS_INDEX cblas_idamax(const int N, const double *X, const int incX);
+CBLAS_INDEX cblas_icamax(const int N, const void   *X, const int incX);
+CBLAS_INDEX cblas_izamax(const int N, const void   *X, const int incX);
+
+/*
+ * ===========================================================================
+ * Prototypes for level 1 BLAS routines
+ * ===========================================================================
+ */
+
+/*
+ * Routines with standard 4 prefixes (s, d, c, z)
+ */
+void cblas_sswap(const int N, float *X, const int incX,
+                 float *Y, const int incY);
+void cblas_scopy(const int N, const float *X, const int incX,
+                 float *Y, const int incY);
+void cblas_saxpy(const int N, const float alpha, const float *X,
+                 const int incX, float *Y, const int incY);
+void catlas_saxpby(const int N, const float alpha, const float *X,
+                  const int incX, const float beta, float *Y, const int incY);
+void catlas_sset
+   (const int N, const float alpha, float *X, const int incX);
+
+void cblas_dswap(const int N, double *X, const int incX,
+                 double *Y, const int incY);
+void cblas_dcopy(const int N, const double *X, const int incX,
+                 double *Y, const int incY);
+void cblas_daxpy(const int N, const double alpha, const double *X,
+                 const int incX, double *Y, const int incY);
+void catlas_daxpby(const int N, const double alpha, const double *X,
+                  const int incX, const double beta, double *Y, const int incY);
+void catlas_dset
+   (const int N, const double alpha, double *X, const int incX);
+
+void cblas_cswap(const int N, void *X, const int incX,
+                 void *Y, const int incY);
+void cblas_ccopy(const int N, const void *X, const int incX,
+                 void *Y, const int incY);
+void cblas_caxpy(const int N, const void *alpha, const void *X,
+                 const int incX, void *Y, const int incY);
+void catlas_caxpby(const int N, const void *alpha, const void *X,
+                  const int incX, const void *beta, void *Y, const int incY);
+void catlas_cset
+   (const int N, const void *alpha, void *X, const int incX);
+
+void cblas_zswap(const int N, void *X, const int incX,
+                 void *Y, const int incY);
+void cblas_zcopy(const int N, const void *X, const int incX,
+                 void *Y, const int incY);
+void cblas_zaxpy(const int N, const void *alpha, const void *X,
+                 const int incX, void *Y, const int incY);
+void catlas_zaxpby(const int N, const void *alpha, const void *X,
+                  const int incX, const void *beta, void *Y, const int incY);
+void catlas_zset
+   (const int N, const void *alpha, void *X, const int incX);
+
+
+/*
+ * Routines with S and D prefix only
+ */
+void cblas_srotg(float *a, float *b, float *c, float *s);
+void cblas_srotmg(float *d1, float *d2, float *b1, const float b2, float *P);
+void cblas_srot(const int N, float *X, const int incX,
+                float *Y, const int incY, const float c, const float s);
+void cblas_srotm(const int N, float *X, const int incX,
+                float *Y, const int incY, const float *P);
+
+void cblas_drotg(double *a, double *b, double *c, double *s);
+void cblas_drotmg(double *d1, double *d2, double *b1, const double b2, double *P);
+void cblas_drot(const int N, double *X, const int incX,
+                double *Y, const int incY, const double c, const double s);
+void cblas_drotm(const int N, double *X, const int incX,
+                double *Y, const int incY, const double *P);
+
+
+/*
+ * Routines with S D C Z CS and ZD prefixes
+ */
+void cblas_sscal(const int N, const float alpha, float *X, const int incX);
+void cblas_dscal(const int N, const double alpha, double *X, const int incX);
+void cblas_cscal(const int N, const void *alpha, void *X, const int incX);
+void cblas_zscal(const int N, const void *alpha, void *X, const int incX);
+void cblas_csscal(const int N, const float alpha, void *X, const int incX);
+void cblas_zdscal(const int N, const double alpha, void *X, const int incX);
+
+/*
+ * Extra reference routines provided by ATLAS, but not mandated by the standard
+ */
+void cblas_crotg(void *a, void *b, void *c, void *s);
+void cblas_zrotg(void *a, void *b, void *c, void *s);
+void cblas_csrot(const int N, void *X, const int incX, void *Y, const int incY,
+                 const float c, const float s);
+void cblas_zdrot(const int N, void *X, const int incX, void *Y, const int incY,
+                 const double c, const double s);
+
+/*
+ * ===========================================================================
+ * Prototypes for level 2 BLAS
+ * ===========================================================================
+ */
+
+/*
+ * Routines with standard 4 prefixes (S, D, C, Z)
+ */
+void cblas_sgemv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const float alpha, const float *A, const int lda,
+                 const float *X, const int incX, const float beta,
+                 float *Y, const int incY);
+void cblas_sgbmv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const int KL, const int KU, const float alpha,
+                 const float *A, const int lda, const float *X,
+                 const int incX, const float beta, float *Y, const int incY);
+void cblas_strmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const float *A, const int lda,
+                 float *X, const int incX);
+void cblas_stbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const float *A, const int lda,
+                 float *X, const int incX);
+void cblas_stpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const float *Ap, float *X, const int incX);
+void cblas_strsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const float *A, const int lda, float *X,
+                 const int incX);
+void cblas_stbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const float *A, const int lda,
+                 float *X, const int incX);
+void cblas_stpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const float *Ap, float *X, const int incX);
+
+void cblas_dgemv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const double alpha, const double *A, const int lda,
+                 const double *X, const int incX, const double beta,
+                 double *Y, const int incY);
+void cblas_dgbmv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const int KL, const int KU, const double alpha,
+                 const double *A, const int lda, const double *X,
+                 const int incX, const double beta, double *Y, const int incY);
+void cblas_dtrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const double *A, const int lda,
+                 double *X, const int incX);
+void cblas_dtbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const double *A, const int lda,
+                 double *X, const int incX);
+void cblas_dtpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const double *Ap, double *X, const int incX);
+void cblas_dtrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const double *A, const int lda, double *X,
+                 const int incX);
+void cblas_dtbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const double *A, const int lda,
+                 double *X, const int incX);
+void cblas_dtpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const double *Ap, double *X, const int incX);
+
+void cblas_cgemv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 const void *X, const int incX, const void *beta,
+                 void *Y, const int incY);
+void cblas_cgbmv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const int KL, const int KU, const void *alpha,
+                 const void *A, const int lda, const void *X,
+                 const int incX, const void *beta, void *Y, const int incY);
+void cblas_ctrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *A, const int lda,
+                 void *X, const int incX);
+void cblas_ctbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const void *A, const int lda,
+                 void *X, const int incX);
+void cblas_ctpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *Ap, void *X, const int incX);
+void cblas_ctrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *A, const int lda, void *X,
+                 const int incX);
+void cblas_ctbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const void *A, const int lda,
+                 void *X, const int incX);
+void cblas_ctpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *Ap, void *X, const int incX);
+
+void cblas_zgemv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 const void *X, const int incX, const void *beta,
+                 void *Y, const int incY);
+void cblas_zgbmv(const enum CBLAS_ORDER Order,
+                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
+                 const int KL, const int KU, const void *alpha,
+                 const void *A, const int lda, const void *X,
+                 const int incX, const void *beta, void *Y, const int incY);
+void cblas_ztrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *A, const int lda,
+                 void *X, const int incX);
+void cblas_ztbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const void *A, const int lda,
+                 void *X, const int incX);
+void cblas_ztpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *Ap, void *X, const int incX);
+void cblas_ztrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *A, const int lda, void *X,
+                 const int incX);
+void cblas_ztbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const int K, const void *A, const int lda,
+                 void *X, const int incX);
+void cblas_ztpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
+                 const int N, const void *Ap, void *X, const int incX);
+
+
+/*
+ * Routines with S and D prefixes only
+ */
+void cblas_ssymv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const float alpha, const float *A,
+                 const int lda, const float *X, const int incX,
+                 const float beta, float *Y, const int incY);
+void cblas_ssbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const int K, const float alpha, const float *A,
+                 const int lda, const float *X, const int incX,
+                 const float beta, float *Y, const int incY);
+void cblas_sspmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const float alpha, const float *Ap,
+                 const float *X, const int incX,
+                 const float beta, float *Y, const int incY);
+void cblas_sger(const enum CBLAS_ORDER Order, const int M, const int N,
+                const float alpha, const float *X, const int incX,
+                const float *Y, const int incY, float *A, const int lda);
+void cblas_ssyr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const float alpha, const float *X,
+                const int incX, float *A, const int lda);
+void cblas_sspr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const float alpha, const float *X,
+                const int incX, float *Ap);
+void cblas_ssyr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const float alpha, const float *X,
+                const int incX, const float *Y, const int incY, float *A,
+                const int lda);
+void cblas_sspr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const float alpha, const float *X,
+                const int incX, const float *Y, const int incY, float *A);
+
+void cblas_dsymv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const double alpha, const double *A,
+                 const int lda, const double *X, const int incX,
+                 const double beta, double *Y, const int incY);
+void cblas_dsbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const int K, const double alpha, const double *A,
+                 const int lda, const double *X, const int incX,
+                 const double beta, double *Y, const int incY);
+void cblas_dspmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const double alpha, const double *Ap,
+                 const double *X, const int incX,
+                 const double beta, double *Y, const int incY);
+void cblas_dger(const enum CBLAS_ORDER Order, const int M, const int N,
+                const double alpha, const double *X, const int incX,
+                const double *Y, const int incY, double *A, const int lda);
+void cblas_dsyr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const double alpha, const double *X,
+                const int incX, double *A, const int lda);
+void cblas_dspr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const double alpha, const double *X,
+                const int incX, double *Ap);
+void cblas_dsyr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const double alpha, const double *X,
+                const int incX, const double *Y, const int incY, double *A,
+                const int lda);
+void cblas_dspr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const double alpha, const double *X,
+                const int incX, const double *Y, const int incY, double *A);
+
+
+/*
+ * Routines with C and Z prefixes only
+ */
+void cblas_chemv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const void *alpha, const void *A,
+                 const int lda, const void *X, const int incX,
+                 const void *beta, void *Y, const int incY);
+void cblas_chbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const int K, const void *alpha, const void *A,
+                 const int lda, const void *X, const int incX,
+                 const void *beta, void *Y, const int incY);
+void cblas_chpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const void *alpha, const void *Ap,
+                 const void *X, const int incX,
+                 const void *beta, void *Y, const int incY);
+void cblas_cgeru(const enum CBLAS_ORDER Order, const int M, const int N,
+                 const void *alpha, const void *X, const int incX,
+                 const void *Y, const int incY, void *A, const int lda);
+void cblas_cgerc(const enum CBLAS_ORDER Order, const int M, const int N,
+                 const void *alpha, const void *X, const int incX,
+                 const void *Y, const int incY, void *A, const int lda);
+void cblas_cher(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const float alpha, const void *X, const int incX,
+                void *A, const int lda);
+void cblas_chpr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const float alpha, const void *X,
+                const int incX, void *A);
+void cblas_cher2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
+                const void *alpha, const void *X, const int incX,
+                const void *Y, const int incY, void *A, const int lda);
+void cblas_chpr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
+                const void *alpha, const void *X, const int incX,
+                const void *Y, const int incY, void *Ap);
+
+void cblas_zhemv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const void *alpha, const void *A,
+                 const int lda, const void *X, const int incX,
+                 const void *beta, void *Y, const int incY);
+void cblas_zhbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const int K, const void *alpha, const void *A,
+                 const int lda, const void *X, const int incX,
+                 const void *beta, void *Y, const int incY);
+void cblas_zhpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const int N, const void *alpha, const void *Ap,
+                 const void *X, const int incX,
+                 const void *beta, void *Y, const int incY);
+void cblas_zgeru(const enum CBLAS_ORDER Order, const int M, const int N,
+                 const void *alpha, const void *X, const int incX,
+                 const void *Y, const int incY, void *A, const int lda);
+void cblas_zgerc(const enum CBLAS_ORDER Order, const int M, const int N,
+                 const void *alpha, const void *X, const int incX,
+                 const void *Y, const int incY, void *A, const int lda);
+void cblas_zher(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const double alpha, const void *X, const int incX,
+                void *A, const int lda);
+void cblas_zhpr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                const int N, const double alpha, const void *X,
+                const int incX, void *A);
+void cblas_zher2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
+                const void *alpha, const void *X, const int incX,
+                const void *Y, const int incY, void *A, const int lda);
+void cblas_zhpr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
+                const void *alpha, const void *X, const int incX,
+                const void *Y, const int incY, void *Ap);
+
+/*
+ * ===========================================================================
+ * Prototypes for level 3 BLAS
+ * ===========================================================================
+ */
+
+/*
+ * Routines with standard 4 prefixes (S, D, C, Z)
+ */
+void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
+                 const int K, const float alpha, const float *A,
+                 const int lda, const float *B, const int ldb,
+                 const float beta, float *C, const int ldc);
+void cblas_ssymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const int M, const int N,
+                 const float alpha, const float *A, const int lda,
+                 const float *B, const int ldb, const float beta,
+                 float *C, const int ldc);
+void cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                 const float alpha, const float *A, const int lda,
+                 const float beta, float *C, const int ldc);
+void cblas_ssyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                  const float alpha, const float *A, const int lda,
+                  const float *B, const int ldb, const float beta,
+                  float *C, const int ldc);
+void cblas_strmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const float alpha, const float *A, const int lda,
+                 float *B, const int ldb);
+void cblas_strsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const float alpha, const float *A, const int lda,
+                 float *B, const int ldb);
+
+void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
+                 const int K, const double alpha, const double *A,
+                 const int lda, const double *B, const int ldb,
+                 const double beta, double *C, const int ldc);
+void cblas_dsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const int M, const int N,
+                 const double alpha, const double *A, const int lda,
+                 const double *B, const int ldb, const double beta,
+                 double *C, const int ldc);
+void cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                 const double alpha, const double *A, const int lda,
+                 const double beta, double *C, const int ldc);
+void cblas_dsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                  const double alpha, const double *A, const int lda,
+                  const double *B, const int ldb, const double beta,
+                  double *C, const int ldc);
+void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const double alpha, const double *A, const int lda,
+                 double *B, const int ldb);
+void cblas_dtrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const double alpha, const double *A, const int lda,
+                 double *B, const int ldb);
+
+void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
+                 const int K, const void *alpha, const void *A,
+                 const int lda, const void *B, const int ldb,
+                 const void *beta, void *C, const int ldc);
+void cblas_csymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 const void *B, const int ldb, const void *beta,
+                 void *C, const int ldc);
+void cblas_csyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                 const void *alpha, const void *A, const int lda,
+                 const void *beta, void *C, const int ldc);
+void cblas_csyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                  const void *alpha, const void *A, const int lda,
+                  const void *B, const int ldb, const void *beta,
+                  void *C, const int ldc);
+void cblas_ctrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 void *B, const int ldb);
+void cblas_ctrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 void *B, const int ldb);
+
+void cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
+                 const int K, const void *alpha, const void *A,
+                 const int lda, const void *B, const int ldb,
+                 const void *beta, void *C, const int ldc);
+void cblas_zsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 const void *B, const int ldb, const void *beta,
+                 void *C, const int ldc);
+void cblas_zsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                 const void *alpha, const void *A, const int lda,
+                 const void *beta, void *C, const int ldc);
+void cblas_zsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                  const void *alpha, const void *A, const int lda,
+                  const void *B, const int ldb, const void *beta,
+                  void *C, const int ldc);
+void cblas_ztrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 void *B, const int ldb);
+void cblas_ztrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
+                 const enum CBLAS_DIAG Diag, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 void *B, const int ldb);
+
+
+/*
+ * Routines with prefixes C and Z only
+ */
+void cblas_chemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 const void *B, const int ldb, const void *beta,
+                 void *C, const int ldc);
+void cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                 const float alpha, const void *A, const int lda,
+                 const float beta, void *C, const int ldc);
+void cblas_cher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                  const void *alpha, const void *A, const int lda,
+                  const void *B, const int ldb, const float beta,
+                  void *C, const int ldc);
+void cblas_zhemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
+                 const enum CBLAS_UPLO Uplo, const int M, const int N,
+                 const void *alpha, const void *A, const int lda,
+                 const void *B, const int ldb, const void *beta,
+                 void *C, const int ldc);
+void cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                 const double alpha, const void *A, const int lda,
+                 const double beta, void *C, const int ldc);
+void cblas_zher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
+                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
+                  const void *alpha, const void *A, const int lda,
+                  const void *B, const int ldb, const double beta,
+                  void *C, const int ldc);
+
+int cblas_errprn(int ierr, int info, char *form, ...);
+
+#endif  /* end #ifdef CBLAS_ENUM_ONLY */
+#endif
diff --git a/src/thirdparty/f77-fcn.h b/src/thirdparty/f77-fcn.h
new file mode 100644
index 0000000..059f776
--- /dev/null
+++ b/src/thirdparty/f77-fcn.h
@@ -0,0 +1,188 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave 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 Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+#if !defined (octave_f77_fcn_h)
+#define octave_f77_fcn_h 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Hack to stringize macro results. */
+#define xSTRINGIZE(x) #x
+#define STRINGIZE(x) xSTRINGIZE(x)
+
+/* How to print an error for the F77_XFCN macro. */
+
+#if !defined (F77_FCN)
+#define F77_FCN(f, F) F77_FUNC (f, F)
+#endif
+
+#if defined (F77_USES_CRAY_CALLING_CONVENTION)
+
+#include <fortran.h>
+
+/* Use these macros to pass character strings from C to Fortran.  */
+#define F77_CHAR_ARG(x) octave_make_cray_ftn_ch_dsc (x, strlen (x))
+#define F77_CONST_CHAR_ARG(x) \
+  octave_make_cray_const_ftn_ch_dsc (x, strlen (x))
+#define F77_CHAR_ARG2(x, l) octave_make_cray_ftn_ch_dsc (x, l)
+#define F77_CONST_CHAR_ARG2(x, l) octave_make_cray_const_ftn_ch_dsc (x, l)
+#define F77_CXX_STRING_ARG(x) \
+  octave_make_cray_const_ftn_ch_dsc (x.c_str (), x.length ())
+#define F77_CHAR_ARG_LEN(l)
+#define F77_CHAR_ARG_DECL octave_cray_ftn_ch_dsc
+#define F77_CONST_CHAR_ARG_DECL octave_cray_ftn_ch_dsc
+#define F77_CHAR_ARG_LEN_DECL
+
+/* Use these macros to write C-language functions that accept
+   Fortran-style character strings.  */
+#define F77_CHAR_ARG_DEF(s, len) octave_cray_ftn_ch_dsc s
+#define F77_CONST_CHAR_ARG_DEF(s, len) octave_cray_ftn_ch_dsc s
+#define F77_CHAR_ARG_LEN_DEF(len) 
+#define F77_CHAR_ARG_USE(s) s.ptr
+#define F77_CHAR_ARG_LEN_USE(s, len) (s.mask.len>>3)
+
+#define F77_RET_T int
+#define F77_RETURN(retval) return retval;
+
+/* FIXME -- these should work for SV1 or Y-MP systems but will
+   need to be changed for others.  */
+
+typedef union
+{
+  const char *const_ptr;
+  char *ptr;
+  struct
+  {
+    unsigned off : 6;
+    unsigned len : 26;
+    unsigned add : 32;
+  } mask;
+} octave_cray_descriptor;
+
+typedef void *octave_cray_ftn_ch_dsc;
+
+#ifdef __cplusplus
+#define OCTAVE_F77_FCN_INLINE inline
+#else
+#define OCTAVE_F77_FCN_INLINE
+#endif
+
+static OCTAVE_F77_FCN_INLINE octave_cray_ftn_ch_dsc
+octave_make_cray_ftn_ch_dsc (char *ptr_arg, unsigned long len_arg)
+{
+  octave_cray_descriptor desc;
+  desc.ptr = ptr_arg;
+  desc.mask.len = len_arg << 3;
+  return *((octave_cray_ftn_ch_dsc *) &desc);
+}
+
+static OCTAVE_F77_FCN_INLINE octave_cray_ftn_ch_dsc
+octave_make_cray_const_ftn_ch_dsc (const char *ptr_arg, unsigned long len_arg)
+{
+  octave_cray_descriptor desc;
+  desc.const_ptr = ptr_arg;
+  desc.mask.len = len_arg << 3;
+  return *((octave_cray_ftn_ch_dsc *) &desc);
+}
+
+#ifdef __cplusplus
+#undef OCTAVE_F77_FCN_INLINE
+#endif
+
+#elif defined (F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION)
+
+/* Use these macros to pass character strings from C to Fortran.  */
+#define F77_CHAR_ARG(x) x, strlen (x)
+#define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x)
+#define F77_CHAR_ARG2(x, l) x, l
+#define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l)
+#define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ())
+#define F77_CHAR_ARG_LEN(l)
+#define F77_CHAR_ARG_DECL char *, int
+#define F77_CONST_CHAR_ARG_DECL const char *, int
+#define F77_CHAR_ARG_LEN_DECL
+
+/* Use these macros to write C-language functions that accept
+   Fortran-style character strings.  */
+#define F77_CHAR_ARG_DEF(s, len) char *s, int len
+#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s, int len
+#define F77_CHAR_ARG_LEN_DEF(len) 
+#define F77_CHAR_ARG_USE(s) s
+#define F77_CHAR_ARG_LEN_USE(s, len) len
+
+#define F77_RET_T void
+#define F77_RETURN(retval)
+
+#else
+
+/* Assume f2c-compatible calling convention.  */
+
+/* Use these macros to pass character strings from C to Fortran.  */
+#define F77_CHAR_ARG(x) x
+#define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x)
+#define F77_CHAR_ARG2(x, l) x
+#define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l)
+#define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ())
+#define F77_CHAR_ARG_LEN(l) , l
+#define F77_CHAR_ARG_DECL char *
+#define F77_CONST_CHAR_ARG_DECL const char *
+#define F77_CHAR_ARG_LEN_DECL , long
+
+/* Use these macros to write C-language functions that accept
+   Fortran-style character strings.  */
+#define F77_CHAR_ARG_DEF(s, len) char *s
+#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s
+#define F77_CHAR_ARG_LEN_DEF(len) , long len
+#define F77_CHAR_ARG_USE(s) s
+#define F77_CHAR_ARG_LEN_USE(s, len) len
+
+#define F77_RET_T int
+#define F77_RETURN(retval) return retval;
+
+#endif
+
+
+/* Build a C string local variable CS from the Fortran string parameter S
+   declared as F77_CHAR_ARG_DEF(s, len) or F77_CONST_CHAR_ARG_DEF(s, len).
+   The string will be cleaned up at the end of the current block.  
+   Needs to include <cstring> and <vector>.  */
+
+#define F77_CSTRING(s, len, cs) \
+ OCTAVE_LOCAL_BUFFER (char, cs, F77_CHAR_ARG_LEN_USE (s, len) + 1); \
+ memcpy (cs, F77_CHAR_ARG_USE (s), F77_CHAR_ARG_LEN_USE (s, len)); \
+ cs[F77_CHAR_ARG_LEN_USE(s, len)] = '\0' 
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/thirdparty/fftw3.h b/src/thirdparty/fftw3.h
new file mode 100644
index 0000000..7ba36a4
--- /dev/null
+++ b/src/thirdparty/fftw3.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2003, 2006 Matteo Frigo
+ * Copyright (c) 2003, 2006 Massachusetts Institute of Technology
+ *
+ * The following statement of license applies *only* to this header file,
+ * and *not* to the other files distributed with FFTW or derived therefrom:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/***************************** NOTE TO USERS *********************************
+ *
+ *                 THIS IS A HEADER FILE, NOT A MANUAL
+ *
+ *    If you want to know how to use FFTW, please read the manual,
+ *    online at http://www.fftw.org/doc/ and also included with FFTW.
+ *    For a quick start, see the manual's tutorial section.
+ *
+ *   (Reading header files to learn how to use a library is a habit
+ *    stemming from code lacking a proper manual.  Arguably, it's a
+ *    *bad* habit in most cases, because header files can contain
+ *    interfaces that are not part of the public, stable API.)
+ *
+ ****************************************************************************/
+
+/* header file for fftw3 */
+/* (The following is the CVS ID for this file, *not* the version
+   number of FFTW:) */
+/* $Id: fftw3.h,v 1.90 2006-01-17 04:03:33 stevenj Exp $ */
+
+#ifndef FFTW3_H
+#define FFTW3_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* If <complex.h> is included, use the C99 complex type.  Otherwise
+   define a type bit-compatible with C99 complex */
+#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
+#  define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
+#else
+#  define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
+#endif
+
+#define FFTW_CONCAT(prefix, name) prefix ## name
+#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
+#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
+#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
+
+/* IMPORTANT: for Windows compilers, you should add a line
+        #define FFTW_DLL
+   here and in kernel/ifftw.h if you are compiling/using FFTW as a
+   DLL, in order to do the proper importing/exporting, or
+   alternatively compile with -DFFTW_DLL or the equivalent
+   command-line flag.  This is not necessary under MinGW/Cygwin, where
+   libtool does the imports/exports automatically. */
+#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
+   /* annoying Windows syntax for shared-library declarations */
+#  if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
+#    define FFTW_EXTERN extern __declspec(dllexport) 
+#  else /* user is calling FFTW; import symbol */
+#    define FFTW_EXTERN extern __declspec(dllimport) 
+#  endif
+#else
+#  define FFTW_EXTERN extern
+#endif
+
+enum fftw_r2r_kind_do_not_use_me {
+     FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
+     FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
+     FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
+};
+
+struct fftw_iodim_do_not_use_me {
+     int n;                     /* dimension size */
+     int is;			/* input stride */
+     int os;			/* output stride */
+};
+
+/*
+  huge second-order macro that defines prototypes for all API
+  functions.  We expand this macro for each supported precision
+ 
+  X: name-mangling macro
+  R: real data type
+  C: complex data type
+*/
+
+#define FFTW_DEFINE_API(X, R, C)					   \
+									   \
+FFTW_DEFINE_COMPLEX(R, C);						   \
+									   \
+typedef struct X(plan_s) *X(plan);					   \
+									   \
+typedef struct fftw_iodim_do_not_use_me X(iodim);			   \
+									   \
+typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind);			   \
+									   \
+FFTW_EXTERN void X(execute)(const X(plan) p);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n,			   \
+		    C *in, C *out, int sign, unsigned flags);		   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign,	   \
+		       unsigned flags);					   \
+FFTW_EXTERN X(plan) X(plan_dft_2d)(int nx, int ny,			   \
+		       C *in, C *out, int sign, unsigned flags);	   \
+FFTW_EXTERN X(plan) X(plan_dft_3d)(int nx, int ny, int nz,		   \
+		       C *in, C *out, int sign, unsigned flags);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n,		   \
+                         int howmany,					   \
+                         C *in, const int *inembed,			   \
+                         int istride, int idist,			   \
+                         C *out, const int *onembed,			   \
+                         int ostride, int odist,			   \
+                         int sign, unsigned flags);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims,	   \
+			 int howmany_rank,				   \
+			 const X(iodim) *howmany_dims,			   \
+			 C *in, C *out,					   \
+			 int sign, unsigned flags);			   \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
+			 int howmany_rank,				   \
+			 const X(iodim) *howmany_dims,			   \
+			 R *ri, R *ii, R *ro, R *io,			   \
+			 unsigned flags);				   \
+									   \
+FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out);	   \
+FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii,	   \
+                                      R *ro, R *io);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n,	   \
+                             int howmany,				   \
+                             R *in, const int *inembed,			   \
+                             int istride, int idist,			   \
+                             C *out, const int *onembed,		   \
+                             int ostride, int odist,			   \
+                             unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n,		   \
+                        R *in, C *out, unsigned flags);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int nx, int ny,			   \
+			   R *in, C *out, unsigned flags);		   \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int nx, int ny,			   \
+			   int nz,					   \
+			   R *in, C *out, unsigned flags);		   \
+									   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n,	   \
+			     int howmany,				   \
+			     C *in, const int *inembed,			   \
+			     int istride, int idist,			   \
+			     R *out, const int *onembed,		   \
+			     int ostride, int odist,			   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n,		   \
+                        C *in, R *out, unsigned flags);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int nx, int ny,			   \
+			   C *in, R *out, unsigned flags);		   \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int nx, int ny,			   \
+			   int nz,					   \
+			   C *in, R *out, unsigned flags);		   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims,   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     R *in, C *out,				   \
+			     unsigned flags);				   \
+FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims,   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     C *in, R *out,				   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)(				   \
+                             int rank, const X(iodim) *dims,		   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     R *in, R *ro, R *io,			   \
+			     unsigned flags);				   \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)(				   \
+                             int rank, const X(iodim) *dims,		   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     R *ri, R *ii, R *out,			   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out);	   \
+FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out);	   \
+									   \
+FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p,		   \
+                                          R *in, R *ro, R *io);		   \
+FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, 		   \
+                                          R *ri, R *ii, R *out);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n,		   \
+                         int howmany,					   \
+                         R *in, const int *inembed,			   \
+                         int istride, int idist,			   \
+                         R *out, const int *onembed,			   \
+                         int ostride, int odist,			   \
+                         const X(r2r_kind) *kind, unsigned flags);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out,	   \
+                    const X(r2r_kind) *kind, unsigned flags);		   \
+									   \
+FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out,		   \
+                       X(r2r_kind) kind, unsigned flags);		   \
+FFTW_EXTERN X(plan) X(plan_r2r_2d)(int nx, int ny, R *in, R *out,	   \
+                       X(r2r_kind) kindx, X(r2r_kind) kindy,		   \
+                       unsigned flags);					   \
+FFTW_EXTERN X(plan) X(plan_r2r_3d)(int nx, int ny, int nz,		   \
+                       R *in, R *out, X(r2r_kind) kindx,		   \
+                       X(r2r_kind) kindy, X(r2r_kind) kindz,		   \
+                       unsigned flags);					   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims,	   \
+                         int howmany_rank,				   \
+                         const X(iodim) *howmany_dims,			   \
+                         R *in, R *out,					   \
+                         const X(r2r_kind) *kind, unsigned flags);	   \
+FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out);	   \
+									   \
+FFTW_EXTERN void X(destroy_plan)(X(plan) p);				   \
+FFTW_EXTERN void X(forget_wisdom)(void);				   \
+FFTW_EXTERN void X(cleanup)(void);					   \
+									   \
+FFTW_EXTERN void X(set_timelimit)(double);				   \
+									   \
+FFTW_EXTERN void X(plan_with_nthreads)(int nthreads);			   \
+FFTW_EXTERN int X(init_threads)(void);					   \
+FFTW_EXTERN void X(cleanup_threads)(void);				   \
+									   \
+FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file);		   \
+FFTW_EXTERN char *X(export_wisdom_to_string)(void);			   \
+FFTW_EXTERN void X(export_wisdom)(void (*write_char)(char c, void *),	   \
+                                  void *data);				   \
+FFTW_EXTERN int X(import_system_wisdom)(void);				   \
+FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file);		   \
+FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string);	   \
+FFTW_EXTERN int X(import_wisdom)(int (*read_char)(void *), void *data);	   \
+									   \
+FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file);	   \
+FFTW_EXTERN void X(print_plan)(const X(plan) p);			   \
+									   \
+FFTW_EXTERN void *X(malloc)(size_t n);					   \
+FFTW_EXTERN void X(free)(void *p);					   \
+									   \
+FFTW_EXTERN void X(flops)(const X(plan) p,				   \
+                          double *add, double *mul, double *fmas);	   \
+FFTW_EXTERN double X(estimate_cost)(const X(plan) p);			   \
+									   \
+FFTW_EXTERN const char X(version)[];					   \
+FFTW_EXTERN const char X(cc)[];						   \
+FFTW_EXTERN const char X(codelet_optim)[];
+
+
+/* end of FFTW_DEFINE_API macro */
+
+FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
+FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
+FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
+
+#define FFTW_FORWARD (-1)
+#define FFTW_BACKWARD (+1)
+
+#define FFTW_NO_TIMELIMIT (-1.0)
+
+/* documented flags */
+#define FFTW_MEASURE (0U)
+#define FFTW_DESTROY_INPUT (1U << 0)
+#define FFTW_UNALIGNED (1U << 1)
+#define FFTW_CONSERVE_MEMORY (1U << 2)
+#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
+#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
+#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
+#define FFTW_ESTIMATE (1U << 6)
+
+/* undocumented beyond-guru flags */
+#define FFTW_ESTIMATE_PATIENT (1U << 7)
+#define FFTW_BELIEVE_PCOST (1U << 8)
+#define FFTW_NO_DFT_R2HC (1U << 9)
+#define FFTW_NO_NONTHREADED (1U << 10)
+#define FFTW_NO_BUFFERING (1U << 11)
+#define FFTW_NO_INDIRECT_OP (1U << 12)
+#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
+#define FFTW_NO_RANK_SPLITS (1U << 14)
+#define FFTW_NO_VRANK_SPLITS (1U << 15)
+#define FFTW_NO_VRECURSE (1U << 16)
+#define FFTW_NO_SIMD (1U << 17)
+#define FFTW_NO_SLOW (1U << 18)
+#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
+#define FFTW_ALLOW_PRUNING (1U << 20)
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* FFTW3_H */
diff --git a/src/thirdparty/portaudio.h b/src/thirdparty/portaudio.h
new file mode 100644
index 0000000..b80e1d1
--- /dev/null
+++ b/src/thirdparty/portaudio.h
@@ -0,0 +1,1174 @@
+#ifndef PORTAUDIO_H
+#define PORTAUDIO_H
+/*
+ * $Id: portaudio.h 1745 2011-08-25 17:44:01Z rossb $
+ * PortAudio Portable Real-Time Audio Library
+ * PortAudio API Header File
+ * Latest version available at: http://www.portaudio.com/
+ *
+ * Copyright (c) 1999-2002 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however, 
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also 
+ * requested that these non-binding requests be included along with the 
+ * license above.
+ */
+
+/** @file
+ @ingroup public_header
+ @brief The portable PortAudio API.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ 
+/** Retrieve the release number of the currently running PortAudio build,
+ eg 1900.
+*/
+int Pa_GetVersion( void );
+
+
+/** Retrieve a textual description of the current PortAudio build,
+ eg "PortAudio V19-devel 13 October 2002".
+*/
+const char* Pa_GetVersionText( void );
+
+
+/** Error codes returned by PortAudio functions.
+ Note that with the exception of paNoError, all PaErrorCodes are negative.
+*/
+
+typedef int PaError;
+typedef enum PaErrorCode
+{
+    paNoError = 0,
+
+    paNotInitialized = -10000,
+    paUnanticipatedHostError,
+    paInvalidChannelCount,
+    paInvalidSampleRate,
+    paInvalidDevice,
+    paInvalidFlag,
+    paSampleFormatNotSupported,
+    paBadIODeviceCombination,
+    paInsufficientMemory,
+    paBufferTooBig,
+    paBufferTooSmall,
+    paNullCallback,
+    paBadStreamPtr,
+    paTimedOut,
+    paInternalError,
+    paDeviceUnavailable,
+    paIncompatibleHostApiSpecificStreamInfo,
+    paStreamIsStopped,
+    paStreamIsNotStopped,
+    paInputOverflowed,
+    paOutputUnderflowed,
+    paHostApiNotFound,
+    paInvalidHostApi,
+    paCanNotReadFromACallbackStream,
+    paCanNotWriteToACallbackStream,
+    paCanNotReadFromAnOutputOnlyStream,
+    paCanNotWriteToAnInputOnlyStream,
+    paIncompatibleStreamHostApi,
+    paBadBufferPtr
+} PaErrorCode;
+
+
+/** Translate the supplied PortAudio error code into a human readable
+ message.
+*/
+const char *Pa_GetErrorText( PaError errorCode );
+
+
+/** Library initialization function - call this before using PortAudio.
+ This function initializes internal data structures and prepares underlying
+ host APIs for use.  With the exception of Pa_GetVersion(), Pa_GetVersionText(),
+ and Pa_GetErrorText(), this function MUST be called before using any other
+ PortAudio API functions.
+
+ If Pa_Initialize() is called multiple times, each successful 
+ call must be matched with a corresponding call to Pa_Terminate(). 
+ Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not 
+ required to be fully nested.
+
+ Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
+ NOT be called.
+
+ @return paNoError if successful, otherwise an error code indicating the cause
+ of failure.
+
+ @see Pa_Terminate
+*/
+PaError Pa_Initialize( void );
+
+
+/** Library termination function - call this when finished using PortAudio.
+ This function deallocates all resources allocated by PortAudio since it was
+ initialized by a call to Pa_Initialize(). In cases where Pa_Initialise() has
+ been called multiple times, each call must be matched with a corresponding call
+ to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically
+ close any PortAudio streams that are still open.
+
+ Pa_Terminate() MUST be called before exiting a program which uses PortAudio.
+ Failure to do so may result in serious resource leaks, such as audio devices
+ not being available until the next reboot.
+
+ @return paNoError if successful, otherwise an error code indicating the cause
+ of failure.
+ 
+ @see Pa_Initialize
+*/
+PaError Pa_Terminate( void );
+
+
+
+/** The type used to refer to audio devices. Values of this type usually
+ range from 0 to (Pa_GetDeviceCount()-1), and may also take on the PaNoDevice
+ and paUseHostApiSpecificDeviceSpecification values.
+
+ @see Pa_GetDeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification
+*/
+typedef int PaDeviceIndex;
+
+
+/** A special PaDeviceIndex value indicating that no device is available,
+ or should be used.
+
+ @see PaDeviceIndex
+*/
+#define paNoDevice ((PaDeviceIndex)-1)
+
+
+/** A special PaDeviceIndex value indicating that the device(s) to be used
+ are specified in the host api specific stream info structure.
+
+ @see PaDeviceIndex
+*/
+#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2)
+
+
+/* Host API enumeration mechanism */
+
+/** The type used to enumerate to host APIs at runtime. Values of this type
+ range from 0 to (Pa_GetHostApiCount()-1).
+
+ @see Pa_GetHostApiCount
+*/
+typedef int PaHostApiIndex;
+
+
+/** Retrieve the number of available host APIs. Even if a host API is
+ available it may have no devices available.
+
+ @return A non-negative value indicating the number of available host APIs
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+
+ @see PaHostApiIndex
+*/
+PaHostApiIndex Pa_GetHostApiCount( void );
+
+
+/** Retrieve the index of the default host API. The default host API will be
+ the lowest common denominator host API on the current platform and is
+ unlikely to provide the best performance.
+
+ @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1)
+ indicating the default host API index or, a PaErrorCode (which are always
+ negative) if PortAudio is not initialized or an error is encountered.
+*/
+PaHostApiIndex Pa_GetDefaultHostApi( void );
+
+
+/** Unchanging unique identifiers for each supported host API. This type
+ is used in the PaHostApiInfo structure. The values are guaranteed to be
+ unique and to never change, thus allowing code to be written that
+ conditionally uses host API specific extensions.
+
+ New type ids will be allocated when support for a host API reaches
+ "public alpha" status, prior to that developers should use the
+ paInDevelopment type id.
+
+ @see PaHostApiInfo
+*/
+typedef enum PaHostApiTypeId
+{
+    paInDevelopment=0, /* use while developing support for a new host API */
+    paDirectSound=1,
+    paMME=2,
+    paASIO=3,
+    paSoundManager=4,
+    paCoreAudio=5,
+    paOSS=7,
+    paALSA=8,
+    paAL=9,
+    paBeOS=10,
+    paWDMKS=11,
+    paJACK=12,
+    paWASAPI=13,
+    paAudioScienceHPI=14
+} PaHostApiTypeId;
+
+
+/** A structure containing information about a particular host API. */
+
+typedef struct PaHostApiInfo
+{
+    /** this is struct version 1 */
+    int structVersion;
+    /** The well known unique identifier of this host API @see PaHostApiTypeId */
+    PaHostApiTypeId type;
+    /** A textual description of the host API for display on user interfaces. */
+    const char *name;
+
+    /**  The number of devices belonging to this host API. This field may be
+     used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate
+     all devices for this host API.
+     @see Pa_HostApiDeviceIndexToDeviceIndex
+    */
+    int deviceCount;
+
+    /** The default input device for this host API. The value will be a
+     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
+     if no default input device is available.
+    */
+    PaDeviceIndex defaultInputDevice;
+
+    /** The default output device for this host API. The value will be a
+     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
+     if no default output device is available.
+    */
+    PaDeviceIndex defaultOutputDevice;
+    
+} PaHostApiInfo;
+
+
+/** Retrieve a pointer to a structure containing information about a specific
+ host Api.
+
+ @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
+
+ @return A pointer to an immutable PaHostApiInfo structure describing
+ a specific host API. If the hostApi parameter is out of range or an error
+ is encountered, the function returns NULL.
+
+ The returned structure is owned by the PortAudio implementation and must not
+ be manipulated or freed. The pointer is only guaranteed to be valid between
+ calls to Pa_Initialize() and Pa_Terminate().
+*/
+const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi );
+
+
+/** Convert a static host API unique identifier, into a runtime
+ host API index.
+
+ @param type A unique host API identifier belonging to the PaHostApiTypeId
+ enumeration.
+
+ @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or,
+ a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+ 
+ The paHostApiNotFound error code indicates that the host API specified by the
+ type parameter is not available.
+
+ @see PaHostApiTypeId
+*/
+PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type );
+
+
+/** Convert a host-API-specific device index to standard PortAudio device index.
+ This function may be used in conjunction with the deviceCount field of
+ PaHostApiInfo to enumerate all devices for the specified host API.
+
+ @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
+
+ @param hostApiDeviceIndex A valid per-host device index in the range
+ 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1)
+
+ @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1)
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+
+ A paInvalidHostApi error code indicates that the host API index specified by
+ the hostApi parameter is out of range.
+
+ A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter
+ is out of range.
+ 
+ @see PaHostApiInfo
+*/
+PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi,
+        int hostApiDeviceIndex );
+
+
+
+/** Structure used to return information about a host error condition.
+*/
+typedef struct PaHostErrorInfo{
+    PaHostApiTypeId hostApiType;    /**< the host API which returned the error code */
+    long errorCode;                 /**< the error code returned */
+    const char *errorText;          /**< a textual description of the error if available, otherwise a zero-length string */
+}PaHostErrorInfo;
+
+
+/** Return information about the last host error encountered. The error
+ information returned by Pa_GetLastHostErrorInfo() will never be modified
+ asynchronously by errors occurring in other PortAudio owned threads
+ (such as the thread that manages the stream callback.)
+
+ This function is provided as a last resort, primarily to enhance debugging
+ by providing clients with access to all available error information.
+
+ @return A pointer to an immutable structure constraining information about
+ the host error. The values in this structure will only be valid if a
+ PortAudio function has previously returned the paUnanticipatedHostError
+ error code.
+*/
+const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void );
+
+
+
+/* Device enumeration and capabilities */
+
+/** Retrieve the number of available devices. The number of available devices
+ may be zero.
+
+ @return A non-negative value indicating the number of available devices or,
+ a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+*/
+PaDeviceIndex Pa_GetDeviceCount( void );
+
+
+/** Retrieve the index of the default input device. The result can be
+ used in the inputDevice parameter to Pa_OpenStream().
+
+ @return The default input device index for the default host API, or paNoDevice
+ if no default input device is available or an error was encountered.
+*/
+PaDeviceIndex Pa_GetDefaultInputDevice( void );
+
+
+/** Retrieve the index of the default output device. The result can be
+ used in the outputDevice parameter to Pa_OpenStream().
+
+ @return The default output device index for the default host API, or paNoDevice
+ if no default output device is available or an error was encountered.
+
+ @note
+ On the PC, the user can specify a default device by
+ setting an environment variable. For example, to use device #1.
+<pre>
+ set PA_RECOMMENDED_OUTPUT_DEVICE=1
+</pre>
+ The user should first determine the available device ids by using
+ the supplied application "pa_devs".
+*/
+PaDeviceIndex Pa_GetDefaultOutputDevice( void );
+
+
+/** The type used to represent monotonic time in seconds. PaTime is 
+ used for the fields of the PaStreamCallbackTimeInfo argument to the 
+ PaStreamCallback and as the result of Pa_GetStreamTime().
+
+ PaTime values have unspecified origin.
+     
+ @see PaStreamCallback, PaStreamCallbackTimeInfo, Pa_GetStreamTime
+*/
+typedef double PaTime;
+
+
+/** A type used to specify one or more sample formats. Each value indicates
+ a possible format for sound data passed to and from the stream callback,
+ Pa_ReadStream and Pa_WriteStream.
+
+ The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
+ and aUInt8 are usually implemented by all implementations.
+
+ The floating point representation (paFloat32) uses +1.0 and -1.0 as the
+ maximum and minimum respectively.
+
+ paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
+
+ The paNonInterleaved flag indicates that audio data is passed as an array 
+ of pointers to separate buffers, one buffer for each channel. Usually,
+ when this flag is not used, audio data is passed as a single buffer with
+ all channels interleaved.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
+ @see paFloat32, paInt16, paInt32, paInt24, paInt8
+ @see paUInt8, paCustomFormat, paNonInterleaved
+*/
+typedef unsigned long PaSampleFormat;
+
+
+#define paFloat32        ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */
+#define paInt32          ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */
+#define paInt24          ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */
+#define paInt16          ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */
+#define paInt8           ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */
+#define paUInt8          ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */
+#define paCustomFormat   ((PaSampleFormat) 0x00010000) /**< @see PaSampleFormat */
+
+#define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */
+
+/** A structure providing information and capabilities of PortAudio devices.
+ Devices may support input, output or both input and output.
+*/
+typedef struct PaDeviceInfo
+{
+    int structVersion;  /* this is struct version 2 */
+    const char *name;
+    PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/
+    
+    int maxInputChannels;
+    int maxOutputChannels;
+
+    /** Default latency values for interactive performance. */
+    PaTime defaultLowInputLatency;
+    PaTime defaultLowOutputLatency;
+    /** Default latency values for robust non-interactive applications (eg. playing sound files). */
+    PaTime defaultHighInputLatency;
+    PaTime defaultHighOutputLatency;
+
+    double defaultSampleRate;
+} PaDeviceInfo;
+
+
+/** Retrieve a pointer to a PaDeviceInfo structure containing information
+ about the specified device.
+ @return A pointer to an immutable PaDeviceInfo structure. If the device
+ parameter is out of range the function returns NULL.
+
+ @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+
+ @note PortAudio manages the memory referenced by the returned pointer,
+ the client must not manipulate or free the memory. The pointer is only
+ guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate().
+
+ @see PaDeviceInfo, PaDeviceIndex
+*/
+const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device );
+
+
+/** Parameters for one direction (input or output) of a stream.
+*/
+typedef struct PaStreamParameters
+{
+    /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+     specifying the device to be used or the special constant
+     paUseHostApiSpecificDeviceSpecification which indicates that the actual
+     device(s) to use are specified in hostApiSpecificStreamInfo.
+     This field must not be set to paNoDevice.
+    */
+    PaDeviceIndex device;
+    
+    /** The number of channels of sound to be delivered to the
+     stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
+     It can range from 1 to the value of maxInputChannels in the
+     PaDeviceInfo record for the device specified by the device parameter.
+    */
+    int channelCount;
+
+    /** The sample format of the buffer provided to the stream callback,
+     a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
+     by the PaSampleFormat enumeration.
+    */
+    PaSampleFormat sampleFormat;
+
+    /** The desired latency in seconds. Where practical, implementations should
+     configure their latency based on these parameters, otherwise they may
+     choose the closest viable latency instead. Unless the suggested latency
+     is greater than the absolute upper limit for the device implementations
+     should round the suggestedLatency up to the next practical value - ie to
+     provide an equal or higher latency than suggestedLatency wherever possible.
+     Actual latency values for an open stream may be retrieved using the
+     inputLatency and outputLatency fields of the PaStreamInfo structure
+     returned by Pa_GetStreamInfo().
+     @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
+    */
+    PaTime suggestedLatency;
+
+    /** An optional pointer to a host api specific data structure
+     containing additional information for device setup and/or stream processing.
+     hostApiSpecificStreamInfo is never required for correct operation,
+     if not used it should be set to NULL.
+    */
+    void *hostApiSpecificStreamInfo;
+
+} PaStreamParameters;
+
+
+/** Return code for Pa_IsFormatSupported indicating success. */
+#define paFormatIsSupported (0)
+
+/** Determine whether it would be possible to open a stream with the specified
+ parameters.
+
+ @param inputParameters A structure that describes the input parameters used to
+ open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+ for a description of these parameters. inputParameters must be NULL for
+ output-only streams.
+
+ @param outputParameters A structure that describes the output parameters used
+ to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+ for a description of these parameters. outputParameters must be NULL for
+ input-only streams.
+
+ @param sampleRate The required sampleRate. For full-duplex streams it is the
+ sample rate for both input and output
+
+ @return Returns 0 if the format is supported, and an error code indicating why
+ the format is not supported otherwise. The constant paFormatIsSupported is
+ provided to compare with the return value for success.
+
+ @see paFormatIsSupported, PaStreamParameters
+*/
+PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
+                              const PaStreamParameters *outputParameters,
+                              double sampleRate );
+
+
+
+/* Streaming types and functions */
+
+
+/**
+ A single PaStream can provide multiple channels of real-time
+ streaming audio input and output to a client application. A stream
+ provides access to audio hardware represented by one or more
+ PaDevices. Depending on the underlying Host API, it may be possible 
+ to open multiple streams using the same device, however this behavior 
+ is implementation defined. Portable applications should assume that 
+ a PaDevice may be simultaneously used by at most one PaStream.
+
+ Pointers to PaStream objects are passed between PortAudio functions that
+ operate on streams.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
+ Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
+ Pa_GetStreamTime, Pa_GetStreamCpuLoad
+
+*/
+typedef void PaStream;
+
+
+/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
+ or Pa_OpenDefaultStream() to indicate that the stream callback will
+ accept buffers of any size.
+*/
+#define paFramesPerBufferUnspecified  (0)
+
+
+/** Flags used to control the behavior of a stream. They are passed as
+ parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
+ ORed together.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream
+ @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
+  paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
+*/
+typedef unsigned long PaStreamFlags;
+
+/** @see PaStreamFlags */
+#define   paNoFlag          ((PaStreamFlags) 0)
+
+/** Disable default clipping of out of range samples.
+ @see PaStreamFlags
+*/
+#define   paClipOff         ((PaStreamFlags) 0x00000001)
+
+/** Disable default dithering.
+ @see PaStreamFlags
+*/
+#define   paDitherOff       ((PaStreamFlags) 0x00000002)
+
+/** Flag requests that where possible a full duplex stream will not discard
+ overflowed input samples without calling the stream callback. This flag is
+ only valid for full duplex callback streams and only when used in combination
+ with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
+ this flag incorrectly results in a paInvalidFlag error being returned from
+ Pa_OpenStream and Pa_OpenDefaultStream.
+
+ @see PaStreamFlags, paFramesPerBufferUnspecified
+*/
+#define   paNeverDropInput  ((PaStreamFlags) 0x00000004)
+
+/** Call the stream callback to fill initial output buffers, rather than the
+ default behavior of priming the buffers with zeros (silence). This flag has
+ no effect for input-only and blocking read/write streams.
+ 
+ @see PaStreamFlags
+*/
+#define   paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008)
+
+/** A mask specifying the platform specific bits.
+ @see PaStreamFlags
+*/
+#define   paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000)
+
+/**
+ Timing information for the buffers passed to the stream callback.
+
+ Time values are expressed in seconds and are synchronised with the time base used by Pa_GetStreamTime() for the associated stream.
+ 
+ @see PaStreamCallback, Pa_GetStreamTime
+*/
+typedef struct PaStreamCallbackTimeInfo{
+    PaTime inputBufferAdcTime;  /**< The time when the first sample of the input buffer was captured at the ADC input */
+    PaTime currentTime;         /**< The time when the stream callback was invoked */
+    PaTime outputBufferDacTime; /**< The time when the first sample of the output buffer will output the DAC */
+} PaStreamCallbackTimeInfo;
+
+
+/**
+ Flag bit constants for the statusFlags to PaStreamCallback.
+
+ @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
+ paPrimingOutput
+*/
+typedef unsigned long PaStreamCallbackFlags;
+
+/** In a stream opened with paFramesPerBufferUnspecified, indicates that
+ input data is all silence (zeros) because no real data is available. In a
+ stream opened without paFramesPerBufferUnspecified, it indicates that one or
+ more zero samples have been inserted into the input buffer to compensate
+ for an input underflow.
+ @see PaStreamCallbackFlags
+*/
+#define paInputUnderflow   ((PaStreamCallbackFlags) 0x00000001)
+
+/** In a stream opened with paFramesPerBufferUnspecified, indicates that data
+ prior to the first sample of the input buffer was discarded due to an
+ overflow, possibly because the stream callback is using too much CPU time.
+ Otherwise indicates that data prior to one or more samples in the
+ input buffer was discarded.
+ @see PaStreamCallbackFlags
+*/
+#define paInputOverflow    ((PaStreamCallbackFlags) 0x00000002)
+
+/** Indicates that output data (or a gap) was inserted, possibly because the
+ stream callback is using too much CPU time.
+ @see PaStreamCallbackFlags
+*/
+#define paOutputUnderflow  ((PaStreamCallbackFlags) 0x00000004)
+
+/** Indicates that output data will be discarded because no room is available.
+ @see PaStreamCallbackFlags
+*/
+#define paOutputOverflow   ((PaStreamCallbackFlags) 0x00000008)
+
+/** Some of all of the output data will be used to prime the stream, input
+ data may be zero.
+ @see PaStreamCallbackFlags
+*/
+#define paPrimingOutput    ((PaStreamCallbackFlags) 0x00000010)
+
+/**
+ Allowable return values for the PaStreamCallback.
+ @see PaStreamCallback
+*/
+typedef enum PaStreamCallbackResult
+{
+    paContinue=0,   /**< Signal that the stream should continue invoking the callback and processing audio. */
+    paComplete=1,   /**< Signal that the stream should stop invoking the callback and finish once all output samples have played. */
+    paAbort=2       /**< Signal that the stream should stop invoking the callback and finish as soon as possible. */
+} PaStreamCallbackResult;
+
+
+/**
+ Functions of type PaStreamCallback are implemented by PortAudio clients.
+ They consume, process or generate audio in response to requests from an
+ active PortAudio stream.
+
+ When a stream is running, PortAudio calls the stream callback periodically.
+ The callback function is responsible for processing buffers of audio samples 
+ passed via the input and output parameters.
+
+ The PortAudio stream callback runs at very high or real-time priority.
+ It is required to consistently meet its time deadlines. Do not allocate 
+ memory, access the file system, call library functions or call other functions 
+ from the stream callback that may block or take an unpredictable amount of
+ time to complete.
+
+ In order for a stream to maintain glitch-free operation the callback
+ must consume and return audio data faster than it is recorded and/or
+ played. PortAudio anticipates that each callback invocation may execute for 
+ a duration approaching the duration of frameCount audio frames at the stream 
+ sample rate. It is reasonable to expect to be able to utilise 70% or more of
+ the available CPU time in the PortAudio callback. However, due to buffer size 
+ adaption and other factors, not all host APIs are able to guarantee audio 
+ stability under heavy CPU load with arbitrary fixed callback buffer sizes. 
+ When high callback CPU utilisation is required the most robust behavior 
+ can be achieved by using paFramesPerBufferUnspecified as the 
+ Pa_OpenStream() framesPerBuffer parameter.
+     
+ @param input and @param output are either arrays of interleaved samples or;
+ if non-interleaved samples were requested using the paNonInterleaved sample 
+ format flag, an array of buffer pointers, one non-interleaved buffer for 
+ each channel.
+
+ The format, packing and number of channels used by the buffers are
+ determined by parameters to Pa_OpenStream().
+     
+ @param frameCount The number of sample frames to be processed by
+ the stream callback.
+
+ @param timeInfo Timestamps indicating the ADC capture time of the first sample
+ in the input buffer, the DAC output time of the first sample in the output buffer
+ and the time the callback was invoked. 
+ See PaStreamCallbackTimeInfo and Pa_GetStreamTime()
+
+ @param statusFlags Flags indicating whether input and/or output buffers
+ have been inserted or will be dropped to overcome underflow or overflow
+ conditions.
+
+ @param userData The value of a user supplied pointer passed to
+ Pa_OpenStream() intended for storing synthesis data etc.
+
+ @return
+ The stream callback should return one of the values in the
+ ::PaStreamCallbackResult enumeration. To ensure that the callback continues
+ to be called, it should return paContinue (0). Either paComplete or paAbort
+ can be returned to finish stream processing, after either of these values is
+ returned the callback will not be called again. If paAbort is returned the
+ stream will finish as soon as possible. If paComplete is returned, the stream
+ will continue until all buffers generated by the callback have been played.
+ This may be useful in applications such as soundfile players where a specific
+ duration of output is required. However, it is not necessary to utilize this
+ mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
+ be used to stop the stream. The callback must always fill the entire output
+ buffer irrespective of its return value.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream
+
+ @note With the exception of Pa_GetStreamCpuLoad() it is not permissible to call
+ PortAudio API functions from within the stream callback.
+*/
+typedef int PaStreamCallback(
+    const void *input, void *output,
+    unsigned long frameCount,
+    const PaStreamCallbackTimeInfo* timeInfo,
+    PaStreamCallbackFlags statusFlags,
+    void *userData );
+
+
+/** Opens a stream for either input, output or both.
+     
+ @param stream The address of a PaStream pointer which will receive
+ a pointer to the newly opened stream.
+     
+ @param inputParameters A structure that describes the input parameters used by
+ the opened stream. See PaStreamParameters for a description of these parameters.
+ inputParameters must be NULL for output-only streams.
+
+ @param outputParameters A structure that describes the output parameters used by
+ the opened stream. See PaStreamParameters for a description of these parameters.
+ outputParameters must be NULL for input-only streams.
+ 
+ @param sampleRate The desired sampleRate. For full-duplex streams it is the
+ sample rate for both input and output
+     
+ @param framesPerBuffer The number of frames passed to the stream callback
+ function, or the preferred block granularity for a blocking read/write stream.
+ The special value paFramesPerBufferUnspecified (0) may be used to request that
+ the stream callback will receive an optimal (and possibly varying) number of
+ frames based on host requirements and the requested latency settings.
+ Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
+ stream may introduce an additional layer of buffering which could introduce
+ additional latency. PortAudio guarantees that the additional latency
+ will be kept to the theoretical minimum however, it is strongly recommended
+ that a non-zero framesPerBuffer value only be used when your algorithm
+ requires a fixed number of frames per stream callback.
+ 
+ @param streamFlags Flags which modify the behavior of the streaming process.
+ This parameter may contain a combination of flags ORed together. Some flags may
+ only be relevant to certain buffer formats.
+     
+ @param streamCallback A pointer to a client supplied function that is responsible
+ for processing and filling input and output buffers. If this parameter is NULL
+ the stream will be opened in 'blocking read/write' mode. In blocking mode,
+ the client can receive sample data using Pa_ReadStream and write sample data
+ using Pa_WriteStream, the number of samples that may be read or written
+ without blocking is returned by Pa_GetStreamReadAvailable and
+ Pa_GetStreamWriteAvailable respectively.
+
+ @param userData A client supplied pointer which is passed to the stream callback
+ function. It could for example, contain a pointer to instance data necessary
+ for processing the audio buffers. This parameter is ignored if streamCallback
+ is NULL.
+     
+ @return
+ Upon success Pa_OpenStream() returns paNoError and places a pointer to a
+ valid PaStream in the stream argument. The stream is inactive (stopped).
+ If a call to Pa_OpenStream() fails, a non-zero error code is returned (see
+ PaError for possible error codes) and the value of stream is invalid.
+
+ @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
+ Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
+*/
+PaError Pa_OpenStream( PaStream** stream,
+                       const PaStreamParameters *inputParameters,
+                       const PaStreamParameters *outputParameters,
+                       double sampleRate,
+                       unsigned long framesPerBuffer,
+                       PaStreamFlags streamFlags,
+                       PaStreamCallback *streamCallback,
+                       void *userData );
+
+
+/** A simplified version of Pa_OpenStream() that opens the default input
+ and/or output devices.
+
+ @param stream The address of a PaStream pointer which will receive
+ a pointer to the newly opened stream.
+ 
+ @param numInputChannels  The number of channels of sound that will be supplied
+ to the stream callback or returned by Pa_ReadStream. It can range from 1 to
+ the value of maxInputChannels in the PaDeviceInfo record for the default input
+ device. If 0 the stream is opened as an output-only stream.
+
+ @param numOutputChannels The number of channels of sound to be delivered to the
+ stream callback or passed to Pa_WriteStream. It can range from 1 to the value
+ of maxOutputChannels in the PaDeviceInfo record for the default output device.
+ If 0 the stream is opened as an output-only stream.
+
+ @param sampleFormat The sample format of both the input and output buffers
+ provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
+ sampleFormat may be any of the formats described by the PaSampleFormat
+ enumeration.
+ 
+ @param sampleRate Same as Pa_OpenStream parameter of the same name.
+ @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
+ @param streamCallback Same as Pa_OpenStream parameter of the same name.
+ @param userData Same as Pa_OpenStream parameter of the same name.
+
+ @return As for Pa_OpenStream
+
+ @see Pa_OpenStream, PaStreamCallback
+*/
+PaError Pa_OpenDefaultStream( PaStream** stream,
+                              int numInputChannels,
+                              int numOutputChannels,
+                              PaSampleFormat sampleFormat,
+                              double sampleRate,
+                              unsigned long framesPerBuffer,
+                              PaStreamCallback *streamCallback,
+                              void *userData );
+
+
+/** Closes an audio stream. If the audio stream is active it
+ discards any pending buffers as if Pa_AbortStream() had been called.
+*/
+PaError Pa_CloseStream( PaStream *stream );
+
+
+/** Functions of type PaStreamFinishedCallback are implemented by PortAudio 
+ clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
+ function. Once registered they are called when the stream becomes inactive
+ (ie once a call to Pa_StopStream() will not block).
+ A stream will become inactive after the stream callback returns non-zero,
+ or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
+ output, if the stream callback returns paComplete, or Pa_StopStream is called,
+ the stream finished callback will not be called until all generated sample data
+ has been played.
+ 
+ @param userData The userData parameter supplied to Pa_OpenStream()
+
+ @see Pa_SetStreamFinishedCallback
+*/
+typedef void PaStreamFinishedCallback( void *userData );
+
+
+/** Register a stream finished callback function which will be called when the 
+ stream becomes inactive. See the description of PaStreamFinishedCallback for 
+ further details about when the callback will be called.
+
+ @param stream a pointer to a PaStream that is in the stopped state - if the
+ stream is not stopped, the stream's finished callback will remain unchanged 
+ and an error code will be returned.
+
+ @param streamFinishedCallback a pointer to a function with the same signature
+ as PaStreamFinishedCallback, that will be called when the stream becomes
+ inactive. Passing NULL for this parameter will un-register a previously
+ registered stream finished callback function.
+
+ @return on success returns paNoError, otherwise an error code indicating the cause
+ of the error.
+
+ @see PaStreamFinishedCallback
+*/
+PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); 
+
+
+/** Commences audio processing.
+*/
+PaError Pa_StartStream( PaStream *stream );
+
+
+/** Terminates audio processing. It waits until all pending
+ audio buffers have been played before it returns.
+*/
+PaError Pa_StopStream( PaStream *stream );
+
+
+/** Terminates audio processing immediately without waiting for pending
+ buffers to complete.
+*/
+PaError Pa_AbortStream( PaStream *stream );
+
+
+/** Determine whether the stream is stopped.
+ A stream is considered to be stopped prior to a successful call to
+ Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
+ If a stream callback returns a value other than paContinue the stream is NOT
+ considered to be stopped.
+
+ @return Returns one (1) when the stream is stopped, zero (0) when
+ the stream is running or, a PaErrorCode (which are always negative) if
+ PortAudio is not initialized or an error is encountered.
+
+ @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
+*/
+PaError Pa_IsStreamStopped( PaStream *stream );
+
+
+/** Determine whether the stream is active.
+ A stream is active after a successful call to Pa_StartStream(), until it
+ becomes inactive either as a result of a call to Pa_StopStream() or
+ Pa_AbortStream(), or as a result of a return value other than paContinue from
+ the stream callback. In the latter case, the stream is considered inactive
+ after the last buffer has finished playing.
+
+ @return Returns one (1) when the stream is active (ie playing or recording
+ audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
+ if PortAudio is not initialized or an error is encountered.
+
+ @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
+*/
+PaError Pa_IsStreamActive( PaStream *stream );
+
+
+
+/** A structure containing unchanging information about an open stream.
+ @see Pa_GetStreamInfo
+*/
+
+typedef struct PaStreamInfo
+{
+    /** this is struct version 1 */
+    int structVersion;
+
+    /** The input latency of the stream in seconds. This value provides the most
+     accurate estimate of input latency available to the implementation. It may
+     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+     The value of this field will be zero (0.) for output-only streams.
+     @see PaTime
+    */
+    PaTime inputLatency;
+
+    /** The output latency of the stream in seconds. This value provides the most
+     accurate estimate of output latency available to the implementation. It may
+     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+     The value of this field will be zero (0.) for input-only streams.
+     @see PaTime
+    */
+    PaTime outputLatency;
+
+    /** The sample rate of the stream in Hertz (samples per second). In cases
+     where the hardware sample rate is inaccurate and PortAudio is aware of it,
+     the value of this field may be different from the sampleRate parameter
+     passed to Pa_OpenStream(). If information about the actual hardware sample
+     rate is not available, this field will have the same value as the sampleRate
+     parameter passed to Pa_OpenStream().
+    */
+    double sampleRate;
+    
+} PaStreamInfo;
+
+
+/** Retrieve a pointer to a PaStreamInfo structure containing information
+ about the specified stream.
+ @return A pointer to an immutable PaStreamInfo structure. If the stream
+ parameter invalid, or an error is encountered, the function returns NULL.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @note PortAudio manages the memory referenced by the returned pointer,
+ the client must not manipulate or free the memory. The pointer is only
+ guaranteed to be valid until the specified stream is closed.
+
+ @see PaStreamInfo
+*/
+const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream );
+
+
+/** Returns the current time in seconds for a stream according to the same clock used
+ to generate callback PaStreamCallbackTimeInfo timestamps. The time values are
+ monotonically increasing and have unspecified origin. 
+ 
+ Pa_GetStreamTime returns valid time values for the entire life of the stream,
+ from when the stream is opened until it is closed. Starting and stopping the stream
+ does not affect the passage of time returned by Pa_GetStreamTime.
+
+ This time may be used for synchronizing other events to the audio stream, for 
+ example synchronizing audio to MIDI.
+                                        
+ @return The stream's current time in seconds, or 0 if an error occurred.
+
+ @see PaTime, PaStreamCallback, PaStreamCallbackTimeInfo
+*/
+PaTime Pa_GetStreamTime( PaStream *stream );
+
+
+/** Retrieve CPU usage information for the specified stream.
+ The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
+ audio processing routines including, but not limited to the client supplied
+ stream callback. This function does not work with blocking read/write streams.
+
+ This function may be called from the stream callback function or the
+ application.
+     
+ @return
+ A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
+ that the stream callback is consuming the maximum number of CPU cycles possible
+ to maintain real-time operation. A value of 0.5 would imply that PortAudio and
+ the stream callback was consuming roughly 50% of the available CPU time. The
+ return value may exceed 1.0. A value of 0.0 will always be returned for a
+ blocking read/write stream, or if an error occurs.
+*/
+double Pa_GetStreamCpuLoad( PaStream* stream );
+
+
+/** Read samples from an input stream. The function doesn't return until
+ the entire buffer has been filled - this may involve waiting for the operating
+ system to supply the data.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+ 
+ @param buffer A pointer to a buffer of sample frames. The buffer contains
+ samples in the format specified by the inputParameters->sampleFormat field
+ used to open the stream, and the number of channels specified by
+ inputParameters->numChannels. If non-interleaved samples were requested using
+ the paNonInterleaved sample format flag, buffer is a pointer to the first element 
+ of an array of buffer pointers, one non-interleaved buffer for each channel.
+
+ @param frames The number of frames to be read into buffer. This parameter
+ is not constrained to a specific range, however high performance applications
+ will want to match this parameter to the framesPerBuffer parameter used
+ when opening the stream.
+
+ @return On success PaNoError will be returned, or PaInputOverflowed if input
+ data was discarded by PortAudio after the previous call and before this call.
+*/
+PaError Pa_ReadStream( PaStream* stream,
+                       void *buffer,
+                       unsigned long frames );
+
+
+/** Write samples to an output stream. This function doesn't return until the
+ entire buffer has been consumed - this may involve waiting for the operating
+ system to consume the data.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @param buffer A pointer to a buffer of sample frames. The buffer contains
+ samples in the format specified by the outputParameters->sampleFormat field
+ used to open the stream, and the number of channels specified by
+ outputParameters->numChannels. If non-interleaved samples were requested using
+ the paNonInterleaved sample format flag, buffer is a pointer to the first element 
+ of an array of buffer pointers, one non-interleaved buffer for each channel.
+
+ @param frames The number of frames to be written from buffer. This parameter
+ is not constrained to a specific range, however high performance applications
+ will want to match this parameter to the framesPerBuffer parameter used
+ when opening the stream.
+
+ @return On success PaNoError will be returned, or paOutputUnderflowed if
+ additional output data was inserted after the previous call and before this
+ call.
+*/
+PaError Pa_WriteStream( PaStream* stream,
+                        const void *buffer,
+                        unsigned long frames );
+
+
+/** Retrieve the number of frames that can be read from the stream without
+ waiting.
+
+ @return Returns a non-negative value representing the maximum number of frames
+ that can be read from the stream without blocking or busy waiting or, a
+ PaErrorCode (which are always negative) if PortAudio is not initialized or an
+ error is encountered.
+*/
+signed long Pa_GetStreamReadAvailable( PaStream* stream );
+
+
+/** Retrieve the number of frames that can be written to the stream without
+ waiting.
+
+ @return Returns a non-negative value representing the maximum number of frames
+ that can be written to the stream without blocking or busy waiting or, a
+ PaErrorCode (which are always negative) if PortAudio is not initialized or an
+ error is encountered.
+*/
+signed long Pa_GetStreamWriteAvailable( PaStream* stream );
+
+
+/* Miscellaneous utilities */
+
+
+/** Retrieve the size of a given sample format in bytes.
+
+ @return The size in bytes of a single sample in the specified format,
+ or paSampleFormatNotSupported if the format is not supported.
+*/
+PaError Pa_GetSampleSize( PaSampleFormat format );
+
+
+/** Put the caller to sleep for at least 'msec' milliseconds. This function is
+ provided only as a convenience for authors of portable code (such as the tests
+ and examples in the PortAudio distribution.)
+
+ The function may sleep longer than requested so don't rely on this for accurate
+ musical timing.
+*/
+void Pa_Sleep( long msec );
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PORTAUDIO_H */
diff --git a/src/wavelets.c b/src/wavelets.c
new file mode 100644
index 0000000..e416e56
--- /dev/null
+++ b/src/wavelets.c
@@ -0,0 +1,754 @@
+/* NOT PROCESSED DIRECTLY, see ltfat_complexindependent.c */
+#ifdef LTFAT_TYPE
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(atrousfilterbank_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g[],
+                                const ltfatInt L, const ltfatInt gl[],
+                                const ltfatInt W, const ltfatInt a[],
+                                const ltfatInt skip[], const ltfatInt M,
+                                LTFAT_TYPE *c, ltfatExtType ext)
+{
+    for(ltfatInt m=0; m<M; m++)
+    {
+        for(ltfatInt w=0; w<W; w++)
+        {
+            LTFAT_NAME(atrousconvsub_td)(f+w*L, g[m], L, gl[m], a[m],
+                                   skip[m],c + w*M*L + m*L, ext);
+        }
+    }
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(iatrousfilterbank_td)(const LTFAT_TYPE *c, const LTFAT_TYPE *g[],
+                                 const ltfatInt L, const ltfatInt gl[],
+                                 const ltfatInt W, const ltfatInt a[],
+                                 const ltfatInt skip[], const ltfatInt M,
+                                 LTFAT_TYPE *f, ltfatExtType ext)
+{
+   // Set output array to zeros, since the array is used as an accumulator
+    memset(f,0,L*W*sizeof*f);
+
+    for(ltfatInt m=0; m<M; m++)
+    {
+        for(ltfatInt w=0; w<W; w++)
+        {
+            LTFAT_NAME(atrousupconv_td)(c + w*M*L + m*L, g[m], L, gl[m], a[m],
+                                  skip[m],f+w*L, ext);
+        }
+    }
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g[],
+                          const ltfatInt L, const ltfatInt gl[],
+                          const ltfatInt W, const ltfatInt a[],
+                          const ltfatInt skip[], const ltfatInt M,
+                          LTFAT_TYPE *c[], ltfatExtType ext)
+{
+    for(ltfatInt m=0; m<M; m++)
+    {
+        const ltfatInt N = filterbank_td_size(L,a[m],gl[m],skip[m],ext);
+        for(ltfatInt w=0; w<W; w++)
+        {
+
+            LTFAT_NAME(convsub_td)(f+w*L, g[m], L, gl[m], a[m],
+                                   skip[m],c[m]+w*N, ext);
+        }
+    }
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_td)(const LTFAT_TYPE *c[], const LTFAT_TYPE *g[],
+                           const ltfatInt L, const ltfatInt gl[],
+                           const ltfatInt W, const ltfatInt a[],
+                           const ltfatInt skip[], const ltfatInt M,
+                           LTFAT_TYPE *f, ltfatExtType ext)
+{
+    memset(f,0,L*W*sizeof*f);
+
+    for(ltfatInt m=0; m<M; m++)
+    {
+        const ltfatInt N = filterbank_td_size(L,a[m],gl[m],skip[m],ext);
+        for(ltfatInt w=0; w<W; w++)
+        {
+
+            LTFAT_NAME(upconv_td)(c[m]+w*N, g[m], L, gl[m], a[m],
+                                  skip[m],f+w*L, ext);
+        }
+    }
+
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(atrousconvsub_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g,
+                             const ltfatInt L, const ltfatInt gl, const ltfatInt ga,
+                             ltfatInt skip, LTFAT_TYPE *c, ltfatExtType ext)
+{
+    memset(c,0,L*sizeof*c);
+    ltfatInt skipLoc = -skip;
+    LTFAT_TYPE *filtRev = ltfat_malloc(gl*sizeof*filtRev);
+    LTFAT_NAME(reverse_array)((LTFAT_TYPE*)g,filtRev,gl);
+
+    ltfatInt glUps = ga*gl-(ga-1);
+
+    LTFAT_TYPE *righExtbuff = 0;
+    // number of output samples that can be calculated "painlessly"
+    ltfatInt Nsafe = imax((L - skipLoc),0);
+
+    // prepare cyclic buf of length of power of two (for effective modulo operations)
+    ltfatInt bufgl = nextPow2(glUps);
+    // buf index
+    ltfatInt buffPtr = 0;
+
+    // allocating and initializing the cyclic buf
+    LTFAT_TYPE *buf = ltfat_calloc(bufgl,sizeof*buf);
+
+    // pointer for moving in the input data
+    const LTFAT_TYPE *tmpIn = f;
+    LTFAT_TYPE *tmpOut = c;
+    LTFAT_TYPE *tmpg = filtRev;
+    LTFAT_TYPE *tmpBuffPtr = buf;
+
+    // fill buf with the initial values from the input signal according to the boundary treatment
+    // last glUps buf samples are filled to keep buffPtr=0
+    LTFAT_NAME(extend_left)(f,L,buf,bufgl,glUps,ext,1);
+
+    if(Nsafe<L)
+    {
+        // right extension is necessary, additional buf from where to copy
+        righExtbuff = ltfat_malloc(bufgl*sizeof(LTFAT_TYPE));
+        memset(righExtbuff,0,bufgl*sizeof(LTFAT_TYPE));
+        // store extension in the buf (must be done now to avoid errors when inplace calculation is done)
+        LTFAT_NAME(extend_right)(f,L,righExtbuff,glUps,ext,1);
+    }
+
+#define ONEOUTSAMPLE                                                    \
+         tmpg = filtRev;                                           \
+         ltfatInt revBufPtr = modPow2(buffPtr-glUps,bufgl);             \
+         ltfatInt loop1it = gl+1;                                         \
+	      while(--loop1it)                                              \
+	      {                                                             \
+		     tmpBuffPtr = buf + modPow2(revBufPtr,bufgl);          \
+		     revBufPtr+=ga;                                         \
+           *tmpOut += *(tmpBuffPtr) * *(tmpg++);                  \
+         }                                                             \
+         tmpOut++;
+
+
+#define READNEXTDATA(samples,wherePtr)                                              \
+	   buffOver = imax(buffPtr+(samples)-bufgl, 0);                               \
+   	memcpy(buf + buffPtr, wherePtr, ((samples)-buffOver)*sizeof(LTFAT_TYPE)); \
+	   memcpy(buf,wherePtr+(samples)-buffOver,buffOver*sizeof(LTFAT_TYPE));      \
+	   buffPtr = modPow2(buffPtr += (samples),bufgl);
+
+#define READNEXTSAMPLE(wherePtr)                               \
+   	   *(buf + buffPtr) = *wherePtr;                        \
+	   buffPtr = modPow2(++buffPtr,bufgl);
+
+
+    ltfatInt buffOver = 0;
+    /*** initial buf fill ***/
+    ltfatInt sampToRead = imin((skipLoc+1),L);
+    READNEXTDATA(sampToRead,tmpIn);
+    tmpIn += sampToRead;
+
+    /*********** STEP 1: FREE LUNCH ( but also a hot-spot) *******************************/
+    // Take the smaller value from "painless" output length and the user defined output length
+    ltfatInt iiLoops = imin(Nsafe-1,L-1);
+
+    // loop trough all output samples, omit the very last one.
+    for (ltfatInt ii = 0; ii < iiLoops; ii++)
+    {
+        ONEOUTSAMPLE
+        READNEXTSAMPLE(tmpIn)
+        tmpIn++;
+    }
+
+    /*********** STEP 2: FINALIZE FREE LUNCH ************************************/
+    if(Nsafe>0)
+    {
+        ONEOUTSAMPLE
+    }
+    /*********** STEP 3: NOW FOR THE TRICKY PART ************************************/
+    if(Nsafe<L)
+    {
+        /************ STEP 3a: DEALING WITH THE REMAINING SAMPLES ******************/
+        // CAREFULL NOW! possibly stepping outside of input signal
+        // last index in the input signal for which reading next a samples reaches outside of the input signal
+        ltfatInt rightExtBuffIdx = 0;
+        if(Nsafe>0)
+        {
+            ltfatInt lastInIdx = ((Nsafe-1)+1+skipLoc);
+            rightExtBuffIdx = lastInIdx + 1 - L;
+            ltfatInt diff = imax(0,L - lastInIdx);
+            READNEXTDATA(diff,(f + lastInIdx))
+        }
+        else
+        {
+            rightExtBuffIdx = 1+skipLoc - L;
+        }
+
+        // now copying samples that are outside
+        READNEXTDATA(rightExtBuffIdx,righExtbuff)
+
+        /************ STEP 3b: ALL OK, proceed reading input values from righExtbuff ******************/
+        // loop for the remaining output samples
+        for(ltfatInt ii=0; ii<L-Nsafe; ii++)
+        {
+            ONEOUTSAMPLE
+            READNEXTSAMPLE((righExtbuff+rightExtBuffIdx))
+            ++rightExtBuffIdx;
+            //rightExtBuffIdx = modPow2(++rightExtBuffIdx,bufgl);
+        }
+    }
+
+
+#undef READNEXTDATA
+#undef READNEXTSAMPLE
+#undef ONEOUTSAMPLE
+    LTFAT_SAFEFREEALL(buf,filtRev,righExtbuff);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME(atrousupconv_td)(const LTFAT_TYPE *c, const LTFAT_TYPE *g,
+                            const ltfatInt L, const ltfatInt gl,
+                            const ltfatInt ga, const ltfatInt skip,
+                            LTFAT_TYPE *f, ltfatExtType ext)
+{
+    ltfatInt skipLoc = -skip;
+    ltfatInt glUps = ga*gl-(ga-1);
+    // Running output pointer
+    LTFAT_TYPE* tmpOut = f;
+    // Running input pointer
+    LTFAT_TYPE* tmpIn =  (LTFAT_TYPE*) c;
+
+    /** prepare cyclic buf */
+    ltfatInt bufgl = nextPow2(glUps);
+    LTFAT_TYPE* buf = ltfat_calloc(bufgl,sizeof*buf);
+    ltfatInt buffPtr = 0;
+
+    ltfatInt iiLoops = 0;
+    ltfatInt remainsOutSamp = L;
+    ltfatInt rightBuffPreLoad = 0;
+
+    if(skipLoc >= L)
+    {
+        rightBuffPreLoad = (skipLoc + 1) - L;
+        skipLoc = L;
+    }
+    else
+    {
+        iiLoops = imin(L - skipLoc,L); // just in case L < L - inSkip
+        remainsOutSamp = L - (iiLoops-1);
+    }
+
+    LTFAT_TYPE *rightbuf = ltfat_calloc(bufgl,sizeof*rightbuf);
+    LTFAT_TYPE *rightbufTmp = rightbuf;
+
+    if(ext==PER) // if periodic extension
+    {
+        LTFAT_NAME(extend_left)(c,L,buf,bufgl,glUps,PER,0); // extension as a last (tmpgl-1) samples of the buf -> pointer dont have to be moved
+        LTFAT_NAME(extend_right)(c,L,rightbuf,glUps,PER,0);
+    }
+
+    ltfatInt iniStoCopy = imin(skipLoc,bufgl);
+    ltfatInt tmpInSkip = imax(0,skipLoc-bufgl);
+    memcpy(buf,tmpIn+tmpInSkip,iniStoCopy*sizeof*buf);
+    tmpIn += (iniStoCopy+tmpInSkip);
+    buffPtr = modPow2(buffPtr += iniStoCopy,bufgl);
+
+
+//LTFAT_TYPE* filtTmp = g;
+#define ONEOUTSAMPLE(filtTmp,jjLoops)                                   \
+	    for(ltfatInt jj=0;jj<(jjLoops);jj++)                                  \
+		    {                                                            \
+				ltfatInt idx = modPow2((-jj*ga+buffPtr-1), bufgl);      \
+				*tmpOut += *(buf+idx) * *((filtTmp) + jj);            \
+		    }                                                            \
+	    tmpOut++;
+
+#define READNEXTSAMPLE(wherePtr)                               \
+   	   *(buf + buffPtr) = *(wherePtr);                      \
+	   buffPtr = modPow2(++buffPtr,bufgl);
+
+
+    /** STEP 2: MAIN LOOP */
+    if(iiLoops>0)
+    {
+        for(ltfatInt ii=0; ii<iiLoops-1; ii++)
+        {
+            READNEXTSAMPLE(tmpIn)
+            tmpIn++;
+            ONEOUTSAMPLE(g,gl)
+        }
+        READNEXTSAMPLE(tmpIn)
+        //tmpIn++;
+    }
+
+
+    /** STEP 3b: load samples from right buf */
+    while(rightBuffPreLoad--)
+    {
+        READNEXTSAMPLE((rightbufTmp))
+        rightbufTmp++;
+    }
+
+
+    /*
+    STEP 3b: calculate remaining output samples,
+    Again, there can be shift/up misaligment thne shift>L
+    */
+
+    for(ltfatInt ii=0; ii<remainsOutSamp; ii++)
+    {
+        if(ii!=0)
+        {
+            READNEXTSAMPLE((rightbufTmp))
+            rightbufTmp++;
+        }
+        ONEOUTSAMPLE((g),(gl))
+    }
+
+#undef READNEXTDATA
+#undef ONEOUTSAMPLE
+    LTFAT_SAFEFREEALL(buf,rightbuf);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g, const ltfatInt L,
+                       const ltfatInt gl, const ltfatInt a, const ltfatInt skip,
+                       LTFAT_TYPE *c, ltfatExtType ext)
+{
+    const ltfatInt N = filterbank_td_size(L,a,gl,skip,ext);
+    // Since c is used as an accu
+    memset(c,0,N*sizeof*c);
+    // Reverse and conjugate the filter
+    LTFAT_TYPE *filtRev = ltfat_malloc(gl*sizeof*filtRev);
+    LTFAT_NAME(reverse_array)((LTFAT_TYPE*)g, filtRev,gl);
+
+    LTFAT_TYPE *righExtbuff = 0;
+    // number of output samples that can be calculated "painlessly"
+    ltfatInt Nsafe = imax((L + skip + a -1)/a,0);
+
+    // prepare cyclic buf of length of power of two (for effective modulo operations)
+    ltfatInt bufgl = nextPow2(imax(gl,a+1));
+    // buf index
+    ltfatInt buffPtr = 0;
+
+    // allocating and initializing the cyclic buf
+    LTFAT_TYPE *buf = ltfat_calloc(bufgl,sizeof*buf);
+
+    // pointer for moving in the input data
+    const LTFAT_TYPE * tmpIn = f;
+    LTFAT_TYPE * tmpOut = c;
+    LTFAT_TYPE *tmpg = filtRev;
+    LTFAT_TYPE *tmpBuffPtr = buf;
+
+    // fill buf with the initial values from the input signal according to the boundary treatment
+    // last glUps buf samples are filled to keep buffPtr=0
+    LTFAT_NAME(extend_left)(f,L,buf,bufgl,gl,ext,a);
+
+    if(Nsafe<N)
+    {
+        // right extension is necessary, additional buf from where to copy
+        righExtbuff = ltfat_calloc(bufgl,sizeof*righExtbuff);
+        // store extension in the buf (must be done now to avoid errors when inplace calculation is done)
+        LTFAT_NAME(extend_right)(f,L,righExtbuff,gl,ext,a);
+    }
+
+#define ONEOUTSAMPLE                                                    \
+          tmpg = filtRev;                                           \
+          ltfatInt revBufPtr = modPow2(buffPtr-gl,bufgl);                \
+          ltfatInt loop1it = gl+1;                                         \
+	      while(--loop1it)                                              \
+	      {                                                             \
+		     tmpBuffPtr = buf + modPow2(revBufPtr++,bufgl);        \
+             *tmpOut += *(tmpBuffPtr) * *(tmpg++);                  \
+          }                                                             \
+          tmpOut++;
+
+
+
+#define READNEXTDATA(samples,wherePtr)                                              \
+	   buffOver = imax(buffPtr+(samples)-bufgl, 0);                               \
+   	memcpy(buf + buffPtr, wherePtr, ((samples)-buffOver)*sizeof*buf); \
+	   memcpy(buf,wherePtr+(samples)-buffOver,buffOver*sizeof*buf);      \
+	   buffPtr = modPow2(buffPtr += (samples),bufgl);
+
+
+    ltfatInt buffOver = 0;
+    /*** initial buf fill ***/
+    ltfatInt sampToRead = imin((-skip+1),L);
+    READNEXTDATA(sampToRead,tmpIn);
+    tmpIn += sampToRead;
+
+    /*********** STEP 1: FREE LUNCH ( but also a hot-spot) *******************************/
+    // Take the smaller value from "painless" output length and the user defined output length
+    ltfatInt iiLoops = imin(Nsafe-1,N-1);
+
+    // loop trough all output samples, omit the very last one.
+    for (ltfatInt ii = 0; ii < iiLoops; ii++)
+    {
+        ONEOUTSAMPLE
+        READNEXTDATA(a,tmpIn)
+        tmpIn += a;
+    }
+
+    /*********** STEP 2: FINALIZE FREE LUNCH ************************************/
+    if(Nsafe>0)
+    {
+        ONEOUTSAMPLE
+    }
+    /*********** STEP 3: NOW FOR THE TRICKY PART ************************************/
+    if(Nsafe<N)
+    {
+        /************ STEP 3a: DEALING WITH THE REMAINING SAMPLES ******************/
+        // CAREFULL NOW! possibly stepping outside of input signal
+        // last index in the input signal for which reading next a samples reaches outside of the input signal
+        ltfatInt rightExtBuffIdx = 0;
+        if(Nsafe>0)
+        {
+            ltfatInt lastInIdx = (a*(Nsafe-1)+1-skip);
+            rightExtBuffIdx = lastInIdx + a - L;
+            ltfatInt diff = imax(0,L - lastInIdx);
+            READNEXTDATA(diff,(f + lastInIdx))
+        }
+        else
+        {
+            rightExtBuffIdx = 1-skip - L;
+        }
+
+        // now copying samples that are outside
+        READNEXTDATA(rightExtBuffIdx,righExtbuff)
+
+        /************ STEP 3b: ALL OK, proceed reading input values from righExtbuff ******************/
+        // loop for the remaining output samples
+        for(ltfatInt ii=0; ii<N-Nsafe; ii++)
+        {
+            ONEOUTSAMPLE
+            READNEXTDATA(a,(righExtbuff+rightExtBuffIdx))
+            rightExtBuffIdx = modPow2(rightExtBuffIdx += a,bufgl);
+        }
+    }
+
+
+#undef READNEXTDATA
+#undef ONEOUTSAMPLE
+    LTFAT_SAFEFREEALL(buf,filtRev,righExtbuff);
+}
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_td)(const LTFAT_TYPE *c, const LTFAT_TYPE *g, const ltfatInt L,
+                      const ltfatInt gl, const ltfatInt a, const ltfatInt skip,
+                      LTFAT_TYPE *f, ltfatExtType ext)
+{
+    const ltfatInt N = filterbank_td_size(L,a,gl,skip,ext);
+
+    // Copy, reverse and conjugate the imp resp.
+    LTFAT_TYPE *gInv = ltfat_malloc(gl*sizeof*gInv);
+    memcpy(gInv,g,gl*sizeof*gInv);
+    LTFAT_NAME(reverse_array)(gInv,gInv,gl);
+    LTFAT_NAME(conjugate_array)(gInv,gInv,gl);
+    ltfatInt skipRev = -(1 - gl - skip);
+
+    // Running output pointer
+    LTFAT_TYPE* tmpOut = f;
+    // Running input pointer
+    const LTFAT_TYPE* tmpIn =  c;
+
+    /** prepare cyclic buf */
+    ltfatInt bufgl = nextPow2(gl);
+    LTFAT_TYPE* buf = ltfat_calloc(bufgl,sizeof*buf);
+    ltfatInt buffPtr = 0;
+
+    ltfatInt inSkip = (skipRev + a - 1)/a;
+    ltfatInt skipModUp = skipRev%a;
+    ltfatInt skipToNextUp = 0;
+    if(skipModUp!=0)  skipToNextUp = a-skipModUp;
+    ltfatInt outAlign = 0;
+
+    ltfatInt iiLoops = 0;
+    ltfatInt uuLoops = 0;
+    ltfatInt remainsOutSamp = L;
+    ltfatInt rightBuffPreLoad = 0;
+
+    if(inSkip >= N)
+    {
+        inSkip = N;
+        outAlign = skipModUp;
+        rightBuffPreLoad = (skipRev + 1 + a - 1)/a - N;
+    }
+    else
+    {
+        uuLoops = skipToNextUp;
+        iiLoops = imin(N - inSkip,(L-skipToNextUp + a -1)/a); // just in case L/a < N - inSkip
+        remainsOutSamp = L - (uuLoops + (iiLoops-1)*a);
+    }
+
+    LTFAT_TYPE *rightbuf = ltfat_calloc(bufgl,sizeof(LTFAT_TYPE));
+    LTFAT_TYPE *rightbufTmp = rightbuf;
+
+    if(ext==PER) // if periodic extension
+    {
+        LTFAT_NAME(extend_left)(c,N,buf,bufgl,gl,PER,0); // extension as a last (tmpgl-1) samples of the buf -> pointer dont have to be moved
+        LTFAT_NAME(extend_right)(c,N,rightbuf,gl,PER,0);
+    }
+
+    ltfatInt iniStoCopy = imin(inSkip,bufgl);
+    ltfatInt tmpInSkip = imax(0,inSkip-bufgl);
+    memcpy(buf,tmpIn+tmpInSkip,iniStoCopy*sizeof*buf);
+    tmpIn += (iniStoCopy+tmpInSkip);
+    buffPtr = modPow2(buffPtr += iniStoCopy,bufgl);
+
+
+
+#define ONEOUTSAMPLE(filtTmp,jjLoops)                                   \
+	    for(ltfatInt jj=0;jj<(jjLoops);jj++)                                  \
+		    {                                                            \
+				ltfatInt idx = modPow2((-jj+buffPtr-1), bufgl);             \
+				*tmpOut += *(buf+idx) * *((filtTmp) +(jj*a));        \
+		    }                                                            \
+	    tmpOut++;
+
+#define READNEXTSAMPLE(wherePtr)                               \
+   	   *(buf + buffPtr) = *(wherePtr);                      \
+	   buffPtr = modPow2(++buffPtr,bufgl);
+
+
+    /** STEP 1: Deal with the shift - upsampling misaligment */
+    for(ltfatInt uu=0; uu<uuLoops; uu++)
+    {
+        ONEOUTSAMPLE((gInv + skipModUp+uu),((gl-(skipModUp+uu)+a-1)/a))
+    }
+
+    /** STEP 2: MAIN LOOP */
+    if(iiLoops>0)
+    {
+        for(ltfatInt ii=0; ii<iiLoops-1; ii++)
+        {
+            READNEXTSAMPLE(tmpIn)
+            tmpIn++;
+            for(ltfatInt uu=0; uu<a; uu++)
+            {
+                ONEOUTSAMPLE((gInv+uu),((gl-uu+a-1)/a))
+            }
+        }
+        READNEXTSAMPLE(tmpIn)
+        tmpIn++;
+    }
+
+
+    /** STEP 3b: load samples from right buf */
+    while(rightBuffPreLoad--)
+    {
+        READNEXTSAMPLE((rightbufTmp))
+        rightbufTmp++;
+    }
+
+
+    /*
+    STEP 3b: calculate remaining output samples,
+    Again, there can be shift/a misaligment thne shift>L
+    */
+
+    for(ltfatInt ii=outAlign; ii<remainsOutSamp+outAlign; ii++)
+    {
+        if(ii!=outAlign&&ii%a==0)
+        {
+            READNEXTSAMPLE((rightbufTmp))
+            rightbufTmp++;
+        }
+        ONEOUTSAMPLE((gInv+ii%a),((gl-ii%a+a-1)/a))
+    }
+
+#undef ONEOUTSAMPLE
+#undef READNEXTSAMPLE
+    LTFAT_SAFEFREEALL(buf,rightbuf,gInv);
+}
+
+
+
+
+
+// fills last buf samples
+LTFAT_EXTERN
+void LTFAT_NAME(extend_left)(const LTFAT_TYPE *in, ltfatInt L, LTFAT_TYPE *buf,ltfatInt bufgl, ltfatInt gl, ltfatExtType ext, ltfatInt a)
+{
+    ltfatInt legalExtLen = (gl-1)%L;
+    ltfatInt LTimes = (gl-1)/L;
+    LTFAT_TYPE *buffTmp = buf + bufgl - legalExtLen;
+    switch (ext)
+    {
+    case SYM: // half-point symmetry
+    case EVEN:
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buffTmp[ii] = in[legalExtLen-ii-1];
+        break;
+    case SYMW: // whole-point symmetry
+        legalExtLen = imin(gl-1, L-1);
+        buffTmp = buf + bufgl - legalExtLen;
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buffTmp[ii] = in[legalExtLen-ii];
+        break;
+    case ASYM: // half-point antisymmetry
+    case ODD:
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buffTmp[ii] = -in[legalExtLen-ii-1];
+        break;
+    case ASYMW: // whole-point antisymmetry
+        legalExtLen = imin(gl-1, L-1);
+        legalExtLen = imin(gl-1, L-1);
+        buffTmp = buf + bufgl - legalExtLen;
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buffTmp[ii] = -in[legalExtLen-ii];
+        break;
+    case PPD: // periodic padding
+    case PER:
+    {
+        LTFAT_TYPE *bufPtr = buf + bufgl - (gl-1);
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+        {
+            *(bufPtr) = in[L-1-(legalExtLen-1)+ii];
+            bufPtr++;
+        }
+
+        for(ltfatInt ii=0; ii<LTimes; ii++)
+        {
+            for(ltfatInt jj=0; jj<L; jj++)
+            {
+                *(bufPtr) = in[jj];
+                bufPtr++;
+            }
+        }
+
+    }
+    break;
+    case SP0: // constant padding
+        buffTmp = buf + bufgl - (gl-1);
+        for(ltfatInt ii=0; ii<gl-1; ii++)
+            buffTmp[ii] = in[0];
+        break;
+    case PERDEC: // periodic padding with possible last sample repplication
+    {
+        ltfatInt rem = L%a;
+        if(rem==0)
+        {
+            for(ltfatInt ii=0; ii<legalExtLen; ii++)
+                buffTmp[ii] = in[L-1-(legalExtLen-1)+ii];
+        }
+        else
+        {
+            ltfatInt remto = a - rem;
+
+            // replicated
+            for(ltfatInt ii=0; ii<remto; ii++)
+                buffTmp[legalExtLen-1-ii] = in[L-1];
+
+            // periodic extension
+            for(ltfatInt ii=0; ii<legalExtLen-remto; ii++)
+                buffTmp[ii] = in[L-1-(legalExtLen-1-1)+ii+remto-1];
+        }
+    }
+    break;
+    case ZPD: // zero-padding by default
+    case ZERO:
+    case VALID:
+    default:
+        break;
+    }
+}
+
+void LTFAT_NAME(extend_right)(const LTFAT_TYPE *in,ltfatInt L, LTFAT_TYPE *buf, ltfatInt gl, ltfatExtType ext, ltfatInt a)
+{
+    ltfatInt legalExtLen = (gl-1)%L;
+    ltfatInt LTimes = (gl-1)/L;
+    switch (ext)
+    {
+    case SYM: // half-point symmetry
+    case EVEN:
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buf[ii] = in[legalExtLen-ii];
+        break;
+    case SYMW: // whole-point symmetry
+        legalExtLen = imin(gl-1, L-1);
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buf[ii] = in[L-1-1-ii];
+        break;
+    case ASYM: // half-point antisymmetry
+    case ODD:
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buf[ii] = -in[L-1-ii];
+        break;
+    case ASYMW: // whole-point antisymmetry
+        legalExtLen = imin(gl-1, L-1);
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+            buf[ii] = -in[L-1-1-ii];
+        break;
+    case PPD: // periodic padding
+    case PER:
+    {
+        LTFAT_TYPE *bufPtr = buf;
+        for(ltfatInt ii=0; ii<LTimes; ii++)
+        {
+            for(ltfatInt jj=0; jj<L; jj++)
+            {
+                *(bufPtr) = in[jj];
+                bufPtr++;
+            }
+        }
+        for(ltfatInt ii=0; ii<legalExtLen; ii++)
+        {
+            *(bufPtr) = in[ii];
+            bufPtr++;
+        }
+    }
+    break;
+    case SP0: // constant padding
+        for(ltfatInt ii=0; ii<gl; ii++)
+            buf[ii] = in[L-1];
+        break;
+    case PERDEC: // periodic padding with possible last sample repplication
+    {
+        ltfatInt rem = L%a;
+        if(rem==0)
+        {
+            for(ltfatInt ii=0; ii<legalExtLen; ii++)
+                buf[ii] = in[ii];
+        }
+        else
+        {
+            ltfatInt remto = a - rem;
+            // replicated
+            for(ltfatInt ii=0; ii<remto; ii++)
+                buf[ii] = in[L-1];
+
+            // periodized
+            for(ltfatInt ii=0; ii<legalExtLen-remto; ii++)
+                buf[ii+remto] = in[ii];
+        }
+        break;
+    }
+    case ZPD: // zero-padding by default
+    case ZERO:
+    case VALID:
+    default:
+        break;
+    }
+
+
+
+}
+
+
+
+
+#endif // LTFAT_TYPE
diff --git a/src/wavelets.h b/src/wavelets.h
new file mode 100644
index 0000000..422b59e
--- /dev/null
+++ b/src/wavelets.h
@@ -0,0 +1,153 @@
+#ifndef _WAVELETS_H
+#define _WAVELETS_H
+#include <string.h>
+
+typedef enum
+{
+    PER,
+    PERDEC,
+    PPD,
+    SYM,
+    EVEN,
+    SYMW,
+    ASYM,
+    ODD,
+    ASYMW,
+    SP0,
+    ZPD,
+    ZERO,
+    VALID,
+    BAD_TYPE
+} ltfatExtType;
+
+inline static ltfatExtType ltfatExtStringToEnum(const char* extType)
+{
+    if(strcmp(extType,"per")==0)
+    {
+        return PER;
+    }
+    else if(strcmp(extType,"perdec")==0)
+    {
+        return PERDEC;
+    }
+    else if(strcmp(extType,"ppd")==0)
+    {
+        return PPD;
+    }
+    else if(strcmp(extType,"sym")==0)
+    {
+        return SYM;
+    }
+    else if(strcmp(extType,"even")==0)
+    {
+        return EVEN;
+    }
+    else if(strcmp(extType,"symw")==0)
+    {
+        return SYMW;
+    }
+    else if(strcmp(extType,"odd")==0)
+    {
+        return ODD;
+    }
+    else if(strcmp(extType,"asymw")==0)
+    {
+        return ASYMW;
+    }
+    else if(strcmp(extType,"sp0")==0)
+    {
+        return SP0;
+    }
+    else if(strcmp(extType,"zpd")==0)
+    {
+        return ZPD;
+    }
+    else if(strcmp(extType,"zero")==0)
+    {
+        return ZERO;
+    }
+    else if(strcmp(extType,"valid")==0)
+    {
+        return VALID;
+    }
+    else
+    {
+        return BAD_TYPE;
+    }
+}
+
+
+
+
+
+#endif
+
+// CAN BE INCLUDED MORE THAN ONCE
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(extend_left)(const LTFAT_TYPE *in,ltfatInt inLen, LTFAT_TYPE *buffer, ltfatInt buffLen, ltfatInt filtLen, ltfatExtType ext, ltfatInt a);
+
+LTFAT_EXTERN void
+LTFAT_NAME(extend_right)(const LTFAT_TYPE *in,ltfatInt inLen, LTFAT_TYPE *buffer, ltfatInt filtLen, ltfatExtType ext, ltfatInt a);
+
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(convsub_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g,
+                       const ltfatInt L, const ltfatInt gl, const ltfatInt a, const ltfatInt skip,
+                       LTFAT_TYPE *c, ltfatExtType ext);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(upconv_td)(const LTFAT_TYPE *c, const LTFAT_TYPE *g,
+                      const ltfatInt L,  const ltfatInt gl, const ltfatInt a, const ltfatInt skip,
+                      LTFAT_TYPE *f, ltfatExtType ext);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(filterbank_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g[],
+                          const ltfatInt L, const ltfatInt gl[], const ltfatInt W,
+                          const ltfatInt a[], const ltfatInt skip[], const ltfatInt M,
+                          LTFAT_TYPE *c[], ltfatExtType ext);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(ifilterbank_td)(const LTFAT_TYPE *c[], const LTFAT_TYPE *g[],
+                           const ltfatInt L, const ltfatInt gl[], const ltfatInt W, const ltfatInt a[],
+                           const ltfatInt skip[], const ltfatInt M, LTFAT_TYPE *f,
+                           ltfatExtType ext);
+
+LTFAT_EXTERN void
+LTFAT_NAME(atrousfilterbank_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g[],
+                                const ltfatInt L, const ltfatInt gl[], const ltfatInt W,
+                                const ltfatInt a[], const ltfatInt skip[], const ltfatInt M,
+                                LTFAT_TYPE *c, ltfatExtType ext);
+
+LTFAT_EXTERN void
+LTFAT_NAME(iatrousfilterbank_td)(const LTFAT_TYPE *c, const LTFAT_TYPE *g[],
+                                 const ltfatInt L, const ltfatInt gl[], const ltfatInt W, const ltfatInt a[],
+                                 const ltfatInt skip[], const ltfatInt M, LTFAT_TYPE *f,
+                                 ltfatExtType ext);
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(atrousconvsub_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g,
+                             const ltfatInt L, const ltfatInt gl,
+                             const ltfatInt ga,ltfatInt skip,
+                             LTFAT_TYPE *c, ltfatExtType ext);
+
+LTFAT_EXTERN void
+LTFAT_NAME(atrousupconv_td)(const LTFAT_TYPE *c, const LTFAT_TYPE *g,
+                            const ltfatInt L, const ltfatInt gl,
+                            const ltfatInt ga, const ltfatInt skip,
+                            LTFAT_TYPE *f, ltfatExtType ext);
+
+
+
+
+
+
+
+
diff --git a/src/wfac.c b/src/wfac.c
new file mode 100644
index 0000000..669e2d3
--- /dev/null
+++ b/src/wfac.c
@@ -0,0 +1,200 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(wfac)(const LTFAT_COMPLEX *g, const ltfatInt L, const ltfatInt R,
+                         const ltfatInt a, const ltfatInt M,
+                         LTFAT_COMPLEX *gf)
+{
+    ltfatInt h_a, h_m, s;
+
+    LTFAT_REAL *sbuf, *gfp;
+
+    ltfatInt rem, negrem;
+
+    LTFAT_FFTW(plan) p_before;
+
+    const ltfatInt b = L/M;
+
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    const double sqrtM=sqrt(M);
+
+    sbuf = (LTFAT_REAL*)ltfat_malloc(2*d*sizeof(LTFAT_REAL));
+
+    /* Create plan. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)sbuf, (LTFAT_COMPLEX*)sbuf,
+                                       FFTW_FORWARD, FFTW_MEASURE);
+
+    const ltfatInt ld3=c*p*q*R;
+    gfp=(LTFAT_REAL*)gf;
+    for (ltfatInt r=0; r<c; r++)
+    {
+        for (ltfatInt w=0; w<R; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    negrem = positiverem(k*M-l*a,L);
+                    for (s=0; s<d; s++)
+                    {
+                        rem = (negrem+s*p*M)%L;
+                        sbuf[2*s]   = LTFAT_COMPLEXH(creal)(sqrtM*g[r+rem+L*w]);
+                        sbuf[2*s+1] = LTFAT_COMPLEXH(cimag)(sqrtM*g[r+rem+L*w]);
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (s=0; s<2*d; s+=2)
+                    {
+                        gfp[s*ld3]  = sbuf[s];
+                        gfp[s*ld3+1]= sbuf[s+1];
+                    }
+                    gfp+=2;
+                }
+            }
+        }
+    }
+
+    ltfat_free(sbuf);
+    LTFAT_FFTW(destroy_plan)(p_before);
+}
+
+
+/* wfac for real valued input. */
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(wfac)(const LTFAT_REAL *g, const ltfatInt L, const ltfatInt R,
+                      const ltfatInt a, const ltfatInt M,
+                      LTFAT_COMPLEX *gf)
+{
+
+    ltfatInt h_a, h_m;
+
+    LTFAT_REAL *sbuf, *gfp;
+
+    ltfatInt s;
+    ltfatInt rem, negrem;
+
+    LTFAT_FFTW(plan) p_before;
+
+    const ltfatInt b=L/M;
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    const double sqrtM=sqrt(M);
+
+    sbuf = (LTFAT_REAL*)ltfat_malloc(2*d*sizeof(LTFAT_REAL));
+
+    /* Create plan. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_1d)(d, (LTFAT_COMPLEX*)sbuf,
+                                       (LTFAT_COMPLEX*)sbuf,
+                                       FFTW_FORWARD, FFTW_MEASURE);
+
+    const ltfatInt ld3=c*p*q*R;
+    gfp=(LTFAT_REAL*)gf;
+    for (ltfatInt r=0; r<c; r++)
+    {
+        for (ltfatInt w=0; w<R; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    negrem = positiverem(k*M-l*a,L);
+                    for (s=0; s<d; s++)
+                    {
+                        rem = (negrem+s*p*M)%L;
+                        sbuf[2*s]   = sqrtM*g[r+rem+L*w];
+                        sbuf[2*s+1] = 0.0;
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (s=0; s<2*d; s+=2)
+                    {
+                        gfp[s*ld3]  = sbuf[s];
+                        gfp[s*ld3+1]= sbuf[s+1];
+                    }
+                    gfp+=2;
+                }
+            }
+        }
+    }
+
+    ltfat_free(sbuf);
+    LTFAT_FFTW(destroy_plan)(p_before);
+}
+
+/* wfac for real valued input. Produces only half the output coefficients of wfac_r */
+LTFAT_EXTERN void
+LTFAT_NAME(wfacreal)(const LTFAT_REAL *g, const ltfatInt L, const ltfatInt R,
+                     const ltfatInt a, const ltfatInt M,
+                     LTFAT_COMPLEX *gf)
+{
+
+    ltfatInt h_a, h_m;
+
+    //LTFAT_REAL *gfp;
+    LTFAT_COMPLEX *gfp = gf;
+
+    ltfatInt s;
+    ltfatInt rem, negrem;
+
+    LTFAT_FFTW(plan) p_before;
+
+    const ltfatInt b=L/M;
+    const ltfatInt c=gcd(a, M,&h_a, &h_m);
+    const ltfatInt p=a/c;
+    const ltfatInt q=M/c;
+    const ltfatInt d=b/p;
+
+    /* This is a floor operation. */
+    const ltfatInt d2= d/2+1;
+
+    const double sqrtM=sqrt(M);
+
+    LTFAT_REAL *sbuf = (LTFAT_REAL*)ltfat_malloc(d*sizeof(LTFAT_REAL));
+    LTFAT_COMPLEX *cbuf = (LTFAT_COMPLEX*)ltfat_malloc(d2*sizeof(LTFAT_COMPLEX));
+
+    /* Create plan. In-place. */
+    p_before = LTFAT_FFTW(plan_dft_r2c_1d)(d, sbuf, cbuf, FFTW_MEASURE);
+
+    // const ltfatInt ld3=2*c*p*q*R;
+    const ltfatInt ld3=c*p*q*R;
+    //gfp=(LTFAT_REAL*)gf;
+    for (ltfatInt r=0; r<c; r++)
+    {
+        for (ltfatInt w=0; w<R; w++)
+        {
+            for (ltfatInt l=0; l<q; l++)
+            {
+                for (ltfatInt k=0; k<p; k++)
+                {
+                    negrem = positiverem(k*M-l*a,L);
+                    for (s=0; s<d; s++)
+                    {
+                        rem = (negrem+s*p*M)%L;
+                        sbuf[s]   = sqrtM*g[r+rem+L*w];
+                    }
+
+                    LTFAT_FFTW(execute)(p_before);
+
+                    for (s=0; s<d2; s++)
+                    {
+                        gfp[s*ld3] = cbuf[s];
+                    }
+                    gfp++;
+                }
+            }
+        }
+    }
+
+    LTFAT_SAFEFREEALL(sbuf,cbuf);
+    LTFAT_FFTW(destroy_plan)(p_before);
+}
diff --git a/src/windows.c b/src/windows.c
new file mode 100644
index 0000000..5fb8254
--- /dev/null
+++ b/src/windows.c
@@ -0,0 +1,88 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+LTFAT_EXTERN void
+LTFAT_NAME(pgauss)(const ltfatInt L, const double w, const double c_t,
+                   LTFAT_REAL *g)
+{
+
+    ltfatInt lr,k,nk;
+    double tmp,sqrtl, safe, gnorm;
+
+    sqrtl=sqrt((double)L);
+    safe=4;
+    gnorm=0;
+
+    /* Outside the interval [-safe,safe] then exp(-pi*x.^2) is numerically zero. */
+    nk=(ltfatInt)ceil(safe/sqrt((double)L/sqrt(w)));
+
+    for ( lr=0; lr<L; lr++)
+    {
+        g[lr]=0.0;
+        for (k=-nk; k<=nk; k++)
+        {
+            /* Use a tmp variable to calculate squaring */
+            tmp = ((double)lr+c_t)/sqrtl-(double)k*sqrtl;
+            g[lr]+=exp(-PI*tmp*tmp/w);
+        }
+        gnorm +=g[lr]*g[lr];
+    }
+
+    /* Normalize it exactly. */
+    gnorm=sqrt(gnorm);
+
+    for ( lr=0; lr<L; lr++)
+    {
+        g[lr] /= gnorm;
+    }
+}
+
+
+/* does not work correctly. This code does:
+%for k=-nk:nk
+%  tmp=exp(-pi*((lr+c_t)/sqrtl-k*sqrtl).^2/w)
+%  g=g+tmp.*cos(2*pi*c_f*(lr/L-k))+i*tmp.*sin(2*pi*c_f*(lr/L-k));
+%end;
+*/
+
+LTFAT_EXTERN void
+LTFAT_NAME(pgauss_cmplx)(const ltfatInt L, const double w, const double c_t, const double c_f,
+                         LTFAT_COMPLEX *g)
+{
+
+    ltfatInt lr,k,nk;
+    double tmp,sqrtl, safe, gnorm;
+
+    sqrtl=sqrt((double)L);
+    safe=4;
+    gnorm=0;
+
+    /* Outside the interval [-safe,safe] then exp(-pi*x.^2) is numerically zero. */
+    nk=(ltfatInt)ceil(safe/sqrt((double)L/sqrt(w)));
+
+    for ( lr=0; lr<L; lr++)
+    {
+        //g[lr][0]=0.0;
+        //g[lr][1]=0.0;
+        g[lr] = (LTFAT_COMPLEX) 0.0;
+        for (k=-nk; k<=nk; k++)
+        {
+            /* Use a tmp variable to calculate squaring */
+            tmp = ((double)lr+c_t)/sqrtl-(double)k*sqrtl;
+            tmp = exp(-PI*tmp*tmp/w);
+            g[lr]+=tmp*LTFAT_COMPLEXH(cexp)(I*2*PI*c_f*((double)lr/L-(double)k));
+
+        }
+        double gReal = LTFAT_COMPLEXH(creal)(g[lr]);
+        double gImag = LTFAT_COMPLEXH(cimag)(g[lr]);
+        gnorm += (gReal*gReal+gImag*gImag);
+    }
+
+    /* Normalize it exactly. */
+    gnorm=sqrt(gnorm);
+
+    for ( lr=0; lr<L; lr++)
+    {
+        g[lr] /= gnorm;
+    }
+}
diff --git a/src/winmanip.c b/src/winmanip.c
new file mode 100644
index 0000000..9150555
--- /dev/null
+++ b/src/winmanip.c
@@ -0,0 +1,187 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+
+/*  This routines changes the center of a vector from the beginning
+ *  to the middle.
+ *
+ *  f  : Real valued input array.
+ *  L  : Length of input array
+ *  W  : Number of arrays to transform.
+ *  h : Output, same size as input.
+ *
+ *  For the typical use of a single vector, set W=1.
+ *
+ *  This function works in the exact same way as the Matlab command
+ *
+ *  h = fftshift(f,1);
+ *
+ */
+
+LTFAT_EXTERN void
+LTFAT_NAME(fftshift_r)(const LTFAT_REAL *f, const ltfatInt L, LTFAT_REAL *h)
+{
+
+    ltfatInt ii;
+
+    const div_t domod=div(L,2);
+
+    for (ii=0; ii<domod.quot; ii++)
+    {
+        h[ii]=f[ii+domod.quot+domod.rem];
+    }
+    for (ii=0; ii<domod.quot+domod.rem; ii++)
+    {
+        h[ii+domod.quot]=f[ii];
+    }
+}
+
+
+/*  This does the reverse of fftshift. When L is even, this function is
+ * identical to fftshift, but for odd L there is a difference.
+ *
+ *  f  : Real valued input array.
+ *  L  : Length of input array
+ *  W  : Number of arrays to transform.
+ *  h  : Output, same size as input.
+ *
+ *  For the typical use of a single vector, set W=1.
+ *
+ *  This function works in the exact same way as the Matlab command
+ *
+ *  h = ifftshift(f,1);
+ *
+ */
+LTFAT_EXTERN void
+LTFAT_NAME(ifftshift_r)(const LTFAT_REAL *f, const ltfatInt L, LTFAT_REAL *h)
+{
+
+    ltfatInt ii;
+    div_t domod;
+
+    domod=div(L,2);
+
+    for (ii=0; ii<domod.quot+domod.rem; ii++)
+    {
+        h[ii]=f[ii+domod.quot];
+    }
+    for (ii=0; ii<domod.quot; ii++)
+    {
+        h[ii+domod.quot+domod.rem]=f[ii];
+    }
+}
+
+
+/* This routine changes an FIR window to a LONG window.
+ *
+ * Input parameters:
+ *  f     : Real valued input array.
+ *  Lfir  : Length of input array
+ *  Llong  : Length of output array
+ *  h     : Output array
+ */
+LTFAT_EXTERN void
+LTFAT_NAME(fir2long_r)(const LTFAT_REAL *f, const ltfatInt Lfir, const ltfatInt Llong,
+                       LTFAT_REAL *h)
+{
+    const div_t domod=div(Lfir,2);
+
+    /* ---- In the odd case, the additional element is kept in the first half. ---*/
+
+    for (ltfatInt ii=0; ii<domod.quot+domod.rem; ii++)
+    {
+        h[ii]=f[ii];
+    }
+    for (ltfatInt ii=domod.quot+domod.rem; ii<Llong-domod.quot; ii++)
+    {
+        h[ii]=0.0;
+    }
+    const ltfatInt ss=Llong-Lfir;
+    for (ltfatInt ii=domod.quot+domod.rem; ii<Lfir; ii++)
+    {
+        h[ii+ss]=f[ii];
+    }
+
+}
+
+/* This routine changes an FIR window to a LONG window.
+ *
+ * Input parameters:
+ *  f     : Complex valued input array.
+ *  Lfir  : Length of input array
+ *  Llong  : Length of output array
+ *  h     : Output array
+ */
+LTFAT_EXTERN void
+LTFAT_NAME(fir2long_c)(const LTFAT_COMPLEX *f, const ltfatInt Lfir, const ltfatInt Llong,
+                       LTFAT_COMPLEX *h)
+{
+    const div_t domod=div(Lfir,2);
+
+    /* ---- In the odd case, the additional element is kept in the first half. ---*/
+
+    for (ltfatInt ii=0; ii<domod.quot+domod.rem; ii++)
+    {
+        h[ii]=f[ii];
+    }
+    for (ltfatInt ii=domod.quot+domod.rem; ii<Llong-domod.quot; ii++)
+    {
+        h[ii] = (LTFAT_COMPLEX) 0.0;
+    }
+    const ltfatInt ss=Llong-Lfir;
+    for (ltfatInt ii=domod.quot+domod.rem; ii<Lfir; ii++)
+    {
+        h[ii+ss]=f[ii];
+    }
+
+}
+
+
+
+/* This routine changes a LONG window to an FIR window.
+ *
+ * Input parameters:
+ *  f     : Real valued input array.
+ *  Llong  : Length of input array
+ *  Lfir  : Length of output array
+ *  h     : Output array
+ */
+LTFAT_EXTERN void
+LTFAT_NAME(long2fir_r)(const LTFAT_REAL *f, const ltfatInt Llong, const ltfatInt Lfir, LTFAT_REAL *h)
+{
+    const div_t domod=div(Lfir,2);
+
+    /* ---- In the odd case, the additional element is kept in the first half. ---*/
+
+    for (ltfatInt ii=0; ii<domod.quot+domod.rem; ii++)
+    {
+        h[ii]=f[ii];
+    }
+    const ltfatInt ss=Llong-Lfir;
+    for (ltfatInt ii=domod.quot+domod.rem; ii<Lfir; ii++)
+    {
+        h[ii]=f[ii+ss];
+    }
+
+}
+
+
+
+LTFAT_EXTERN void
+LTFAT_NAME(long2fir_c)(const LTFAT_COMPLEX *f, const ltfatInt Llong, const ltfatInt Lfir, LTFAT_COMPLEX *h)
+{
+    const div_t domod=div(Lfir,2);
+
+    /* ---- In the odd case, the additional element is kept in the first half. ---*/
+
+    for (ltfatInt ii=0; ii<domod.quot+domod.rem; ii++)
+    {
+        h[ii]=f[ii];
+    }
+    const ltfatInt ss=Llong-Lfir;
+    for (ltfatInt ii=domod.quot+domod.rem; ii<Lfir; ii++)
+    {
+        h[ii]=f[ii+ss];
+    }
+
+}
diff --git a/src/wmdct.c b/src/wmdct.c
new file mode 100644
index 0000000..bb48e19
--- /dev/null
+++ b/src/wmdct.c
@@ -0,0 +1,173 @@
+#include "ltfat.h"
+#include "ltfat_types.h"
+
+#define CH(name) LTFAT_COMPLEXH(name)
+
+#define POSTPROC_REAL \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     for (ltfatInt m=0;m<M;m+=2) \
+     { \
+       pcoef[m]=CH(creal)(pcoef2[m])+CH(cimag)(pcoef2[m]); \
+       pcoef[m+M]=CH(creal)(pcoef2[m+M2])-CH(cimag)(pcoef2[m+M2]); \
+     } \
+     \
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+       pcoef[m]=CH(creal)(pcoef2[m])-CH(cimag)(pcoef2[m]); \
+       pcoef[m+M]=CH(creal)(pcoef2[m+M2])+CH(cimag)(pcoef2[m+M2]); \
+     } \
+ \
+     pcoef+=M2; \
+     pcoef2+=M4; \
+  }
+
+#define POSTPROC_COMPLEX \
+  for (ltfatInt n=0;n<N*W;n+=2) \
+  { \
+     for (ltfatInt m=0;m<M;m+=2) \
+     { \
+         pcoef[m] =   scalconst*(emipi4*pcoef2[m]  +eipi4*pcoef2[M2-1-m]); \
+         pcoef[m+M] = scalconst*(eipi4*pcoef2[m+M2]+emipi4*pcoef2[M4-1-m]); \
+     } \
+ \
+     for (ltfatInt m=1;m<M;m+=2) \
+     { \
+       pcoef[m] = scalconst*(eipi4*pcoef2[m]    +emipi4*pcoef2[M2-1-m]); \
+       pcoef[m+M]=scalconst*(emipi4*pcoef2[m+M2]+eipi4*pcoef2[M4-1-m]); \
+     } \
+ \
+     pcoef+=M2; \
+     pcoef2+=M4; \
+  }
+
+#define PREPROC \
+   for(ltfatInt n=0;n<L;n++) \
+      f2[n] = (LTFAT_COMPLEX) cexp(-PI*I*n/(2.0*M)); \
+   for(ltfatInt w=W-1;w>=0;w--) \
+      for(ltfatInt n=0;n<L;n++) \
+         f2[n+w*L] = f2[n]*f[n+w*L];
+
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dwiltiii_long)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                                  const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                                  LTFAT_COMPLEX *cout)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0);
+    const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+
+    PREPROC
+
+    LTFAT_NAME_COMPLEX(dgt_long)(f2, g, L, W, M, 2*M, coef2);
+
+    LTFAT_COMPLEX *pcoef  = cout;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    POSTPROC_COMPLEX
+
+    LTFAT_SAFEFREEALL(coef2,f2);
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(dwiltiii_long)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                               const ltfatInt L, const ltfatInt W, const ltfatInt M,
+                               LTFAT_REAL *cout)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2 = 2*M;
+    const ltfatInt M4=4*M;
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+    LTFAT_COMPLEX *g2 = ltfat_malloc(L*sizeof*g2);
+
+    // Real to complex
+    for(ltfatInt ii=0; ii<L; ii++)
+        g2[ii]=g[ii];
+
+    PREPROC
+
+    LTFAT_NAME_COMPLEX(dgt_long)(f2, g2, L, W, M, 2*M, coef2);
+
+
+    LTFAT_REAL *pcoef  = cout;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    POSTPROC_REAL
+
+    LTFAT_SAFEFREEALL(coef2,f2,g2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_COMPLEX(dwiltiii_fb)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g,
+                                const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                                LTFAT_COMPLEX *cout)
+{
+    const ltfatInt N=L/M;
+    const ltfatInt M2=2*M;
+    const ltfatInt M4=4*M;
+    const LTFAT_REAL scalconst = 1.0/sqrt(2.0);
+    const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0);
+    const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0);
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+
+    PREPROC
+
+    /* coef2=comp_dgt(f,g,a,2*M,L); */
+    LTFAT_NAME_COMPLEX(dgt_fb)(f2, g, L, gl, W, M, 2*M, coef2);
+
+
+    LTFAT_COMPLEX *pcoef  = cout;
+    LTFAT_COMPLEX *pcoef2 = coef2;
+
+    POSTPROC_COMPLEX
+
+    LTFAT_SAFEFREEALL(coef2,f2);
+
+}
+
+LTFAT_EXTERN void
+LTFAT_NAME_REAL(dwiltiii_fb)(const LTFAT_REAL *f, const LTFAT_REAL *g,
+                             const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M,
+                             LTFAT_REAL *cout)
+{
+    const ltfatInt N = L/M;
+    const ltfatInt M2 = 2*M;
+    const ltfatInt M4=4*M;
+
+    LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2);
+    LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2);
+    LTFAT_COMPLEX *g2 = ltfat_malloc(gl*sizeof*g2);
+
+    //Real to complex
+    for(ltfatInt ii=0; ii<gl; ii++)
+        g2[ii]=g[ii];
+
+    PREPROC
+
+    LTFAT_NAME_COMPLEX(dgt_fb)(f2, g2, L, gl, W, M, 2*M, coef2);
+
+    LTFAT_REAL* pcoef  = cout;
+    LTFAT_COMPLEX* pcoef2 = coef2;
+
+    POSTPROC_REAL
+
+    LTFAT_SAFEFREEALL(coef2,f2,g2);
+}
+
+#undef CH
+#undef POSTPROC_REAL
+#undef POSTPROC_COMPLEX
+#undef PREPROC
+
diff --git a/thirdparty/Playrec/Makefile_mac b/thirdparty/Playrec/Makefile_mac
new file mode 100644
index 0000000..cc4a079
--- /dev/null
+++ b/thirdparty/Playrec/Makefile_mac
@@ -0,0 +1,35 @@
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default MATLABROOT="/Applications/MATLAB_R2013a.app/")
+  MATLABROOT=/Applications/MATLAB_R2013a.app/
+endif
+
+ifndef EXT
+  $(warning EXT variable is udefined. Using default EXT=mexmaci64)
+  EXT=mexmaci64
+endif
+
+ifndef ARCH
+  $(warning ARCH variable is udefined. Using default ARCH=maci64 )
+  ARCH=maci64
+endif
+
+ifndef PORTAUDIO
+  PORTAUDIO=-lportaudio
+endif
+
+include ../../src/ostools.mk
+
+MEXTGT=playrec.$(EXT)
+MEXSRC=mex_dll_core.c pa_dll_playrec.c
+LIBS= -L. -L"$(MATLABROOT)/bin/$(ARCH)" -lmex -lmx $(PORTAUDIO) 
+	  
+INCLUDES= -I"$(MATLABROOT)/extern/include" -I. -I../../src/thirdparty
+CFLAGS=-fPIC -std=c99 -O3 -Wall -shared -DMATLAB_MEX_FILE
+
+all:
+	$(CC) $(CFLAGS) $(INCLUDES) $(MEXSRC) $(LIBS) -o $(MEXTGT) 
+
+clean:
+	$(RM) $(MEXTGT)
+
+.PHONY: all clean
diff --git a/thirdparty/Playrec/Makefile_macoct b/thirdparty/Playrec/Makefile_macoct
new file mode 100644
index 0000000..9ecc765
--- /dev/null
+++ b/thirdparty/Playrec/Makefile_macoct
@@ -0,0 +1 @@
+include Makefile_unixoct
diff --git a/thirdparty/Playrec/Makefile_mingw b/thirdparty/Playrec/Makefile_mingw
new file mode 100644
index 0000000..2d39bfd
--- /dev/null
+++ b/thirdparty/Playrec/Makefile_mingw
@@ -0,0 +1,23 @@
+# To run this makefile, you must provide your system specific EXT and MATLABROOT
+# variables on the command line e.g.:
+#
+# make -f Makefile_mingw64 MATLABROOT="C:\Program Files\MATLAB\R2011b"  EXT=mexw64 ARCH=win64
+
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default MATLABROOT="C:\Program Files\MATLAB\R2011b" )
+  MATLABROOT=C:\Program Files\MATLAB\R2011b
+endif
+
+ifndef EXT
+  $(warning EXT variable is udefined. Using default EXT=mexw64 )
+  EXT=mexw64
+endif
+
+ifndef ARCH
+  $(warning ARCH variable is udefined. Using default ARCH=win64 )
+  ARCH=win64
+endif
+
+include Makefile_unix
+
+
diff --git a/thirdparty/Playrec/Makefile_mingwoct b/thirdparty/Playrec/Makefile_mingwoct
new file mode 100644
index 0000000..b3fd011
--- /dev/null
+++ b/thirdparty/Playrec/Makefile_mingwoct
@@ -0,0 +1,4 @@
+# Use GNU Make to process this file.
+# mingw32-make -f Makefile_mingw32
+
+include Makefile_unixoct
diff --git a/thirdparty/Playrec/Makefile_unix b/thirdparty/Playrec/Makefile_unix
new file mode 100644
index 0000000..0f07d17
--- /dev/null
+++ b/thirdparty/Playrec/Makefile_unix
@@ -0,0 +1,41 @@
+# To run this makefile, you must provide your system specific EXT and MATLABROOT
+# variables on the command line e.g.:
+#
+# make -f Makefile_unix MATLABROOT="/usr/local/MATLAB/R2011a"  EXT=mexa64 ARCH=glnxa64
+
+ifndef MATLABROOT
+  $(warning MATLABROOT variable is udefined. Using default MATLABROOT="C:\Program Files\MATLAB\R2011b" )
+  MATLABROOT=/usr/local/MATLAB/R2011a
+endif
+
+ifndef EXT
+  $(warning EXT variable is udefined. Using default EXT=mexa64 )
+  EXT=mexa64
+endif
+
+ifndef ARCH
+  $(warning ARCH variable is udefined. Using default ARCH=win64 )
+  ARCH=glnxa64
+endif
+
+ifndef PORTAUDIO
+  PORTAUDIO=-lportaudio
+endif
+
+include ../../src/ostools.mk
+
+MEXTGT=playrec.$(EXT)
+MEXSRC=mex_dll_core.c pa_dll_playrec.c
+LIBS=-Wl,--no-undefined -L. -L"$(MATLABROOT)/bin/$(ARCH)" -lmex -lmx $(PORTAUDIO)
+	  
+INCLUDES= -I"$(MATLABROOT)/extern/include" -I. -I../../src/thirdparty
+CFLAGS=-static-libgcc -fPIC -std=c99 -O3 -Wall -shared -DMATLAB_MEX_FILE
+
+all:
+	$(CC) $(CFLAGS) $(INCLUDES) $(MEXSRC) $(LIBS) -o $(MEXTGT) 
+
+clean:
+	$(RM) $(MEXTGT)
+
+.PHONY: all clean
+
diff --git a/thirdparty/Playrec/Makefile_unixoct b/thirdparty/Playrec/Makefile_unixoct
new file mode 100644
index 0000000..3468fd8
--- /dev/null
+++ b/thirdparty/Playrec/Makefile_unixoct
@@ -0,0 +1,23 @@
+# Use GNU Make to process this file.
+MKOCTFILE ?= mkoctfile
+
+ifndef EXT
+  EXT=mex
+endif
+
+ifndef PORTAUDIO
+  PORTAUDIO=-lportaudio
+endif
+
+include ../../src/ostools.mk
+
+ADDITIONALFLAGS = -L. $(PORTAUDIO) -I. -I../../src/thirdparty
+
+all:
+	$(MKOCTFILE) -Wall -mex mex_dll_core.c pa_dll_playrec.c \
+	             $(ADDITIONALFLAGS)	-o playrec.$(EXT)
+
+clean:
+	$(RM) *.o *.$(EXT)
+
+.PHONY: all clean
diff --git a/thirdparty/Playrec/license.txt b/thirdparty/Playrec/license.txt
new file mode 100644
index 0000000..bba7218
--- /dev/null
+++ b/thirdparty/Playrec/license.txt
@@ -0,0 +1,9 @@
+Copyright © 2006-2008 Robert Humphrey
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Although not required by the license it is requested that users of Playrec inform the author to help understand the distribution of the utility. 
diff --git a/thirdparty/Playrec/mex_dll_core.c b/thirdparty/Playrec/mex_dll_core.c
new file mode 100644
index 0000000..7251432
--- /dev/null
+++ b/thirdparty/Playrec/mex_dll_core.c
@@ -0,0 +1,653 @@
+/*
+ * Playrec
+ * Copyright (c) 2006-2008 Robert Humphrey
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * 'Core' functions to be used when creating dll files for use with MATLAB.
+ * The main function, mexFunction, allows multiple functions to be called from
+ * within MATLAB through the single entry point function by specifying the name
+ * of the required function/'command' as the first argument.  The available
+ * functions must be included in an array _funcLookup[] defined in an alternate
+ * file with the number of available functions defined as _funcLookupSize.
+ *
+ * One such command might be a 'help' function such as that supplied below,
+ * which must be specified in _funcLookup[] if required.  To just have this
+ * command, _funcLookup[] and _funcLookupSize can be specified as:
+
+const FuncLookupStruct _funcLookup[] = {
+    {"help",
+        showHelp,
+        0, 0, 1, 1,
+        "Provides usage information for each command",
+        "Displays command specific usage instructions.",
+        {
+            {"commandName", "name of the command for which information is required"}
+        },
+        {
+            {NULL}
+        },
+    }
+}
+
+const int _funcLookupSize = sizeof(_funcLookup)/sizeof(funcLookupStruct);
+
+ * (note that HELP_FUNC_LOOKUP is defined in mex_dll_core.h to ease the inclusion
+ * of the help command)
+ *
+ * For a description of all the fields to be included, see the definition of
+ * FuncLookupStruct in mex_dll_core.h
+ *
+ * Every time the entry-point function is called the function
+
+bool mexFunctionCalled(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+
+ * is called with the same arguments as supplied to the entry-point function. This
+ * function must have a definition supplied, which returns true to continue
+ * distributing the function call to the appropriate function, or false for the
+ * entry-point function to return immediately.
+ *
+ * If a command 'name' in _funcLookup[] matches the first argument supplied
+ * then the number of arguments supplied (nrhs) and expected (nlhs) are
+ * checked against those required.  If these are valid the function is called,
+ * or otherwise an error is generated including help on the command concerned.
+ * Additionally, if the function returns false it indicates the arguments were
+ * invalid and an error is generated.  NOTE: The first argument to the entry-
+ * point function (the name of the command) is NOT supplied to the
+ * function called.  That is, the function is called with arguments as though
+ * it had been called directly from MATLAB.  The min and max tests on nrhs
+ * occur AFTER the removal of this argument.
+ *
+ * The function linewrapString can be used whenever text needs to be displayed
+ * in the MATLAB command window.  As its name suggests, this takes a string
+ * and linewraps it to fit the width of display specified when calling the
+ * function.  This supports strings containing new line characters ('\n') and
+ * tab characters ('\t'), as well as being able to indent the text relative to
+ * the left hand side of the command window.
+ */
+
+#include "mex.h"
+#include "mex_dll_core.h"
+#include <string.h>
+
+/*
+ * FUNCTION:    mexFunction(int nlhs, mxArray *plhs[],
+ *                                  int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ * Returns:     void
+ *
+ * Description: The entry point function for the MEX-file.  Called whenever
+ *              the utility is used within MATLAB.  Initially calls
+ *              mexFunctionCalled and, depending on the return value of this,
+ *              will continue to process the first argument supplied.
+ *              If no arguments are supplied, a list of all available commands
+ *              (as defined in _funcLookup) is displayed.  Otherwise the
+ *              supplied command name is compared to each one in _funcLookup
+ *              until a match is found.  If a match is found, the number of
+ *              arguments is compared to that expected (given in _funcLookup)
+ *              and if they are valid, the associated function is called.
+ *              If this function returns false, or no match is found for the
+ *              command name, or the incorrect number of arguments are supplied
+ *              then an error is generated.
+ *
+ *              If CASE_INSENSITIVE_COMMAND_NAME is defined, the command name
+ *              matching is case insensitive, although a message is displayed
+ *              if the incorrect case has been used.
+ * TODO:
+ *
+ */
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    int i;
+    bool validFuncName = false;
+    bool validArgNumber;
+    unsigned int charCount, maxFuncNameLen = 0;
+    char *namebuf;
+
+    if(!mexFunctionCalled(nlhs, plhs, nrhs, prhs))
+        return;
+
+    if(nrhs < 1) {
+        if(nlhs < 1) {
+            mexPrintf("\nFirst argument must be one of following strings:\n");
+
+            /* Determine the maximum length of any function name */
+            for(i=0; i<_funcLookupSize; i++) {
+                if((_funcLookup[i].func!=NULL) && _funcLookup[i].name)
+                    maxFuncNameLen = max(maxFuncNameLen, strlen(_funcLookup[i].name));
+            }
+
+            /* Display all function names and descriptions */
+            for(i=0; i<_funcLookupSize; i++) {
+                if((_funcLookup[i].func!=NULL) && _funcLookup[i].name) {
+                    mexPrintf("%s", _funcLookup[i].name);
+
+                    /* Space out correctly, independant of function name length */
+                    charCount = strlen(_funcLookup[i].name);
+                    while(charCount++ < maxFuncNameLen)
+                        mexPrintf(" ");
+
+                    if(_funcLookup[i].desc)
+                        mexPrintf(" - %s\n", _funcLookup[i].desc);
+                    else
+                        mexPrintf(" -\n");
+                }
+            }
+        }
+        else {
+            /* Return argument expected so return info on all available functions */
+            const char *fieldNames[] = {"name", "description",
+                                         "minInputArgs", "maxInputArgs",
+                                         "minOutputArgs", "maxOutputArgs",
+                                         "help",
+                                         "inputArgs", "outputArgs"};
+            const char *paramFieldNames[] = {"name", "description", "isOptional"};
+
+            int argCount, argNum;
+            mxArray *pParamFields;
+
+            plhs[0] = mxCreateStructMatrix(1, _funcLookupSize,
+                    sizeof(fieldNames)/sizeof(char*), fieldNames);
+
+            for(i=0; i<_funcLookupSize; i++) {
+                mxSetField(plhs[0],i,"name", mxCreateString(_funcLookup[i].name));
+                mxSetField(plhs[0],i,"description", mxCreateString(_funcLookup[i].desc));
+                mxSetField(plhs[0],i,"minInputArgs",
+                    mxCreateDoubleScalar(_funcLookup[i].minInputArgs));
+                mxSetField(plhs[0],i,"maxInputArgs",
+                    mxCreateDoubleScalar(_funcLookup[i].maxInputArgs));
+                mxSetField(plhs[0],i,"minOutputArgs",
+                    mxCreateDoubleScalar(_funcLookup[i].minOutputArgs));
+                mxSetField(plhs[0],i,"maxOutputArgs",
+                    mxCreateDoubleScalar(_funcLookup[i].maxOutputArgs));
+                mxSetField(plhs[0],i,"help", mxCreateString(_funcLookup[i].help));
+
+                argCount = 0;
+
+                for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                    if((_funcLookup[i].inputArgs[argNum].name)
+                        && (_funcLookup[i].inputArgs[argNum].desc)) {
+
+                        argCount++;
+                    }
+                }
+
+                pParamFields = mxCreateStructMatrix(1, argCount,
+                        sizeof(paramFieldNames)/sizeof(char*), paramFieldNames);
+
+                mxSetField(plhs[0],i,"inputArgs", pParamFields);
+
+                argCount = 0;
+                for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                    if((_funcLookup[i].inputArgs[argNum].name)
+                        && (_funcLookup[i].inputArgs[argNum].desc)) {
+
+                        mxSetField(pParamFields,argCount,"name",
+                            mxCreateString(_funcLookup[i].inputArgs[argNum].name));
+                        mxSetField(pParamFields,argCount,"description",
+                            mxCreateString(_funcLookup[i].inputArgs[argNum].desc));
+                        mxSetField(pParamFields,argCount,"isOptional",
+                            mxCreateDoubleScalar(_funcLookup[i].inputArgs[argNum].isOptional ? 1 : 0));
+                        argCount++;
+                    }
+                }
+
+                argCount = 0;
+
+                for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                    if((_funcLookup[i].outputArgs[argNum].name)
+                        && (_funcLookup[i].outputArgs[argNum].desc)) {
+
+                        argCount++;
+                    }
+                }
+
+                pParamFields = mxCreateStructMatrix(1, argCount,
+                        sizeof(paramFieldNames)/sizeof(char*), paramFieldNames);
+
+                mxSetField(plhs[0],i,"outputArgs", pParamFields);
+
+                argCount = 0;
+                for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                    if((_funcLookup[i].outputArgs[argNum].name)
+                        && (_funcLookup[i].outputArgs[argNum].desc)) {
+
+                        mxSetField(pParamFields,argCount,"name",
+                            mxCreateString(_funcLookup[i].outputArgs[argNum].name));
+                        mxSetField(pParamFields,argCount,"description",
+                            mxCreateString(_funcLookup[i].outputArgs[argNum].desc));
+                        mxSetField(pParamFields,argCount,"isOptional",
+                            mxCreateDoubleScalar(_funcLookup[i].outputArgs[argNum].isOptional ? 1 : 0));
+                        argCount++;
+                    }
+                }
+            }
+        }
+        return;
+    }
+
+    if(!mxIsChar(prhs[0])) {
+        mexErrMsgTxt("First argument must be a string.\nSupply no arguments to list all valid command names.");
+    }
+
+    /* Provided we can get the string out of the first argument, try and find a match! */
+    if((namebuf=mxArrayToString(prhs[0]))!=NULL) {
+        for(i=0; i<_funcLookupSize; i++) {
+#ifdef CASE_INSENSITIVE_COMMAND_NAME
+            if((_funcLookup[i].name) && (_strcmpi(_funcLookup[i].name, namebuf)==0) && (_funcLookup[i].func!=NULL)) {
+                if(strcmp(_funcLookup[i].name, namebuf)!=0) {
+                    mexPrintf("Using '%s' instead of '%s'\n", _funcLookup[i].name, namebuf);
+                }
+#else
+            if((_funcLookup[i].name) && (strcmp(_funcLookup[i].name, namebuf)==0) && (_funcLookup[i].func!=NULL)) {
+#endif
+                validFuncName = true;
+                validArgNumber = true;
+
+                /* Call function 'removing' the first element of prhs, */
+                if((_funcLookup[i].minInputArgs >= 0) && (_funcLookup[i].minInputArgs > (nrhs-1))) {
+                    mexPrintf("Not enough input arguments specified\n");
+                    validArgNumber = false;
+                }
+                if((_funcLookup[i].maxInputArgs >= 0) && (_funcLookup[i].maxInputArgs < (nrhs-1))) {
+                    mexPrintf("Too many input arguments specified\n");
+                    validArgNumber = false;
+                }
+                if((_funcLookup[i].minOutputArgs >= 0) && (_funcLookup[i].minOutputArgs > nlhs)) {
+                    mexPrintf("Not enough output arguments specified\n");
+                    validArgNumber = false;
+                }
+                if((_funcLookup[i].maxOutputArgs >= 0) && (_funcLookup[i].maxOutputArgs < nlhs)) {
+                    mexPrintf("Too many output arguments specified\n");
+                    validArgNumber = false;
+                }
+                /* This will only call the function if there are valid numbers of arguments */
+                if(!validArgNumber || !(*_funcLookup[i].func)(nlhs, plhs, nrhs - 1, &prhs[1])) {
+                    /* Input arguments were not valid - display command help */
+                    mexPrintf("\n%s - %s\n\n", _funcLookup[i].name, _funcLookup[i].desc);
+                    mexPrintf("Use the arguments \"'help', '%s'\" to see usage instructions\n\n", _funcLookup[i].name);
+                    mexErrMsgTxt("Invalid argument combination for command");
+                }
+                break;
+            }
+        }
+
+        if(!validFuncName) {
+            mexErrMsgTxt("First argument is not a valid command call name.\nSupply no arguments to list all valid command names.");
+        }
+
+        mxFree(namebuf);
+
+    }
+    else {
+        mexErrMsgTxt("Error obtaining string from first argument");
+    }
+}
+
+/*
+ * FUNCTION:    showHelp(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of prhs is used, and should contain the name
+ *              of the command on which help is required
+ *
+ * Returns:     false if more than one input argument is supplied in prhs or if the
+ *              first argument is not a string.  Otherwise returns true.
+ *
+ * Description: Displays help information on the specified command using the
+ *              text stored in _funcLookup.  Provided the first element of
+ *              prhs is a valid string, searches through _funcLookup until
+ *              a match is found.  Then displays the help information on the
+ *              command including a list of arguments and their descriptions.
+ *
+ *              If CASE_INSENSITIVE_COMMAND_NAME is defined, the command name
+ *              matching is case insensitive.
+ *
+ * TODO:
+ *
+ */
+bool showHelp(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    int i, argNum;
+    bool validFuncName, firstParam;
+    char *namebuf;
+
+    validFuncName = false;
+
+    if((nrhs==1) && mxIsChar(prhs[0])) {
+        if((namebuf=mxArrayToString(prhs[0]))!=NULL) {
+            for(i=0; i<_funcLookupSize; i++) {
+
+#ifdef CASE_INSENSITIVE_COMMAND_NAME
+                if((_funcLookup[i].name) && (_strcmpi(_funcLookup[i].name, namebuf)==0)
+                    && (_funcLookup[i].func!=NULL)) {
+
+                    if(strcmp(_funcLookup[i].name, namebuf)!=0) {
+                        mexPrintf("Found case insensitive match to supplied argument '%s'\n", namebuf);
+                    }
+#else
+                if((_funcLookup[i].name) && (strcmp(_funcLookup[i].name, namebuf)==0)
+                    && (_funcLookup[i].func!=NULL)) {
+#endif
+                    validFuncName = true;
+
+                    /* Display the command usage on one line, nomatter how long it is */
+                    mexPrintf("[");
+                    firstParam = true;
+                    /* Display left hand arguments */
+                    for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                        if((_funcLookup[i].outputArgs[argNum].name)
+                            && (_funcLookup[i].outputArgs[argNum].desc)) {
+
+                            if(!firstParam) {
+                                mexPrintf(", ");
+                            }
+                            firstParam = false;
+                            if(_funcLookup[i].outputArgs[argNum].isOptional)
+                                mexPrintf("{%s}", _funcLookup[i].outputArgs[argNum].name);
+                            else
+                                mexPrintf("%s", _funcLookup[i].outputArgs[argNum].name);
+                        }
+                    }
+
+                    mexPrintf("] = %s(", _funcLookup[i].name);
+
+                    /* Display right hand arguments */
+                    firstParam = true;
+                    for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                        if((_funcLookup[i].inputArgs[argNum].name)
+                            && (_funcLookup[i].inputArgs[argNum].desc)) {
+
+                            if(!firstParam) {
+                                mexPrintf(", ");
+                            }
+                            firstParam = false;
+                            if(_funcLookup[i].inputArgs[argNum].isOptional)
+                                mexPrintf("{%s}", _funcLookup[i].inputArgs[argNum].name);
+                            else
+                                mexPrintf("%s", _funcLookup[i].inputArgs[argNum].name);
+                        }
+                    }
+
+                    mexPrintf(")\n\n");
+
+                    /* Display the body of the help for the command */
+                    linewrapString(_funcLookup[i].help, SCREEN_CHAR_WIDTH, 0, 0, SCREEN_TAB_STOP);
+                    mexPrintf("\n");
+
+                    /* Display information on input arguments if they exist */
+                    firstParam = true;
+                    for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                        if((_funcLookup[i].inputArgs[argNum].name)
+                            && (_funcLookup[i].inputArgs[argNum].desc)) {
+
+                            if(firstParam) {
+                                firstParam = false;
+                                mexPrintf("Input Arguments:\n");
+                            }
+                            mexPrintf("    %s %s\n", _funcLookup[i].inputArgs[argNum].name,
+                                _funcLookup[i].inputArgs[argNum].isOptional ? "{optional}" : "");
+
+                            linewrapString(_funcLookup[i].inputArgs[argNum].desc,
+                                    SCREEN_CHAR_WIDTH, 8, 0, SCREEN_TAB_STOP);
+                        }
+                    }
+
+                    /* Add an extra line if there's at least one paramter */
+                    if(!firstParam)
+                        mexPrintf("\n");
+
+                    /* Display information on output arguments if they exist */
+                    firstParam = true;
+                    for(argNum = 0; argNum < MAX_ARG_COUNT; argNum++) {
+                        if((_funcLookup[i].outputArgs[argNum].name)
+                            && (_funcLookup[i].outputArgs[argNum].desc)) {
+
+                            if(firstParam) {
+                                firstParam = false;
+                                mexPrintf("Output Arguments:\n");
+                            }
+                            mexPrintf("    %s %s\n", _funcLookup[i].outputArgs[argNum].name,
+                                _funcLookup[i].outputArgs[argNum].isOptional ? "{optional}" : "");
+
+                            linewrapString(_funcLookup[i].outputArgs[argNum].desc,
+                                    SCREEN_CHAR_WIDTH, 8, 0, SCREEN_TAB_STOP);
+                        }
+                    }
+
+                    /* Add an extra line if there's at least one paramter */
+                    if(!firstParam)
+                        mexPrintf("\n");
+
+                }
+            }
+            mxFree(namebuf);
+        }
+
+        if(!validFuncName) {
+            mexErrMsgTxt("No help available for specified command.\n"
+                         "Supply no arguments to list all valid command names.");
+        }
+    }
+    else {
+        mexPrintf("Help command requires a single string argument");
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    linewrapString( const char *pdisplayStr,
+ *                              unsigned int maxLineLength,
+ *                              unsigned int blockIndent,
+ *                              int firstLineIndent,
+ *                              unsigned int tabSize )
+ *
+ * Inputs:      *pdisplayStr    pointer to the string to be displayed
+ *              maxLineLength   the maximum line length (including any indent that may be required)
+ *              blockindent     indentation to be applied to all lines
+ *              firstlineindent indent to be applied to first line in addition to blockindent
+ *                              note that this is the first line of the text,
+ *                              and not the first line of every paragraph.
+ *              tabSize         size of tab stops (must be 0 or power of 2 eg 0, 1, 2, 4, 8, ...)
+ *                              if not, will default to 4.
+ *
+ * Returns:     number of lines required to display the text
+ *
+ * Description: Word wraps a line to fit the dimensions specified by breaking
+ *              at spaces where required.  If a word is too long for one line
+ *              it is split at the end of the line.  Tabs can be included and
+ *              will align to the next integer multiple of tabSize along the
+ *              line.  When a line is wrapped, any white space between the last
+ *              character of one line and the first character of the next line
+ *              is removed.  However, any white space following a forced line
+ *              break is not removed, although will only take up at most one
+ *              line.
+ *
+ * TODO:        Do not add extra line if last line in string just contains spaces
+ */
+
+unsigned int linewrapString( const char *pdisplayStr, unsigned int maxLineLength, unsigned int blockIndent,
+                             int firstLineIndent, unsigned int tabSize ) {
+    unsigned int lineStartChar = 0; /* index of character used at the start of the line             */
+    unsigned int lineEndChar;       /* index of last character on the line (includes white space)   */
+    int lastPrintChar;              /* index of the last printable character on the line            */
+    int lastPrintCharTmp;           /* temporary index of the last printable character on the line  */
+    bool stringEnd = false;         /* true -> the end of the string has been reached               */
+    unsigned int thisLineIndent;    /* the limit of the length of this line                         */
+    unsigned int lineNumber = 0;    /* Line number being displayed                                  */
+    unsigned int lineCharPos;       /* Position on the line (0 is first character)                  */
+    bool tooLongWord;               /* used to determine if a word is longer than a single line     */
+    unsigned int tabSpaceTmp;       /* temporary counter used to add the correct number             */
+                                    /* of spaces to effectively insert a tab                        */
+
+    unsigned int i;                 /* general counting index                                       */
+
+    unsigned int tabStopBitMask = tabSize - 1;  /* Mask used when calculating the position
+                                                 * of the next tab stop
+                                                 */
+
+    if(tabSize == 0) {
+        tabStopBitMask = 0;
+    }
+    else if(tabStopBitMask & tabSize) {
+        /* tabSize is not power of 2 */
+        tabSize = 4;
+        tabStopBitMask = tabSize - 1;
+    }
+
+    /* Don't even attempt to display if the formatting values supplied are silly */
+    if(!pdisplayStr
+        || !pdisplayStr[0]
+        || (maxLineLength < 1)
+        || (blockIndent + firstLineIndent < 0)
+        || (maxLineLength < blockIndent)
+        || (maxLineLength < blockIndent + firstLineIndent)) {
+
+            stringEnd = true;
+    }
+
+    /* step through each line, one at a time */
+    while( !stringEnd ) {
+        lineNumber++;
+
+        /* Calculate available length of this line */
+        thisLineIndent = blockIndent;
+        if(lineNumber==1)
+            thisLineIndent += firstLineIndent;
+
+        /* Set 'defaults' for the line */
+        lineEndChar = lineStartChar;
+        lastPrintChar = lineStartChar - 1;
+        lastPrintCharTmp = lineStartChar - 1;
+        lineCharPos = thisLineIndent;
+
+        tooLongWord = true;
+
+        /* go though to the end of the line, keeping track of the last printing character
+         * or find a new line character if that occurs before the end of the line
+         */
+
+        for( i = lineStartChar; ( lineCharPos < maxLineLength ) && pdisplayStr[ i ]; i++ ) {
+            if( pdisplayStr[ i ] == ' ' ) {
+                lineEndChar = i;
+                lastPrintChar = lastPrintCharTmp;
+                lineCharPos++;
+                tooLongWord = false;
+            }
+            else if( pdisplayStr[ i ] == '\t' ) {
+                lineEndChar = i;
+                lastPrintChar = lastPrintCharTmp;
+                tabSpaceTmp = tabSize - (lineCharPos & tabStopBitMask);
+                lineCharPos += tabSpaceTmp;
+                tooLongWord = false;
+            }
+            else if( pdisplayStr[ i ] == '\n' ) {
+                /* Do not include new line character at end of current line */
+                lineEndChar = i;
+                lastPrintChar = lastPrintCharTmp;
+                tooLongWord = false;
+                break;
+            }
+            else {
+                lineCharPos++;
+                lastPrintCharTmp = i;
+            }
+        }
+
+        if(!pdisplayStr[ i ]) {
+            /* end of the string has been reached */
+            lineEndChar = i;
+            lastPrintChar = i - 1;
+            tooLongWord = false;
+            stringEnd = true;
+        }
+
+        /* Generate initial padding */
+        lineCharPos = thisLineIndent;
+
+        for( i = 0; i < thisLineIndent; i++)
+            mexPrintf( " " );
+
+        /* display the line of text going up to either the last printing character
+         * or the end of the line if the word is longer than a single line
+         */
+        for( i = lineStartChar; (((int)i <= lastPrintChar) || tooLongWord) && ( lineCharPos < maxLineLength ); i++ ) {
+            if( pdisplayStr[ i ] == '\t' ) {
+                tabSpaceTmp = tabSize - (lineCharPos & tabStopBitMask);
+                lineCharPos += tabSpaceTmp;
+                while(tabSpaceTmp--)
+                    mexPrintf( " " );
+            }
+            else {
+                mexPrintf( "%c", pdisplayStr[ i ] );
+                lineCharPos++;
+            }
+
+            /* Keep track of end of line if tooLongWord */
+            if(tooLongWord) {
+                lastPrintChar = i;
+                lineEndChar = i;
+            }
+        }
+
+        mexPrintf("\n");
+
+        /* Now find the last non printing character of the line */
+        if(pdisplayStr[ lineEndChar ] && pdisplayStr[ lineEndChar ] != '\n') {
+            /* Get to the end of the white space at the end of the line */
+            while((pdisplayStr[ lineEndChar + 1 ] == ' ')
+                || (pdisplayStr[ lineEndChar + 1 ] == '\t')) {
+
+                    lineEndChar++;
+            }
+
+            if(pdisplayStr[ lineEndChar + 1 ] == '\n') {
+                /* If at the end of all this white space there's a new line
+                 * include it in the current line
+                 */
+                lineEndChar++;
+            }
+
+            if(!pdisplayStr[ lineEndChar + 1 ]) {
+                /* end of the string has been reached */
+                lineEndChar++;
+                stringEnd = true;
+            }
+        }
+
+        /* make the first character of the next line the next character in the string */
+        lineStartChar = lineEndChar + 1;
+    }
+
+    return lineNumber;
+}
+
diff --git a/thirdparty/Playrec/mex_dll_core.h b/thirdparty/Playrec/mex_dll_core.h
new file mode 100644
index 0000000..df65cc0
--- /dev/null
+++ b/thirdparty/Playrec/mex_dll_core.h
@@ -0,0 +1,165 @@
+/*
+ * Playrec
+ * Copyright (c) 2006-2008 Robert Humphrey
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Header for mex_dll_core.c which contains 'core' functions to be used when
+ * creating dll files for use with MATLAB.  This allows multiple functions to
+ * be called from within MATLAB through the single entry point function by
+ * specifying the name of the required command/function as the first input
+ * argument.
+ */
+
+#ifndef MEX_DLL_CORE_H
+#define MEX_DLL_CORE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/** Adds symbol exporting function decorator to mexFunction.
+    On windows, def file is no longer needed. For MinGW, it
+    suppresses the default "export-all-symbols" behavior. **/
+#if defined(_WIN32) || defined(__WIN32__)
+#  define DLL_EXPORT_SYM __declspec(dllexport)
+#else
+#  define EXPORT_SYM __attribute__((visibility("default")))
+#endif
+
+#include "mex.h"
+
+/* Macro defintions to avoid crashes under Mac OS X */
+#ifndef max
+#define max(a,b) ((a)>(b)? (a):(b))
+#endif
+
+#ifndef min
+#define min(a,b) ((a)<(b)? (a):(b))
+#endif
+
+/* Macro defintions to avoid problems when not compiling with Matlab's mex.h */
+#ifndef true
+#define true 1
+#endif
+#ifndef false
+#define false 0
+#endif
+
+/* Include this in _funcLookup[] to include the help command */
+#define HELP_FUNC_LOOKUP {"help",                                           \
+        showHelp,                                                           \
+        1, 1, 0, 0,                                                         \
+        "Provides usage information for each command",                      \
+        "Displays command specific usage instructions.",                    \
+        {                                                                   \
+            {"commandName", "name of the command for which information is required"}    \
+        },                                                                  \
+        {                                                                   \
+            {NULL}                                                          \
+        },                                                                  \
+    }
+
+/* The maximum number of arguments that can be listed for lhs and rhs in funcLookupStruct_t */
+#define MAX_ARG_COUNT 10
+
+/* Width of the screen in characters when displaying help */
+#define SCREEN_CHAR_WIDTH 80
+
+/* Position of tab stops - must be 0 or power of 2 (eg 0, 1, 2, 4, 8, 16 etc); */
+#define SCREEN_TAB_STOP 4
+
+/* Including this #define makes command names case insensitive */
+/* #define CASE_INSENSITIVE_COMMAND_NAME */
+
+/* Structure to contain information about a single input or output argument. */
+typedef struct {
+    char *name;         /* the argument name                                            */
+    char *desc;         /* description of the argument - can be multilined
+                         * and will be line wrapped if longer than one line
+                         */
+    bool isOptional;    /* true if the argument is optional                             */
+} ParamDescStruct;
+
+/* Sturcture containing information associated for each command that can
+ * be called from within MATLAB.
+ */
+typedef struct {
+    char *name;             /* Textual string used to identify command in MATLAB        */
+    bool (*func)(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+                            /* Pointer to the actual function to call.
+                             * The arguments are those received by the entry point
+                             * function, apart from the function name is NOT supplied
+                             * and so prhs starts with the second argument and
+                             * nrhs is one less. ie the arguments are as if the
+                             * function was called directly from within MATLAB
+                             */
+
+    int  minInputArgs;      /* The minimum and maximum values of nlhs and nrhs that     */
+    int  maxInputArgs;      /* *func should be called with. Use -1 to not check the     */
+    int  minOutputArgs;     /* particular value.  This can be used to reduce the        */
+    int  maxOutputArgs;     /* amount of input/output count checks in the function.     */
+
+    char *desc;             /* Short (1 line) command description - not line wrapped    */
+    char *help;             /* Complete help for the command.  Can be any length and
+                             * can contain new line characters.  Will be line wrapped
+                             * to fit the width of the screen as defined as
+                             * SCREEN_CHAR_WIDTH with tab stops every
+                             * SCREEN_TAB_STOP characters.
+                             */
+
+        /* descriptions of all input arguments in the order they are required */
+    ParamDescStruct inputArgs[MAX_ARG_COUNT];
+        /* descriptions of all output arguments in the order they are returned */
+    ParamDescStruct outputArgs[MAX_ARG_COUNT];
+} FuncLookupStruct;
+
+/* Function prototypes */
+bool showHelp(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+unsigned int linewrapString( const char *pdisplayStr, unsigned int maxLineLength,
+                             unsigned int blockIndent, int firstLineIndent,
+                             unsigned int tabSize );
+
+/* Function which must have its definition supplied elsewhere.
+ * Returning false makes the call to mexFunction return immediately.
+ * Returning true means the first argument is analysed and the
+ * appropriate function called.
+ */
+extern bool mexFunctionCalled(int nlhs, mxArray *plhs[],
+                              int nrhs, const mxArray *prhs[]);
+
+/* These two variables must be defined elsewhere, containing a list of all the
+ * commands which the MEX-file should recognise.  See above and mex_dll_core.c
+ * for more information on the fields that must be included within _funcLookup.
+ * The order of the commands in _funcLookup is the order they will be displayed
+ * when the available command list is generated (produced when no arguments are
+ * supplied when calling the MEX-file from MATLAB).
+ */
+extern const FuncLookupStruct _funcLookup[];
+extern const int _funcLookupSize;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* MEX_DLL_CORE_H */
diff --git a/thirdparty/Playrec/pa_dll_playrec.c b/thirdparty/Playrec/pa_dll_playrec.c
new file mode 100644
index 0000000..4adc1d9
--- /dev/null
+++ b/thirdparty/Playrec/pa_dll_playrec.c
@@ -0,0 +1,4038 @@
+/*
+ * Playrec
+ * Copyright (c) 2006-2008 Robert Humphrey
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * There are two different sets of functions in this file - the first are
+ * 'helper' functions used to perform operations that are not directly called
+ * by MATLAB, and the second are the functions referred to in _funcLookup and
+ * map to commands in MATLAB. The latter begin 'do' to easily identify them.
+ */
+
+#include "mex.h"
+#include "portaudio.h"
+#include "mex_dll_core.h"
+#include "pa_dll_playrec.h"
+#include <stdio.h>
+#include <string.h>
+
+
+/*
+ * States are used to ensure code is only run when it will not cause problems
+ * Multiple states can be set at one time by using single bits for each state
+ * If required more states can be used by adding an additional #define and
+ * an additional element in _stateOpts[] for each state required.
+
+ *
+ * BASIC_INIT = The exit function has been registered with mexAtExit.
+ *              PortAudio has been succesfully initialised
+ *              The state to return to on reset.
+ *              There should be no method of clearing from this state
+ *              If not in this state, only execute code to achieve this state
+ * FULL_INIT  = The global streamInfoStruct has been created
+ *              The PortAudio stream has been created and is running
+ */
+
+#define BASIC_INIT (1<<0)
+#define FULL_INIT (1<<1)
+
+/* macros to manipulate the _currentState variable
+ * OR together (|) states to complete a combined state test
+ * ie ISSTATE would only return true if all OR'd states are set.
+ */
+
+/* Set all the states OR'd together in setState */
+#define SETSTATE(setState) ((_currentState) |= (setState))
+
+/* Clear all the states OR'd together in clearState */
+#define CLEARSTATE(clearState) ((_currentState) &= ~(clearState))
+
+/* return true only if all states OR'd together in isState are set. */
+#define ISSTATE(isState) (((_currentState) & (isState))==(isState))
+
+/* Variable used to store the current system state */
+int _currentState=0;
+
+/* Structure used to store human readable information on each state, used to
+ * give feedback when a state has the wrong value.
+ */
+const StateOptsStruct _stateOpts[] = {
+    {   BASIC_INIT,
+        "Basic initialisation",
+        "This should have started automatically - something must be wrong.",
+        "This state connot be stopped without clearing the utility from memory."
+    },
+    {   FULL_INIT,
+        "Full initialisation",
+        "Call \"init\" command to run initialisation.",
+        "Call \"reset\" command."
+    }
+};
+
+/* The number of elements in the above structure */
+const int _stateOptsSize = sizeof(_stateOpts)/sizeof(StateOptsStruct);
+
+/* Structure used to provide a lookup between all commands accessible from
+ * MATLAB and their associated functions here.  All functions have been given
+ * the same name as the MATLAB command, prefixed with 'do'.  The structure also
+ * contains help information for the function, descriptions of each input and
+ * output value, and upper and lower limits on the number of acceptable
+ * arguments.  This structure is used by mex_dll_core.c, and all fields are
+ * described in mex_dll_core.h.  The order of commands in this array is the
+ * order they will be shown when listed in MATLAB.
+ */
+const FuncLookupStruct _funcLookup[] = {
+    HELP_FUNC_LOOKUP,   /* Add the help function provided in mex_dll_core */
+    {   "about",
+        doAbout,
+        0, 0, 0, 1,
+        "Displays information about the playrec utility",
+
+        "Displays information about the playrec utility",
+        {
+            {NULL}
+        },
+        {
+            {   "aboutInfo", "String containing information about this build of "
+                "playrec. If no output argument is specified then the information "
+                "is printed in the command window."
+            }
+        }
+    },
+    {   "overview",
+        doOverview,
+        0, 0, 0, 1,
+        "Displays an overview on using this playrec utility",
+
+        "Displays an overview on using this playrec utility",
+        {
+            {NULL}
+        },
+        {
+            {   "overviewInfo", "String containing information about how to use playrec. "
+                "If no output argument is specified then the information is printed "
+                "in the command window."
+            }
+        }
+    },
+    {   "getDevices",
+        doGetDevices,
+        0, 0, 0, 1,
+        "Returns a list of available audio devices",
+
+        "Returns information on the available devices within the system, including "
+        "ID, name, host API and number of channels supported.",
+        {
+            {NULL}
+        },
+        {
+            {   "deviceList", "Structure array containing the following fields for "
+                "each device:\n"
+                "\t'deviceID' - ID used to refer to the device,\n"
+                "\t'name' - textual name of the device,\n"
+                "\t'hostAPI' - the host API used to access the device,\n"
+                "\t'defaultLowInputLatency' - device default input latency used "
+                "for interactive performance.  This is the value suggested to "
+                "the soundcard when the device is used for input.\n"
+                "\t'defaultLowOutputLatency' - device default output latency used "
+                "for interactive performance.  This is the value suggested to "
+                "the soundcard when the device is used for output.\n"
+                "\t'defaultHighInputLatency' - device default input latency for "
+                "robust non-interactive applications (eg. playing sound files),\n"
+                "\t'defaultHighOutputLatency' - device default output latency for "
+                "robust non-interactive applications (eg. playing sound files),\n"
+                "\t'defaultSampleRate' - device default sample rate,\n"
+                "\t'inputChans' - maximum number of input channels supported by the device\n"
+                "\t'outputChans' - maximum number of output channels supported by the device"
+            }
+        }
+    },
+    {   "init",
+        doInit,
+        3, 8, 0, 0,
+        "Initialises the utility",
+
+        "Configures the utility for audio input and/or output based on the specified "
+        "configuration.  If successful the chosen device(s) will be running in "
+        "the background waiting for the first pages to be received.  If unsuccessful "
+        "an error will be generated containing an error number and description.\n\n"
+        "All channel numbers are assumed to start at 1.  The maximum number of "
+        "channels support by the device will be used if the maximum channel number "
+        "is not specified.  Specifying a maximum number of channels verifies that the "
+        "device will support them and slightly reduces the utility's processor usage."
+        "\n\nIf an optional value is specified, all previous optional values must also "
+        "be specified.",
+        {
+            {"sampleRate", "the sample rate at which both devices will operate"},
+            {   "playDevice", "the ID of the device to be used for sample output (as "
+                "returned by 'getDevices'), or -1 for no device (ie output not required)"
+            },
+            {   "recDevice", "the ID of the device to be used for sample input (as "
+                "returned by 'getDevices'), or -1 for no device (ie input not required)"
+            },
+            {   "playMaxChannel", "a number greater than or equal to the maximum channel "
+                "that will be used for output.  This must be less than or equal to the "
+                "maximum number of output channels that the device supports.  The value "
+                "is ignored if playDevice is -1.",
+                true
+            },
+            {   "recMaxChannel", "a number greater than or equal to the maximum channel "
+                "that will be used for input.  This must be less than or equal to the "
+                "maximum number of input channels that the device supports.  The value "
+                "is ignored if recDevice is -1.",
+                true
+            },
+            {   "framesPerBuffer", "the number of samples to be processed in each callback "
+                "within the utility (ie the length of each block of samples transferred "
+                "between the utility and the soundcard).  The lower the value specified "
+                "the shorter the latency but also the greater the likelihood of glitches "
+                "within the audio.  This has no influence on the size of pages that can "
+                "be used.  The default is 0 which lets the utility use an optimal, and "
+                "potentially different, value in each callback.  A value other than the "
+                "default may introduce a second layer of buffering, increasing latency, "
+                "and so should only be used in exceptional circumstances.",
+                true
+            },
+            {   "playSuggestedLatency", "the play latency, in seconds, the device should try "
+                "to use where possible.  Defaults to the default low output latency for the "
+                "device.",
+                true
+            },
+            {   "recSuggestedLatency", "the record latency, in seconds, the device should try "
+                "to use where possible.  Defaults to the default low input latency for the "
+                "device.",
+                true
+            }
+        },
+        {
+            {NULL}
+        }
+    },
+    {   "reset",
+        doReset,
+        0, 0, 0, 0,
+        "Resets the system to allow re-initialisation",
+
+        "Resets the system to its state prior to initialisation through the 'init' "
+        "command.  This includes deleting all pages and stopping the connection "
+        "to the previously selected audio device(s).  Generates an error if the "
+        "utility is not already initialised - use 'isInitialised' to determine "
+        "if the utility is initialised.\n\n"
+        "Use with care as there is no way to recover previously recorded data "
+        "once this has been called.",
+        {
+            {NULL}
+        },
+        {
+            {NULL}
+        }
+    },
+    {   "isInitialised",
+        doIsInitialised,
+        0, 0, 0, 1,
+        "Indicates if the system is initialised",
+
+        "Indicates if the system is currently initialised, and hence if 'reset' or 'init' "
+        "can be called without generating an error.",
+        {
+            {NULL}
+        },
+        {
+            {"currentState", "1 if the utility is currently initialised, otherwise 0."}
+        }
+    },
+
+    {   "playrec",
+        doPlayrec,
+        4, 4, 0, 1,
+        "Adds a new page with simultaneous input and output",
+
+        "Adds a new page containing both sample input (recording) and output (playing).  "
+        "Generates an error if the required memory cannot be allocated or if any "
+        "other problems are encountered.\n\n"
+        "The length of the page is equal to whichever is longer: the number of "
+        "samples to play or the number of samples to record.",
+        {
+            {   "playBuffer", "a MxN matrix containing the samples to be output.  M is "
+                "the number of samples and N is the number of channels of data."
+            },
+            {   "playChanList", "a 1xN vector containing the channels on which the "
+                "playBuffer samples should be output.  N is the number of channels "
+                "of data, and should be the same as playBuffer (a warning is generated "
+                "if they are different, but the utility will still try and create the "
+                "page).  Can only contain each channel number once, but the channel "
+                "order is not important and does not need to include all the channels "
+                "the device supports. All output channels no specified will automatically "
+                "output zeros.  The maximum channel number cannot be greater than that "
+                "specified during initialisation."
+            },
+            {   "recDuration", "the number of samples that should be recorded in this "
+                "page, or -1 to record the same number of samples as in playBuffer."
+            },
+            {   "recChanList", "a row vector containing the channel numbers of all channels "
+                "to be recorded.  Can only contain each channel number once, but the "
+                "channel order is not important and does not need to include all the "
+                "channels the device supports.  This order of channels is used when "
+                "recorded samples are returned by 'getRec'.  The maximum channel number "
+                "cannot be greater than that specified during initialisation."
+            }
+        },
+        {
+            {   "pageNumber", "a unique integer number identifying the page that has been "
+                "added - use this with all other functions that query specific pages, "
+                "such as 'isFinished'."
+            }
+        }
+    },
+    {   "play",
+        doPlay,
+        2, 2, 0, 1,
+        "Adds a new output only page",
+
+        "Adds a new page containing only sample output (playing).  Generates an error if "
+        "the required memory cannot be allocated or if any other problems are "
+        "encountered.\n\nThe page is the same length as that of playBuffer.",
+        {
+            {   "playBuffer", "a MxN matrix containing the samples to be output.  M is "
+                "the number of samples and N is the number of channels of data."
+            },
+            {   "playChanList", "a 1xN vector containing the channels on which the "
+                "playBuffer samples should be output.  N is the number of channels "
+                "of data, and should be the same as playBuffer (a warning is generated "
+                "if they are different, but the utility will still try and create the "
+                "page).  Can only contain each channel number once, but the channel "
+                "order is not important and does not need to include all the channels "
+                "the device supports. All output channels no specified will automatically "
+                "output zeros.  The maximum channel number cannot be greater than that "
+                "specified during initialisation."
+            },
+        },
+        {
+            {   "pageNumber", "a unique integer number identifying the page that has been "
+                "added - use this with all other functions that query specific pages, "
+                "such as 'isFinished'."
+            }
+        }
+    },
+    {   "rec",
+        doRec,
+        2, 2, 0, 1,
+        "Adds a new input only page",
+
+        "Adds a new page containing only sample input (recording).  Generates an error if "
+        "the required memory cannot be allocated or if any other problems are "
+        "encountered.\n\nThe page is recDuration samples long.",
+        {
+            {   "recDuration", "the number of samples that should be recorded on each channel "
+                "specified in recChanList."
+            },
+            {   "recChanList", "a row vector containing the channel numbers of all channels "
+                "to be recorded.  Can only contain each channel number once, but the "
+                "channel order is not important and does not need to include all the "
+                "channels the device supports.  This order of channels is used when "
+                "recorded samples are returned by 'getRec'.  The maximum channel number "
+                "cannot be greater than that specified during initialisation."
+            }
+        },
+        {
+            {   "pageNumber", "a unique integer number identifying the page that has been "
+                "added - use this with all other functions that query specific pages, "
+                "such as 'isFinished'."
+            }
+        }
+    },
+    {   "pause",
+        doPause,
+        0, 1, 0, 1,
+        "Sets or queries the current pause state",
+
+        "Queries or updates the current pause state of the utility.  If no argument is "
+        "supplied then just returns the current pause status, otherwise returns the "
+        "status after applying the change to newPause.",
+        {
+            {   "newPause", "the new state of the utility: 1 to pause or 0 to resume the "
+                "stream.  This can be either a scalar or logical value.  If newState is "
+                "the same as the current state of the utility, no change occurs.",
+                true
+            }
+        },
+        {
+            {   "currentState", "the state of the utility (including the update to newPause "
+                "if newPause is specified): 1 if the utility is paused or otherwise 0."
+            }
+        }
+    },
+    {   "block",
+        doBlock,
+        0, 1, 0, 1,
+        "Waits for the specified page to finish before returning",
+
+        "Waits for the specified page to finish or, if no pageNumber is supplied, waits "
+        "until all pages have finish.  Note that the command returns immediately if "
+        "the utility is paused to avoid the system locking up.\n\n"
+        "This uses very little processing power whilst waiting for the page to finish, "
+        "although as a result will not necessarily return as soon as the page "
+        "specified finishes.  For a faster response to pages finishing use the "
+        "'isFinished' command in a tight while loop within MATLAB, such as\n\n"
+        "\twhile(playrec('isFinished', pageNumber) == 0);end;\n\n"
+        "This will run the processor at full power and will be very wasteful, "
+        "but it does reduce the delay between a page finishing and the MATLAB "
+        "code continuing, which is essential when trying to achieve very low latency.",
+        {
+            {"pageNumber", "the number of the page to wait until finished", true}
+        },
+        {
+            {   "completionState", "1 if either pageNumber is a valid page and has finished "
+                "being processed or pageNumber was not specified and all pages have "
+                "finished being processed.  Note that page validity refers to when the "
+                "function was called and so now the page has finished it may no longer "
+                "be a valid page due to automatic page condensing.\n\n"
+                "-1 if the specified page is invalid or no longer exists.  This includes "
+                "pages that have automatically been condensed, and hence have finished.\n\n"
+                "0 if the stream is currently paused and neither return values of 1 or -1 apply."
+            }
+        }
+    },
+    {   "isFinished",
+        doIsFinished,
+        0, 1, 0, 1,
+        "Indicates if the specified page has finished",
+
+        "Indicates if the specified page is finished or, if no pageNumber is supplied, "
+        "indicates if all pages have finished.",
+        {
+            {"pageNumber", "the number of the page being tested", true}
+        },
+        {
+            {   "completionState", "1 if either pageNumber is a valid page that has finished "
+                "being processed or pageNumber was not specified and all pages have "
+                "finished being processed.\n\n"
+                "-1 if the specified page is invalid or no longer exists.  This includes "
+                "pages that have automatically been condensed, and hence have finished.\n\n"
+                "0 if either pageNumber is a valid page that has not finished being processed "
+                "or pageNumber was not specified and not all pages have finished being processed."
+            }
+        }
+    },
+    {   "getRec",
+        doGetRec,
+        1, 1, 0, 2,
+        "Returns the samples recorded in a page",
+
+        "Returns all the recorded data available for the page identified by pageNumber.  "
+        "If the page specified does not exist, was not specified to record any data, "
+        "or has not yet started to record any data then empty array(s) are returned.  "
+        "If the page is currently being processed, only the recorded data currently "
+        "available is returned.",
+        {
+            {"pageNumber", "used to identifying the page containing the required recorded data"}
+        },
+        {
+            {   "recBuffer", "a MxN matrix where M is the number of samples that have been "
+                "recorded and N is the number of channels of data"
+            },
+            {   "recChanList", "a 1xN vector containing the channel numbers associated with "
+                "each channel in recBuffer.  These channels are in the same order as that "
+                "specified when the page was added."
+            }
+        }
+    },
+    {   "delPage",
+        doDelPage,
+        0, 1, 0, 1,
+        "Deletes the specified page or all pages",
+
+        "Deletes either the specified page or, if no pageNumber is supplied, deletes all "
+        "pages.  Pages can be in any state when they are deleted - the do not have "
+        "to be finished and they can even be deleted part way through being processed "
+        "without any problems (in this case the utility will automatically continue "
+        "with the next page in the page list).",
+        {
+            {"pageNumber", "the number of the page to be deleted.", true}
+        },
+        {
+            {   "completionState", "0 if nothing is deleted (either there are no pages in "
+                "the page list or, if pageNumber was specified, no page with the "
+                "specified number exists), otherwise 1 is returned."
+            }
+        }
+    },
+    {   "getCurrentPosition",
+        doGetCurrentPosition,
+        0, 0, 0, 2,
+        "Returns the currently active page and sample number",
+
+        "Returns the sample and page number for the last sample transferred to the "
+        "soundcard.  Due to sample buffering this will always be slightly further "
+        "through a page than the actual sample being output by the soundcard at that "
+        "point in time.  For pages that record input, the sample number shows how "
+        "many samples have been recorded by the page, up to the recording length limit "
+        "of the page.",
+        {
+            {NULL}
+        },
+        {
+            {   "currentPage", "the current page number, or -1 if either the utility is not "
+                "initialised or no page is currently being processed (there are no pages "
+                "in the list or all pages are finished)."
+            },
+            {   "currentSample", "the current sample number within currentPage, or -1 if "
+                "currentPage is also -1.  This is only accurate to maxFramesPerBuffer samples, "
+                "as returned by 'getFramesPerBuffer'."
+            }
+        }
+    },
+    {   "getLastFinishedPage",
+        doGetLastFinishedPage,
+        0, 0, 0, 1,
+        "Returns the page number of the last completed page",
+
+        "Returns the page number of the last finished page still resident in memory.  Due "
+        "to automatic condensing/removal of pages that are no longer required, such "
+        "as finished pages with only output data, this may not be the most recent page "
+        "to have finished.  Put another way, this returns the page number of the last "
+        "finished page in the pageList returned by 'getPageList'.",
+        {
+            {NULL}
+        },
+        {
+            {"lastPage", "pageNumber of the most recently finished page still resident in memory."}
+        }
+    },
+    {   "getPageList",
+        doGetPageList,
+        0, 0, 0, 1,
+        "Returns an ordered list of all page numbers",
+
+        "Returns a list of all the pages that are resident in memory.  The list is ordered "
+        "chronologically from the earliest to latest addition.\n\n"
+        "Due to automatic condensing/removal of pages that are no longer required, such "
+        "as finished pages with only output data, this will not be a complete list of "
+        "all pages that have ever been used with the utility.",
+        {
+            {NULL}
+        },
+        {
+            {   "pageList", "a 1xN vector containing the chronological list of pages, where N "
+                "is the number of pages resident in memory."
+            }
+        }
+    },
+    {   "getFramesPerBuffer",
+        doGetFramesPerBuffer,
+        0, 0, 0, 3,
+        "Returns internal number of frames per buffer",
+
+        "Returns the number of frames (samples) that are processed by the callback "
+        "internally within the utility (ie the length of each block of samples "
+        "sent by the utility to the soundcard).  This is either the value specified "
+        "when using 'init', or the default value if the optional argument was not "
+        "specified. A value of 0 means the utility is using an optimal, but potentially "
+        "varying, value.",
+        {
+            {NULL}
+        },
+        {
+            {   "suggestedFramesPerBuffer", "the number of frames returned by the utility internally "
+                "during each callback as specified during initialisation, or -1 if the "
+                "utility is not initialised."
+            },
+            {   "minFramesPerBuffer", "the minimum number of frames actually processed by the "
+                "utility internally during a callback, or -1 if the utility is not initialised."
+            },
+            {   "maxFramesPerBuffer", "the maximum number of frames actually proccessed by the "
+                "utility internally during a callback, or -1 if the utility is not initialised."
+            }
+        }
+    },
+    {   "getSampleRate",
+        doGetSampleRate,
+        0, 0, 0, 2,
+        "Returns the current sample rate",
+
+        "Returns the sample rate that was specified when using 'init'.",
+        {
+            {NULL}
+        },
+        {
+            {   "suggestedSampleRate", "the sample rate used during initialisation or -1 if the utility "
+                "is not initialised."
+            },
+            {   "sampleRate", "the current sample rate (obtained from the hardware if possible) "
+                "or -1 if the utility is not initialised."
+            }
+        }
+    },
+    {   "getStreamStartTime",
+        doGetStreamStartTime,
+        0, 0, 0, 1,
+        "Returns the time at which the stream was started",
+
+        "Returns the unix time when the stream was started (number of seconds since the "
+        "standard epoch of 01/01/1970).\n\n"
+        "This is included so that when using the utility to run experiments it is "
+        "possible to determine which tests are conducted as part of the same stream, "
+        "and so identify if restarting the stream (and hence the soundcard in some "
+        "scenarios) may have caused variations in results.",
+        {
+            {NULL}
+        },
+        {
+            {   "streamStartTime", "time at which the stream was started (in seconds since "
+                "the Epoch), or -1 if the utility is not initialised."
+            }
+        }
+    },
+    {   "getPlayDevice",
+        doGetPlayDevice,
+        0, 0, 0, 1,
+        "Returns the current output (play) device",
+
+        "Returns the deviceID (as returned by 'getDevices') for the currently selected "
+        "output device.",
+        {
+            {NULL}
+        },
+        {
+            {   "playDevice", "the deviceID for the output (play) device or -1 if no device "
+                "was specified during initialisation or the utility is not initialised."
+            }
+        }
+    },
+    {   "getPlayMaxChannel",
+        doGetPlayMaxChannel,
+        0, 0, 0, 1,
+        "Returns the current maximum output (play) channel",
+
+        "Returns the number of the maximum output (play) channel that can currently be "
+        "used.  This might be less than the number of channels that the device can "
+        "support if a lower limit was specified during initialisation.",
+        {
+            {NULL}
+        },
+        {
+            {   "playMaxChannel", "the maximum output (play) channel number that can "
+                "currently be used, or -1 if either no play device was specified during "
+                "initialisation or the utility is not initialised."
+            }
+        }
+    },
+    {   "getPlayLatency",
+        doGetPlayLatency,
+        0, 0, 0, 2,
+        "Returns the current output (play) device latency",
+
+        "Returns the output latency for the currently selected output device as well as "
+        "the suggested output latency used during initialisation",
+        {
+            {NULL}
+        },
+        {
+            {   "playSuggestedLatency", "the suggested latency for the output (play) device "
+                "used during initialisation, or -1 if no device was specified during "
+                "initialisation or the utility is not initialised."
+            },
+            {   "playLatency", "the actual latency for the output (play) device or -1 if no device "
+                "was specified during initialisation or the utility is not initialised."
+            }
+        }
+    },
+    {   "getRecDevice",
+        doGetRecDevice,
+        0, 0, 0, 1,
+        "Returns the current input (record) device",
+
+        "Returns the deviceID (as returned by 'getDevices') for the currently selected "
+        "input device.",
+        {
+            {NULL}
+        },
+        {
+            {   "recDevice", "the deviceID for the input (record) device or -1 if no device "
+                "was specified during initialisation or the utility is not initialised."
+            }
+        }
+    },
+    {   "getRecMaxChannel",
+        doGetRecMaxChannel,
+        0, 0, 0, 1,
+        "Returns the current maximum input (record) channel",
+
+        "Returns the number of the maximum input (record) channel that can currently be "
+        "used.  This might be less than the number of channels that the device can "
+        "support if a lower limit was specified during initialisation.",
+        {
+            {NULL}
+        },
+        {
+            {   "recMaxChannel", "the maximum input (record) channel number that can "
+                "currently be used, or -1 if either no record device was specified during "
+                "initialisation or the utility is not initialised."
+            }
+        }
+    },
+    {   "getRecLatency",
+        doGetRecLatency,
+        0, 0, 0, 2,
+        "Returns the current input (record) device latency",
+
+        "Returns the input latency for the currently selected input device as well as "
+        "the suggested input latency used during initialisation",
+        {
+            {NULL}
+        },
+        {
+            {   "recSuggestedLatency", "the suggested latency for the input (record) device "
+                "used during initialisation, or -1 if no device was specified during "
+                "initialisation or the utility is not initialised."
+            },
+            {   "recLatency", "the actual latency for the input (record) device or -1 if no device "
+                "was specified during initialisation or the utility is not initialised."
+            }
+        }
+    },
+    {   "resetSkippedSampleCount",
+        doResetSkippedSampleCount,
+        0, 0, 0, 0,
+        "Resets the skipped samples counter",
+
+        "Resets the counter containing the number of samples that have been 'missed' due to "
+        "no new pages existing in the page list.  See the help on 'getSkippedSampleCount' "
+        "for more information.",
+        {
+            {NULL}
+        },
+        {
+            {NULL}
+        }
+    },
+    {   "getSkippedSampleCount",
+        doGetSkippedSampleCount,
+        0, 0, 0, 1,
+        "Returns the number of skipped samples",
+
+        "Returns the counter containing the number of samples that have been 'missed' due "
+        "to no new pages existing in the page list when the soundcard requires samples "
+        "to be transferred.  The term 'missed' is specifically referring to the case "
+        "where multiple consecutive pages are used to record a continuous audio stream "
+        "(and so input samples are missed), but is the same also for output samples "
+        "because the input and output samples within a page are always processed "
+        "simultaneously.\n\n"
+        "This value is incremented by one for every frame (ie one sample on every "
+        "input/output channel) of data communicated between the utility and soundcard "
+        "that occurred whilst there were no new pages in the page list.  Using this it "
+        "is possible to determine, from within MATLAB, if any glitches in the audio have "
+        "occurred through not adding a new page to the page list before all other pages "
+        "have finished, such as in the case where the code within MATLAB is trying to "
+        "play/record a continuous stream.\n\n"
+        "The counter can be reset using 'resetSkippedSampleCount' so to check for any "
+        "breaks in a continuous stream of pages: add the first page of the stream; reset "
+        "the counter; continue to add pages as required; if getSkippedSampleCount ever "
+        "returns a value greater than zero then there has been a break in the stream.",
+        {
+            {NULL}
+        },
+        {
+            {   "skippedSampleCount", "the number of frames (samples per channel) transferred "
+                "with the soundcard that have occurred when there are no unfinished pages in "
+                "the pageList, or -1 if the utility is not initialised"
+            }
+        }
+    }
+};
+
+/* The number of elements in the above structure array */
+const int _funcLookupSize = sizeof(_funcLookup)/sizeof(FuncLookupStruct);
+
+/* Pointer to the only StreamInfoStruct */
+StreamInfoStruct *_pstreamInfo;
+
+/* The last PortAudio error */
+PaError lastPaError;
+
+/*
+ * FUNCTION:    convDouble(double *oldBuf, int buflen)
+ *
+ * Inputs:      *oldBuf pointer to an array of type double
+ *              buflen  length of oldBuf
+ *
+ * Returns:     pointer to an array of type SAMPLE containing a copy of the
+ *              data in oldBuf, or NULL if memory for the new array could not
+ *              be allocated.
+ *
+ * Description: Makes a complete copy of oldBuf, converting all values to type
+ *              SAMPLE from type double.  The returned array must be freed
+ *              using mxFree once it is no longer required.
+ *
+ * TODO:        change to use memcpy if SAMPLE is of type double
+ */
+SAMPLE *convDouble(double *oldBuf, int buflen)
+{
+    SAMPLE *newBuf = mxCalloc(buflen, sizeof(SAMPLE));
+    SAMPLE *pnew = newBuf;
+    double *pold = oldBuf;
+
+    if(newBuf)
+        while (pnew < &newBuf[buflen])
+            *pnew++ = (SAMPLE)*pold++;
+
+    return newBuf;
+}
+
+/*
+ * FUNCTION:    convFloat(float *oldBuf, int buflen)
+ *
+ * Inputs:      *oldBuf pointer to an array of type float
+ *              buflen  length of oldBuf
+ *
+ * Returns:     pointer to an array of type SAMPLE containing a copy of the
+ *              data in oldBuf, or NULL if memory for the new array could not
+ *              be allocated.
+ *
+ * Description: Makes a complete copy of oldBuf, converting all values to type
+ *              SAMPLE from type float.  The returned array must be freed
+ *              using mxFree once it is no longer required.
+ *
+ * TODO:        change to use memcpy if SAMPLE is of type float
+ */
+SAMPLE *convFloat(float *oldBuf, int buflen)
+{
+    SAMPLE *newBuf = mxCalloc(buflen, sizeof(SAMPLE));
+    SAMPLE *pnew = newBuf;
+    float *pold = oldBuf;
+
+    if(newBuf)
+        while (pnew < &newBuf[buflen])
+            *pnew++ = (SAMPLE)*pold++;
+
+    return newBuf;
+}
+
+/*
+ * FUNCTION:    validateState(int wantedStates, int rejectStates)
+ *
+ * Inputs:      wantedStates    all states that must be set, OR'd (|) together
+ *              rejectStates    all states that must NOT be set, OR'd (|) together
+ *
+ * Returns:     void
+ *
+ * Description: Tests _currentState to ensure that all wantedStates are set and
+ *              all rejectStates are not set.  If any wanted state is unset or
+ *              any unwanted state is set, an error is generated including
+ *              instructions on how to obtain the required state (based on the
+ *              strings in _stateOpts).
+ *
+ * TODO:
+ */
+void validateState(int wantedStates, int rejectStates) {
+    int i;
+    char *buffer;
+
+    for(i=0; i<_stateOptsSize; i++) {
+        if(((wantedStates & _stateOpts[i].num)!=0) && !ISSTATE(_stateOpts[i].num)) {
+            /* This is a wanted state which doesn't exist in _currentState */
+            buffer = mxCalloc( strlen( _stateOpts[i].name) +
+                               + strlen( _stateOpts[i].startString ) + 60, sizeof( char ));
+
+            if( buffer ) {
+                sprintf( buffer, "This command can only be called if in state \"%s\".\n%s",
+                         _stateOpts[i].name, _stateOpts[i].startString);
+
+                mexErrMsgTxt( buffer );
+                /* No need to free memory here as execution will always stop at the error */
+            }
+            else {
+                mexErrMsgTxt( "Error allocating memory in validateState" );
+            }
+        }
+        if(((rejectStates & _stateOpts[i].num)!=0) && ISSTATE(_stateOpts[i].num)) {
+            /* This is a reject state which does exist in _currentState */
+            buffer = mxCalloc( strlen( _stateOpts[i].name) +
+                               + strlen( _stateOpts[i].stopString ) + 60, sizeof( char ));
+
+            if( buffer ) {
+                sprintf( buffer, "This command cannot be called in state \"%s\".\n%s",
+                         _stateOpts[i].name, _stateOpts[i].stopString);
+
+                mexErrMsgTxt( buffer );
+                /* No need to free memory here as execution will always stop at the error */
+            }
+            else {
+                mexErrMsgTxt( "Error allocating memory in validateState" );
+            }
+        }
+    }
+}
+
+/*
+ * FUNCTION:    freeChanBufStructs(ChanBufStruct **ppcbs)
+ *
+ * Inputs:      **ppcbs pointer to pointer to first ChanBufStruct to be freed
+ *
+ * Returns:     void
+ *
+ * Description: Progresses along the ChanBufStruct linked list starting at
+ *              the supplied location, freeing each ChanBufStruct and its
+ *              contained pbuffer (if it exists).  The pointer pointing
+ *              to the start of the linked list (*ppcbs) is set to NULL prior
+ *              to any memory being freed.
+ *
+ * TODO:
+ */
+void freeChanBufStructs(ChanBufStruct **ppcbs) {
+    ChanBufStruct *pcurrentStruct, *pnextStruct;
+
+    if(ppcbs) {
+        pcurrentStruct = *ppcbs;
+
+        *ppcbs = NULL;  /* Clear pointer to first structure before freeing it! */
+
+        while(pcurrentStruct) {
+            if(pcurrentStruct->pbuffer)
+                mxFree(pcurrentStruct->pbuffer);
+
+            pnextStruct = pcurrentStruct->pnextChanBuf;
+            mxFree(pcurrentStruct);
+            pcurrentStruct = pnextStruct;
+        }
+    }
+}
+
+/*
+ * FUNCTION:    freeStreamPageStruct(StreamPageStruct **ppsps)
+ *
+ * Inputs:      **ppsps pointer to pointer to StreamPageStruct to be freed
+ *
+ * Returns:     void
+ *
+ * Description: Removes the StreamPageStruct, pointed to by the supplied
+ *              pointer, from the linked list.  The order of the linked list
+ *              is changed by altering the destination of the supplied pointer
+ *              to skip the StreamPageStruct being freed.  To ensure no
+ *              problems are encountered with the callback accessing the freed
+ *              structure, after the change to the link list order is made the
+ *              function waits for the callback not to be active before freeing
+ *              the memory.  Although by the time the structure is freed the
+ *              callback may be active again, it must have been through a 'not
+ *              active' state after the change to the linked list, and
+ *              therefore can not have any pointers left referring to the
+ *              structure being freed.
+ *
+ * TODO:        Add a timeout on the loop waiting to not be in the callback, or
+ *              change how this operates so there is a way to determine if the
+ *              callback has ended and restarted (which is sufficient to avoid
+ *              any memory sharing problems).
+ *
+ *              Determine the timing advantages of using a loop without 'pause'
+ *              when waiting for a time not in the callback.  This will be more
+ *              processor intensive, but may well enable pages to be deleted
+ *              faster because the point at which the callback ends will be
+ *              detected sooner.
+ */
+
+void freeStreamPageStruct(StreamPageStruct **ppsps) {
+    StreamPageStruct *pcurrentStruct;
+    if(ppsps && *ppsps) {
+        /* Bypass the structure to be freed so it is not in the linked list */
+        pcurrentStruct = *ppsps;
+        *ppsps = pcurrentStruct->pnextStreamPage;
+
+        /* Having completed the pointer switch, ensure not in callback before continuing */
+        while(_pstreamInfo->inCallback)
+            Pa_Sleep(1);
+
+        /* Although the callback may have resumed again by now,
+         * there is no way it can have a pointer to this struct
+         * because since the pointer switch there has been an
+         * occasion when the callback was not active.
+         */
+        freeChanBufStructs(&pcurrentStruct->pfirstPlayChan);
+        freeChanBufStructs(&pcurrentStruct->pfirstRecChan);
+
+        if(pcurrentStruct->pplayChansInUse)
+            mxFree(pcurrentStruct->pplayChansInUse);
+
+        mxFree(pcurrentStruct);
+    }
+}
+
+/*
+ * FUNCTION:    freeStreamInfoStruct(StreamInfoStruct **psis)
+ *
+ * Inputs:      **ppsis pointer to pointer to StreamInfoStruct to be freed
+ *
+ * Returns:     void
+ *
+ * Description: Frees the StreamInfoStruct pointed to indirectly by the
+ *              supplied pointer.  If the stream is active, it is stopped
+ *              by setting stopStream within the structure and then polling
+ *              the stream until it has stopped, which occurs after the next
+ *              time the callback is executed.  This method is used instead
+ *              of calling Pa_StopStream because this was found to not always
+ *              work correctly (the callback would sometimes be called after
+ *              Pa_StreamActive reports the stream to not be active, and so
+ *              would try to use the structure after it had been freed).
+ *              After stopping the stream, it is closed and then all pages
+ *              are freed before finally the StreamInfoStruct is freed and
+ *              the pointer to this structure (*ppsis) is set to NULL.
+ *
+ * TODO:
+ */
+void freeStreamInfoStruct(StreamInfoStruct **ppsis) {
+    unsigned int stopTime = 0;  /* elapsed time waited in msec */
+
+    if(ppsis && *ppsis) {
+        /* Stop and close the stream as necessary */
+        if((*ppsis)->pstream) {
+            /* Try to stop stream nicely so we are certain it has stopped
+             * before freeing memory.  However, if this takes longer than 10s
+             * change to do so using Pa_StopStream.  This may generate problems
+             * with the PortAudio callback trying to access memory that has been
+             * freed, but this is the best option to avoid the function hanging
+             * forever.
+             */
+            if(Pa_IsStreamActive((*ppsis)->pstream) == 1) {
+#ifdef DEBUG
+                mexPrintf("...Stopping PortAudio Stream...");
+#endif
+                while((Pa_IsStreamActive((*ppsis)->pstream) == 1)
+                        && (stopTime < 10000)) {
+
+                    (*ppsis)->stopStream = true;
+                    Pa_Sleep(2);
+                    stopTime += 2;
+                }
+
+                if(stopTime >= 10000) {
+#ifdef DEBUG
+                    mexPrintf("Not stopped after %dms - forcing stop!\n", stopTime);
+#endif
+                    checkPAErr(Pa_StopStream((*ppsis)->pstream));
+                    Pa_Sleep(2000); /* Wait for this to ideally have an effect */
+                }
+                else {
+#ifdef DEBUG
+                    mexPrintf("Stopped after %dms\n", stopTime);
+#endif
+                }
+            }
+#ifdef DEBUG
+            mexPrintf("...Closing PortAudio Stream.\n");
+#endif
+            checkPAErr(Pa_CloseStream((*ppsis)->pstream));
+            (*ppsis)->pstream = NULL;
+
+            abortIfPAErr("freeStreamInfoStruct failed to close stream");
+        }
+
+        /* Remove each page structure one at a time. freeStreamPageStruct
+         * automatically makes (*ppsis)->pfirstStreamPage point at the
+         * next page so this doesn't need to do so
+         */
+        while((*ppsis)->pfirstStreamPage)
+            freeStreamPageStruct(&(*ppsis)->pfirstStreamPage);
+
+        /* Free the structure and clear the pointer */
+        mxFree(*ppsis);
+        *ppsis = NULL;
+
+        CLEARSTATE(FULL_INIT);
+    }
+}
+
+/*
+ * FUNCTION:    newStreamInfoStruct(bool makeMemoryPersistent)
+ *
+ * Inputs:      makeMemoryPersistent    true to make all allocated memory persistent
+ *
+ * Returns:     StreamInfoStruct *  pointer to the new structure, or NULL
+ *                                      if the memory could not be allocated
+ *
+ * Description: Creates a new StreamInfoStruct and sets all contained values
+ *              to their default values.
+ *
+ * TODO:
+ */
+StreamInfoStruct *newStreamInfoStruct(bool makeMemoryPersistent) {
+    StreamInfoStruct *psis = mxCalloc(1, sizeof(StreamInfoStruct));
+
+    if(!psis) {
+        mexWarnMsgTxt("Unable to allocate memory for streamInfoStruct.");
+        return NULL;
+    }
+
+    if(makeMemoryPersistent)
+        mexMakeMemoryPersistent(psis);
+
+    psis->pfirstStreamPage = NULL;
+
+    psis->pstream = NULL;
+
+    psis->streamStartTime = -1;
+
+    psis->suggestedFramesPerBuffer = paFramesPerBufferUnspecified;
+    psis->minFramesPerBuffer = paFramesPerBufferUnspecified;
+    psis->maxFramesPerBuffer = paFramesPerBufferUnspecified;
+
+    psis->recSuggestedLatency = 0;
+    psis->playSuggestedLatency = 0;
+
+    psis->suggestedSampleRate = 44100;
+    psis->streamFlags = paNoFlag;
+
+    psis->isPaused = false;
+
+    psis->stopStream = false;
+
+    psis->inCallback = false;
+
+    psis->skippedSampleCount = 0;
+    psis->resetSkippedSampleCount = false;
+
+    psis->playChanCount = 0;
+    psis->playDeviceID = paNoDevice;
+
+    psis->recChanCount = 0;
+    psis->recDeviceID = paNoDevice;
+
+    return psis;
+}
+
+/*
+ * FUNCTION:    newStreamPageStruct(unsigned int portAudioPlayChanCount,
+ *                      bool makeMemoryPersistent)
+ *
+ * Inputs:      portAudioPlayChanCount  The number of play channels that the
+ *                                      PortAudio stream will be configured
+ *                                      to use (should be same as the
+ *                                      playChanCount in the StreamInfoStruct
+ *                                      to which the page will be added)
+ *              makeMemoryPersistent    true to make all allocated memory persistent
+ *
+ * Returns:     StreamPageStruct *  pointer to the new structure, or NULL
+ *                                      if the memory could not be allocated
+ *
+ * Description: Creates a new StreamPageStruct and sets all contained values
+ *              to their default values, including allocating memory for
+ *              the pplayChansInUse array (and setting all entires to false)
+ *              and giving the page a unique page number.
+ *
+ * TODO:
+ */
+StreamPageStruct *newStreamPageStruct(unsigned int portAudioPlayChanCount, bool makeMemoryPersistent) {
+    static unsigned int nextPageNum = 0;    /* Unique page number genearator */
+    unsigned int i;
+
+    StreamPageStruct *pnewPage = mxCalloc(1, sizeof(StreamPageStruct));
+
+    if(!pnewPage) {
+        mexWarnMsgTxt("Unable to allocate memory for streamPageStruct.");
+        return NULL;
+    }
+
+    if(makeMemoryPersistent)
+        mexMakeMemoryPersistent(pnewPage);
+
+    pnewPage->pageFinished = false;
+    pnewPage->pageUsed = false;
+
+    pnewPage->pagePos = 0;
+    pnewPage->pageLength = 0;
+    pnewPage->pageNum = nextPageNum++;
+
+    pnewPage->playChanCount = portAudioPlayChanCount;
+    pnewPage->pplayChansInUse = mxCalloc(pnewPage->playChanCount, sizeof(bool));
+
+    if(!pnewPage->pplayChansInUse && (pnewPage->playChanCount > 0)) {
+        mexWarnMsgTxt("Unable to allocate memory for chansInUse buffer.");
+        mxFree(pnewPage);
+        return NULL;
+    }
+
+    if(makeMemoryPersistent)
+        mexMakeMemoryPersistent(pnewPage->pplayChansInUse);
+
+    for(i=0; i<pnewPage->playChanCount; i++)
+        pnewPage->pplayChansInUse[i] = false;
+
+    pnewPage->pfirstPlayChan = NULL;
+    pnewPage->pfirstRecChan = NULL;
+    pnewPage->pnextStreamPage = NULL;
+
+    return pnewPage;
+}
+
+/*
+ * FUNCTION:    addStreamPageStruct(StreamInfoStruct *psis,
+ *                      StreamPageStruct *psps)
+ *
+ * Inputs:      *psis   StreamInfoStruct to which the page should be added
+ *              *psps   StreamPageStruct to be added to the linked list
+ *
+ * Returns:     StreamPageStruct *  pointer to the stream page if
+ *                                      successful, or NULL if unsuccesful
+ *
+ * Description: adds the supplied StreamPageStruct to the end of the page
+ *              link list in StreamInfoStruct.  Verifies that the
+ *              playChanCount in both the page and stream are the same before
+ *              the page is added.
+ *
+ * TODO:
+ */
+StreamPageStruct *addStreamPageStruct(StreamInfoStruct *psis, StreamPageStruct *psps) {
+    StreamPageStruct **ppcurrentPage;
+
+    if(!psis || !psps) {
+        return NULL;
+    }
+
+    if(psis->playChanCount != psps->playChanCount) {
+        mexWarnMsgTxt("playChanCounts in stream page is not equal to that of the stream");
+        return NULL;
+    }
+
+    /* Both pointers not NULL */
+    ppcurrentPage = &psis->pfirstStreamPage;
+
+    /* Get a pointer to the stream page pointer which points to NULL
+     * (ie a pointer to the pointer at the end of the linked list)
+     */
+    while(*ppcurrentPage)
+        ppcurrentPage = &(*ppcurrentPage)->pnextStreamPage;
+
+    /* Add the stream page */
+    *ppcurrentPage = psps;
+
+    return psps;
+}
+
+/*
+ * FUNCTION:    playrecCallback(const void *inputBuffer,
+ *                              void *outputBuffer,
+ *                              unsigned long frameCount,
+ *                              const PaStreamCallbackTimeInfo *timeInfo,
+ *                              PaStreamCallbackFlags statusFlags,
+ *                              void *userData )
+ *
+ * Inputs:      inputBuffer     array of interleaved input samples
+ *              outputBuffer    array of interleaved output samples
+ *              frameCount      number of sample frames to be processed
+ *              timeInfo        struct with time in seconds
+ *              statusFlags     flags indicating whether input and/or output
+ *                              buffers have been inserted or will be dropped
+ *                              to overcome underflow or overflow conditions
+ *              userData        pointer to the StreamInfoStruct for this
+ *                              stream, as passed to Pa_OpenStream()
+ *
+ * Returns:     paComplete or paAbort to stop the stream if either userData is NULL
+ *              or stopStream has been set, or paContinue (0) for the stream to
+ *              continue running
+ *
+ * Description: Implementation of PortAudioCallback called by PortAudio to
+ *              process recorded data and supply more output samples.  See
+ *              portaudio.h for more information on the supplied parameters.
+ *
+ *              Iterates through the page linked list to find the first
+ *              unfinished page. If no unfinished pages exist, all input
+ *              samples are ignored and all output samples are set to zero.
+ *              Otherwise, the output samples are set according to the data
+ *              contained in the page, or set to zero if either the channel is
+ *              not in use, or there are no more samples remaining for the
+ *              channel.  Recorded data is stored as required by the page.
+ *              The page linked list is descended until all samples within both
+ *              buffers have been used as required, even if the data is spread
+ *              throughout multiple consecutive pages.
+ *
+ *              NOTE: None of the PortAudio functions may be called from
+ *              within this callback function except for Pa_GetCPULoad().
+ *
+ * TODO:
+ */
+static int playrecCallback(const void *inputBuffer, void *outputBuffer,
+                           unsigned long frameCount,
+                           const PaStreamCallbackTimeInfo *timeInfo,
+                           PaStreamCallbackFlags statusFlags, void *userData )
+{
+    /* Cast to stream info structure */
+    StreamInfoStruct *psis = (StreamInfoStruct*)userData;
+
+    /* The current page within which we are working */
+    StreamPageStruct *pcurrentsps = NULL;
+
+    unsigned int samplesProcessed = 0;
+    unsigned int samplesFromPage = 0;
+
+    SAMPLE *pout = (SAMPLE *)outputBuffer;
+    SAMPLE *pin = (SAMPLE *)inputBuffer;
+
+    SAMPLE *ps;     /* A generic SAMPLE pointer used for pointer
+                     * arithmetic in multiple occasions
+                     */
+
+    bool isPaused;  /* Used to get value of psis->isPaused so this is only tested
+                     * once at the start of the callback, avoiding problems with
+                     * it changing during the callback!
+                     */
+
+    unsigned int chan;  /* Channel number being processed */
+
+    unsigned int tmpBufPos; /* used as a buffer location index, because
+                             * there is no longer one per buffer
+                             */
+    ChanBufStruct *pcbs;
+
+    /* Check valid pointer has been supplied, otherwise stop the stream */
+    if(!psis) {
+        return paAbort;
+    }
+
+    /* Signal we're in callback - this does not have to be the first
+     * statement within the callback provided it is set prior to any
+     * manipulation of the stream pages.
+     */
+    psis->inCallback = true;
+
+    /* Find the first unfinished page */
+    pcurrentsps = psis->pfirstStreamPage;
+    while(pcurrentsps && pcurrentsps->pageFinished)
+        pcurrentsps = pcurrentsps->pnextStreamPage;
+
+    /* Only process samples from a page if not paused.
+     * Copy pause to avoid problems with it changing during the callback!
+     */
+    isPaused = psis->isPaused;
+
+    if(!isPaused) {
+
+        /* Loop through as many pages as required to process frameCount samples
+         * break is used to exit the loop once enough samples have been processed
+         */
+        while(pcurrentsps) {
+
+            /* None of the pages looked at by this code should have pageFinished
+             * set, although check it just to be on the safe side!
+             */
+            if(!pcurrentsps->pageFinished) {
+
+                pcurrentsps->pageUsed = true;
+
+                /* Determine how many samples to use from this page */
+                samplesFromPage = min(frameCount - samplesProcessed, pcurrentsps->pageLength - pcurrentsps->pagePos);
+
+                /* Blank all channels that are not in use by this page (that are valid channels!)
+                 * This might turn out to be quicker just blanking all of the buffer
+                 */
+                if(pout && pcurrentsps->pplayChansInUse) {
+                    for(chan = 0; (chan < pcurrentsps->playChanCount) && (chan < psis->playChanCount); chan++) {
+                        if(!pcurrentsps->pplayChansInUse[chan]) {
+
+                            /* psis->playChanCount must be greater than 0 to have
+                             * reached this point, so no need to worry about this
+                             * for loop never ending
+                             */
+                            for(ps = (pout + samplesProcessed * psis->playChanCount + chan);
+                                    ps < (pout + (samplesProcessed + samplesFromPage) * psis->playChanCount);
+                                    ps += psis->playChanCount) {
+
+                                *ps = 0;
+                            }
+                        }
+                    }
+                }
+
+                /* Step through all channels that may contain data */
+                if(pout && (psis->playChanCount > 0)) {
+                    for(pcbs = pcurrentsps->pfirstPlayChan; pcbs; pcbs = pcbs->pnextChanBuf) {
+                        tmpBufPos = pcurrentsps->pagePos;
+
+                        if(pcbs->pbuffer
+                                && (tmpBufPos < pcbs->bufLen)
+                                && (pcbs->channel >= 0)
+                                && (pcbs->channel < psis->playChanCount)) {
+
+                            /* This chanBuf contains a valid buffer and has data left to use!
+                             * Step through the frame copying data.
+                             */
+
+                            /* psis->playChanCount must be greater than 0 to have
+                             * reached this point, so no need to worry about this
+                             * for loop never ending
+                             */
+
+                            for(ps = (pout + samplesProcessed * psis->playChanCount + pcbs->channel);
+                                    ps < (pout + (samplesProcessed + samplesFromPage) * psis->playChanCount);
+                                    ps += psis->playChanCount) {
+
+                                if(tmpBufPos < pcbs->bufLen) {
+                                    *ps = *(pcbs->pbuffer + tmpBufPos);
+                                    tmpBufPos++;
+                                }
+                                else {
+                                    *ps = 0;
+                                }
+                            }
+                        }
+                        else {
+                            /* There is nothing in this channels buffer to be used,
+                             * so zero the output channel
+                             */
+
+                            /* psis->playChanCount must be greater than 0 to have
+                             * reached this point, so no need to worry about this
+                             * for loop never ending
+                             */
+                            for(ps = (pout + samplesProcessed * psis->playChanCount + pcbs->channel);
+                                    ps < (pout + (samplesProcessed + samplesFromPage) * psis->playChanCount);
+                                    ps += psis->playChanCount) {
+
+                                *ps = 0;
+                            }
+                        }
+                    }
+                }
+
+                /* Record all channels as required */
+                if(pin) {
+                    for(pcbs = pcurrentsps->pfirstRecChan; pcbs; pcbs = pcbs->pnextChanBuf) {
+                        tmpBufPos = pcurrentsps->pagePos;
+
+                        if(pcbs->pbuffer
+                                && (tmpBufPos < pcbs->bufLen)
+                                && (pcbs->channel >= 0)
+                                && (pcbs->channel < psis->recChanCount)) {
+
+                            /* This chanBuf contains a valid buffer and has space left to use!
+                             * Channels without a valid buffer, or that have reached the end of
+                             * their buffer, should not need anything doing to them
+                             */
+
+                            /* Step through each frame copying data */
+
+                            for(ps = (pin + samplesProcessed * psis->recChanCount + pcbs->channel);
+                                    (ps < (pin + (samplesProcessed + samplesFromPage) * psis->recChanCount)) && (tmpBufPos < pcbs->bufLen);
+                                    ps += psis->recChanCount)   {
+
+                                *(pcbs->pbuffer + tmpBufPos) = *ps;
+                                tmpBufPos++;
+                            }
+                        }
+                    }
+                }
+
+                /* Either the end of the page, or the end of the frame should have been reached
+                 * Both might also have occurred simultaneously!
+                 */
+                samplesProcessed += samplesFromPage;
+                pcurrentsps->pagePos += samplesFromPage;
+
+                if(pcurrentsps->pagePos >= pcurrentsps->pageLength) {
+                    /* Page is finished */
+                    pcurrentsps->pageFinished = true;
+                }
+
+                if(samplesProcessed >= frameCount) {
+                    /* buffer is finished */
+                    break;
+                }
+
+            } /* if(!pcurrentsps->pageFinished) */
+
+            /* buffer not finished - go to the next page */
+            pcurrentsps = pcurrentsps->pnextStreamPage;
+
+        } /* while(pcurrentsps) */
+
+    } /* if(!isPaused) */
+
+
+    /* Either the buffer is finished, or we've run out of pages, or we're paused */
+    if(pout && (samplesProcessed < frameCount)) {
+        /* Run out of pages, or paused (doesn't matter which) */
+
+        /* Zero all remaining output samples */
+        for(chan = 0; chan < psis->playChanCount; chan++) {
+            /* psis->playChanCount must be greater than 0 to have
+             * reached this point, so no need to worry about this
+             * for loop never ending
+             */
+
+            for(ps = (pout + samplesProcessed * psis->playChanCount + chan);
+                    ps < (pout + frameCount * psis->playChanCount);
+                    ps += psis->playChanCount) {
+
+                *ps = 0;
+            }
+        }
+    }
+
+    if(psis->resetSkippedSampleCount) {
+        /* Clear the value of skippedSampleCount BEFORE
+         * clearing resetSkippedSampleCount to ensure there is no
+         * chance of reading an incorrect value.
+         */
+        psis->skippedSampleCount = 0;
+        psis->resetSkippedSampleCount = false;
+    }
+
+    if(!isPaused && (samplesProcessed < frameCount)) {
+        /* Not paused, so increment skippedSampleCount */
+        psis->skippedSampleCount += frameCount - samplesProcessed;
+    }
+
+    if(!isPaused && (statusFlags & (paOutputUnderflow | paOutputOverflow
+                                    | paInputUnderflow | paInputOverflow))) {
+        /* Not paused, and we've not processed/provided data fast
+         * enough, or the input and output buffers became out of sync.
+         * Either way, increment skippedSampleCount so Matlab can tell
+         * that something's gone wrong.
+         */
+        psis->skippedSampleCount++;
+    }
+
+    if((psis->minFramesPerBuffer == paFramesPerBufferUnspecified)
+            || (frameCount < psis->minFramesPerBuffer)) {
+
+        psis->minFramesPerBuffer = frameCount;
+    }
+
+    if((psis->maxFramesPerBuffer == paFramesPerBufferUnspecified)
+            || (frameCount > psis->maxFramesPerBuffer)) {
+
+        psis->maxFramesPerBuffer = frameCount;
+    }
+
+    /* Signal we're leaving the callback - this does not have to be the last
+     * statement within the callback provided no manipulation of the stream
+     * pages occurs after it is cleared.
+     */
+    psis->inCallback = false;
+
+    return psis->stopStream ? paComplete : paContinue;
+}
+
+/*
+ * FUNCTION:    mexFunctionCalled(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ * Returns:     true, or aborts with an error if initialisation of PortAudio
+ *              failed.
+ *
+ * Description: initialises PortAudio, if not already initialised, and
+ *              registers exitFunc as the mex exit function if this has not
+ *              already been done.  Calls condensePages() to minimise memory
+ *              usage as frequently as possible.  See mex_dll_core.c for
+ *              information on when this function is called, including the
+ *              possible return values.
+ *
+ * TODO:        Add seperate function accessible from MATLAB to disable
+ *              automatic page condensing if optimum speed is more important
+ *              than minimizing memory usage
+ */
+bool mexFunctionCalled(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    /* Reset error on each function call */
+    lastPaError = paNoError;
+
+    if(_currentState==0) {
+        /* initialise PortAudio and register exit function */
+#ifdef DEBUG
+        mexPrintf("First call to function...\n");
+        mexPrintf("...initialising PortAudio.\n");
+#endif
+        /* In this case a little more than checkPAErr is required,
+         * becase the terminate must occur before displaying the
+         * error message
+         */
+        if(checkPAErr(Pa_Initialize())!=paNoError) {
+            checkPAErr(Pa_Terminate());
+            abortIfPAErr("Failed to initialise PortAudio...Terminating");
+        }
+
+#ifdef DEBUG
+        mexPrintf("...Registering exit function.\n");
+#endif
+        mexAtExit(exitFunc);
+        SETSTATE(BASIC_INIT);
+    }
+
+    condensePages();
+
+    /* Always continue processing if we get this far */
+    return true;
+}
+
+/*
+ * FUNCTION:    condensePages(void)
+ *
+ * Inputs:      void
+ *
+ * Returns:     void
+ *
+ * Description: Iterates through all finished pages freeing as much memory
+ *              as possible without deleting any recorded data.  For pages
+ *              only containing output data the page is completely removed
+ *              whereas pages also containing recorded data have their output
+ *              data and pplayChansInUse freed leaving the minimum amount of
+ *              memory in use.
+ *
+ * TODO:        Change to take a pointer to the StreamInfoStruct to be
+ *              condensed, thus making the function compatible if the utility
+ *              is adapted to use more than one stream simultaneously.
+ */
+void condensePages(void) {
+    StreamPageStruct **ppsps;
+
+    if(_pstreamInfo) {
+        ppsps = &_pstreamInfo->pfirstStreamPage;
+
+        while(*ppsps) {
+            /* Move through all stream pages, clearing the play buffers
+             * if the stream is finished, to conserve space
+             */
+            if((*ppsps)->pageFinished) {
+
+                /* if there are no record buffers, completely remove the page */
+                if(!(*ppsps)->pfirstRecChan) {
+                    freeStreamPageStruct(ppsps);
+                    /* Do not select the next page, as this has happened
+                     * automatically by supplying ppsps to
+                     * freeStreamPageStruct
+                     */
+                }
+                else {
+                    /* This conditional if is not required, as it is also
+                     * checked within freeChanBufStructs.  However, this
+                     * will reduce the number of function calls that just
+                     * return immediately!
+                     */
+                    if((*ppsps)->pfirstPlayChan)
+                        freeChanBufStructs(&(*ppsps)->pfirstPlayChan);
+
+                    if((*ppsps)->pplayChansInUse) {
+                        mxFree((*ppsps)->pplayChansInUse);
+                        (*ppsps)->pplayChansInUse = NULL;
+                        (*ppsps)->playChanCount = 0;
+                    }
+                    ppsps = &(*ppsps)->pnextStreamPage;
+                }
+            }
+            else {
+                break;  /* Once the first unFinished page has been reached
+                         * all the subsequent pages will also be unFinished.
+                         */
+            }
+        }
+    }
+}
+
+/*
+ * FUNCTION:    exitFunc(void)
+ *
+ * Inputs:      void
+ *
+ * Returns:     void
+ *
+ * Description: Function registered using mexAtExit and called whenever the
+ *              MEX-function is cleared or MATLAB is terminated.  Frees all
+ *              allocated memory and terminates PortAudio if required.
+ *
+ * TODO:
+ */
+void exitFunc(void) {
+#ifdef DEBUG
+    mexPrintf("Running playrec exitFunc...\n");
+#endif
+
+    /* Let freeStreamInfoStruct handle the closing of PortAudio */
+    freeStreamInfoStruct(&_pstreamInfo);
+
+    if(ISSTATE(BASIC_INIT)) {
+#ifdef DEBUG
+        mexPrintf("...Terminating PortAudio.\n");
+#endif
+        checkPAErr(Pa_Terminate());
+    }
+
+    CLEARSTATE(BASIC_INIT);
+
+    abortIfPAErr("PortAudio error during exitFunc");
+}
+
+/*
+ * FUNCTION:    checkPAErr(PaError err)
+ *
+ * Inputs:      err             the PaError returned by any PortAudio function
+ *
+ * Returns:     paError         the err value supplied
+ *
+ * Description: Verifies if err is equal to paNoError.  If not, the PortAudio
+ *              error number is stored in lastPaError so it can be recalled
+ *              later.
+ *
+ * TODO:
+ */
+PaError checkPAErr(PaError err) {
+    if( err != paNoError ) {
+        lastPaError = err;
+    }
+
+    return err;
+}
+
+/*
+ * FUNCTION:    abortIfPAErr(const char* msg)
+ *
+ * Inputs:      msg             the message to add to the start of the error
+ *
+ * Returns:     void
+ *
+ * Description: Verifies if lastPaError is equal to paNoError.  If not, then
+ *              an error message is displayed and the mex function aborts.
+ *
+ * TODO:
+ */
+void abortIfPAErr(const char* msg) {
+    char *buffer;
+
+    if( lastPaError != paNoError ) {
+        buffer = mxCalloc( strlen( Pa_GetErrorText( lastPaError ))
+                           + strlen( msg ) + 40, sizeof( char ));
+
+        if( buffer ) {
+            sprintf( buffer, "%s \n{PortAudio Error [%d]: %s}",
+                     msg, lastPaError, Pa_GetErrorText( lastPaError ));
+
+            mexErrMsgTxt( buffer );
+            /* No need to free memory here as execution will always stop at the error */
+        }
+        else {
+            mexErrMsgTxt( "Error allocating memory in abortPAErr" );
+        }
+    }
+}
+
+/*
+ * FUNCTION:    channelListToChanBufStructs(const mxArray *pmxChanArray,
+ *                      ChanBufStruct **ppfirstcbs, unsigned int minChanNum,
+ *                      unsigned int maxChanNum, bool makeMemoryPersistent)
+ *
+ * Inputs:      pmxChanArray    pointer to mxArray containing channel list
+ *                              as a row vector (chan numbers are base 1)
+ *                              The order of channel numbers is preserved in
+ *                              the linked list, and no channel number can be
+ *                              duplicated (this is checked).
+ *              ppfirstcbs      pointer to the pointer which should be set
+ *                              to point at the first ChanBufStruct
+ *              minChanNum      the minimum channel number to be accepted
+ *                              (base 0, NOT base 1)
+ *              maxChanNum      the maximum channel number to be accepted
+ *                              (base 0, NOT base 1)
+ *              makeMemoryPersistent    true to make all allocated memory persistent
+ *
+ * Returns:     true if the channel list is valid and all memory has been
+ *              allocated successfully, otherwise a description of the error
+ *              is printed to the MATLAB command window and false is returned.
+ *
+ * Description: Allocates and arranges all of the memory required for a
+ *              ChanBufStruct linked list based on the list of channels
+ *              provided in the mxArray pointed to by pmxChanArray.
+ *              Note that this array specifies channels starting at number 1
+ *              whilst the minChanNum and maxChanNum are based on the channel
+ *              numbers starting at zero.  This is also how the channel numbers
+ *              are stored within the ChanBufStruct, and the pmxChanArray
+ *              only uses values starting at 1 to make it the utility user friendly
+ *
+ *              Rather than returning a pointer to the start of the linked list,
+ *              this directly updates the pointer which will be used to point at
+ *              the start of the list.
+ *
+ *              Note that if ppfirstcbs points to the start of a linked list before
+ *              calling this function, the linked list is not freed and instead
+ *              this pointer to the start of it is just overwritten!
+ *
+ * TODO:        Change implementation to return the pointer to the start of the
+ *              linked list, or NULL if there was an error.  Therefore removing
+ *              the need for ppfirstcbs to be supplied, which can be confusing.
+ */
+
+bool channelListToChanBufStructs(const mxArray *pmxChanArray, ChanBufStruct **ppfirstcbs,
+                                 unsigned int minChanNum, unsigned int maxChanNum,
+                                 bool makeMemoryPersistent) {
+    unsigned int chanUseCount = 0;
+    double *pchani, *pchanj, *pchanList;
+    ChanBufStruct **ppcbs;
+
+    if(!pmxChanArray || !ppfirstcbs) {
+        mexWarnMsgTxt("Invalid pointer in channelListToChanBufStructs.");
+        return false;
+    }
+
+    if(!mxIsNumeric(pmxChanArray)) {
+        mexWarnMsgTxt("Channel array must be numeric.");
+        return false;
+    }
+    if(mxIsComplex(pmxChanArray)) {
+        mexWarnMsgTxt("Channel array must not be complex.");
+        return false;
+    }
+    if(mxGetM(pmxChanArray)!=1) {
+        mexWarnMsgTxt("Channel array must have 1 row.");
+        return false;
+    }
+
+    chanUseCount = mxGetN(pmxChanArray);
+    pchanList = mxGetPr(pmxChanArray);
+
+    /* Check all channel values are unique */
+
+    for(pchani = pchanList; pchani < &pchanList[chanUseCount]; pchani++) {
+        if(*pchani != (int)*pchani) {
+            mexWarnMsgTxt("Channel values must all be integers.");
+            return false;
+        }
+
+        if(*pchani <= minChanNum || *pchani > (maxChanNum + 1)) {
+            /* mexPrintf("Channel numbers must all be between %d and %d.\n", minChanNum + 1, maxChanNum + 1); */
+            mexWarnMsgTxt("Channel numbers out of range.");
+            return false;
+        }
+
+        for(pchanj = pchanList; pchanj < &pchanList[chanUseCount]; pchanj++) {
+            if((pchani != pchanj) && (*pchani == *pchanj)) {
+                /* Pointers are different, but point to the same value */
+                /* mexPrintf("Each channel may only be specified once in a list: value %d duplicated.\n", (int)*pchani); */
+                mexWarnMsgTxt("Channel number duplicated within channel list.");
+                return false;
+            }
+        }
+    }
+
+    /* Generate the linked list, iterating through the list of channels */
+    ppcbs = ppfirstcbs;
+
+    for(pchani = pchanList; pchani < &pchanList[chanUseCount]; pchani++) {
+        *ppcbs = mxCalloc(1, sizeof(ChanBufStruct));
+        if(!*ppcbs) {
+            mexWarnMsgTxt("Unable to allocate memory for channel buffer structure.");
+            freeChanBufStructs(ppfirstcbs);
+            return false;
+        }
+
+        if(makeMemoryPersistent)
+            mexMakeMemoryPersistent(*ppcbs);
+
+        (*ppcbs)->pbuffer = NULL;
+        (*ppcbs)->bufLen = 0;
+        (*ppcbs)->channel = (int)*pchani - 1;   /* Storing channel numbers base 0, whereas they are supplied by the user base 1; */
+        (*ppcbs)->pnextChanBuf = NULL;
+
+        ppcbs = &(*ppcbs)->pnextChanBuf;
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    addPlayrecPage(mxArray **ppmxPageNum, const mxArray *pplayData,
+ *                  const mxArray *pplayChans, const mxArray *precDataLength,
+ *                  const mxArray *precChans)
+ *
+ * Inputs:      **ppmxPageNum   pointer to a pointer which will be changed to
+ *                              point at an mxArray containing the page number
+ *                              of the page added.
+ *              *pplayData      pointer to an MxN mxArray containing the play
+ *                              data for the page, or NULL for no output. M is
+ *                              the number of samples and N is the number of
+ *                              channels of data.
+ *              pplayChans      pointer to a 1xN mxArray containing the order
+ *                              of channels in pplayData or NULL for no output
+ *              *precDataLength pointer to a scalar mxArray containing the
+ *                              number of samples to record, or -1 to use the
+ *                              same length as pplayData (only valid if
+ *                              pplayData is not NULL).
+ *              *precChans      pointer to a 1xP mxArray containing the order
+ *                              of channels to record where P is the total
+ *                              number of channels to record (this is the order
+ *                              the channels are retured).
+ *
+ * Returns:     true if page added successfully, false if an error occurred
+ *              (returned after displaying an error message), or aborts with
+ *              an error if not in full initialisation state.
+ *              ppmsPageNum is only valid if true is returned.
+ *
+ * Description: Adds a new page at the end of the current page list.  The new
+ *              page contains the play data (if specified) and is configured
+ *              to record the specified channels.  Completes all validation
+ *              checks and completely creates the page before adding it to the
+ *              page linked list.  In doing so, the output and recording will
+ *              always remain synchronised nomatter if there are or aren't
+ *              other pages in the list.
+ *
+ *              All memory allocated and referenced from within the created
+ *              page is made persistent.  If false is returned then all this
+ *              memory is freed up before returning and all references to
+ *              the page are removed.  However, if true is returned (page
+ *              created successfully) then appropriate measures to free
+ *              the page must be made once the page is nolonger required.
+ *
+ * TODO:
+ */
+bool addPlayrecPage(mxArray **ppmxPageNum, const mxArray *pplayData,
+                    const mxArray *pplayChans, const mxArray *precDataLength,
+                    const mxArray *precChans) {
+    StreamPageStruct *psps;
+    ChanBufStruct *pcbs;
+    unsigned int dataChanCount, playSamplePerChan=0, recSamplePerChan;
+    unsigned int i, chansCopied;
+
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    /* Should not get here if _pstreamInfo is null */
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet _pstreamInfo is NULL.");
+    }
+
+    if((pplayData && !pplayChans) || (!pplayData && pplayChans)) {
+        mexWarnMsgTxt("Either both or neither of playData and playChans should be NULL.");
+        return false;
+    }
+
+    if((precDataLength && !precChans) || (!precDataLength && precChans)) {
+        mexWarnMsgTxt("Either both or neither of recDataLength and recChans should be NULL.");
+        return false;
+    }
+
+    if(pplayData && (_pstreamInfo->playDeviceID==paNoDevice)) {
+        mexWarnMsgTxt("Unable to play when no play device has been selected.");
+        return false;
+    }
+
+    if(precDataLength && (_pstreamInfo->recDeviceID==paNoDevice)) {
+        mexWarnMsgTxt("Unable to record when no record device has been selected.");
+        return false;
+    }
+
+    psps = newStreamPageStruct(_pstreamInfo->playChanCount, true);
+
+    if(!psps) {
+        mexWarnMsgTxt("Unable to create new page.");
+        return false;
+    }
+
+    if(pplayData && pplayChans) {
+        if(!mxIsNumeric(pplayData) || mxIsComplex(pplayData)
+                || (!mxIsSingle(pplayData) && !mxIsDouble(pplayData))) {
+
+            mexWarnMsgTxt("Audio buffer must be non-complex numbers of type single or double.");
+            freeStreamPageStruct(&psps);
+            return false;
+        }
+
+        /* Create a linked list of all the channels required, checking they're all
+         * within the valid range of channel numbers
+         */
+        if(!channelListToChanBufStructs(pplayChans, &psps->pfirstPlayChan, 0, _pstreamInfo->playChanCount - 1, true)) {
+            freeStreamPageStruct(&psps);
+            return false;
+        }
+
+        /* Clear chansInUse array */
+        if(psps->pplayChansInUse) {
+            for(i = 0; i < psps->playChanCount; i++)
+                psps->pplayChansInUse[i] = false;
+        }
+        else {
+            mexWarnMsgTxt("chansInUse buffer has not be created successfully.");
+            freeStreamPageStruct(&psps);
+            return false;
+        }
+
+        /* Copy across all data */
+        dataChanCount = mxGetN(pplayData);
+        playSamplePerChan = mxGetM(pplayData);
+
+        psps->pageLength = max(psps->pageLength, playSamplePerChan);
+
+        pcbs = psps->pfirstPlayChan;
+        chansCopied = 0;
+
+        if(playSamplePerChan > 0) {
+            while(pcbs && (chansCopied < dataChanCount)) {
+                /* Float32 input data */
+                if(mxIsSingle(pplayData))
+                    pcbs->pbuffer = convFloat((float *)mxGetData(pplayData) + chansCopied * playSamplePerChan, playSamplePerChan);
+                else if(mxIsDouble(pplayData)) /* Double */
+                    pcbs->pbuffer = convDouble((double *)mxGetData(pplayData) + chansCopied * playSamplePerChan, playSamplePerChan);
+                else {
+                    /* This should never be called as the if statement above should
+                     * catch this condition
+                     */
+                    mexWarnMsgTxt("Audio buffer of incorrect data type.");
+                    freeStreamPageStruct(&psps);
+                    return false;
+                }
+
+                if (!pcbs->pbuffer) {
+                    mexWarnMsgTxt("Audio buffer conversion returned NULL.");
+                    freeStreamPageStruct(&psps);
+                    return false;
+                }
+
+                /* This if statement should not be required (included for safety) */
+                if((pcbs->channel >= 0) && (pcbs->channel < psps->playChanCount))
+                    psps->pplayChansInUse[pcbs->channel] = true;
+
+                chansCopied++;
+
+                mexMakeMemoryPersistent(pcbs->pbuffer);
+                pcbs->bufLen = playSamplePerChan;
+                pcbs = pcbs->pnextChanBuf;
+            }
+        }
+        /* Check to see if either there are more channels than required, or too few channels */
+        if((chansCopied < dataChanCount) && (playSamplePerChan > 0))
+            mexWarnMsgTxt("More channels of data supplied than channels in channel list; ignoring remaining channels.");
+        else if(pcbs)
+            mexWarnMsgTxt("Fewer channels of data supplied than channels in channel list; \"Zeroing\" all other channels.");
+    }
+
+    if(precDataLength && precChans) {
+        if(!mxIsNumeric(precDataLength) || mxIsComplex(precDataLength)
+                || (mxGetN(precDataLength)!=1) || (mxGetM(precDataLength)!=1)
+                || (mxGetScalar(precDataLength) != (int)mxGetScalar(precDataLength))) {
+
+            mexWarnMsgTxt("Number of record samples must be a non-complex integer.");
+            return false;
+        }
+        else if(mxGetScalar(precDataLength) < 0) {
+            if(_pstreamInfo->playDeviceID == paNoDevice || !pplayData) {
+                mexWarnMsgTxt("Cannot use play sample count for record sample count when no play buffer in page.");
+                freeStreamPageStruct(&psps);
+                return false;
+            }
+            recSamplePerChan = playSamplePerChan;
+        }
+        else {
+            recSamplePerChan = (int)mxGetScalar(precDataLength);
+        }
+
+        if(recSamplePerChan > 0) {
+            /* Only process recording if there are going ot be some samples recorded!
+             * Create a linked list of all the channels required, checking they're all
+             * within the valid range of channel numbers
+             */
+            if(!channelListToChanBufStructs(precChans, &psps->pfirstRecChan, 0, _pstreamInfo->recChanCount - 1, true)) {
+                freeStreamPageStruct(&psps);
+                return false;
+            }
+
+            pcbs = psps->pfirstRecChan;
+            psps->pageLength = max(psps->pageLength, recSamplePerChan);
+
+            while(pcbs) {
+                pcbs->pbuffer = mxCalloc(recSamplePerChan, sizeof(SAMPLE));
+
+                if (!pcbs->pbuffer) {
+                    mexWarnMsgTxt("Unable to create audio record buffer.");
+                    freeStreamPageStruct(&psps);
+                    return false;
+                }
+
+                mexMakeMemoryPersistent(pcbs->pbuffer);
+                pcbs->bufLen = recSamplePerChan;
+                pcbs = pcbs->pnextChanBuf;
+            }
+        }
+    }
+
+    /* This should be used here to avoid problems with clearing the
+     * zero length page and then accessing this!
+     */
+    *ppmxPageNum = mxCreateDoubleScalar(psps->pageNum);
+
+    /* Reaching here means the page has been created successfully, so add
+     * to end of page list provided it is worth adding!
+     */
+    if(psps->pageLength == 0) {
+        mexWarnMsgTxt("Page added has zero length.");
+        freeStreamPageStruct(&psps);
+        /* Still return the pageNumber without an error as this is not fatal */
+    }
+    else if(!addStreamPageStruct(_pstreamInfo, psps)) {
+        mexWarnMsgTxt("Unable to add page to stream");
+        freeStreamPageStruct(&psps);
+        mxDestroyArray(*ppmxPageNum);
+        *ppmxPageNum = NULL;
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doInit(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *          Requires between 3 and 8 right-hand side arguments (ie nrhs
+ *          between 3 and 8, and prhs with at least this many elements).
+ *          These elements store, in order, sampleRate, playDevice,
+ *          recDevice, playMaxChannel, recMaxChannel, framesPerBuffer,
+ *          playSuggestedLatency, recSuggestedLatency.
+ *          Where:
+ *  sampleRate
+ *      the sample rate at which both devices will operate
+ *  playDevice
+ *      the ID of the device to be used for output (as returned by
+ *      'getDevices'), or -1 for no device (ie output not required)
+ *  recDevice
+ *      the ID of the device to be used for recording (as returned by
+ *      'getDevices'), or -1 for no device (ie recording not required)
+ *  playMaxChannel {optional}
+ *      a number greater than or equal to the maximum channel that will be used
+ *      for output.  This must be less than or equal to the maximum number of
+ *      output channels that the device supports.  Value ignored if playDevice
+ *      is -1.
+ *  recMaxChannel {optional}
+ *      a number greater than or equal to the maximum channel that will be used
+ *      for recording.  This must be less than or equal to the maximum number
+ *      of input channels that the device supports.  Value ignored if recDevice
+ *      is -1.
+ * framesPerBuffer {optional}
+ *      the number of samples to be processed in each callback within the
+ *      utility (ie the length of each block of samples sent by the utility to
+ *      the soundcard).  The lower the value specified the shorter the latency
+ *      but also the greater the likelihood of glitches within the audio.
+ *      A value of 0 lets the utility use an optimal, and potentially different,
+ *      value in each callback.
+ * playSuggestedLatency {optional}
+ *      the play latency, in seconds, the device should try to use where possible.
+ *      Defaults to the default low output latency for the device if not specified.
+ * recSuggestedLatency {optional}
+ *      the record latency, in seconds, the device should try to use where possible.
+ *      Defaults to the default low input latency for the device if not specified.
+ *
+ * Returns:     true if stream opened succesfully or there is no stream to open
+ *              (ie both playDevice and recDevice are -1).  Otherwise false after
+ *              an appropriate error message has been displayed in the MATLAB
+ *              command window.
+ *
+ * Description: Initialises the PortAudio stream based on the arguments supplied.
+ *              If the maxChannel values are not specified, the maximum channel
+ *              number supported by the relevant device is determined and used.  If
+ *              the framesPerBuffer value is not specified, the default, as set in
+ *              newStreamInfoStruct() is used.  All other initialisation values used
+ *              are also set in this other function.
+ *
+ *              Note that this also starts the PortAudio stream, so by the end, or
+ *              shortly afterwars, the playrecCallback() function will start being
+ *              called.
+ *
+ * TODO:
+ */
+bool doInit(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    PaStreamParameters inputParameters;
+    PaStreamParameters outputParameters;
+    validateState(BASIC_INIT, FULL_INIT );
+
+    /* Completely clear out the previous stream */
+    if(_pstreamInfo) {
+        freeStreamInfoStruct(&_pstreamInfo);
+    }
+
+    /* Check stream info structure created successfully */
+    if(!(_pstreamInfo = newStreamInfoStruct(true))) {
+        return false;
+    }
+
+    /* Get sample rate */
+    if(!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])
+            || (mxGetN(prhs[0])!=1) || (mxGetM(prhs[0])!=1)
+            || (mxGetScalar(prhs[0]) != (int)mxGetScalar(prhs[0]))
+            || (mxGetScalar(prhs[0]) <= 0)) {
+
+        mexWarnMsgTxt("Samplerate must be a non-complex scalar integer greater than zero.");
+        freeStreamInfoStruct(&_pstreamInfo);
+        return false;
+    }
+
+    _pstreamInfo->suggestedSampleRate = mxGetScalar(prhs[0]);
+
+    /* Get play device -  <0 is no device */
+    if(!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1])
+            || (mxGetN(prhs[1])!=1) || (mxGetM(prhs[1])!=1)
+            || (mxGetScalar(prhs[1]) != (int)mxGetScalar(prhs[1]))) {
+
+        mexWarnMsgTxt("Play DeviceID must be a non-complex integer.");
+        freeStreamInfoStruct(&_pstreamInfo);
+        return false;
+    }
+    else if(mxGetScalar(prhs[1]) >= Pa_GetDeviceCount()) {
+        mexWarnMsgTxt("Play DeviceID must be a valid device number.");
+        freeStreamInfoStruct(&_pstreamInfo);
+        return false;
+    }
+    else if(mxGetScalar(prhs[1]) < 0) {
+        _pstreamInfo->playDeviceID = paNoDevice;
+    }
+    else {
+        _pstreamInfo->playDeviceID = (PaDeviceIndex)mxGetScalar(prhs[1]);
+    }
+
+    /* Get record device - <0 is no device */
+    if(!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2])
+            || (mxGetN(prhs[2])!=1) || (mxGetM(prhs[2])!=1)
+            || (mxGetScalar(prhs[2]) != (int)mxGetScalar(prhs[2]))) {
+
+        mexWarnMsgTxt("Record DeviceID must be a non-complex integer.");
+        freeStreamInfoStruct(&_pstreamInfo);
+        return false;
+    }
+    else if(mxGetScalar(prhs[2]) >= Pa_GetDeviceCount()) {
+        mexWarnMsgTxt("Record DeviceID must be a valid device number.");
+        freeStreamInfoStruct(&_pstreamInfo);
+        return false;
+    }
+    else if(mxGetScalar(prhs[2]) < 0) {
+        _pstreamInfo->recDeviceID = paNoDevice;
+    }
+    else {
+        _pstreamInfo->recDeviceID = (PaDeviceIndex)mxGetScalar(prhs[2]);
+    }
+
+    /* Check there is at least a play or record device */
+    if ((_pstreamInfo->playDeviceID == paNoDevice)
+            && (_pstreamInfo->recDeviceID == paNoDevice)) {
+        mexWarnMsgTxt("playdevice < 0 and recdevice < 0. Nothing to be done - initialisation not complete.");
+        freeStreamInfoStruct(&_pstreamInfo);
+        return true;
+    }
+
+    /* Check maximum play channel number */
+    if (_pstreamInfo->playDeviceID != paNoDevice) {
+        if(nrhs >= 4) {
+            if(!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3])
+                    || (mxGetN(prhs[3])!=1) || (mxGetM(prhs[3])!=1)
+                    || (mxGetScalar(prhs[3]) != (int)mxGetScalar(prhs[3]))
+                    || (mxGetScalar(prhs[3]) <= 0)) {
+
+                mexWarnMsgTxt("Maximum channel number for output must be a non-complex scalar integer greater than zero.");
+                freeStreamInfoStruct(&_pstreamInfo);
+                return false;
+            }
+
+            /* The supplied value is the channel number, base 1
+             * This is the same as the number of channels (even though we are using base 0)
+             */
+            _pstreamInfo->playChanCount = (unsigned int)mxGetScalar(prhs[3]);
+        }
+        else {
+            /* Determine maximum number from PortAudio and use that */
+            const PaDeviceInfo *pdi = Pa_GetDeviceInfo(_pstreamInfo->playDeviceID);
+
+            if (pdi) {
+                _pstreamInfo->playChanCount = pdi->maxOutputChannels;
+            }
+            else {
+                mexWarnMsgTxt("Unable to retrieve maximum play channel number for device.");
+                freeStreamInfoStruct(&_pstreamInfo);
+                return false;
+            }
+        }
+    }
+
+    /* Check maxmimum record channel number */
+    if (_pstreamInfo->recDeviceID != paNoDevice) {
+        if(nrhs >= 5) {
+            if(!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4])
+                    || (mxGetN(prhs[4])!=1) || (mxGetM(prhs[4])!=1)
+                    || (mxGetScalar(prhs[4]) != (int)mxGetScalar(prhs[4]))
+                    || (mxGetScalar(prhs[4]) <= 0)) {
+
+                mexWarnMsgTxt("Maximum channel number for recording must be a non-complex scalar integer greater than zero.");
+                freeStreamInfoStruct(&_pstreamInfo);
+                return false;
+            }
+
+            /* The supplied value is the channel number, base 1
+             * This is the same as the number of channels (even though we are using base 0)
+             */
+            _pstreamInfo->recChanCount = (unsigned int)mxGetScalar(prhs[4]);
+        }
+        else {
+            /* Determine maximum number from PortAudio and use that */
+            const PaDeviceInfo *pdi = Pa_GetDeviceInfo(_pstreamInfo->recDeviceID);
+
+            if (pdi) {
+                _pstreamInfo->recChanCount = pdi->maxInputChannels;
+            }
+            else {
+                mexWarnMsgTxt("Unable to retrieve maximum record channel number for device.");
+                freeStreamInfoStruct(&_pstreamInfo);
+                return false;
+            }
+        }
+    }
+
+    /* Get framesPerBuffer if valid */
+    if(nrhs >= 6) {
+        if(!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5])
+                || (mxGetN(prhs[5])!=1) || (mxGetM(prhs[5])!=1)
+                || (mxGetScalar(prhs[5]) != (int)mxGetScalar(prhs[5]))
+                || (mxGetScalar(prhs[5]) < 0)) {
+
+            /* Zero is used for 'Unspecified' ie let PortAudio choose */
+            mexWarnMsgTxt("Frame buffer size must be a non-complex scalar integer "
+                          "greater than or equal to zero.");
+            freeStreamInfoStruct(&_pstreamInfo);
+            return false;
+        }
+
+        _pstreamInfo->suggestedFramesPerBuffer = (unsigned int)mxGetScalar(prhs[5]);
+    }
+
+    /* Get playSuggestedLatency if valid */
+    if(_pstreamInfo->playDeviceID != paNoDevice) {
+        if(nrhs >= 7) {
+            if(!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6])
+                    || (mxGetN(prhs[6])!=1) || (mxGetM(prhs[6])!=1)
+                    || (mxGetScalar(prhs[6]) < 0)) {
+
+                mexWarnMsgTxt("Play suggested latency must be a non-complex "
+                              "scalar value greater than or equal to zero.");
+                freeStreamInfoStruct(&_pstreamInfo);
+                return false;
+            }
+
+            _pstreamInfo->playSuggestedLatency = (PaTime)mxGetScalar(prhs[6]);
+        }
+        else {
+            _pstreamInfo->playSuggestedLatency =
+                Pa_GetDeviceInfo( _pstreamInfo->playDeviceID )->defaultLowOutputLatency;
+        }
+    }
+
+    /* Get recSuggestedLatency if valid */
+    if(_pstreamInfo->recDeviceID != paNoDevice) {
+        if(nrhs >= 8) {
+            if(!mxIsNumeric(prhs[7]) || mxIsComplex(prhs[7])
+                    || (mxGetN(prhs[7])!=1) || (mxGetM(prhs[7])!=1)
+                    || (mxGetScalar(prhs[7]) < 0)) {
+
+                mexWarnMsgTxt("Record suggested latency must be a non-complex "
+                              "scalar value greater than or equal to zero.");
+                freeStreamInfoStruct(&_pstreamInfo);
+                return false;
+            }
+
+            _pstreamInfo->recSuggestedLatency = (PaTime)mxGetScalar(prhs[7]);
+        }
+        else {
+            _pstreamInfo->recSuggestedLatency =
+                Pa_GetDeviceInfo( _pstreamInfo->recDeviceID )->defaultLowInputLatency;
+        }
+    }
+
+    if(_pstreamInfo->recDeviceID != paNoDevice)
+    {
+        inputParameters.device = _pstreamInfo->recDeviceID;
+        inputParameters.channelCount = _pstreamInfo->recChanCount;
+        inputParameters.sampleFormat = paFloat32;
+        inputParameters.suggestedLatency = _pstreamInfo->recSuggestedLatency;
+        inputParameters.hostApiSpecificStreamInfo = NULL;
+    }
+
+    if(_pstreamInfo->playDeviceID != paNoDevice)
+    {
+        outputParameters.device = _pstreamInfo->playDeviceID;
+        outputParameters.channelCount = _pstreamInfo->playChanCount;
+        outputParameters.sampleFormat = paFloat32;
+        outputParameters.suggestedLatency = _pstreamInfo->playSuggestedLatency;
+        outputParameters.hostApiSpecificStreamInfo = NULL;
+    }
+
+    /* Open an audio I/O stream. */
+    if(checkPAErr(Pa_OpenStream(
+                      &_pstreamInfo->pstream,
+                      (_pstreamInfo->recDeviceID != paNoDevice) ? &inputParameters : NULL,
+                      (_pstreamInfo->playDeviceID != paNoDevice) ? &outputParameters : NULL,
+                      _pstreamInfo->suggestedSampleRate,
+                      _pstreamInfo->suggestedFramesPerBuffer,
+                      _pstreamInfo->streamFlags,
+                      playrecCallback,
+                      _pstreamInfo))!=paNoError) {
+
+        /* the value of stream is invalid, so clear it before freeing the stream
+         * structure */
+        _pstreamInfo->pstream = NULL;
+        freeStreamInfoStruct(&_pstreamInfo);
+        abortIfPAErr("Init failed to open PortAudio stream");
+    }
+
+    /* Stream is open, so now store time and start stream. */
+    time(&_pstreamInfo->streamStartTime);
+
+    if(checkPAErr(Pa_StartStream( _pstreamInfo->pstream ))!=paNoError) {
+        /* Stream cannot be started */
+        freeStreamInfoStruct(&_pstreamInfo);
+        abortIfPAErr("Init failed to start PortAudio stream");
+    }
+
+    SETSTATE(FULL_INIT);
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doPlayrec(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *          4 right-hand side arguments (stored in the first 4 elements of prhs)
+ *          must be provided containing the following values (in this order):
+ *  playBuffer
+ *      a MxN matrix containing the samples to be played.  M is the number of
+ *      samples and N is the number of channels of data.
+ *  playChanList
+ *      a 1xN vector containing the channels on which the playBuffer samples
+ *      should be output.  N is the number of channels of data, and should be
+ *      the same as playBuffer (a warning is generated if they are different
+ *      but the utility will still try and create the page).  Can only contain
+ *      each channel number once, but the channel order is not important and
+ *      does not need to include all the channels the device supports (all
+ *      unspecified channels will automatically output zeros).  The maximum
+ *      channel number cannot be greater than that specified during
+ *      initialisation.
+ *  recDuration
+ *      the number of samples that should be recorded in this page, or -1 to
+ *      record the same number of samples as in playBuffer.
+ *  recChanList
+ *      a row vector containing the channel numbers of all channels to be
+ *      recorded.  Can only contain each channel number once, but the channel
+ *      order is not important and does not need to include all the channels
+ *      the device supports.
+ *
+ * Returns:     true if page added successfully, false if an error occurred
+ *              (returned after displaying an error message)
+ *
+ * Description: Adds a page (containging play and record) to the end of the
+ *              current list of pages, returning the number of the new page
+ *              in the first element of plhs.
+ *
+ *              See addPlayrecPage for more information.
+ *
+ * TODO:
+ */
+bool doPlayrec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    return addPlayrecPage(&plhs[0], prhs[0], prhs[1], prhs[2], prhs[3]);
+}
+
+/*
+ * FUNCTION:    doPlay(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *          2 right-hand side arguments (stored in the first 2 elements of prhs)
+ *          must be provided containing the following values (in this order):
+ *  playBuffer
+ *      a MxN matrix containing the samples to be played.  M is the number of
+ *      samples and N is the number of channels of data.
+ *  playChanList
+ *      a 1xN vector containing the channels on which the playBuffer samples
+ *      should be output.  N is the number of channels of data, and should be
+ *      the same as playBuffer (a warning is generated if they are different
+ *      but the utility will still try and create the page).  Can only contain
+ *      each channel number once, but the channel order is not important and
+ *      does not need to include all the channels the device supports (all
+ *      unspecified channels will automatically output zeros).  The maximum
+ *      channel number cannot be greater than that specified during
+ *      initialisation.
+ *
+ * Returns:     true if page added successfully, false if an error occurred
+ *              (returned after displaying an error message)
+ *
+ * Description: Adds a page (containging only play channels) to the end of the
+ *              current list of pages, returning the number of the new page
+ *              in the first element of plhs.
+ *
+ *              See addPlayrecPage for more information.
+ *
+ * TODO:
+ */
+bool doPlay(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    return addPlayrecPage(&plhs[0], prhs[0], prhs[1], NULL, NULL);
+}
+
+/*
+ * FUNCTION:    doRec(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *          2 right-hand side arguments (stored in the first 2 elements of prhs)
+ *          must be provided containing the following values (in this order):
+ *
+ *  recDuration
+ *      the number of samples that should be recorded on each channel specified
+ *      in recChanList.
+ *  recChanList
+ *      a row vector containing the channel numbers of all channels to be
+ *      recorded.  Can only contain each channel number once, but the channel
+ *      order is not important and does not need to include all the channels
+ *      the device supports.  This is the same as the order of channels
+ *      returned by 'getRec'.  The maximum channel number cannot be greater
+ *      than that specified during initialisation.
+ *
+ * Returns:     true if page added successfully, false if an error occurred
+ *              (returned after displaying an error message)
+ *
+ * Description: Adds a page (containging only record channels) to the end of the
+ *              current list of pages, returning the number of the new page
+ *              in the first element of plhs.
+ *
+ *              See addPlayrecPage for more information.
+ *
+ * TODO:
+ */
+bool doRec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    return addPlayrecPage(&plhs[0], NULL, NULL, prhs[0], prhs[1]);
+}
+
+/*
+ * FUNCTION:    doPause(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  If (nrhs > 0) then the first element
+ *              of prhs must also be valid and must point to a scalar.
+ *
+ * Returns:     true is successful, false if the supplied argument is invalid,
+ *              or aborts with an error if not in full initialisation state.
+ *              The first element in plhs is only valid when true is returned.
+ *
+ * Description: If (nrhs > 0) then the stream pause state is updated with that
+ *              contained in the first element of prhs which should be 1 to
+ *              pause the stream or 0 to unpause the stream.  If no arguments
+ *              are supplied then the stream pause state is not altered.
+ *
+ *              Returns a double scalar in the first element of plhs containing
+ *              the current pause state (1 for paused, 0 for running).  If a
+ *              new pause state was supplied, the returned state is that after
+ *              the update has occurred.
+ *
+ * TODO:
+ */
+bool doPause(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet "
+                     " _pstreamInfo is NULL.");
+    }
+
+    if(nrhs > 0) {
+        if(!(mxIsNumeric(prhs[0]) || mxIsLogical(prhs[0]))
+                || mxIsComplex(prhs[0])
+                || (mxGetN(prhs[0])!=1) || (mxGetM(prhs[0])!=1)
+                || ((mxGetScalar(prhs[0]) != 0)
+                    && (mxGetScalar(prhs[0]) != 1))) {
+
+            mexWarnMsgTxt("New pause state must be either 0 (off) or 1 (on).");
+            return false;
+        }
+
+        _pstreamInfo->isPaused = (mxGetScalar(prhs[0]) == 1);
+    }
+
+    plhs[0] = mxCreateDoubleScalar(_pstreamInfo->isPaused?1:0);
+    return true;
+}
+
+/*
+ * FUNCTION:    doBlock(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  If (nrhs > 0) then the first element
+ *              of prhs must also be valid and must point to a scalar.
+ *
+ * Returns:     true, or aborts with an error if not in full initialisation
+ *              state.
+ *
+ * Description: Waits until the specified page has finished before returning.
+ *
+ *              If (nrhs > 0), and hence at least one argument is supplied,
+ *              then the first element of prhs is assumed to contain a page
+ *              number.  Otherwise the utility automatically uses the page
+ *              number of the last page resident in memory.
+ *
+ *              Returns a double scalar in the first element of plhs containing:
+ *              1 if the specified page is a valid page and has finished being
+ *              processed (note that page validity refers to when the function
+ *              was called and so now the page has finished it may no longer
+ *              be a valid page).
+ *              0 if the specified page is a valid page that has not finished
+ *              being processed.  This is only returned if the stream is paused
+ *              and is used to avoid the function blocking indefinitely.
+ *              -1 if the specified page is invalid or no longer exists.  This
+ *              includes pages that have automatically been condensed, and hence
+ *              have finished.
+ *
+ * TODO:
+ */
+bool doBlock(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct *psps;
+
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet "
+                     "_pstreamInfo is NULL.");
+    }
+
+    if(!_pstreamInfo->pfirstStreamPage) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+        return true;
+    }
+
+    psps = _pstreamInfo->pfirstStreamPage;
+
+    if(nrhs > 0) {
+        if(!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])
+                || (mxGetN(prhs[0])!=1) || (mxGetM(prhs[0])!=1)) {
+
+            plhs[0] = mxCreateDoubleScalar(-1);
+            return true;
+        }
+
+        while(psps) {
+            if(psps->pageNum == (int)mxGetScalar(prhs[0]))
+                break;
+
+            psps = psps->pnextStreamPage;
+        }
+
+        if(!psps) {
+            /* page does not exist, so return immediately */
+            plhs[0] = mxCreateDoubleScalar(-1);
+            return true;
+        }
+    }
+    else {
+        /* Find the last page */
+        while(psps) {
+            if(!psps->pnextStreamPage)
+                break;
+
+            psps = psps->pnextStreamPage;
+        }
+
+        if(!psps) {
+            /* page does not exist, so return immediately
+             * This condition should have been caught earlier
+             */
+            plhs[0] = mxCreateDoubleScalar(-1);
+            return true;
+        }
+    }
+
+    while(!psps->pageFinished) {
+        if(_pstreamInfo->isPaused) {
+            plhs[0] = mxCreateDoubleScalar(0);
+            return true;
+        }
+        Pa_Sleep(1);
+    }
+
+    plhs[0] = mxCreateDoubleScalar(1);
+    return true;
+}
+
+/*
+ * FUNCTION:    doIsFinished(int nlhs, mxArray *plhs[],
+                        int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  If (nrhs > 0) then the first element
+ *              of prhs must also be valid and must point to a scalar.
+ *
+ * Returns:     true, or aborts with an error if not in full initialisation
+ *              state.
+ *
+ * Description: If (nrhs > 0), and hence at least one argument is supplied,
+ *              then the first element of prhs is assumed to contain a page
+ *              number.  Otherwise the utility automatically uses the page
+ *              number of the last page resident in memory.
+ *
+ *              Returns a double scalar in the first element of plhs containing:
+ *              1 if the specified page is a valid page and has finished being
+ *              processed or all pages are finished,
+ *              0 if the specified page is a valid page but has not finished
+ *              being processed or there are unfinished pages,
+ *              -1 if the specified page is invalid or no longer exists.  This
+ *              includes pages that have automatically been condensed, and hence
+ *              have finished.
+ *
+ * TODO:
+ */
+bool doIsFinished(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct *psps;
+
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet "
+                     "_pstreamInfo is NULL.");
+    }
+
+    if(!_pstreamInfo->pfirstStreamPage) {
+        /* No pages - they must have all finished! */
+        plhs[0] = mxCreateDoubleScalar(1);
+        return true;
+    }
+
+    psps = _pstreamInfo->pfirstStreamPage;
+
+    if(nrhs > 0) {
+        /* Page has been specified */
+        if(!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])
+                || (mxGetN(prhs[0])!=1) || (mxGetM(prhs[0])!=1)) {
+
+            plhs[0] = mxCreateDoubleScalar(-1);
+            return true;
+        }
+
+        /* Find specified page */
+        while(psps) {
+            if(psps->pageNum == (int)mxGetScalar(prhs[0]))
+                break;
+
+            psps = psps->pnextStreamPage;
+        }
+
+        if(!psps) {
+            /* page does not exist, */
+            plhs[0] = mxCreateDoubleScalar(-1);
+        }
+        else {
+            /* page does exist, so indicate if finished */
+            plhs[0] = mxCreateDoubleScalar(psps->pageFinished?1:0);
+        }
+    }
+    else {
+        /* Find the last page, or any page not finished */
+        while(psps) {
+            if(!psps->pnextStreamPage || !psps->pageFinished)
+                break;
+
+            psps = psps->pnextStreamPage;
+        }
+
+        if(!psps) {
+            /* This condition should have been caught earlier */
+            plhs[0] = mxCreateDoubleScalar(1);
+        }
+        else {
+            plhs[0] = mxCreateDoubleScalar(psps->pageFinished?1:0);
+        }
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doIsInitialised(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              1 if the utility is fully initialised, otherwise 0.
+ *
+ * TODO:
+ */
+bool doIsInitialised(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    if(ISSTATE(FULL_INIT))
+        plhs[0] = mxCreateDoubleScalar(1);
+    else if(ISSTATE(BASIC_INIT))
+        /* If required can return different values for BASIC_INIT and no init! */
+        plhs[0] = mxCreateDoubleScalar(0);
+    else
+        plhs[0] = mxCreateDoubleScalar(0);
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doDelPage(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  If (nrhs != 0) then the first element
+ *              of prhs must also be valid and must point to a scalar.
+ *
+ * Returns:     true, or aborts with an error if not in full initialisation
+ *              state.
+ *
+ * Description: If (nrhs==0), and hence no arguments are supplied, then all
+ *              pages resident in memory are deleted.  Otherwise it is assumed
+ *              that a argument is supplied in the first element of prhs,
+ *              containing the page number of the page to be deleted.
+ *
+ *              If nothing is deleted (no pages resident in memory or there is
+ *              no page with the specified page number) then 0 is returned as
+ *              the first element of plhs.  Otherwise, 1 is returned as the
+ *              first element of plhs.
+ *
+ * TODO:
+ */
+bool doDelPage(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct **ppsps;
+
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet "
+                     "_pstreamInfo is NULL.");
+    }
+
+    if(nrhs==0) {
+        /* Deleting all */
+
+        if(!_pstreamInfo->pfirstStreamPage) {
+            /* Nothing to delete */
+            plhs[0] = mxCreateDoubleScalar(0);
+            return true;
+        }
+
+        while(_pstreamInfo->pfirstStreamPage)
+            freeStreamPageStruct(&_pstreamInfo->pfirstStreamPage);
+    }
+    else  {
+        /* Been supplied a argument */
+        if(!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])
+                || (mxGetN(prhs[0])!=1) || (mxGetM(prhs[0])!=1)) {
+
+            plhs[0] = mxCreateDoubleScalar(0);
+            return true;
+        }
+
+        /* Find the corresponding page */
+        ppsps = &_pstreamInfo->pfirstStreamPage;
+
+        while(*ppsps) {
+            if((*ppsps)->pageNum == (int)mxGetScalar(prhs[0]))
+                break;
+
+            ppsps = &(*ppsps)->pnextStreamPage;
+        }
+
+        if(!*ppsps) {
+            /* page does not exist, so return immediately */
+            plhs[0] = mxCreateDoubleScalar(0);
+            return true;
+        }
+
+        freeStreamPageStruct(ppsps);
+    }
+
+    plhs[0] = mxCreateDoubleScalar(1);
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetRec(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  Additionally, if (nlhs >= 2) then the
+ *              second element of plhs must also be valid.  The first element
+ *              of prhs must also be valid and must point to an mxArray (the
+ *              type of mxArray is checked).
+ *
+ * Returns:     true, or aborts with an error if not in full initialisation
+ *              state.
+ *
+ * Description: Returns all recorded samples available for the page specified.
+ *              The page required is identified by its page number, supplied as
+ *              the first element of prhs.  An array is always returned in the
+ *              first element of plhs, and if (nlhs >= 2) then an array is also
+ *              returned in the second element of plhs.  The first of these
+ *              contains the recorded data in an MxN array where M is the
+ *              number of samples that have been recorded (if the page is
+ *              currently being processed this will be the number of valid
+ *              samples at the specific point in time) and N is the number
+ *              of channels of data.  The second array is a 1xN array
+ *              containing the channel number asssociated with each channel
+ *              of data in the first array.  If the page requested does not
+ *              exist, or contains no recorded data (either because there are
+ *              no channels set to record, or because the page is waiting to be
+ *              processed) then the array(s) returned are empty.
+ *
+ * TODO:
+ */
+bool doGetRec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct *psps;
+    ChanBufStruct *pcbs;
+
+    SAMPLE *poutBuf;
+    mxArray *mxChanList;
+    unsigned int *pChanList;
+    unsigned int recSamples;
+    unsigned int recChannels;
+
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet "
+                     "_pstreamInfo is NULL.");
+    }
+
+    /* Configure return values to defaults, and then change if necessary */
+    plhs[0] = mxCreateNumericMatrix(0, 0, mxSAMPLE, mxREAL);
+    if(nlhs >= 2)
+        plhs[1] = mxCreateNumericMatrix(0, 0, mxSAMPLE, mxREAL);
+
+    /* No pages */
+    if(!_pstreamInfo->pfirstStreamPage) {
+        return true;
+    }
+
+    /* There must be one element on rhs before function is called */
+    if(!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])
+            || (mxGetN(prhs[0])!=1) || (mxGetM(prhs[0])!=1)
+            || (mxGetScalar(prhs[0])!=(int)mxGetScalar(prhs[0]))) {
+
+        return true;
+    }
+
+    /* Try and find requested stream. */
+    psps = _pstreamInfo->pfirstStreamPage;
+
+    while(psps) {
+        if(psps->pageNum == (int)mxGetScalar(prhs[0]))
+            break;
+
+        psps = psps->pnextStreamPage;
+    }
+
+    if(!psps) {
+        /* page does not exist, so return immediately */
+        return true;
+    }
+
+    /* Found the required page */
+
+    /* Determine the maximum number of samples recorded by finding the longest
+     * buffer, and then limiting to how far through the page we currently are.
+     * This allows for different length buffers in the future.
+     */
+    recSamples = 0;
+    recChannels = 0;
+
+    pcbs = psps->pfirstRecChan;
+
+    while(pcbs) {
+        /* Check for valid buffer */
+        if(pcbs->pbuffer && (pcbs->bufLen > 0)) {
+            recSamples = max(recSamples, pcbs->bufLen);
+            recChannels++;
+        }
+        pcbs = pcbs->pnextChanBuf;
+    }
+
+    recSamples = min(recSamples, psps->pagePos);
+
+    /* If there are no samples recorded, no need to continue */
+    if((recSamples == 0) || (recChannels == 0)) {
+        return true;
+    }
+
+    /* This initialises all elements to zero, so for shorter channels no
+     * problems should arise. Although on exit MATLAB frees the arrays created
+     * above, do so here for completeness
+     */
+    mxDestroyArray(plhs[0]);
+    plhs[0] = mxCreateNumericMatrix(recSamples,recChannels, mxSAMPLE, mxREAL);
+    poutBuf = (SAMPLE*)mxGetData(plhs[0]);
+
+    /* Create the channel list, but only return it if its required */
+    mxChanList = mxCreateNumericMatrix(1, recChannels, mxUNSIGNED_INT, mxREAL);
+    pChanList = (unsigned int*)mxGetData(mxChanList);
+
+    if(poutBuf && pChanList) {
+        pcbs = psps->pfirstRecChan;
+
+        /* Copy the data across, decrement recChannels to make sure
+         * the end of the buffer isn't overwritten
+         */
+        while(pcbs && (recChannels > 0)) {
+            if(pcbs->pbuffer && (pcbs->bufLen > 0)) {
+                memcpy(poutBuf, pcbs->pbuffer,
+                       min(recSamples, pcbs->bufLen) * sizeof(SAMPLE));
+                poutBuf += recSamples;
+
+                *pChanList++ = pcbs->channel + 1;   /* Add 1 for base 1 channels */
+                recChannels--;
+            }
+            pcbs = pcbs->pnextChanBuf;
+        }
+    }
+
+    if(nlhs >= 2) {
+        mxDestroyArray(plhs[1]);
+        plhs[1] = mxChanList;
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetSampleRate(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  Additionally, if (nlhs >= 2) then the
+ *              second element of plhs must also be valid.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first two elements of plhs.
+ *              The first contains the suggested sample rate during initialisation
+ *              and the second contains the current sample rate available from
+ *              the hardware (if possible). Alternatively, -1 if the stream has
+ *              not been initialised.
+ *
+ * TODO:
+ */
+bool doGetSampleRate(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    const PaStreamInfo *streamInfo;
+
+    if(!_pstreamInfo) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+
+        if(nlhs >= 2) {
+            plhs[1] = mxCreateDoubleScalar(-1);
+        }
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->suggestedSampleRate);
+
+        if(nlhs >= 2) {
+            streamInfo = Pa_GetStreamInfo(_pstreamInfo->pstream);
+            if(streamInfo) {
+                plhs[1] = mxCreateDoubleScalar(streamInfo->sampleRate);
+            }
+            else {
+                plhs[1] = mxCreateDoubleScalar(-1);
+            }
+        }
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetFramesPerBuffer(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  Additionally, if (nlhs >= 2) then the
+ *              second element of plhs must also be valid and if (nlhs >= 2)
+ *              then also the third element.
+ *
+ * Returns:     true
+ *
+ * Description: Returns double scalars in the first three elements of plhs
+ *              containing the suggested value during initialisation and the minimum
+ *              and maximum number of samples processed in any single callback.
+ *              Alternatively, -1 if the stream has not been initialised.
+ *
+ * TODO:
+ */
+bool
+doGetFramesPerBuffer(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+
+        if(nlhs >= 2) {
+            plhs[1] = mxCreateDoubleScalar(-1);
+        }
+
+        if(nlhs >= 3) {
+            plhs[2] = mxCreateDoubleScalar(-1);
+        }
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->suggestedFramesPerBuffer);
+
+        if(nlhs >= 2) {
+            plhs[1] = mxCreateDoubleScalar(_pstreamInfo->minFramesPerBuffer);
+        }
+
+        if(nlhs >= 3) {
+            plhs[2] = mxCreateDoubleScalar(_pstreamInfo->maxFramesPerBuffer);
+        }
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetStreamStartTime((int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the unix time (number of seconds since the standard epoch of
+ *              1/1/1970) for when the current stream was started, or -1 if the
+ *              stream has not been initialised.  This can be used as an
+ *              identifying value for the stream, to help keep track of what
+ *              data was recorded using each stream (ie all recordings with the
+ *              same stream start time must have been recorded at the same
+ *              sample rate using the same device(s)).
+ *
+ * TODO:
+ */
+bool
+doGetStreamStartTime(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar((double)_pstreamInfo->streamStartTime);
+        /* mexPrintf("%s\n", asctime(localtime(&_pstreamInfo->streamStartTime))); */
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetPlayDevice(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the ID of the current play device, or -1 if either the stream
+ *              has not been initialised or it was initialised with no play
+ *              device.
+ *
+ * TODO:
+ */
+bool doGetPlayDevice(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo || (_pstreamInfo->playDeviceID == paNoDevice)) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->playDeviceID);
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetRecDevice(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the ID of the current record device, or -1 if either the stream
+ *              has not been initialised or it was initialised with no record
+ *              device.
+ *
+ * TODO:
+ */
+bool doGetRecDevice(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo || (_pstreamInfo->recDeviceID == paNoDevice)) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->recDeviceID);
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetPlayMaxChannel(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the maximum number of play channels, or -1 if either the stream
+ *              has not been initialised or it was initialised with no play
+ *              device.
+ *
+ * TODO:
+ */
+bool
+doGetPlayMaxChannel(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo || (_pstreamInfo->playDeviceID == paNoDevice)) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->playChanCount);
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetRecMaxChannel(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the maximum number of record channels, or -1 if either the stream
+ *              has not been initialised or it was initialised with no record
+ *              device.
+ *
+ * TODO:
+ */
+bool
+doGetRecMaxChannel(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo || (_pstreamInfo->recDeviceID == paNoDevice)) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->recChanCount);
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetPlayLatency(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  Additionally, if (nlhs >= 2) then the
+ *              second element of plhs must also be valid.  All other inputs
+ *              are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs with
+ *              the latency used during initialisation. The second element
+ *              contains the actual latency for the play device, or -1 if
+ *              either the stream has not been initialised or it was
+ *              initialised with no play device.
+ *
+ * TODO:
+ */
+bool
+doGetPlayLatency(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    const PaStreamInfo *streamInfo;
+
+    if(!_pstreamInfo || (_pstreamInfo->playDeviceID == paNoDevice)) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+
+        if(nlhs >= 2) {
+            plhs[1] = mxCreateDoubleScalar(-1);
+        }
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->playSuggestedLatency);
+
+        if(nlhs >= 2) {
+            streamInfo = Pa_GetStreamInfo(_pstreamInfo->pstream);
+            if(streamInfo) {
+                plhs[1] = mxCreateDoubleScalar(streamInfo->outputLatency);
+            }
+            else {
+                plhs[1] = mxCreateDoubleScalar(-1);
+            }
+        }
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetRecLatency(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  Additionally, if (nlhs >= 2) then the
+ *              second element of plhs must also be valid.  All other inputs
+ *              are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs with
+ *              the latency used during initialisation. The second element
+ *              contains the actual latency for the record device, or -1 if
+ *              either the stream has not been initialised or it was
+ *              initialised with no record device.
+ *
+ * TODO:
+ */
+bool doGetRecLatency(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    const PaStreamInfo *streamInfo;
+
+    if(!_pstreamInfo || (_pstreamInfo->recDeviceID == paNoDevice)) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+
+        if(nlhs >= 2) {
+            plhs[1] = mxCreateDoubleScalar(-1);
+        }
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->recSuggestedLatency);
+
+        if(nlhs >= 2) {
+            streamInfo = Pa_GetStreamInfo(_pstreamInfo->pstream);
+            if(streamInfo) {
+                plhs[1] = mxCreateDoubleScalar(streamInfo->inputLatency);
+            }
+            else {
+                plhs[1] = mxCreateDoubleScalar(-1);
+            }
+        }
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetPageList(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a 1xN array of unsigned integers in the first element
+ *              of plhs.  The array contains the page numbers of all pages
+ *              resident in memory, arranged chronologically from the earliest
+ *              to latest addition.  As such, the lenght of the array, N, is
+ *              the number of pages currently resident in memory.
+ *
+ * TODO:
+ */
+bool doGetPageList(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct *psps;
+    unsigned int *ppageList;
+    unsigned int pageCount = 0;
+
+    /* Not initialised or no pages */
+    if(!_pstreamInfo || !_pstreamInfo->pfirstStreamPage) {
+        plhs[0] = mxCreateNumericMatrix(1, 0, mxUNSIGNED_INT, mxREAL);
+        return true;
+    }
+
+    psps = _pstreamInfo->pfirstStreamPage;
+
+    while(psps) {
+        pageCount++;
+        psps = psps->pnextStreamPage;
+    }
+
+    plhs[0] = mxCreateNumericMatrix(1, pageCount, mxUNSIGNED_INT, mxREAL);
+
+    ppageList = (unsigned int*)mxGetData(plhs[0]);
+
+    if(ppageList) {
+        psps = _pstreamInfo->pfirstStreamPage;
+
+        /* Copy the data across.
+         * Decrement pageCount incase another item has been added simultaneously
+         */
+        while(psps && (pageCount > 0)) {
+            pageCount--;
+            *ppageList++ = psps->pageNum;
+            psps = psps->pnextStreamPage;
+        }
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetCurrentPosition(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The first element of plhs is always used and so must be valid
+ *              (this is not checked).  Additionally, if (nlhs >= 2) then the
+ *              second element of plhs must also be valid.  All other inputs
+ *              are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Always returns a double scalar in the first element of plhs
+ *              containing the page number of the current page being processed.
+ *              If there is no page currently being processed (there are no
+ *              pages, or all pages are finished) then the returned page number
+ *              is -1.  If (nlhs >= 2) then a double scalar in the second
+ *              element of plhs is also returned.  This represents the current
+ *              sample number within the current page, or -1 if there is no
+ *              current page.
+ *
+ * TODO:
+ */
+bool
+doGetCurrentPosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct *psps;
+
+    if(!_pstreamInfo || !_pstreamInfo->pfirstStreamPage) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+        if(nlhs >= 2)
+            plhs[1] = mxCreateDoubleScalar(-1);
+        return true;
+    }
+
+    psps = _pstreamInfo->pfirstStreamPage;
+
+    while(psps->pnextStreamPage && psps->pageFinished)
+        psps = psps->pnextStreamPage;
+
+    if(!psps->pnextStreamPage && psps->pageFinished) {
+        /* The last stream page is finished, so there is no current page */
+        plhs[0] = mxCreateDoubleScalar(-1);
+        if(nlhs >= 2)
+            plhs[1] = mxCreateDoubleScalar(-1);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(psps->pageNum);
+        if(nlhs >= 2)
+            plhs[1] = mxCreateDoubleScalar(psps->pagePos);
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetLastFinishedPage(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the page number of the last finished page still resident in
+ *              memory (ie pages that have not been deleted either
+ *              automatically during page condensing or through a call to
+ *              delPage). If there are no finished pages resident in memory
+ *              then the returned page number is -1.
+ *
+ * TODO:
+ */
+bool
+doGetLastFinishedPage(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    StreamPageStruct *psps;
+    unsigned int finishedPage;
+
+    /* Check there is at least one finished page */
+    if(!_pstreamInfo || !_pstreamInfo->pfirstStreamPage ||
+            !_pstreamInfo->pfirstStreamPage->pageFinished) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+        return true;
+    }
+
+    /* To get here the first page is finished */
+    finishedPage = _pstreamInfo->pfirstStreamPage->pageNum;
+    psps = _pstreamInfo->pfirstStreamPage->pnextStreamPage;
+
+    while(psps && psps->pageFinished) {
+        finishedPage = psps->pageNum;
+        psps = psps->pnextStreamPage;
+    }
+
+    plhs[0] = mxCreateDoubleScalar(finishedPage);
+    return true;
+}
+
+/*
+ * FUNCTION:    doReset(int nlhs, mxArray *plhs[],
+ *                       int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              No inputs are used or verified.
+ *
+ * Returns:     true, or aborts with an error if not in full initialisation
+ *              state.
+ *
+ * Description: Resets the utility to the basic initialisation state,
+ *              including deleting all pages and stopping the PortAudio stream.
+ *
+ * TODO:
+ */
+bool doReset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    validateState(BASIC_INIT | FULL_INIT, 0);
+
+    /* Should not get here if _pstreamInfo is null */
+    if(!_pstreamInfo) {
+        mexErrMsgTxt("An error has occurred - in full initialisation yet "
+                     "_pstreamInfo is NULL.");
+    }
+
+    /* freeing the stream info structure also closes the stream */
+    freeStreamInfoStruct(&_pstreamInfo);
+
+    CLEARSTATE(FULL_INIT);
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetDevices(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true, or aborts with an error if not in basic initialisation
+ *              state
+ *
+ * Description: Returns a 1xN struct array as the first element of plhs,
+ *              containing the name, ID and number of input and output channels
+ *              for all availables devices.
+ *
+ * TODO:
+ */
+bool doGetDevices(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    const char *fieldNames[] = {"deviceID", "name",
+                                "hostAPI", "defaultLowInputLatency",
+                                "defaultLowOutputLatency",
+                                "defaultHighInputLatency",
+                                "defaultHighOutputLatency",
+                                "defaultSampleRate",
+                                "supportedSampleRates",
+                                "inputChans", "outputChans"
+                               };
+
+    const double samplingRates[] = { 8000.0, 11025.0, 16000.0, 22050.0,
+                                     32000.0, 44100.0, 48000.0
+                                   };
+    const int numSamplingRates = sizeof(samplingRates)/sizeof(samplingRates[0]);
+
+    const PaDeviceInfo *pdi;
+    PaDeviceIndex i;
+    int ii;
+    int numDevices;
+
+    validateState(BASIC_INIT, 0);
+
+    numDevices = Pa_GetDeviceCount();
+
+    if( numDevices < 0 )
+    {
+        mexPrintf( "PortAudio Error, Pa_CountDevices returned 0x%x\n",
+                   numDevices );
+    }
+
+    plhs[0] = mxCreateStructMatrix(1, numDevices,
+                                   sizeof(fieldNames)/sizeof(char*), fieldNames);
+
+    for( i = 0; i < numDevices; i++)
+    {
+        pdi = Pa_GetDeviceInfo(i);
+
+        if (pdi != NULL)
+        {
+            mxSetField(plhs[0],i,"deviceID", mxCreateDoubleScalar(i));
+            mxSetField(plhs[0],i,"name",mxCreateString(pdi->name));
+            mxSetField(plhs[0],i,"hostAPI",
+                       mxCreateString(Pa_GetHostApiInfo( pdi->hostApi )->name));
+            mxSetField(plhs[0],i,"defaultLowInputLatency",
+                       mxCreateDoubleScalar(pdi->defaultLowInputLatency));
+            mxSetField(plhs[0],i,"defaultLowOutputLatency",
+                       mxCreateDoubleScalar(pdi->defaultLowOutputLatency));
+            mxSetField(plhs[0],i,"defaultHighInputLatency",
+                       mxCreateDoubleScalar(pdi->defaultHighInputLatency));
+            mxSetField(plhs[0],i,"defaultHighOutputLatency",
+                       mxCreateDoubleScalar(pdi->defaultHighOutputLatency));
+            mxSetField(plhs[0],i,"defaultSampleRate",
+                       mxCreateDoubleScalar(pdi->defaultSampleRate));
+            mxSetField(plhs[0],i,"inputChans",
+                       mxCreateDoubleScalar(pdi->maxInputChannels));
+            mxSetField(plhs[0],i,"outputChans",
+                       mxCreateDoubleScalar(pdi->maxOutputChannels));
+            /*
+             * This is a workaround how to obtain list of supported sampling
+             * frequencies. Only the ones in the samplingRates array are
+             * tested. The device might be actually capabe of more.
+             * */
+            PaStreamParameters* dummyIn;
+            PaStreamParameters* dummyOut;
+            if(pdi->maxInputChannels>0)
+            {
+                dummyIn = calloc(1,sizeof(PaStreamParameters));
+                dummyIn->device = i;
+                dummyIn->channelCount = pdi->maxInputChannels;
+                dummyIn->sampleFormat = paFloat32;
+            }
+            else
+            {
+                dummyIn = NULL;
+            }
+            if(pdi->maxOutputChannels>0)
+            {
+                dummyOut = calloc(1,sizeof(PaStreamParameters));
+                dummyOut->device = i;
+                dummyOut->channelCount = pdi->maxOutputChannels;
+                dummyOut->sampleFormat = paFloat32;
+            }
+            else
+            {
+                dummyOut = NULL;
+            }
+            int numSupSampRates = 0;
+            double supSampRates[numSamplingRates];
+            for(ii = 0; ii<numSamplingRates; ii++)
+            {
+                if(!Pa_IsFormatSupported(dummyIn,dummyOut,
+                                         samplingRates[ii]))
+                {
+                    supSampRates[numSupSampRates++] = samplingRates[ii];
+                }
+            }
+
+            if(dummyIn!=NULL)
+                free(dummyIn);
+            if(dummyOut!=NULL)
+                free(dummyOut);
+
+            mxArray* mxSubSampRates =
+                mxCreateDoubleMatrix(1,numSupSampRates,mxREAL);
+            memcpy(mxGetData(mxSubSampRates),supSampRates,
+                   numSupSampRates*sizeof(double));
+
+            mxSetField(plhs[0],i,"supportedSampleRates",mxSubSampRates);
+
+
+        }
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doGetSkippedSampleCount(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              The only input used is the first element of plhs, which must
+ *              be a valid array with at least one element (this is not
+ *              checked).  All other inputs are not used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Returns a double scalar in the first element of plhs containing
+ *              the number of samples that have occurred whilst there are no new
+ *              pages in the pageList, or -1 if either the stream
+ *              has not been initialised.
+ *
+ * TODO:
+ */
+bool doGetSkippedSampleCount(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+
+    if(!_pstreamInfo) {
+        plhs[0] = mxCreateDoubleScalar(-1);
+    }
+    else if(_pstreamInfo->resetSkippedSampleCount) {
+        plhs[0] = mxCreateDoubleScalar(0);
+    }
+    else {
+        plhs[0] = mxCreateDoubleScalar(_pstreamInfo->skippedSampleCount);
+    }
+    return true;
+}
+
+/*
+ * FUNCTION:    doResetSkippedSampleCount(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              No inputs are used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Resets the skipped sample count to zero.
+ *
+ * TODO:
+ */
+bool doResetSkippedSampleCount(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    if(!_pstreamInfo) {
+        return true;
+    }
+
+    _pstreamInfo->resetSkippedSampleCount = true;
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doAbout(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              No inputs are used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Outputs as either a argument or to the command window information
+ *              about the version of playrec.
+ *
+ * TODO:
+ */
+bool doAbout(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    static const char *aboutString =
+
+        "Playrec is a Matlab utility (MEX file) that provides simple yet versatile access to \
+soundcards using PortAudio, a free, open-source audio I/O library. It can be used on \
+different platforms (Windows, Macintosh, Unix) and access the soundcard via different \
+host API including ASIO, WMME and DirectSound under Windows.\n\n\
+A list of all commands implemented by the utility can be obtained by calling playrec \
+with no arguments.  A basic outline of how to use this utility is provided by typing \
+'overview' as the first argument.  For more information on any command type 'help' as \
+the first argument followed by the command of interest as the second argument.\n\n\
+This utility was initially written as part of a Robert Humphrey's MEng project for \
+The University of York, UK, in 2006. This was undertaken at TMH (Speech, Music and \
+Hearing) at The Royal Institute of Technology (KTH) in Stockholm and was funded by \
+The Swedish Foundation for International Cooperation in Research and Higher Education \
+(STINT). The project was titled Automatic Speaker Location Detection for use in \
+Ambisonic Systems.\n\n\
+ASIO is a trademark and software of Steinberg Media Technologies GmbH\n\n\
+Version: " VERSION "\nDate: " DATE "\nAuthor: " AUTHOR "\nCompiled on: "
+        __DATE__ " at " __TIME__ "\nBuilt with defines: "
+
+#ifdef CASE_INSENSITIVE_COMMAND_NAME
+        "CASE_INSENSITIVE_COMMAND_NAME, "
+#endif
+#ifdef DEBUG
+        "DEBUG, "
+#endif
+
+        "\nAvailable host API: ";
+
+    PaHostApiIndex apiCount = Pa_GetHostApiCount();
+    PaHostApiIndex i;
+    const PaHostApiInfo *apiInfo;
+
+    int bufLen = strlen(aboutString);
+
+    char *buffer, *write_point;
+
+    /* Calculate required buffer length, being over generous to avoid problems */
+    for(i = 0; i < apiCount; i++) {
+        apiInfo = Pa_GetHostApiInfo(i);
+        bufLen += strlen(apiInfo->name) + 20;
+    }
+
+    buffer = mxCalloc( bufLen + 20, sizeof( char ));
+
+    if( buffer ) {
+        write_point = buffer;
+
+        strcpy(write_point, aboutString);
+        write_point += strlen(aboutString);
+
+        for(i = 0; i < apiCount; i++) {
+            apiInfo = Pa_GetHostApiInfo(i);
+            write_point += sprintf(write_point, "%s (%d devices), ", apiInfo->name, apiInfo->deviceCount);
+        }
+
+        *write_point = '\0';
+
+        if(nlhs < 1) {
+            linewrapString(buffer, SCREEN_CHAR_WIDTH, 0, 0, SCREEN_TAB_STOP);
+        }
+        else {
+            plhs[0] = mxCreateString(buffer);
+        }
+        /* No need to free memory here as execution will always stop at the error */
+    }
+    else {
+        mexErrMsgTxt( "Error allocating memory in doAbout" );
+    }
+
+    return true;
+}
+
+/*
+ * FUNCTION:    doOverview(int nlhs, mxArray *plhs[],
+ *                      int nrhs, const mxArray *prhs[])
+ *
+ * Inputs:      nlhs - number of mexFunction output arguments
+ *              plhs - pointer to array of mexFunction output arguments
+ *              nrhs - number of mexFunction input arguments
+ *              prhs - pointer to array of mexFunction input arguments
+ *
+ *              No inputs are used or verified.
+ *
+ * Returns:     true
+ *
+ * Description: Outputs as either a argument or to the command window an
+ *              overview of how to use playrec.
+ *
+ * TODO:
+ */
+bool doOverview(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
+    /* To do this line wrapping quickly can use "^(.{1,90} )" and "\1\\\n" as
+       find and replace regular expressions in Textpad */
+    static const char *overviewString =
+        "This page provides a basic outline of how to use the Playrec utility. More information \
+on any command can be found by using \"playrec('help', 'command_name')\" or simply \
+\"playrec help command_name\".\n\n"
+        "To simplify operation, all functionality is accessed through one function in Matlab.  \
+To achieve this the first argument in the function call is always the name of the \
+command/operation required, eg \"playrec('getDevices')\" or \"playrec('isInitialised')\". \
+If additional arguments are required then they are specified after this, eg \
+\"playrec('init', 48000, 1, -1)\". A list of all available commands can be displayed by \
+supplying no arguments.\n\n"
+        "Before any audio can be played or recorded, the utility must be initialised to use the \
+required sample rate and device(s).  Initialisation is achieved using the \"init\" \
+command, supplying the ID of the required audio device(s) as returned by \"getDevices\". \
+Once successfully initialised, the sample rate or device(s) to be used cannot be changed \
+without first resetting the utility using the \"reset\" command.  This clears all \
+previously recorded data so use it with care. To check if the utility is currently \
+initialised, use the \"isInitialised\" command.\n\n"
+        "The utility divides time up into pages with no restrictions on the duration of any one \
+page, although with very short pages skipping in the audio may occur if they cannot be \
+supplied fast enough. There can be as many pages as required provided the utility can \
+allocate enough memory. Pages are joined together sequentially in the order they are \
+added, with each page starting the sample after the previous page finishes.  A page can \
+contain samples that are to be output on one or more channels and buffers to store \
+recorded samples on one or more channels.  The duration of a page is determined by the \
+longest channel contained within the page.  Therefore if, for example, the record channels \
+are 1000 samples long whilst output channels are only 900 samples long, the page will be \
+1000 samples long and the final 100 output samples of the page will automatically be set \
+to 0.\n\n"
+        "When each page is added, the channels that are to be used for recording and/or output are \
+specified (depending on the command used to add the page).  The channels used must be \
+within the range specified during initialisation and no channel can be duplicated within a \
+channel list.  Within these limits, the channel list for each page can be different and \
+each list can contain as many or as few channels as required in any order.  All output \
+channels not provided with any data within a page will output 0 for the duration of the \
+page.  Similarly, during any times when there are no further pages to process 0 will be \
+output on all channels.\n\n"
+        "Each page has a unique number which is returned by any of the commands used to add pages \
+(\"playrec\", \"play\" or \"rec\").  When a page is added, the utility does not wait until \
+the page has completed before returning.  Instead, the page is queued up and the page \
+number can then be used to check if the page has finished, using \"isFinished\".  \
+Alternatively a blocking command, \"block\", can be used to wait until the page has \
+finished.  To reduce the amount of memory used, finished pages are automatically condensed \
+whenever any command is called in the utility.  If a page contains any recorded data, this \
+is left untouched although any output data within the page is removed.  If the page does \
+not contain any recorded data, the whole page is deleted during this page condensing.  For \
+this reason if either \"isFinished\", \"block\" or \"delPage\" indicate the page number is \
+invalid this means the page either never existed or has already finished and then been \
+deleted during page condensing.\n\n"
+        "For pages containing recorded data, the data can be accessed using the \"getRec\" command \
+once the page is finished (indicating the recording has completed).  This does not delete \
+the data so it can be accessed as many times as required.  To delete the recorded data, \
+the whole page must be deleted using the \"delPage\" command.  This command will delete \
+pages nomatter what their current state: waiting to start, currently active or finished.  \
+If no page number is supplied, all pages will be deleted, again regardless of their state \
+so use with care.\n\n"
+        "To ascertain which pages are still left in memory, the \"getPageList\" command can be \
+used, returning a list of the pages in chronological order.  NOTE: there may have been \
+gaps of silence or other pages between consecutive pages in this list due to pages either \
+being automatically or explicitly deleted as detailed above.  To determine if there were \
+gaps between pages due to all pages finishing processing before new ones are added, the \
+commands \"getSkippedSampleCount\" and \"resetSkippedSampleCount\" can be used.\n\n"
+        "The page that is currently being output is returned by \"getCurrentPosition\", along with \
+an approximate sample position within the page.  Additionally, the page number of the last \
+completed page still resident in memory is returned by \"getLastFinishedPage\".  NOTE: \
+this might not be the most recent page to finish if that page has been deleted either \
+during page condensing (ie contained no recorded data) or through the use of \"delPage\".\n\n"
+        "Finally, the utility can be paused and resumed using the \"pause\" command.  This will \
+manipulate all output and recording channels simultaneously to ensure synchronisation is \
+always maintained.  This command can also be used to ascertain if the utility is currently \
+running or paused.";
+
+    if(nlhs < 1) {
+        linewrapString(overviewString,SCREEN_CHAR_WIDTH, 0, 0, SCREEN_TAB_STOP);
+    }
+    else {
+        plhs[0] = mxCreateString(overviewString);
+    }
+
+    return true;
+}
+
diff --git a/thirdparty/Playrec/pa_dll_playrec.h b/thirdparty/Playrec/pa_dll_playrec.h
new file mode 100644
index 0000000..378ce32
--- /dev/null
+++ b/thirdparty/Playrec/pa_dll_playrec.h
@@ -0,0 +1,244 @@
+/*
+ * Playrec
+ * Copyright (c) 2006-2008 Robert Humphrey
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PA_DLL_PLAYREC_H
+#define PA_DLL_PLAYREC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <time.h>
+#include "mex.h"
+#include "portaudio.h"
+
+#define VERSION "2.1.0"
+#define DATE "15 April 2008"
+#define AUTHOR "Robert Humphrey"
+
+/* The mx class equivalent to unsigned int */
+#define mxUNSIGNED_INT mxUINT32_CLASS
+
+/* The mx class equivalent to SAMPLE */
+#define mxSAMPLE    mxSINGLE_CLASS
+
+/* Format to be used for samples with PortAudio = 32bit */
+typedef float SAMPLE;
+
+/* Structure to contain 'human readable' advice for each state */
+typedef struct {
+    int num;            /* State numerical representation (single bit set) */
+    char *name;         /* Name used to textually refer to the state */
+    char *startString;  /* String providing advice on how to start the state */
+                        /* if it is not currently active but is required */
+    char *stopString;   /* String providing advice on how to clear the state */
+                        /* if it is currently active and shouldn't be */
+} StateOptsStruct;
+
+/* Structure to contain all the per-channel data for one 'page' */
+typedef struct ChanBufStruct_tag {
+    SAMPLE *pbuffer;                    /* The channel audio data */
+    unsigned int bufLen;                /* Length of the audio buffer */
+    unsigned int channel;               /* Channel number on the audio device */
+                                        /* that this buffer is associated with */
+                                        /* (first channel = 0) */
+    struct ChanBufStruct_tag *pnextChanBuf; /* Pointer to the next channel */
+                                        /* buffer in the linked list.  The */
+                                        /* order of buffers in the linked list */
+                                        /* is the order of 'channel' data */
+                                        /* received from and returned to MATLAB */
+} ChanBufStruct;
+
+/* Structure to organise 'pages' */
+typedef struct StreamPageStruct_tag {
+    ChanBufStruct *pfirstRecChan;   /* First record channel within this page */
+    ChanBufStruct *pfirstPlayChan;  /* First play channel within the page */
+
+    unsigned int pageLength;        /* The maximum length of a channel in this page */
+    volatile unsigned int pagePos;  /* The current position within the page */
+    unsigned int pageNum;           /* A unique id to identify the page */
+
+    unsigned int playChanCount;     /* The number of channels used to communicate */
+                                    /* with PortAudio.  Must be greater than */
+                                    /* the maximum channel number used. */
+    bool *pplayChansInUse;          /* Pointer to array type bool, size playChanCount. */
+                                    /* Each element can be: */
+                                    /* true - the channel is in the play linked list */
+                                    /* false - the channel is not in linked list */
+                                    /* Setting false means that the channel is set */
+                                    /* to all zeros within the callback.  Any channels */
+                                    /* not included in this list (or set true) must */
+                                    /* be included in the play channel linked list. */
+
+    volatile bool pageUsed;         /* Set true in if the page has been used in the */
+                                    /* PortAudio callback function */
+    volatile bool pageFinished;     /* True if the page has been finished (all record */
+                                    /* buffers full and all playout buffers 'empty') */
+                                    /* Once set, this and pnextStreamPage are the */
+                                    /* only variables the PortAudio callback will check */
+                                    /* (none are written) */
+    struct StreamPageStruct_tag *pnextStreamPage;
+                                    /* The next page in the linked list */
+} StreamPageStruct;
+
+
+/* The top level structure used to organise the stream and all data associated */
+/* with it.  If more than one stream is required simultaneously use multiple */
+/* StreamInfoStruct's with one per stream.  Provided some way to indicate */
+/* which stream to use is added to the commands, each stream should be able to */
+/* run completely independantly with only very little work. */
+/* For example, have a linked list containing all StreamInfoStruct's and then */
+/* a global variable pointing to the one in use.  An additional command would */
+/* be required to select which stream all other commands refer to, and doInit, */
+/* doReset and mexFunctionCalled would need to be modified slightly, but apart */
+/* from that everything else should be able to remain the same. */
+typedef struct {
+    StreamPageStruct *pfirstStreamPage;
+                                    /* First page in the linked list */
+
+    PaStream *pstream;              /* Pointer to the stream, or NULL for no stream */
+
+    time_t streamStartTime;         /* The start time of the stream, can be used to */
+                                    /* detemine if a new stream has been started. */
+
+    /* Configuration settings used when opening the stream - see Pa_OpenStream */
+    /* in portaudio.h for descriptions of these parameters: */
+    double suggestedSampleRate;
+
+    unsigned long suggestedFramesPerBuffer;
+    unsigned long minFramesPerBuffer;
+    unsigned long maxFramesPerBuffer;
+
+    PaTime        recSuggestedLatency;
+    PaTime        playSuggestedLatency;
+
+    PaStreamFlags streamFlags;
+
+    volatile bool stopStream;       /* Set true to trigger the callback to stop the */
+                                    /* stream. */
+
+    volatile bool inCallback;       /* Set true whilst in the callback. */
+
+    volatile unsigned long skippedSampleCount;
+                                    /* The number of samples that have been zeroed */
+                                    /* whilst there are no unfinished pages in the */
+                                    /* linked list.  Should only be modified in */
+                                    /* the callback.  Use resetSkippedSampleCount */
+                                    /* to reset the counter. */
+                                    /* If resetSkippedSampleCount is true the value */
+                                    /* of skippedSampleCount should be ignored and */
+                                    /* instead assumed to be 0. */
+    volatile bool resetSkippedSampleCount;
+                                    /* Set true to reset skippedSampleCount.  The reset */
+                                    /* takes place within the callback, at which point */
+                                    /* this is cleared.  This is to ensure it does always */
+                                    /* get cleared. */
+
+    volatile bool isPaused;         /* set true to 'pause' playback and recording */
+                                    /* Never stops the PortAudio stream, just alters */
+                                    /* the data transferred. */
+
+    PaDeviceIndex playDeviceID;     /* Device ID for the device being used, or */
+                                    /* PaNoDevice for no device */
+    PaDeviceIndex recDeviceID;      /* Device ID for the device being used, or */
+                                    /* PaNoDevice for no device */
+    unsigned int playChanCount;     /* The number of channels used to communicate */
+                                    /* with PortAudio.  Must be greater than */
+                                    /* the maximum channel number used. */
+    unsigned int recChanCount;      /* The number of channels used to communicate */
+                                    /* with PortAudio.  Must be greater than */
+                                    /* the maximum channel number used. */
+} StreamInfoStruct;
+
+/* Function prototypes */
+
+SAMPLE *convDouble(double *oldBuf, int buflen);
+SAMPLE *convFloat(float *oldBuf, int buflen);
+
+void validateState(int wantedStates, int rejectStates);
+
+void freeChanBufStructs(ChanBufStruct **ppcbs);
+void freeStreamPageStruct(StreamPageStruct **ppsps);
+void freeStreamInfoStruct(StreamInfoStruct **psis);
+
+StreamInfoStruct *newStreamInfoStruct(bool makeMemoryPersistent);
+
+StreamPageStruct *addStreamPageStruct(StreamInfoStruct *psis, StreamPageStruct *psps);
+StreamPageStruct *newStreamPageStruct(unsigned int portAudioPlayChanCount, bool makeMemoryPersistent);
+
+static int playrecCallback(const void *inputBuffer, void *outputBuffer,
+                           unsigned long frameCount,
+                           const PaStreamCallbackTimeInfo *timeInfo,
+                           PaStreamCallbackFlags statusFlags, void *userData );
+
+bool mexFunctionCalled(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+void condensePages(void);
+
+void exitFunc(void);
+PaError checkPAErr(PaError err);
+void abortIfPAErr(const char* msg);
+
+bool channelListToChanBufStructs(const mxArray *pmxChanArray, ChanBufStruct **ppfirstcbs, unsigned int minChanNum, unsigned int maxChanNum, bool makeMemoryPersistent);
+
+bool addPlayrecPage(mxArray **ppmxPageNum, const mxArray *pplayData, const mxArray *pplayChans, const mxArray *precDataLength, const mxArray *precChans);
+
+/* all 'do' functions return true if all input arguments are valid, otherwise */
+/* false (triggering display of the list of valid arguments) */
+bool doAbout(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doOverview(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doInit(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doPlayrec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doPlay(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doRec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetRec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetSampleRate(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetFramesPerBuffer(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetStreamStartTime(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetPlayDevice(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetRecDevice(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetPlayMaxChannel(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetRecMaxChannel(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetPlayLatency(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetRecLatency(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetPageList(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetCurrentPosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetLastFinishedPage(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doPause(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doBlock(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doIsFinished(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doIsInitialised(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doDelPage(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doReset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetDevices(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doGetSkippedSampleCount(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+bool doResetSkippedSampleCount(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PA_DLL_PLAYREC_H */

-- 
Alioth's /home/groups/pkg-octave/bin/git-commit-notice on /srv/git.debian.org/git/pkg-octave/octave-ltfat.git



More information about the Pkg-octave-commit mailing list