ltfat/0000775000175000017500000000000013026262276011572 5ustar susnaksusnakltfat/thirdparty/0000775000175000017500000000000013026262276013764 5ustar susnaksusnakltfat/thirdparty/polyboolclipper/0000775000175000017500000000000013026262276017202 5ustar susnaksusnakltfat/thirdparty/polyboolclipper/Makefile_mingw0000664000175000017500000000046413026262276022047 0ustar susnaksusnak# 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 MATLABROOT?=C:\Program Files\MATLAB\R2011b EXT?=mexw64 ARCH?=win64 include Makefile_unix ltfat/thirdparty/polyboolclipper/polyboolmex.cpp0000664000175000017500000001527313026262276022267 0ustar susnaksusnak// A mex interface to the Clipper library // // [pc, hf] = = polyboolmex(pa, pb, op, ha, hb, ug); // // pa : cell array with polygons (nx2 matrices) // pb : cell array with polygons (nx2 matrices) // op : polygon operation // ug : conversion factor for conversion from user // coordinates to integer grid coordinates // pc : a cell array containing one or more polygons that result // from applying the polygon operation to each (pair pa{k}, pb). // hf : hole flag array; when hf(k)==1, pc{k} is the interior boundary // of a hole. // // polygon operations are: // 'and' : polygon intersection // 'or' : polygon union // 'notb' or 'diff' : polygon difference // 'xor' : polygon union minus polygon difference // // Ulf Griesmann, NIST, August 2014 /* DISCLAIMER This software was developed at the National Institute of Standards and Technology by employees of the United States Federal Government in the course of their official duties. Pursuant to title 17 Section 105 of the United States Code this software is not subject to copyright protection and is in the public domain. This software is an experimental system. NIST assumes no responsibility whatsoever for its use by other parties, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Ulf Griesmann, June 2013 ulf.griesmann@nist.gov, ulfgri@gmail.com */ // NOTE: // C++ memory management in mex functions is a nightmare. In C, // calls to malloc can simply be redirected to mxMalloc etc., but in C++, // memory management is baked into the language. I am not sure that // all memory allocated by the Clipper library is freed, and memory // leaks are possible. Need to keep an eye on this ... #include "mex.h" #include "clipper.hpp" #define STR_LEN 8 //----------------------------------------------------------------- using namespace ClipperLib; // declare static to avoid memory leaks when the mex function exits static Paths pa, pb, pc; static Clipper C; void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray *par; // ptr to mxArray structure double *pda; // ptr to polynomial data double *pud; // pointer to unit conversion factor mxLogical *ph; // pointer to hole flags double ug, iug; unsigned int Na, Nb, vnu; unsigned int k, m; ClipType pop; char ostr[STR_LEN]; //string with polygon operation ////////////////// // check arguments // // argument number if (nrhs != 6) { mexErrMsgTxt("polyboolmex : expected 6 input arguments."); } // argument pa if ( !mxIsCell(prhs[0]) ) { mexErrMsgTxt("polyboolmex : argument pa must be a cell array."); } Na = mxGetM(prhs[0])*mxGetN(prhs[0]); if (!Na) { mexErrMsgTxt("polyboolmex : no input polygons pa."); } // argument pb if ( !mxIsCell(prhs[1]) ) { mexErrMsgTxt("polyboolmex : argument pb must be a cell array."); } Nb = mxGetM(prhs[1])*mxGetN(prhs[1]); if (!Nb) { mexErrMsgTxt("polyboolmex : no input polygons pb."); } // get operation argument mxGetString(prhs[2], ostr, STR_LEN); if ( !strncmp(ostr, "or", 2) ) pop = ctUnion; else if ( !strncmp(ostr, "and", 3) ) pop = ctIntersection; else if ( !strncmp(ostr, "notb", 4) ) pop = ctDifference; else if ( !strncmp(ostr, "diff", 4) ) pop = ctDifference; else if ( !strncmp(ostr, "xor", 3) ) pop = ctXor; else { pop = ctIntersection; // Just to avoid warning: ‘pop’ may be used uninitialized mexErrMsgTxt("polyboolmex : unknown boolean set algebra operation."); } // conversion factor argument pud = (double*)mxGetData(prhs[5]); ug = *pud; iug = 1.0/ug; //////////////////////// // copy and prepare data // // pa ph = (mxLogical *)mxGetData(prhs[3]); pa.resize(Na); for (k=0; k #include #include #include #include #include #include #include namespace ClipperLib { static double const pi = 3.141592653589793238; static double const two_pi = pi *2; static double const def_arc_tolerance = 0.25; enum Direction { dRightToLeft, dLeftToRight }; static int const Unassigned = -1; //edge not currently 'owning' a solution static int const Skip = -2; //edge that would otherwise close a path #define HORIZONTAL (-1.0E+40) #define TOLERANCE (1.0e-20) #define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE)) struct TEdge { IntPoint Bot; IntPoint Curr; IntPoint Top; IntPoint Delta; double Dx; PolyType PolyTyp; EdgeSide Side; int WindDelta; //1 or -1 depending on winding direction int WindCnt; int WindCnt2; //winding count of the opposite polytype int OutIdx; TEdge *Next; TEdge *Prev; TEdge *NextInLML; TEdge *NextInAEL; TEdge *PrevInAEL; TEdge *NextInSEL; TEdge *PrevInSEL; }; struct IntersectNode { TEdge *Edge1; TEdge *Edge2; IntPoint Pt; }; struct LocalMinimum { cInt Y; TEdge *LeftBound; TEdge *RightBound; }; struct OutPt; struct OutRec { int Idx; bool IsHole; bool IsOpen; OutRec *FirstLeft; //see comments in clipper.pas PolyNode *PolyNd; OutPt *Pts; OutPt *BottomPt; }; struct OutPt { int Idx; IntPoint Pt; OutPt *Next; OutPt *Prev; }; struct Join { OutPt *OutPt1; OutPt *OutPt2; IntPoint OffPt; }; struct LocMinSorter { inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2) { return locMin2.Y < locMin1.Y; } }; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ inline cInt Round(double val) { if ((val < 0)) return static_cast(val - 0.5); else return static_cast(val + 0.5); } //------------------------------------------------------------------------------ inline cInt Abs(cInt val) { return val < 0 ? -val : val; } //------------------------------------------------------------------------------ // PolyTree methods ... //------------------------------------------------------------------------------ void PolyTree::Clear() { for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i) delete AllNodes[i]; AllNodes.resize(0); Childs.resize(0); } //------------------------------------------------------------------------------ PolyNode* PolyTree::GetFirst() const { if (!Childs.empty()) return Childs[0]; else return 0; } //------------------------------------------------------------------------------ int PolyTree::Total() const { int result = (int)AllNodes.size(); //with negative offsets, ignore the hidden outer polygon ... if (result > 0 && Childs[0] != AllNodes[0]) result--; return result; } //------------------------------------------------------------------------------ // PolyNode methods ... //------------------------------------------------------------------------------ PolyNode::PolyNode(): Childs(), Parent(0), Index(0), m_IsOpen(false) { } //------------------------------------------------------------------------------ int PolyNode::ChildCount() const { return (int)Childs.size(); } //------------------------------------------------------------------------------ void PolyNode::AddChild(PolyNode& child) { unsigned cnt = (unsigned)Childs.size(); Childs.push_back(&child); child.Parent = this; child.Index = cnt; } //------------------------------------------------------------------------------ PolyNode* PolyNode::GetNext() const { if (!Childs.empty()) return Childs[0]; else return GetNextSiblingUp(); } //------------------------------------------------------------------------------ PolyNode* PolyNode::GetNextSiblingUp() const { if (!Parent) //protects against PolyTree.GetNextSiblingUp() return 0; else if (Index == Parent->Childs.size() - 1) return Parent->GetNextSiblingUp(); else return Parent->Childs[Index + 1]; } //------------------------------------------------------------------------------ bool PolyNode::IsHole() const { bool result = true; PolyNode* node = Parent; while (node) { result = !result; node = node->Parent; } return result; } //------------------------------------------------------------------------------ bool PolyNode::IsOpen() const { return m_IsOpen; } //------------------------------------------------------------------------------ #ifndef use_int32 //------------------------------------------------------------------------------ // Int128 class (enables safe math on signed 64bit integers) // eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1 // Int128 val2((long64)9223372036854775807); // Int128 val3 = val1 * val2; // val3.AsString => "85070591730234615847396907784232501249" (8.5e+37) //------------------------------------------------------------------------------ class Int128 { public: ulong64 lo; long64 hi; Int128(long64 _lo = 0) { lo = (ulong64)_lo; if (_lo < 0) hi = -1; else hi = 0; } Int128(const Int128 &val): lo(val.lo), hi(val.hi){} Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){} Int128& operator = (const long64 &val) { lo = (ulong64)val; if (val < 0) hi = -1; else hi = 0; return *this; } bool operator == (const Int128 &val) const {return (hi == val.hi && lo == val.lo);} bool operator != (const Int128 &val) const { return !(*this == val);} bool operator > (const Int128 &val) const { if (hi != val.hi) return hi > val.hi; else return lo > val.lo; } bool operator < (const Int128 &val) const { if (hi != val.hi) return hi < val.hi; else return lo < val.lo; } bool operator >= (const Int128 &val) const { return !(*this < val);} bool operator <= (const Int128 &val) const { return !(*this > val);} Int128& operator += (const Int128 &rhs) { hi += rhs.hi; lo += rhs.lo; if (lo < rhs.lo) hi++; return *this; } Int128 operator + (const Int128 &rhs) const { Int128 result(*this); result+= rhs; return result; } Int128& operator -= (const Int128 &rhs) { *this += -rhs; return *this; } Int128 operator - (const Int128 &rhs) const { Int128 result(*this); result -= rhs; return result; } Int128 operator-() const //unary negation { if (lo == 0) return Int128(-hi, 0); else return Int128(~hi, ~lo + 1); } operator double() const { const double shift64 = 18446744073709551616.0; //2^64 if (hi < 0) { if (lo == 0) return (double)hi * shift64; else return -(double)(~lo + ~hi * shift64); } else return (double)(lo + hi * shift64); } }; //------------------------------------------------------------------------------ Int128 Int128Mul (long64 lhs, long64 rhs) { bool negate = (lhs < 0) != (rhs < 0); if (lhs < 0) lhs = -lhs; ulong64 int1Hi = ulong64(lhs) >> 32; ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF); if (rhs < 0) rhs = -rhs; ulong64 int2Hi = ulong64(rhs) >> 32; ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF); //nb: see comments in clipper.pas ulong64 a = int1Hi * int2Hi; ulong64 b = int1Lo * int2Lo; ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi; Int128 tmp; tmp.hi = long64(a + (c >> 32)); tmp.lo = long64(c << 32); tmp.lo += long64(b); if (tmp.lo < b) tmp.hi++; if (negate) tmp = -tmp; return tmp; }; #endif //------------------------------------------------------------------------------ // Miscellaneous global functions //------------------------------------------------------------------------------ void Swap(cInt& val1, cInt& val2) { cInt tmp = val1; val1 = val2; val2 = tmp; } //------------------------------------------------------------------------------ bool Orientation(const Path &poly) { return Area(poly) >= 0; } //------------------------------------------------------------------------------ double Area(const Path &poly) { int size = (int)poly.size(); if (size < 3) return 0; double a = 0; for (int i = 0, j = size -1; i < size; ++i) { a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y); j = i; } return -a * 0.5; } //------------------------------------------------------------------------------ double Area(const OutRec &outRec) { OutPt *op = outRec.Pts; if (!op) return 0; double a = 0; do { a += (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y); op = op->Next; } while (op != outRec.Pts); return a * 0.5; } //------------------------------------------------------------------------------ bool PointIsVertex(const IntPoint &Pt, OutPt *pp) { OutPt *pp2 = pp; do { if (pp2->Pt == Pt) return true; pp2 = pp2->Next; } while (pp2 != pp); return false; } //------------------------------------------------------------------------------ int PointInPolygon (const IntPoint &pt, const Path &path) { //returns 0 if false, +1 if true, -1 if pt ON polygon boundary //See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos //http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf int result = 0; size_t cnt = path.size(); if (cnt < 3) return 0; IntPoint ip = path[0]; for(size_t i = 1; i <= cnt; ++i) { IntPoint ipNext = (i == cnt ? path[0] : path[i]); if (ipNext.Y == pt.Y) { if ((ipNext.X == pt.X) || (ip.Y == pt.Y && ((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1; } if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y)) { if (ip.X >= pt.X) { if (ipNext.X > pt.X) result = 1 - result; else { double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - (double)(ipNext.X - pt.X) * (ip.Y - pt.Y); if (!d) return -1; if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result; } } else { if (ipNext.X > pt.X) { double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - (double)(ipNext.X - pt.X) * (ip.Y - pt.Y); if (!d) return -1; if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result; } } } ip = ipNext; } return result; } //------------------------------------------------------------------------------ int PointInPolygon (const IntPoint &pt, OutPt *op) { //returns 0 if false, +1 if true, -1 if pt ON polygon boundary int result = 0; OutPt* startOp = op; for(;;) { if (op->Next->Pt.Y == pt.Y) { if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y && ((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1; } if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y)) { if (op->Pt.X >= pt.X) { if (op->Next->Pt.X > pt.X) result = 1 - result; else { double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); if (!d) return -1; if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; } } else { if (op->Next->Pt.X > pt.X) { double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); if (!d) return -1; if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; } } } op = op->Next; if (startOp == op) break; } return result; } //------------------------------------------------------------------------------ bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2) { OutPt* op = OutPt1; do { //nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon int res = PointInPolygon(op->Pt, OutPt2); if (res >= 0) return res > 0; op = op->Next; } while (op != OutPt1); return true; } //---------------------------------------------------------------------- bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range) { #ifndef use_int32 if (UseFullInt64Range) return Int128Mul(e1.Delta.Y, e2.Delta.X) == Int128Mul(e1.Delta.X, e2.Delta.Y); else #endif return e1.Delta.Y * e2.Delta.X == e1.Delta.X * e2.Delta.Y; } //------------------------------------------------------------------------------ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3, bool UseFullInt64Range) { #ifndef use_int32 if (UseFullInt64Range) return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y); else #endif return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); } //------------------------------------------------------------------------------ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) { #ifndef use_int32 if (UseFullInt64Range) return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y); else #endif return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); } //------------------------------------------------------------------------------ inline bool IsHorizontal(TEdge &e) { return e.Delta.Y == 0; } //------------------------------------------------------------------------------ inline double GetDx(const IntPoint pt1, const IntPoint pt2) { return (pt1.Y == pt2.Y) ? HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); } //--------------------------------------------------------------------------- inline void SetDx(TEdge &e) { e.Delta.X = (e.Top.X - e.Bot.X); e.Delta.Y = (e.Top.Y - e.Bot.Y); if (e.Delta.Y == 0) e.Dx = HORIZONTAL; else e.Dx = (double)(e.Delta.X) / e.Delta.Y; } //--------------------------------------------------------------------------- inline void SwapSides(TEdge &Edge1, TEdge &Edge2) { EdgeSide Side = Edge1.Side; Edge1.Side = Edge2.Side; Edge2.Side = Side; } //------------------------------------------------------------------------------ inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2) { int OutIdx = Edge1.OutIdx; Edge1.OutIdx = Edge2.OutIdx; Edge2.OutIdx = OutIdx; } //------------------------------------------------------------------------------ inline cInt TopX(TEdge &edge, const cInt currentY) { return ( currentY == edge.Top.Y ) ? edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); } //------------------------------------------------------------------------------ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip) { #ifdef use_xyz ip.Z = 0; #endif double b1, b2; if (Edge1.Dx == Edge2.Dx) { ip.Y = Edge1.Curr.Y; ip.X = TopX(Edge1, ip.Y); return; } else if (Edge1.Delta.X == 0) { ip.X = Edge1.Bot.X; if (IsHorizontal(Edge2)) ip.Y = Edge2.Bot.Y; else { b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx); ip.Y = Round(ip.X / Edge2.Dx + b2); } } else if (Edge2.Delta.X == 0) { ip.X = Edge2.Bot.X; if (IsHorizontal(Edge1)) ip.Y = Edge1.Bot.Y; else { b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx); ip.Y = Round(ip.X / Edge1.Dx + b1); } } else { b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx; b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx; double q = (b2-b1) / (Edge1.Dx - Edge2.Dx); ip.Y = Round(q); if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) ip.X = Round(Edge1.Dx * q + b1); else ip.X = Round(Edge2.Dx * q + b2); } if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y) { if (Edge1.Top.Y > Edge2.Top.Y) ip.Y = Edge1.Top.Y; else ip.Y = Edge2.Top.Y; if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) ip.X = TopX(Edge1, ip.Y); else ip.X = TopX(Edge2, ip.Y); } //finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ... if (ip.Y > Edge1.Curr.Y) { ip.Y = Edge1.Curr.Y; //use the more vertical edge to derive X ... if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx)) ip.X = TopX(Edge2, ip.Y); else ip.X = TopX(Edge1, ip.Y); } } //------------------------------------------------------------------------------ void ReversePolyPtLinks(OutPt *pp) { if (!pp) return; OutPt *pp1, *pp2; pp1 = pp; do { pp2 = pp1->Next; pp1->Next = pp1->Prev; pp1->Prev = pp2; pp1 = pp2; } while( pp1 != pp ); } //------------------------------------------------------------------------------ void DisposeOutPts(OutPt*& pp) { if (pp == 0) return; pp->Prev->Next = 0; while( pp ) { OutPt *tmpPp = pp; pp = pp->Next; delete tmpPp; } } //------------------------------------------------------------------------------ inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt) { std::memset(e, 0, sizeof(TEdge)); e->Next = eNext; e->Prev = ePrev; e->Curr = Pt; e->OutIdx = Unassigned; } //------------------------------------------------------------------------------ void InitEdge2(TEdge& e, PolyType Pt) { if (e.Curr.Y >= e.Next->Curr.Y) { e.Bot = e.Curr; e.Top = e.Next->Curr; } else { e.Top = e.Curr; e.Bot = e.Next->Curr; } SetDx(e); e.PolyTyp = Pt; } //------------------------------------------------------------------------------ TEdge* RemoveEdge(TEdge* e) { //removes e from double_linked_list (but without removing from memory) e->Prev->Next = e->Next; e->Next->Prev = e->Prev; TEdge* result = e->Next; e->Prev = 0; //flag as removed (see ClipperBase.Clear) return result; } //------------------------------------------------------------------------------ inline void ReverseHorizontal(TEdge &e) { //swap horizontal edges' Top and Bottom x's so they follow the natural //progression of the bounds - ie so their xbots will align with the //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] Swap(e.Top.X, e.Bot.X); #ifdef use_xyz Swap(e.Top.Z, e.Bot.Z); #endif } //------------------------------------------------------------------------------ void SwapPoints(IntPoint &pt1, IntPoint &pt2) { IntPoint tmp = pt1; pt1 = pt2; pt2 = tmp; } //------------------------------------------------------------------------------ bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, IntPoint pt2b, IntPoint &pt1, IntPoint &pt2) { //precondition: segments are Collinear. if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y)) { if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b); if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b); if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a; if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b; return pt1.X < pt2.X; } else { if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b); if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b); if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a; if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b; return pt1.Y > pt2.Y; } } //------------------------------------------------------------------------------ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) { OutPt *p = btmPt1->Prev; while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev; double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt)); p = btmPt1->Next; while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next; double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt)); p = btmPt2->Prev; while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev; double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt)); p = btmPt2->Next; while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next; double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt)); return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); } //------------------------------------------------------------------------------ OutPt* GetBottomPt(OutPt *pp) { OutPt* dups = 0; OutPt* p = pp->Next; while (p != pp) { if (p->Pt.Y > pp->Pt.Y) { pp = p; dups = 0; } else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X) { if (p->Pt.X < pp->Pt.X) { dups = 0; pp = p; } else { if (p->Next != pp && p->Prev != pp) dups = p; } } p = p->Next; } if (dups) { //there appears to be at least 2 vertices at BottomPt so ... while (dups != p) { if (!FirstIsBottomPt(p, dups)) pp = dups; dups = dups->Next; while (dups->Pt != pp->Pt) dups = dups->Next; } } return pp; } //------------------------------------------------------------------------------ bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3) { if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) return false; else if (pt1.X != pt3.X) return (pt2.X > pt1.X) == (pt2.X < pt3.X); else return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y); } //------------------------------------------------------------------------------ bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b) { if (seg1a > seg1b) Swap(seg1a, seg1b); if (seg2a > seg2b) Swap(seg2a, seg2b); return (seg1a < seg2b) && (seg2a < seg1b); } //------------------------------------------------------------------------------ // ClipperBase class methods ... //------------------------------------------------------------------------------ ClipperBase::ClipperBase() //constructor { m_CurrentLM = m_MinimaList.begin(); //begin() == end() here m_UseFullRange = false; } //------------------------------------------------------------------------------ ClipperBase::~ClipperBase() //destructor { Clear(); } //------------------------------------------------------------------------------ void RangeTest(const IntPoint& Pt, bool& useFullRange) { if (useFullRange) { if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) throw "Coordinate outside allowed range"; } else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) { useFullRange = true; RangeTest(Pt, useFullRange); } } //------------------------------------------------------------------------------ TEdge* FindNextLocMin(TEdge* E) { for (;;) { while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next; if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break; while (IsHorizontal(*E->Prev)) E = E->Prev; TEdge* E2 = E; while (IsHorizontal(*E)) E = E->Next; if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz. if (E2->Prev->Bot.X < E->Bot.X) E = E2; break; } return E; } //------------------------------------------------------------------------------ TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) { TEdge *Result = E; TEdge *Horz = 0; if (E->OutIdx == Skip) { //if edges still remain in the current bound beyond the skip edge then //create another LocMin and call ProcessBound once more if (NextIsForward) { while (E->Top.Y == E->Next->Bot.Y) E = E->Next; //don't include top horizontals when parsing a bound a second time, //they will be contained in the opposite bound ... while (E != Result && IsHorizontal(*E)) E = E->Prev; } else { while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev; while (E != Result && IsHorizontal(*E)) E = E->Next; } if (E == Result) { if (NextIsForward) Result = E->Next; else Result = E->Prev; } else { //there are more edges in the bound beyond result starting with E if (NextIsForward) E = Result->Next; else E = Result->Prev; MinimaList::value_type locMin; locMin.Y = E->Bot.Y; locMin.LeftBound = 0; locMin.RightBound = E; E->WindDelta = 0; Result = ProcessBound(E, NextIsForward); m_MinimaList.push_back(locMin); } return Result; } TEdge *EStart; if (IsHorizontal(*E)) { //We need to be careful with open paths because this may not be a //true local minima (ie E may be following a skip edge). //Also, consecutive horz. edges may start heading left before going right. if (NextIsForward) EStart = E->Prev; else EStart = E->Next; if (EStart->OutIdx != Skip) { if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge { if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X) ReverseHorizontal(*E); } else if (EStart->Bot.X != E->Bot.X) ReverseHorizontal(*E); } } EStart = E; if (NextIsForward) { while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip) Result = Result->Next; if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip) { //nb: at the top of a bound, horizontals are added to the bound //only when the preceding edge attaches to the horizontal's left vertex //unless a Skip edge is encountered when that becomes the top divide Horz = Result; while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev; if (Horz->Prev->Top.X == Result->Next->Top.X) { if (!NextIsForward) Result = Horz->Prev; } else if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev; } while (E != Result) { E->NextInLML = E->Next; if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); E = E->Next; } if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); Result = Result->Next; //move to the edge just beyond current bound } else { while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip) Result = Result->Prev; if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip) { Horz = Result; while (IsHorizontal(*Horz->Next)) Horz = Horz->Next; if (Horz->Next->Top.X == Result->Prev->Top.X) { if (!NextIsForward) Result = Horz->Next; } else if (Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next; } while (E != Result) { E->NextInLML = E->Prev; if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) ReverseHorizontal(*E); E = E->Prev; } if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) ReverseHorizontal(*E); Result = Result->Prev; //move to the edge just beyond current bound } return Result; } //------------------------------------------------------------------------------ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) { #ifdef use_lines if (!Closed && PolyTyp == ptClip) throw clipperException("AddPath: Open paths must be subject."); #else if (!Closed) throw clipperException("AddPath: Open paths have been disabled."); #endif int highI = (int)pg.size() -1; if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI; while (highI > 0 && (pg[highI] == pg[highI -1])) --highI; if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; //create a new edge array ... TEdge *edges = new TEdge [highI +1]; bool IsFlat = true; //1. Basic (first) edge initialization ... try { edges[1].Curr = pg[1]; RangeTest(pg[0], m_UseFullRange); RangeTest(pg[highI], m_UseFullRange); InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]); InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]); for (int i = highI - 1; i >= 1; --i) { RangeTest(pg[i], m_UseFullRange); InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); } } catch(...) { delete [] edges; throw; //range test fails } TEdge *eStart = &edges[0]; //2. Remove duplicate vertices, and (when closed) collinear edges ... TEdge *E = eStart, *eLoopStop = eStart; for (;;) { //nb: allows matching start and end points when not Closed ... if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart)) { if (E == E->Next) break; if (E == eStart) eStart = E->Next; E = RemoveEdge(E); eLoopStop = E; continue; } if (E->Prev == E->Next) break; //only two vertices else if (Closed && SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) && (!m_PreserveCollinear || !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr))) { //Collinear edges are allowed for open paths but in closed paths //the default is to merge adjacent collinear edges into a single edge. //However, if the PreserveCollinear property is enabled, only overlapping //collinear edges (ie spikes) will be removed from closed paths. if (E == eStart) eStart = E->Next; E = RemoveEdge(E); E = E->Prev; eLoopStop = E; continue; } E = E->Next; if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break; } if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next))) { delete [] edges; return false; } if (!Closed) { m_HasOpenPaths = true; eStart->Prev->OutIdx = Skip; } //3. Do second stage of edge initialization ... E = eStart; do { InitEdge2(*E, PolyTyp); E = E->Next; if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false; } while (E != eStart); //4. Finally, add edge bounds to LocalMinima list ... //Totally flat paths must be handled differently when adding them //to LocalMinima list to avoid endless loops etc ... if (IsFlat) { if (Closed) { delete [] edges; return false; } E->Prev->OutIdx = Skip; if (E->Prev->Bot.X < E->Prev->Top.X) ReverseHorizontal(*E->Prev); MinimaList::value_type locMin; locMin.Y = E->Bot.Y; locMin.LeftBound = 0; locMin.RightBound = E; locMin.RightBound->Side = esRight; locMin.RightBound->WindDelta = 0; while (E->Next->OutIdx != Skip) { E->NextInLML = E->Next; if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); E = E->Next; } m_MinimaList.push_back(locMin); m_edges.push_back(edges); return true; } m_edges.push_back(edges); bool leftBoundIsForward; TEdge* EMin = 0; //workaround to avoid an endless loop in the while loop below when //open paths have matching start and end points ... if (E->Prev->Bot == E->Prev->Top) E = E->Next; for (;;) { E = FindNextLocMin(E); if (E == EMin) break; else if (!EMin) EMin = E; //E and E.Prev now share a local minima (left aligned if horizontal). //Compare their slopes to find which starts which bound ... MinimaList::value_type locMin; locMin.Y = E->Bot.Y; if (E->Dx < E->Prev->Dx) { locMin.LeftBound = E->Prev; locMin.RightBound = E; leftBoundIsForward = false; //Q.nextInLML = Q.prev } else { locMin.LeftBound = E; locMin.RightBound = E->Prev; leftBoundIsForward = true; //Q.nextInLML = Q.next } locMin.LeftBound->Side = esLeft; locMin.RightBound->Side = esRight; if (!Closed) locMin.LeftBound->WindDelta = 0; else if (locMin.LeftBound->Next == locMin.RightBound) locMin.LeftBound->WindDelta = -1; else locMin.LeftBound->WindDelta = 1; locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta; E = ProcessBound(locMin.LeftBound, leftBoundIsForward); if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward); TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward); if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward); if (locMin.LeftBound->OutIdx == Skip) locMin.LeftBound = 0; else if (locMin.RightBound->OutIdx == Skip) locMin.RightBound = 0; m_MinimaList.push_back(locMin); if (!leftBoundIsForward) E = E2; } return true; } //------------------------------------------------------------------------------ bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) { bool result = false; for (Paths::size_type i = 0; i < ppg.size(); ++i) if (AddPath(ppg[i], PolyTyp, Closed)) result = true; return result; } //------------------------------------------------------------------------------ void ClipperBase::Clear() { DisposeLocalMinimaList(); for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) { //for each edge array in turn, find the first used edge and //check for and remove any hiddenPts in each edge in the array. TEdge* edges = m_edges[i]; delete [] edges; } m_edges.clear(); m_UseFullRange = false; m_HasOpenPaths = false; } //------------------------------------------------------------------------------ void ClipperBase::Reset() { m_CurrentLM = m_MinimaList.begin(); if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter()); //reset all edges ... for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm) { TEdge* e = lm->LeftBound; if (e) { e->Curr = e->Bot; e->Side = esLeft; e->OutIdx = Unassigned; } e = lm->RightBound; if (e) { e->Curr = e->Bot; e->Side = esRight; e->OutIdx = Unassigned; } } } //------------------------------------------------------------------------------ void ClipperBase::DisposeLocalMinimaList() { m_MinimaList.clear(); m_CurrentLM = m_MinimaList.begin(); } //------------------------------------------------------------------------------ void ClipperBase::PopLocalMinima() { if (m_CurrentLM == m_MinimaList.end()) return; ++m_CurrentLM; } //------------------------------------------------------------------------------ IntRect ClipperBase::GetBounds() { IntRect result; MinimaList::iterator lm = m_MinimaList.begin(); if (lm == m_MinimaList.end()) { result.left = result.top = result.right = result.bottom = 0; return result; } result.left = lm->LeftBound->Bot.X; result.top = lm->LeftBound->Bot.Y; result.right = lm->LeftBound->Bot.X; result.bottom = lm->LeftBound->Bot.Y; while (lm != m_MinimaList.end()) { result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y); TEdge* e = lm->LeftBound; for (;;) { TEdge* bottomE = e; while (e->NextInLML) { if (e->Bot.X < result.left) result.left = e->Bot.X; if (e->Bot.X > result.right) result.right = e->Bot.X; e = e->NextInLML; } result.left = std::min(result.left, e->Bot.X); result.right = std::max(result.right, e->Bot.X); result.left = std::min(result.left, e->Top.X); result.right = std::max(result.right, e->Top.X); result.top = std::min(result.top, e->Top.Y); if (bottomE == lm->LeftBound) e = lm->RightBound; else break; } ++lm; } return result; } //------------------------------------------------------------------------------ // TClipper methods ... //------------------------------------------------------------------------------ Clipper::Clipper(int initOptions) : ClipperBase() //constructor { m_ActiveEdges = 0; m_SortedEdges = 0; m_ExecuteLocked = false; m_UseFullRange = false; m_ReverseOutput = ((initOptions & ioReverseSolution) != 0); m_StrictSimple = ((initOptions & ioStrictlySimple) != 0); m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0); m_HasOpenPaths = false; #ifdef use_xyz m_ZFill = 0; #endif } //------------------------------------------------------------------------------ Clipper::~Clipper() //destructor { Clear(); } //------------------------------------------------------------------------------ #ifdef use_xyz void Clipper::ZFillFunction(ZFillCallback zFillFunc) { m_ZFill = zFillFunc; } //------------------------------------------------------------------------------ #endif void Clipper::Reset() { ClipperBase::Reset(); m_Scanbeam = ScanbeamList(); m_ActiveEdges = 0; m_SortedEdges = 0; for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm) InsertScanbeam(lm->Y); } //------------------------------------------------------------------------------ bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, PolyFillType clipFillType) { if( m_ExecuteLocked ) return false; if (m_HasOpenPaths) throw clipperException("Error: PolyTree struct is need for open path clipping."); m_ExecuteLocked = true; solution.resize(0); m_SubjFillType = subjFillType; m_ClipFillType = clipFillType; m_ClipType = clipType; m_UsingPolyTree = false; bool succeeded = ExecuteInternal(); if (succeeded) BuildResult(solution); DisposeAllOutRecs(); m_ExecuteLocked = false; return succeeded; } //------------------------------------------------------------------------------ bool Clipper::Execute(ClipType clipType, PolyTree& polytree, PolyFillType subjFillType, PolyFillType clipFillType) { if( m_ExecuteLocked ) return false; m_ExecuteLocked = true; m_SubjFillType = subjFillType; m_ClipFillType = clipFillType; m_ClipType = clipType; m_UsingPolyTree = true; bool succeeded = ExecuteInternal(); if (succeeded) BuildResult2(polytree); DisposeAllOutRecs(); m_ExecuteLocked = false; return succeeded; } //------------------------------------------------------------------------------ void Clipper::FixHoleLinkage(OutRec &outrec) { //skip OutRecs that (a) contain outermost polygons or //(b) already have the correct owner/child linkage ... if (!outrec.FirstLeft || (outrec.IsHole != outrec.FirstLeft->IsHole && outrec.FirstLeft->Pts)) return; OutRec* orfl = outrec.FirstLeft; while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts)) orfl = orfl->FirstLeft; outrec.FirstLeft = orfl; } //------------------------------------------------------------------------------ bool Clipper::ExecuteInternal() { bool succeeded = true; try { Reset(); if (m_CurrentLM == m_MinimaList.end()) return true; cInt botY = PopScanbeam(); do { InsertLocalMinimaIntoAEL(botY); ClearGhostJoins(); ProcessHorizontals(false); if (m_Scanbeam.empty()) break; cInt topY = PopScanbeam(); succeeded = ProcessIntersections(topY); if (!succeeded) break; ProcessEdgesAtTopOfScanbeam(topY); botY = topY; } while (!m_Scanbeam.empty() || m_CurrentLM != m_MinimaList.end()); } catch(...) { succeeded = false; } if (succeeded) { //fix orientations ... for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { OutRec *outRec = m_PolyOuts[i]; if (!outRec->Pts || outRec->IsOpen) continue; if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0)) ReversePolyPtLinks(outRec->Pts); } if (!m_Joins.empty()) JoinCommonEdges(); //unfortunately FixupOutPolygon() must be done after JoinCommonEdges() for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { OutRec *outRec = m_PolyOuts[i]; if (outRec->Pts && !outRec->IsOpen) FixupOutPolygon(*outRec); } if (m_StrictSimple) DoSimplePolygons(); } ClearJoins(); ClearGhostJoins(); return succeeded; } //------------------------------------------------------------------------------ void Clipper::InsertScanbeam(const cInt Y) { //if (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) return;// avoid duplicates. m_Scanbeam.push(Y); } //------------------------------------------------------------------------------ cInt Clipper::PopScanbeam() { const cInt Y = m_Scanbeam.top(); m_Scanbeam.pop(); while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates. return Y; } //------------------------------------------------------------------------------ void Clipper::DisposeAllOutRecs(){ for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) DisposeOutRec(i); m_PolyOuts.clear(); } //------------------------------------------------------------------------------ void Clipper::DisposeOutRec(PolyOutList::size_type index) { OutRec *outRec = m_PolyOuts[index]; if (outRec->Pts) DisposeOutPts(outRec->Pts); delete outRec; m_PolyOuts[index] = 0; } //------------------------------------------------------------------------------ void Clipper::SetWindingCount(TEdge &edge) { TEdge *e = edge.PrevInAEL; //find the edge of the same polytype that immediately preceeds 'edge' in AEL while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL; if (!e) { edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); edge.WindCnt2 = 0; e = m_ActiveEdges; //ie get ready to calc WindCnt2 } else if (edge.WindDelta == 0 && m_ClipType != ctUnion) { edge.WindCnt = 1; edge.WindCnt2 = e->WindCnt2; e = e->NextInAEL; //ie get ready to calc WindCnt2 } else if (IsEvenOddFillType(edge)) { //EvenOdd filling ... if (edge.WindDelta == 0) { //are we inside a subj polygon ... bool Inside = true; TEdge *e2 = e->PrevInAEL; while (e2) { if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0) Inside = !Inside; e2 = e2->PrevInAEL; } edge.WindCnt = (Inside ? 0 : 1); } else { edge.WindCnt = edge.WindDelta; } edge.WindCnt2 = e->WindCnt2; e = e->NextInAEL; //ie get ready to calc WindCnt2 } else { //nonZero, Positive or Negative filling ... if (e->WindCnt * e->WindDelta < 0) { //prev edge is 'decreasing' WindCount (WC) toward zero //so we're outside the previous polygon ... if (Abs(e->WindCnt) > 1) { //outside prev poly but still inside another. //when reversing direction of prev poly use the same WC if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; //otherwise continue to 'decrease' WC ... else edge.WindCnt = e->WindCnt + edge.WindDelta; } else //now outside all polys of same polytype so set own WC ... edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); } else { //prev edge is 'increasing' WindCount (WC) away from zero //so we're inside the previous polygon ... if (edge.WindDelta == 0) edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1); //if wind direction is reversing prev then use same WC else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; //otherwise add to WC ... else edge.WindCnt = e->WindCnt + edge.WindDelta; } edge.WindCnt2 = e->WindCnt2; e = e->NextInAEL; //ie get ready to calc WindCnt2 } //update WindCnt2 ... if (IsEvenOddAltFillType(edge)) { //EvenOdd filling ... while (e != &edge) { if (e->WindDelta != 0) edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0); e = e->NextInAEL; } } else { //nonZero, Positive or Negative filling ... while ( e != &edge ) { edge.WindCnt2 += e->WindDelta; e = e->NextInAEL; } } } //------------------------------------------------------------------------------ bool Clipper::IsEvenOddFillType(const TEdge& edge) const { if (edge.PolyTyp == ptSubject) return m_SubjFillType == pftEvenOdd; else return m_ClipFillType == pftEvenOdd; } //------------------------------------------------------------------------------ bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const { if (edge.PolyTyp == ptSubject) return m_ClipFillType == pftEvenOdd; else return m_SubjFillType == pftEvenOdd; } //------------------------------------------------------------------------------ bool Clipper::IsContributing(const TEdge& edge) const { PolyFillType pft, pft2; if (edge.PolyTyp == ptSubject) { pft = m_SubjFillType; pft2 = m_ClipFillType; } else { pft = m_ClipFillType; pft2 = m_SubjFillType; } switch(pft) { case pftEvenOdd: //return false if a subj line has been flagged as inside a subj polygon if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; break; case pftNonZero: if (Abs(edge.WindCnt) != 1) return false; break; case pftPositive: if (edge.WindCnt != 1) return false; break; default: //pftNegative if (edge.WindCnt != -1) return false; } switch(m_ClipType) { case ctIntersection: switch(pft2) { case pftEvenOdd: case pftNonZero: return (edge.WindCnt2 != 0); case pftPositive: return (edge.WindCnt2 > 0); default: return (edge.WindCnt2 < 0); } break; case ctUnion: switch(pft2) { case pftEvenOdd: case pftNonZero: return (edge.WindCnt2 == 0); case pftPositive: return (edge.WindCnt2 <= 0); default: return (edge.WindCnt2 >= 0); } break; case ctDifference: if (edge.PolyTyp == ptSubject) switch(pft2) { case pftEvenOdd: case pftNonZero: return (edge.WindCnt2 == 0); case pftPositive: return (edge.WindCnt2 <= 0); default: return (edge.WindCnt2 >= 0); } else switch(pft2) { case pftEvenOdd: case pftNonZero: return (edge.WindCnt2 != 0); case pftPositive: return (edge.WindCnt2 > 0); default: return (edge.WindCnt2 < 0); } break; case ctXor: if (edge.WindDelta == 0) //XOr always contributing unless open switch(pft2) { case pftEvenOdd: case pftNonZero: return (edge.WindCnt2 == 0); case pftPositive: return (edge.WindCnt2 <= 0); default: return (edge.WindCnt2 >= 0); } else return true; break; default: return true; } } //------------------------------------------------------------------------------ OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) { OutPt* result; TEdge *e, *prevE; if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx )) { result = AddOutPt(e1, Pt); e2->OutIdx = e1->OutIdx; e1->Side = esLeft; e2->Side = esRight; e = e1; if (e->PrevInAEL == e2) prevE = e2->PrevInAEL; else prevE = e->PrevInAEL; } else { result = AddOutPt(e2, Pt); e1->OutIdx = e2->OutIdx; e1->Side = esRight; e2->Side = esLeft; e = e2; if (e->PrevInAEL == e1) prevE = e1->PrevInAEL; else prevE = e->PrevInAEL; } if (prevE && prevE->OutIdx >= 0 && (TopX(*prevE, Pt.Y) == TopX(*e, Pt.Y)) && SlopesEqual(*e, *prevE, m_UseFullRange) && (e->WindDelta != 0) && (prevE->WindDelta != 0)) { OutPt* outPt = AddOutPt(prevE, Pt); AddJoin(result, outPt, e->Top); } return result; } //------------------------------------------------------------------------------ void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) { AddOutPt( e1, Pt ); if (e2->WindDelta == 0) AddOutPt(e2, Pt); if( e1->OutIdx == e2->OutIdx ) { e1->OutIdx = Unassigned; e2->OutIdx = Unassigned; } else if (e1->OutIdx < e2->OutIdx) AppendPolygon(e1, e2); else AppendPolygon(e2, e1); } //------------------------------------------------------------------------------ void Clipper::AddEdgeToSEL(TEdge *edge) { //SEL pointers in PEdge are reused to build a list of horizontal edges. //However, we don't need to worry about order with horizontal edge processing. if( !m_SortedEdges ) { m_SortedEdges = edge; edge->PrevInSEL = 0; edge->NextInSEL = 0; } else { edge->NextInSEL = m_SortedEdges; edge->PrevInSEL = 0; m_SortedEdges->PrevInSEL = edge; m_SortedEdges = edge; } } //------------------------------------------------------------------------------ void Clipper::CopyAELToSEL() { TEdge* e = m_ActiveEdges; m_SortedEdges = e; while ( e ) { e->PrevInSEL = e->PrevInAEL; e->NextInSEL = e->NextInAEL; e = e->NextInAEL; } } //------------------------------------------------------------------------------ void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt) { Join* j = new Join; j->OutPt1 = op1; j->OutPt2 = op2; j->OffPt = OffPt; m_Joins.push_back(j); } //------------------------------------------------------------------------------ void Clipper::ClearJoins() { for (JoinList::size_type i = 0; i < m_Joins.size(); i++) delete m_Joins[i]; m_Joins.resize(0); } //------------------------------------------------------------------------------ void Clipper::ClearGhostJoins() { for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++) delete m_GhostJoins[i]; m_GhostJoins.resize(0); } //------------------------------------------------------------------------------ void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt) { Join* j = new Join; j->OutPt1 = op; j->OutPt2 = 0; j->OffPt = OffPt; m_GhostJoins.push_back(j); } //------------------------------------------------------------------------------ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) { while (m_CurrentLM != m_MinimaList.end() && (m_CurrentLM->Y == botY)) { TEdge* lb = m_CurrentLM->LeftBound; TEdge* rb = m_CurrentLM->RightBound; PopLocalMinima(); OutPt *Op1 = 0; if (!lb) { //nb: don't insert LB into either AEL or SEL InsertEdgeIntoAEL(rb, 0); SetWindingCount(*rb); if (IsContributing(*rb)) Op1 = AddOutPt(rb, rb->Bot); } else if (!rb) { InsertEdgeIntoAEL(lb, 0); SetWindingCount(*lb); if (IsContributing(*lb)) Op1 = AddOutPt(lb, lb->Bot); InsertScanbeam(lb->Top.Y); } else { InsertEdgeIntoAEL(lb, 0); InsertEdgeIntoAEL(rb, lb); SetWindingCount( *lb ); rb->WindCnt = lb->WindCnt; rb->WindCnt2 = lb->WindCnt2; if (IsContributing(*lb)) Op1 = AddLocalMinPoly(lb, rb, lb->Bot); InsertScanbeam(lb->Top.Y); } if (rb) { if(IsHorizontal(*rb)) AddEdgeToSEL(rb); else InsertScanbeam( rb->Top.Y ); } if (!lb || !rb) continue; //if any output polygons share an edge, they'll need joining later ... if (Op1 && IsHorizontal(*rb) && m_GhostJoins.size() > 0 && (rb->WindDelta != 0)) { for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) { Join* jr = m_GhostJoins[i]; //if the horizontal Rb and a 'ghost' horizontal overlap, then convert //the 'ghost' join to a real join ready for later ... if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X)) AddJoin(jr->OutPt1, Op1, jr->OffPt); } } if (lb->OutIdx >= 0 && lb->PrevInAEL && lb->PrevInAEL->Curr.X == lb->Bot.X && lb->PrevInAEL->OutIdx >= 0 && SlopesEqual(*lb->PrevInAEL, *lb, m_UseFullRange) && (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0)) { OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot); AddJoin(Op1, Op2, lb->Top); } if(lb->NextInAEL != rb) { if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 && SlopesEqual(*rb->PrevInAEL, *rb, m_UseFullRange) && (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0)) { OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot); AddJoin(Op1, Op2, rb->Top); } TEdge* e = lb->NextInAEL; if (e) { while( e != rb ) { //nb: For calculating winding counts etc, IntersectEdges() assumes //that param1 will be to the Right of param2 ABOVE the intersection ... IntersectEdges(rb , e , lb->Curr); //order important here e = e->NextInAEL; } } } } } //------------------------------------------------------------------------------ void Clipper::DeleteFromAEL(TEdge *e) { TEdge* AelPrev = e->PrevInAEL; TEdge* AelNext = e->NextInAEL; if( !AelPrev && !AelNext && (e != m_ActiveEdges) ) return; //already deleted if( AelPrev ) AelPrev->NextInAEL = AelNext; else m_ActiveEdges = AelNext; if( AelNext ) AelNext->PrevInAEL = AelPrev; e->NextInAEL = 0; e->PrevInAEL = 0; } //------------------------------------------------------------------------------ void Clipper::DeleteFromSEL(TEdge *e) { TEdge* SelPrev = e->PrevInSEL; TEdge* SelNext = e->NextInSEL; if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted if( SelPrev ) SelPrev->NextInSEL = SelNext; else m_SortedEdges = SelNext; if( SelNext ) SelNext->PrevInSEL = SelPrev; e->NextInSEL = 0; e->PrevInSEL = 0; } //------------------------------------------------------------------------------ #ifdef use_xyz void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2) { if (pt.Z != 0 || !m_ZFill) return; else if (pt == e1.Bot) pt.Z = e1.Bot.Z; else if (pt == e1.Top) pt.Z = e1.Top.Z; else if (pt == e2.Bot) pt.Z = e2.Bot.Z; else if (pt == e2.Top) pt.Z = e2.Top.Z; else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt); } //------------------------------------------------------------------------------ #endif void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt) { bool e1Contributing = ( e1->OutIdx >= 0 ); bool e2Contributing = ( e2->OutIdx >= 0 ); #ifdef use_xyz SetZ(Pt, *e1, *e2); #endif #ifdef use_lines //if either edge is on an OPEN path ... if (e1->WindDelta == 0 || e2->WindDelta == 0) { //ignore subject-subject open path intersections UNLESS they //are both open paths, AND they are both 'contributing maximas' ... if (e1->WindDelta == 0 && e2->WindDelta == 0) return; //if intersecting a subj line with a subj poly ... else if (e1->PolyTyp == e2->PolyTyp && e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion) { if (e1->WindDelta == 0) { if (e2Contributing) { AddOutPt(e1, Pt); if (e1Contributing) e1->OutIdx = Unassigned; } } else { if (e1Contributing) { AddOutPt(e2, Pt); if (e2Contributing) e2->OutIdx = Unassigned; } } } else if (e1->PolyTyp != e2->PolyTyp) { //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ... if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && (m_ClipType != ctUnion || e2->WindCnt2 == 0)) { AddOutPt(e1, Pt); if (e1Contributing) e1->OutIdx = Unassigned; } else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && (m_ClipType != ctUnion || e1->WindCnt2 == 0)) { AddOutPt(e2, Pt); if (e2Contributing) e2->OutIdx = Unassigned; } } return; } #endif //update winding counts... //assumes that e1 will be to the Right of e2 ABOVE the intersection if ( e1->PolyTyp == e2->PolyTyp ) { if ( IsEvenOddFillType( *e1) ) { int oldE1WindCnt = e1->WindCnt; e1->WindCnt = e2->WindCnt; e2->WindCnt = oldE1WindCnt; } else { if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt; else e1->WindCnt += e2->WindDelta; if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt; else e2->WindCnt -= e1->WindDelta; } } else { if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta; else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0; if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta; else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0; } PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; if (e1->PolyTyp == ptSubject) { e1FillType = m_SubjFillType; e1FillType2 = m_ClipFillType; } else { e1FillType = m_ClipFillType; e1FillType2 = m_SubjFillType; } if (e2->PolyTyp == ptSubject) { e2FillType = m_SubjFillType; e2FillType2 = m_ClipFillType; } else { e2FillType = m_ClipFillType; e2FillType2 = m_SubjFillType; } cInt e1Wc, e2Wc; switch (e1FillType) { case pftPositive: e1Wc = e1->WindCnt; break; case pftNegative: e1Wc = -e1->WindCnt; break; default: e1Wc = Abs(e1->WindCnt); } switch(e2FillType) { case pftPositive: e2Wc = e2->WindCnt; break; case pftNegative: e2Wc = -e2->WindCnt; break; default: e2Wc = Abs(e2->WindCnt); } if ( e1Contributing && e2Contributing ) { if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) ) { AddLocalMaxPoly(e1, e2, Pt); } else { AddOutPt(e1, Pt); AddOutPt(e2, Pt); SwapSides( *e1 , *e2 ); SwapPolyIndexes( *e1 , *e2 ); } } else if ( e1Contributing ) { if (e2Wc == 0 || e2Wc == 1) { AddOutPt(e1, Pt); SwapSides(*e1, *e2); SwapPolyIndexes(*e1, *e2); } } else if ( e2Contributing ) { if (e1Wc == 0 || e1Wc == 1) { AddOutPt(e2, Pt); SwapSides(*e1, *e2); SwapPolyIndexes(*e1, *e2); } } else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1)) { //neither edge is currently contributing ... cInt e1Wc2, e2Wc2; switch (e1FillType2) { case pftPositive: e1Wc2 = e1->WindCnt2; break; case pftNegative : e1Wc2 = -e1->WindCnt2; break; default: e1Wc2 = Abs(e1->WindCnt2); } switch (e2FillType2) { case pftPositive: e2Wc2 = e2->WindCnt2; break; case pftNegative: e2Wc2 = -e2->WindCnt2; break; default: e2Wc2 = Abs(e2->WindCnt2); } if (e1->PolyTyp != e2->PolyTyp) { AddLocalMinPoly(e1, e2, Pt); } else if (e1Wc == 1 && e2Wc == 1) switch( m_ClipType ) { case ctIntersection: if (e1Wc2 > 0 && e2Wc2 > 0) AddLocalMinPoly(e1, e2, Pt); break; case ctUnion: if ( e1Wc2 <= 0 && e2Wc2 <= 0 ) AddLocalMinPoly(e1, e2, Pt); break; case ctDifference: if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) AddLocalMinPoly(e1, e2, Pt); break; case ctXor: AddLocalMinPoly(e1, e2, Pt); } else SwapSides( *e1, *e2 ); } } //------------------------------------------------------------------------------ void Clipper::SetHoleState(TEdge *e, OutRec *outrec) { bool IsHole = false; TEdge *e2 = e->PrevInAEL; while (e2) { if (e2->OutIdx >= 0 && e2->WindDelta != 0) { IsHole = !IsHole; if (! outrec->FirstLeft) outrec->FirstLeft = m_PolyOuts[e2->OutIdx]; } e2 = e2->PrevInAEL; } if (IsHole) outrec->IsHole = true; } //------------------------------------------------------------------------------ OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) { //work out which polygon fragment has the correct hole state ... if (!outRec1->BottomPt) outRec1->BottomPt = GetBottomPt(outRec1->Pts); if (!outRec2->BottomPt) outRec2->BottomPt = GetBottomPt(outRec2->Pts); OutPt *OutPt1 = outRec1->BottomPt; OutPt *OutPt2 = outRec2->BottomPt; if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1; else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2; else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1; else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2; else if (OutPt1->Next == OutPt1) return outRec2; else if (OutPt2->Next == OutPt2) return outRec1; else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1; else return outRec2; } //------------------------------------------------------------------------------ bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2) { do { outRec1 = outRec1->FirstLeft; if (outRec1 == outRec2) return true; } while (outRec1); return false; } //------------------------------------------------------------------------------ OutRec* Clipper::GetOutRec(int Idx) { OutRec* outrec = m_PolyOuts[Idx]; while (outrec != m_PolyOuts[outrec->Idx]) outrec = m_PolyOuts[outrec->Idx]; return outrec; } //------------------------------------------------------------------------------ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) { //get the start and ends of both output polygons ... OutRec *outRec1 = m_PolyOuts[e1->OutIdx]; OutRec *outRec2 = m_PolyOuts[e2->OutIdx]; OutRec *holeStateRec; if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; else holeStateRec = GetLowermostRec(outRec1, outRec2); //get the start and ends of both output polygons and //join e2 poly onto e1 poly and delete pointers to e2 ... OutPt* p1_lft = outRec1->Pts; OutPt* p1_rt = p1_lft->Prev; OutPt* p2_lft = outRec2->Pts; OutPt* p2_rt = p2_lft->Prev; EdgeSide Side; //join e2 poly onto e1 poly and delete pointers to e2 ... if( e1->Side == esLeft ) { if( e2->Side == esLeft ) { //z y x a b c ReversePolyPtLinks(p2_lft); p2_lft->Next = p1_lft; p1_lft->Prev = p2_lft; p1_rt->Next = p2_rt; p2_rt->Prev = p1_rt; outRec1->Pts = p2_rt; } else { //x y z a b c p2_rt->Next = p1_lft; p1_lft->Prev = p2_rt; p2_lft->Prev = p1_rt; p1_rt->Next = p2_lft; outRec1->Pts = p2_lft; } Side = esLeft; } else { if( e2->Side == esRight ) { //a b c z y x ReversePolyPtLinks(p2_lft); p1_rt->Next = p2_rt; p2_rt->Prev = p1_rt; p2_lft->Next = p1_lft; p1_lft->Prev = p2_lft; } else { //a b c x y z p1_rt->Next = p2_lft; p2_lft->Prev = p1_rt; p1_lft->Prev = p2_rt; p2_rt->Next = p1_lft; } Side = esRight; } outRec1->BottomPt = 0; if (holeStateRec == outRec2) { if (outRec2->FirstLeft != outRec1) outRec1->FirstLeft = outRec2->FirstLeft; outRec1->IsHole = outRec2->IsHole; } outRec2->Pts = 0; outRec2->BottomPt = 0; outRec2->FirstLeft = outRec1; int OKIdx = e1->OutIdx; int ObsoleteIdx = e2->OutIdx; e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly e2->OutIdx = Unassigned; TEdge* e = m_ActiveEdges; while( e ) { if( e->OutIdx == ObsoleteIdx ) { e->OutIdx = OKIdx; e->Side = Side; break; } e = e->NextInAEL; } outRec2->Idx = outRec1->Idx; } //------------------------------------------------------------------------------ OutRec* Clipper::CreateOutRec() { OutRec* result = new OutRec; result->IsHole = false; result->IsOpen = false; result->FirstLeft = 0; result->Pts = 0; result->BottomPt = 0; result->PolyNd = 0; m_PolyOuts.push_back(result); result->Idx = (int)m_PolyOuts.size()-1; return result; } //------------------------------------------------------------------------------ OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) { bool ToFront = (e->Side == esLeft); if( e->OutIdx < 0 ) { OutRec *outRec = CreateOutRec(); outRec->IsOpen = (e->WindDelta == 0); OutPt* newOp = new OutPt; outRec->Pts = newOp; newOp->Idx = outRec->Idx; newOp->Pt = pt; newOp->Next = newOp; newOp->Prev = newOp; if (!outRec->IsOpen) SetHoleState(e, outRec); e->OutIdx = outRec->Idx; return newOp; } else { OutRec *outRec = m_PolyOuts[e->OutIdx]; //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most' OutPt* op = outRec->Pts; if (ToFront && (pt == op->Pt)) return op; else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev; OutPt* newOp = new OutPt; newOp->Idx = outRec->Idx; newOp->Pt = pt; newOp->Next = op; newOp->Prev = op->Prev; newOp->Prev->Next = newOp; op->Prev = newOp; if (ToFront) outRec->Pts = newOp; return newOp; } } //------------------------------------------------------------------------------ void Clipper::ProcessHorizontals(bool IsTopOfScanbeam) { TEdge* horzEdge = m_SortedEdges; while(horzEdge) { DeleteFromSEL(horzEdge); ProcessHorizontal(horzEdge, IsTopOfScanbeam); horzEdge = m_SortedEdges; } } //------------------------------------------------------------------------------ inline bool IsMinima(TEdge *e) { return e && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e); } //------------------------------------------------------------------------------ inline bool IsMaxima(TEdge *e, const cInt Y) { return e && e->Top.Y == Y && !e->NextInLML; } //------------------------------------------------------------------------------ inline bool IsIntermediate(TEdge *e, const cInt Y) { return e->Top.Y == Y && e->NextInLML; } //------------------------------------------------------------------------------ TEdge *GetMaximaPair(TEdge *e) { TEdge* result = 0; if ((e->Next->Top == e->Top) && !e->Next->NextInLML) result = e->Next; else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML) result = e->Prev; if (result && (result->OutIdx == Skip || //result is false if both NextInAEL & PrevInAEL are nil & not horizontal ... (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0; return result; } //------------------------------------------------------------------------------ void Clipper::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) { //check that one or other edge hasn't already been removed from AEL ... if (Edge1->NextInAEL == Edge1->PrevInAEL || Edge2->NextInAEL == Edge2->PrevInAEL) return; if( Edge1->NextInAEL == Edge2 ) { TEdge* Next = Edge2->NextInAEL; if( Next ) Next->PrevInAEL = Edge1; TEdge* Prev = Edge1->PrevInAEL; if( Prev ) Prev->NextInAEL = Edge2; Edge2->PrevInAEL = Prev; Edge2->NextInAEL = Edge1; Edge1->PrevInAEL = Edge2; Edge1->NextInAEL = Next; } else if( Edge2->NextInAEL == Edge1 ) { TEdge* Next = Edge1->NextInAEL; if( Next ) Next->PrevInAEL = Edge2; TEdge* Prev = Edge2->PrevInAEL; if( Prev ) Prev->NextInAEL = Edge1; Edge1->PrevInAEL = Prev; Edge1->NextInAEL = Edge2; Edge2->PrevInAEL = Edge1; Edge2->NextInAEL = Next; } else { TEdge* Next = Edge1->NextInAEL; TEdge* Prev = Edge1->PrevInAEL; Edge1->NextInAEL = Edge2->NextInAEL; if( Edge1->NextInAEL ) Edge1->NextInAEL->PrevInAEL = Edge1; Edge1->PrevInAEL = Edge2->PrevInAEL; if( Edge1->PrevInAEL ) Edge1->PrevInAEL->NextInAEL = Edge1; Edge2->NextInAEL = Next; if( Edge2->NextInAEL ) Edge2->NextInAEL->PrevInAEL = Edge2; Edge2->PrevInAEL = Prev; if( Edge2->PrevInAEL ) Edge2->PrevInAEL->NextInAEL = Edge2; } if( !Edge1->PrevInAEL ) m_ActiveEdges = Edge1; else if( !Edge2->PrevInAEL ) m_ActiveEdges = Edge2; } //------------------------------------------------------------------------------ void Clipper::SwapPositionsInSEL(TEdge *Edge1, TEdge *Edge2) { if( !( Edge1->NextInSEL ) && !( Edge1->PrevInSEL ) ) return; if( !( Edge2->NextInSEL ) && !( Edge2->PrevInSEL ) ) return; if( Edge1->NextInSEL == Edge2 ) { TEdge* Next = Edge2->NextInSEL; if( Next ) Next->PrevInSEL = Edge1; TEdge* Prev = Edge1->PrevInSEL; if( Prev ) Prev->NextInSEL = Edge2; Edge2->PrevInSEL = Prev; Edge2->NextInSEL = Edge1; Edge1->PrevInSEL = Edge2; Edge1->NextInSEL = Next; } else if( Edge2->NextInSEL == Edge1 ) { TEdge* Next = Edge1->NextInSEL; if( Next ) Next->PrevInSEL = Edge2; TEdge* Prev = Edge2->PrevInSEL; if( Prev ) Prev->NextInSEL = Edge1; Edge1->PrevInSEL = Prev; Edge1->NextInSEL = Edge2; Edge2->PrevInSEL = Edge1; Edge2->NextInSEL = Next; } else { TEdge* Next = Edge1->NextInSEL; TEdge* Prev = Edge1->PrevInSEL; Edge1->NextInSEL = Edge2->NextInSEL; if( Edge1->NextInSEL ) Edge1->NextInSEL->PrevInSEL = Edge1; Edge1->PrevInSEL = Edge2->PrevInSEL; if( Edge1->PrevInSEL ) Edge1->PrevInSEL->NextInSEL = Edge1; Edge2->NextInSEL = Next; if( Edge2->NextInSEL ) Edge2->NextInSEL->PrevInSEL = Edge2; Edge2->PrevInSEL = Prev; if( Edge2->PrevInSEL ) Edge2->PrevInSEL->NextInSEL = Edge2; } if( !Edge1->PrevInSEL ) m_SortedEdges = Edge1; else if( !Edge2->PrevInSEL ) m_SortedEdges = Edge2; } //------------------------------------------------------------------------------ TEdge* GetNextInAEL(TEdge *e, Direction dir) { return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL; } //------------------------------------------------------------------------------ void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right) { if (HorzEdge.Bot.X < HorzEdge.Top.X) { Left = HorzEdge.Bot.X; Right = HorzEdge.Top.X; Dir = dLeftToRight; } else { Left = HorzEdge.Top.X; Right = HorzEdge.Bot.X; Dir = dRightToLeft; } } //------------------------------------------------------------------------ /******************************************************************************* * Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or * * Bottom of a scanbeam) are processed as if layered. The order in which HEs * * are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] * * (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), * * and with other non-horizontal edges [*]. Once these intersections are * * processed, intermediate HEs then 'promote' the Edge above (NextInLML) into * * the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. * *******************************************************************************/ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) { Direction dir; cInt horzLeft, horzRight; GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); TEdge* eLastHorz = horzEdge, *eMaxPair = 0; while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML)) eLastHorz = eLastHorz->NextInLML; if (!eLastHorz->NextInLML) eMaxPair = GetMaximaPair(eLastHorz); for (;;) { bool IsLastHorz = (horzEdge == eLastHorz); TEdge* e = GetNextInAEL(horzEdge, dir); while(e) { //Break if we've got to the end of an intermediate horizontal edge ... //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML && e->Dx < horzEdge->NextInLML->Dx) break; TEdge* eNext = GetNextInAEL(e, dir); //saves eNext for later if ((dir == dLeftToRight && e->Curr.X <= horzRight) || (dir == dRightToLeft && e->Curr.X >= horzLeft)) { //so far we're still in range of the horizontal Edge but make sure //we're at the last of consec. horizontals when matching with eMaxPair if(e == eMaxPair && IsLastHorz) { if (horzEdge->OutIdx >= 0) { OutPt* op1 = AddOutPt(horzEdge, horzEdge->Top); TEdge* eNextHorz = m_SortedEdges; while (eNextHorz) { if (eNextHorz->OutIdx >= 0 && HorzSegmentsOverlap(horzEdge->Bot.X, horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) { OutPt* op2 = AddOutPt(eNextHorz, eNextHorz->Bot); AddJoin(op2, op1, eNextHorz->Top); } eNextHorz = eNextHorz->NextInSEL; } AddGhostJoin(op1, horzEdge->Bot); AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top); } DeleteFromAEL(horzEdge); DeleteFromAEL(eMaxPair); return; } else if(dir == dLeftToRight) { IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); IntersectEdges(horzEdge, e, Pt); } else { IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); IntersectEdges( e, horzEdge, Pt); } SwapPositionsInAEL( horzEdge, e ); } else if( (dir == dLeftToRight && e->Curr.X >= horzRight) || (dir == dRightToLeft && e->Curr.X <= horzLeft) ) break; e = eNext; } //end while if (horzEdge->NextInLML && IsHorizontal(*horzEdge->NextInLML)) { UpdateEdgeIntoAEL(horzEdge); if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot); GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); } else break; } //end for (;;) if(horzEdge->NextInLML) { if(horzEdge->OutIdx >= 0) { OutPt* op1 = AddOutPt( horzEdge, horzEdge->Top); if (isTopOfScanbeam) AddGhostJoin(op1, horzEdge->Bot); UpdateEdgeIntoAEL(horzEdge); if (horzEdge->WindDelta == 0) return; //nb: HorzEdge is no longer horizontal here TEdge* ePrev = horzEdge->PrevInAEL; TEdge* eNext = horzEdge->NextInAEL; if (ePrev && ePrev->Curr.X == horzEdge->Bot.X && ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 && (ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && SlopesEqual(*horzEdge, *ePrev, m_UseFullRange))) { OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot); AddJoin(op1, op2, horzEdge->Top); } else if (eNext && eNext->Curr.X == horzEdge->Bot.X && eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 && eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && SlopesEqual(*horzEdge, *eNext, m_UseFullRange)) { OutPt* op2 = AddOutPt(eNext, horzEdge->Bot); AddJoin(op1, op2, horzEdge->Top); } } else UpdateEdgeIntoAEL(horzEdge); } else { if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top); DeleteFromAEL(horzEdge); } } //------------------------------------------------------------------------------ void Clipper::UpdateEdgeIntoAEL(TEdge *&e) { if( !e->NextInLML ) throw clipperException("UpdateEdgeIntoAEL: invalid call"); e->NextInLML->OutIdx = e->OutIdx; TEdge* AelPrev = e->PrevInAEL; TEdge* AelNext = e->NextInAEL; if (AelPrev) AelPrev->NextInAEL = e->NextInLML; else m_ActiveEdges = e->NextInLML; if (AelNext) AelNext->PrevInAEL = e->NextInLML; e->NextInLML->Side = e->Side; e->NextInLML->WindDelta = e->WindDelta; e->NextInLML->WindCnt = e->WindCnt; e->NextInLML->WindCnt2 = e->WindCnt2; e = e->NextInLML; e->Curr = e->Bot; e->PrevInAEL = AelPrev; e->NextInAEL = AelNext; if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y); } //------------------------------------------------------------------------------ bool Clipper::ProcessIntersections(const cInt topY) { if( !m_ActiveEdges ) return true; try { BuildIntersectList(topY); size_t IlSize = m_IntersectList.size(); if (IlSize == 0) return true; if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); else return false; } catch(...) { m_SortedEdges = 0; DisposeIntersectNodes(); throw clipperException("ProcessIntersections error"); } m_SortedEdges = 0; return true; } //------------------------------------------------------------------------------ void Clipper::DisposeIntersectNodes() { for (size_t i = 0; i < m_IntersectList.size(); ++i ) delete m_IntersectList[i]; m_IntersectList.clear(); } //------------------------------------------------------------------------------ void Clipper::BuildIntersectList(const cInt topY) { if ( !m_ActiveEdges ) return; //prepare for sorting ... TEdge* e = m_ActiveEdges; m_SortedEdges = e; while( e ) { e->PrevInSEL = e->PrevInAEL; e->NextInSEL = e->NextInAEL; e->Curr.X = TopX( *e, topY ); e = e->NextInAEL; } //bubblesort ... bool isModified; do { isModified = false; e = m_SortedEdges; while( e->NextInSEL ) { TEdge *eNext = e->NextInSEL; IntPoint Pt; if(e->Curr.X > eNext->Curr.X) { IntersectPoint(*e, *eNext, Pt); IntersectNode * newNode = new IntersectNode; newNode->Edge1 = e; newNode->Edge2 = eNext; newNode->Pt = Pt; m_IntersectList.push_back(newNode); SwapPositionsInSEL(e, eNext); isModified = true; } else e = eNext; } if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = 0; else break; } while ( isModified ); m_SortedEdges = 0; //important } //------------------------------------------------------------------------------ void Clipper::ProcessIntersectList() { for (size_t i = 0; i < m_IntersectList.size(); ++i) { IntersectNode* iNode = m_IntersectList[i]; { IntersectEdges( iNode->Edge1, iNode->Edge2, iNode->Pt); SwapPositionsInAEL( iNode->Edge1 , iNode->Edge2 ); } delete iNode; } m_IntersectList.clear(); } //------------------------------------------------------------------------------ bool IntersectListSort(IntersectNode* node1, IntersectNode* node2) { return node2->Pt.Y < node1->Pt.Y; } //------------------------------------------------------------------------------ inline bool EdgesAdjacent(const IntersectNode &inode) { return (inode.Edge1->NextInSEL == inode.Edge2) || (inode.Edge1->PrevInSEL == inode.Edge2); } //------------------------------------------------------------------------------ bool Clipper::FixupIntersectionOrder() { //pre-condition: intersections are sorted Bottom-most first. //Now it's crucial that intersections are made only between adjacent edges, //so to ensure this the order of intersections may need adjusting ... CopyAELToSEL(); std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort); size_t cnt = m_IntersectList.size(); for (size_t i = 0; i < cnt; ++i) { if (!EdgesAdjacent(*m_IntersectList[i])) { size_t j = i + 1; while (j < cnt && !EdgesAdjacent(*m_IntersectList[j])) j++; if (j == cnt) return false; std::swap(m_IntersectList[i], m_IntersectList[j]); } SwapPositionsInSEL(m_IntersectList[i]->Edge1, m_IntersectList[i]->Edge2); } return true; } //------------------------------------------------------------------------------ void Clipper::DoMaxima(TEdge *e) { TEdge* eMaxPair = GetMaximaPair(e); if (!eMaxPair) { if (e->OutIdx >= 0) AddOutPt(e, e->Top); DeleteFromAEL(e); return; } TEdge* eNext = e->NextInAEL; while(eNext && eNext != eMaxPair) { IntersectEdges(e, eNext, e->Top); SwapPositionsInAEL(e, eNext); eNext = e->NextInAEL; } if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned) { DeleteFromAEL(e); DeleteFromAEL(eMaxPair); } else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 ) { if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top); DeleteFromAEL(e); DeleteFromAEL(eMaxPair); } #ifdef use_lines else if (e->WindDelta == 0) { if (e->OutIdx >= 0) { AddOutPt(e, e->Top); e->OutIdx = Unassigned; } DeleteFromAEL(e); if (eMaxPair->OutIdx >= 0) { AddOutPt(eMaxPair, e->Top); eMaxPair->OutIdx = Unassigned; } DeleteFromAEL(eMaxPair); } #endif else throw clipperException("DoMaxima error"); } //------------------------------------------------------------------------------ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) { TEdge* e = m_ActiveEdges; while( e ) { //1. process maxima, treating them as if they're 'bent' horizontal edges, // but exclude maxima with horizontal edges. nb: e can't be a horizontal. bool IsMaximaEdge = IsMaxima(e, topY); if(IsMaximaEdge) { TEdge* eMaxPair = GetMaximaPair(e); IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair)); } if(IsMaximaEdge) { TEdge* ePrev = e->PrevInAEL; DoMaxima(e); if( !ePrev ) e = m_ActiveEdges; else e = ePrev->NextInAEL; } else { //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML)) { UpdateEdgeIntoAEL(e); if (e->OutIdx >= 0) AddOutPt(e, e->Bot); AddEdgeToSEL(e); } else { e->Curr.X = TopX( *e, topY ); e->Curr.Y = topY; } if (m_StrictSimple) { TEdge* ePrev = e->PrevInAEL; if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) && (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0)) { IntPoint pt = e->Curr; #ifdef use_xyz SetZ(pt, *ePrev, *e); #endif OutPt* op = AddOutPt(ePrev, pt); OutPt* op2 = AddOutPt(e, pt); AddJoin(op, op2, pt); //StrictlySimple (type-3) join } } e = e->NextInAEL; } } //3. Process horizontals at the Top of the scanbeam ... ProcessHorizontals(true); //4. Promote intermediate vertices ... e = m_ActiveEdges; while(e) { if(IsIntermediate(e, topY)) { OutPt* op = 0; if( e->OutIdx >= 0 ) op = AddOutPt(e, e->Top); UpdateEdgeIntoAEL(e); //if output polygons share an edge, they'll need joining later ... TEdge* ePrev = e->PrevInAEL; TEdge* eNext = e->NextInAEL; if (ePrev && ePrev->Curr.X == e->Bot.X && ePrev->Curr.Y == e->Bot.Y && op && ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && SlopesEqual(*e, *ePrev, m_UseFullRange) && (e->WindDelta != 0) && (ePrev->WindDelta != 0)) { OutPt* op2 = AddOutPt(ePrev, e->Bot); AddJoin(op, op2, e->Top); } else if (eNext && eNext->Curr.X == e->Bot.X && eNext->Curr.Y == e->Bot.Y && op && eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && SlopesEqual(*e, *eNext, m_UseFullRange) && (e->WindDelta != 0) && (eNext->WindDelta != 0)) { OutPt* op2 = AddOutPt(eNext, e->Bot); AddJoin(op, op2, e->Top); } } e = e->NextInAEL; } } //------------------------------------------------------------------------------ void Clipper::FixupOutPolygon(OutRec &outrec) { //FixupOutPolygon() - removes duplicate points and simplifies consecutive //parallel edges by removing the middle vertex. OutPt *lastOK = 0; outrec.BottomPt = 0; OutPt *pp = outrec.Pts; for (;;) { if (pp->Prev == pp || pp->Prev == pp->Next ) { DisposeOutPts(pp); outrec.Pts = 0; return; } //test for duplicate points and collinear edges ... if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) || (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) && (!m_PreserveCollinear || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) { lastOK = 0; OutPt *tmp = pp; pp->Prev->Next = pp->Next; pp->Next->Prev = pp->Prev; pp = pp->Prev; delete tmp; } else if (pp == lastOK) break; else { if (!lastOK) lastOK = pp; pp = pp->Next; } } outrec.Pts = pp; } //------------------------------------------------------------------------------ int PointCount(OutPt *Pts) { if (!Pts) return 0; int result = 0; OutPt* p = Pts; do { result++; p = p->Next; } while (p != Pts); return result; } //------------------------------------------------------------------------------ void Clipper::BuildResult(Paths &polys) { polys.reserve(m_PolyOuts.size()); for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { if (!m_PolyOuts[i]->Pts) continue; Path pg; OutPt* p = m_PolyOuts[i]->Pts->Prev; int cnt = PointCount(p); if (cnt < 2) continue; pg.reserve(cnt); for (int i = 0; i < cnt; ++i) { pg.push_back(p->Pt); p = p->Prev; } polys.push_back(pg); } } //------------------------------------------------------------------------------ void Clipper::BuildResult2(PolyTree& polytree) { polytree.Clear(); polytree.AllNodes.reserve(m_PolyOuts.size()); //add each output polygon/contour to polytree ... for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) { OutRec* outRec = m_PolyOuts[i]; int cnt = PointCount(outRec->Pts); if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3)) continue; FixHoleLinkage(*outRec); PolyNode* pn = new PolyNode(); //nb: polytree takes ownership of all the PolyNodes polytree.AllNodes.push_back(pn); outRec->PolyNd = pn; pn->Parent = 0; pn->Index = 0; pn->Contour.reserve(cnt); OutPt *op = outRec->Pts->Prev; for (int j = 0; j < cnt; j++) { pn->Contour.push_back(op->Pt); op = op->Prev; } } //fixup PolyNode links etc ... polytree.Childs.reserve(m_PolyOuts.size()); for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) { OutRec* outRec = m_PolyOuts[i]; if (!outRec->PolyNd) continue; if (outRec->IsOpen) { outRec->PolyNd->m_IsOpen = true; polytree.AddChild(*outRec->PolyNd); } else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd) outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd); else polytree.AddChild(*outRec->PolyNd); } } //------------------------------------------------------------------------------ void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) { //just swap the contents (because fIntersectNodes is a single-linked-list) IntersectNode inode = int1; //gets a copy of Int1 int1.Edge1 = int2.Edge1; int1.Edge2 = int2.Edge2; int1.Pt = int2.Pt; int2.Edge1 = inode.Edge1; int2.Edge2 = inode.Edge2; int2.Pt = inode.Pt; } //------------------------------------------------------------------------------ inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) { if (e2.Curr.X == e1.Curr.X) { if (e2.Top.Y > e1.Top.Y) return e2.Top.X < TopX(e1, e2.Top.Y); else return e1.Top.X > TopX(e2, e1.Top.Y); } else return e2.Curr.X < e1.Curr.X; } //------------------------------------------------------------------------------ bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, cInt& Left, cInt& Right) { if (a1 < a2) { if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);} else {Left = std::max(a1,b2); Right = std::min(a2,b1);} } else { if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);} else {Left = std::max(a2,b2); Right = std::min(a1,b1);} } return Left < Right; } //------------------------------------------------------------------------------ inline void UpdateOutPtIdxs(OutRec& outrec) { OutPt* op = outrec.Pts; do { op->Idx = outrec.Idx; op = op->Prev; } while(op != outrec.Pts); } //------------------------------------------------------------------------------ void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge) { if(!m_ActiveEdges) { edge->PrevInAEL = 0; edge->NextInAEL = 0; m_ActiveEdges = edge; } else if(!startEdge && E2InsertsBeforeE1(*m_ActiveEdges, *edge)) { edge->PrevInAEL = 0; edge->NextInAEL = m_ActiveEdges; m_ActiveEdges->PrevInAEL = edge; m_ActiveEdges = edge; } else { if(!startEdge) startEdge = m_ActiveEdges; while(startEdge->NextInAEL && !E2InsertsBeforeE1(*startEdge->NextInAEL , *edge)) startEdge = startEdge->NextInAEL; edge->NextInAEL = startEdge->NextInAEL; if(startEdge->NextInAEL) startEdge->NextInAEL->PrevInAEL = edge; edge->PrevInAEL = startEdge; startEdge->NextInAEL = edge; } } //---------------------------------------------------------------------- OutPt* DupOutPt(OutPt* outPt, bool InsertAfter) { OutPt* result = new OutPt; result->Pt = outPt->Pt; result->Idx = outPt->Idx; if (InsertAfter) { result->Next = outPt->Next; result->Prev = outPt; outPt->Next->Prev = result; outPt->Next = result; } else { result->Prev = outPt->Prev; result->Next = outPt; outPt->Prev->Next = result; outPt->Prev = result; } return result; } //------------------------------------------------------------------------------ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, const IntPoint Pt, bool DiscardLeft) { Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight); Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight); if (Dir1 == Dir2) return false; //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we //want Op1b to be on the Right. (And likewise with Op2 and Op2b.) //So, to facilitate this while inserting Op1b and Op2b ... //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) if (Dir1 == dLeftToRight) { while (op1->Next->Pt.X <= Pt.X && op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) op1 = op1->Next; if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; op1b = DupOutPt(op1, !DiscardLeft); if (op1b->Pt != Pt) { op1 = op1b; op1->Pt = Pt; op1b = DupOutPt(op1, !DiscardLeft); } } else { while (op1->Next->Pt.X >= Pt.X && op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) op1 = op1->Next; if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; op1b = DupOutPt(op1, DiscardLeft); if (op1b->Pt != Pt) { op1 = op1b; op1->Pt = Pt; op1b = DupOutPt(op1, DiscardLeft); } } if (Dir2 == dLeftToRight) { while (op2->Next->Pt.X <= Pt.X && op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) op2 = op2->Next; if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; op2b = DupOutPt(op2, !DiscardLeft); if (op2b->Pt != Pt) { op2 = op2b; op2->Pt = Pt; op2b = DupOutPt(op2, !DiscardLeft); }; } else { while (op2->Next->Pt.X >= Pt.X && op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) op2 = op2->Next; if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; op2b = DupOutPt(op2, DiscardLeft); if (op2b->Pt != Pt) { op2 = op2b; op2->Pt = Pt; op2b = DupOutPt(op2, DiscardLeft); }; }; if ((Dir1 == dLeftToRight) == DiscardLeft) { op1->Prev = op2; op2->Next = op1; op1b->Next = op2b; op2b->Prev = op1b; } else { op1->Next = op2; op2->Prev = op1; op1b->Prev = op2b; op2b->Next = op1b; } return true; } //------------------------------------------------------------------------------ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) { OutPt *op1 = j->OutPt1, *op1b; OutPt *op2 = j->OutPt2, *op2b; //There are 3 kinds of joins for output polygons ... //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same //location at the Bottom of the overlapping segment (& Join.OffPt is above). //3. StrictSimple joins where edges touch but are not collinear and where //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. bool isHorizontal = (j->OutPt1->Pt.Y == j->OffPt.Y); if (isHorizontal && (j->OffPt == j->OutPt1->Pt) && (j->OffPt == j->OutPt2->Pt)) { //Strictly Simple join ... if (outRec1 != outRec2) return false; op1b = j->OutPt1->Next; while (op1b != op1 && (op1b->Pt == j->OffPt)) op1b = op1b->Next; bool reverse1 = (op1b->Pt.Y > j->OffPt.Y); op2b = j->OutPt2->Next; while (op2b != op2 && (op2b->Pt == j->OffPt)) op2b = op2b->Next; bool reverse2 = (op2b->Pt.Y > j->OffPt.Y); if (reverse1 == reverse2) return false; if (reverse1) { op1b = DupOutPt(op1, false); op2b = DupOutPt(op2, true); op1->Prev = op2; op2->Next = op1; op1b->Next = op2b; op2b->Prev = op1b; j->OutPt1 = op1; j->OutPt2 = op1b; return true; } else { op1b = DupOutPt(op1, true); op2b = DupOutPt(op2, false); op1->Next = op2; op2->Prev = op1; op1b->Prev = op2b; op2b->Next = op1b; j->OutPt1 = op1; j->OutPt2 = op1b; return true; } } else if (isHorizontal) { //treat horizontal joins differently to non-horizontal joins since with //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt //may be anywhere along the horizontal edge. op1b = op1; while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2) op1 = op1->Prev; while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2) op1b = op1b->Next; if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon' op2b = op2; while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b) op2 = op2->Prev; while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1) op2b = op2b->Next; if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon' cInt Left, Right; //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right)) return false; //DiscardLeftSide: when overlapping edges are joined, a spike will created //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up //on the discard Side as either may still be needed for other joins ... IntPoint Pt; bool DiscardLeftSide; if (op1->Pt.X >= Left && op1->Pt.X <= Right) { Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X); } else if (op2->Pt.X >= Left&& op2->Pt.X <= Right) { Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X); } else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right) { Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X; } else { Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X); } j->OutPt1 = op1; j->OutPt2 = op2; return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide); } else { //nb: For non-horizontal joins ... // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y // 2. Jr.OutPt1.Pt > Jr.OffPt.Y //make sure the polygons are correctly oriented ... op1b = op1->Next; while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next; bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) || !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)); if (Reverse1) { op1b = op1->Prev; while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev; if ((op1b->Pt.Y > op1->Pt.Y) || !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false; }; op2b = op2->Next; while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next; bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) || !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)); if (Reverse2) { op2b = op2->Prev; while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev; if ((op2b->Pt.Y > op2->Pt.Y) || !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false; } if ((op1b == op1) || (op2b == op2) || (op1b == op2b) || ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false; if (Reverse1) { op1b = DupOutPt(op1, false); op2b = DupOutPt(op2, true); op1->Prev = op2; op2->Next = op1; op1b->Next = op2b; op2b->Prev = op1b; j->OutPt1 = op1; j->OutPt2 = op1b; return true; } else { op1b = DupOutPt(op1, true); op2b = DupOutPt(op2, false); op1->Next = op2; op2->Prev = op1; op1b->Prev = op2b; op2b->Next = op1b; j->OutPt1 = op1; j->OutPt2 = op1b; return true; } } } //---------------------------------------------------------------------- static OutRec* ParseFirstLeft(OutRec* FirstLeft) { while (FirstLeft && !FirstLeft->Pts) FirstLeft = FirstLeft->FirstLeft; return FirstLeft; } //------------------------------------------------------------------------------ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) { //tests if NewOutRec contains the polygon before reassigning FirstLeft for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { OutRec* outRec = m_PolyOuts[i]; if (!outRec->Pts || !outRec->FirstLeft) continue; OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); if (firstLeft == OldOutRec) { if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts)) outRec->FirstLeft = NewOutRec; } } } //---------------------------------------------------------------------- void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) { //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { OutRec* outRec = m_PolyOuts[i]; if (outRec->FirstLeft == OldOutRec) outRec->FirstLeft = NewOutRec; } } //---------------------------------------------------------------------- void Clipper::JoinCommonEdges() { for (JoinList::size_type i = 0; i < m_Joins.size(); i++) { Join* join = m_Joins[i]; OutRec *outRec1 = GetOutRec(join->OutPt1->Idx); OutRec *outRec2 = GetOutRec(join->OutPt2->Idx); if (!outRec1->Pts || !outRec2->Pts) continue; //get the polygon fragment with the correct hole state (FirstLeft) //before calling JoinPoints() ... OutRec *holeStateRec; if (outRec1 == outRec2) holeStateRec = outRec1; else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; else holeStateRec = GetLowermostRec(outRec1, outRec2); if (!JoinPoints(join, outRec1, outRec2)) continue; if (outRec1 == outRec2) { //instead of joining two polygons, we've just created a new one by //splitting one polygon into two. outRec1->Pts = join->OutPt1; outRec1->BottomPt = 0; outRec2 = CreateOutRec(); outRec2->Pts = join->OutPt2; //update all OutRec2.Pts Idx's ... UpdateOutPtIdxs(*outRec2); //We now need to check every OutRec.FirstLeft pointer. If it points //to OutRec1 it may need to point to OutRec2 instead ... if (m_UsingPolyTree) for (PolyOutList::size_type j = 0; j < m_PolyOuts.size() - 1; j++) { OutRec* oRec = m_PolyOuts[j]; if (!oRec->Pts || ParseFirstLeft(oRec->FirstLeft) != outRec1 || oRec->IsHole == outRec1->IsHole) continue; if (Poly2ContainsPoly1(oRec->Pts, join->OutPt2)) oRec->FirstLeft = outRec2; } if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts)) { //outRec2 is contained by outRec1 ... outRec2->IsHole = !outRec1->IsHole; outRec2->FirstLeft = outRec1; //fixup FirstLeft pointers that may need reassigning to OutRec1 if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0)) ReversePolyPtLinks(outRec2->Pts); } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts)) { //outRec1 is contained by outRec2 ... outRec2->IsHole = outRec1->IsHole; outRec1->IsHole = !outRec2->IsHole; outRec2->FirstLeft = outRec1->FirstLeft; outRec1->FirstLeft = outRec2; //fixup FirstLeft pointers that may need reassigning to OutRec1 if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0)) ReversePolyPtLinks(outRec1->Pts); } else { //the 2 polygons are completely separate ... outRec2->IsHole = outRec1->IsHole; outRec2->FirstLeft = outRec1->FirstLeft; //fixup FirstLeft pointers that may need reassigning to OutRec2 if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); } } else { //joined 2 polygons together ... outRec2->Pts = 0; outRec2->BottomPt = 0; outRec2->Idx = outRec1->Idx; outRec1->IsHole = holeStateRec->IsHole; if (holeStateRec == outRec2) outRec1->FirstLeft = outRec2->FirstLeft; outRec2->FirstLeft = outRec1; //fixup FirstLeft pointers that may need reassigning to OutRec1 if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); } } } //------------------------------------------------------------------------------ // ClipperOffset support functions ... //------------------------------------------------------------------------------ DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2) { if(pt2.X == pt1.X && pt2.Y == pt1.Y) return DoublePoint(0, 0); double Dx = (double)(pt2.X - pt1.X); double dy = (double)(pt2.Y - pt1.Y); double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy ); Dx *= f; dy *= f; return DoublePoint(dy, -Dx); } //------------------------------------------------------------------------------ // ClipperOffset class //------------------------------------------------------------------------------ ClipperOffset::ClipperOffset(double miterLimit, double arcTolerance) { this->MiterLimit = miterLimit; this->ArcTolerance = arcTolerance; m_lowest.X = -1; } //------------------------------------------------------------------------------ ClipperOffset::~ClipperOffset() { Clear(); } //------------------------------------------------------------------------------ void ClipperOffset::Clear() { for (int i = 0; i < m_polyNodes.ChildCount(); ++i) delete m_polyNodes.Childs[i]; m_polyNodes.Childs.clear(); m_lowest.X = -1; } //------------------------------------------------------------------------------ void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType) { int highI = (int)path.size() - 1; if (highI < 0) return; PolyNode* newNode = new PolyNode(); newNode->m_jointype = joinType; newNode->m_endtype = endType; //strip duplicate points from path and also get index to the lowest point ... if (endType == etClosedLine || endType == etClosedPolygon) while (highI > 0 && path[0] == path[highI]) highI--; newNode->Contour.reserve(highI + 1); newNode->Contour.push_back(path[0]); int j = 0, k = 0; for (int i = 1; i <= highI; i++) if (newNode->Contour[j] != path[i]) { j++; newNode->Contour.push_back(path[i]); if (path[i].Y > newNode->Contour[k].Y || (path[i].Y == newNode->Contour[k].Y && path[i].X < newNode->Contour[k].X)) k = j; } if (endType == etClosedPolygon && j < 2) { delete newNode; return; } m_polyNodes.AddChild(*newNode); //if this path's lowest pt is lower than all the others then update m_lowest if (endType != etClosedPolygon) return; if (m_lowest.X < 0) m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k); else { IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X]->Contour[(int)m_lowest.Y]; if (newNode->Contour[k].Y > ip.Y || (newNode->Contour[k].Y == ip.Y && newNode->Contour[k].X < ip.X)) m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k); } } //------------------------------------------------------------------------------ void ClipperOffset::AddPaths(const Paths& paths, JoinType joinType, EndType endType) { for (Paths::size_type i = 0; i < paths.size(); ++i) AddPath(paths[i], joinType, endType); } //------------------------------------------------------------------------------ void ClipperOffset::FixOrientations() { //fixup orientations of all closed paths if the orientation of the //closed path with the lowermost vertex is wrong ... if (m_lowest.X >= 0 && !Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour)) { for (int i = 0; i < m_polyNodes.ChildCount(); ++i) { PolyNode& node = *m_polyNodes.Childs[i]; if (node.m_endtype == etClosedPolygon || (node.m_endtype == etClosedLine && Orientation(node.Contour))) ReversePath(node.Contour); } } else { for (int i = 0; i < m_polyNodes.ChildCount(); ++i) { PolyNode& node = *m_polyNodes.Childs[i]; if (node.m_endtype == etClosedLine && !Orientation(node.Contour)) ReversePath(node.Contour); } } } //------------------------------------------------------------------------------ void ClipperOffset::Execute(Paths& solution, double delta) { solution.clear(); FixOrientations(); DoOffset(delta); //now clean up 'corners' ... Clipper clpr; clpr.AddPaths(m_destPolys, ptSubject, true); if (delta > 0) { clpr.Execute(ctUnion, solution, pftPositive, pftPositive); } else { IntRect r = clpr.GetBounds(); Path outer(4); outer[0] = IntPoint(r.left - 10, r.bottom + 10); outer[1] = IntPoint(r.right + 10, r.bottom + 10); outer[2] = IntPoint(r.right + 10, r.top - 10); outer[3] = IntPoint(r.left - 10, r.top - 10); clpr.AddPath(outer, ptSubject, true); clpr.ReverseSolution(true); clpr.Execute(ctUnion, solution, pftNegative, pftNegative); if (solution.size() > 0) solution.erase(solution.begin()); } } //------------------------------------------------------------------------------ void ClipperOffset::Execute(PolyTree& solution, double delta) { solution.Clear(); FixOrientations(); DoOffset(delta); //now clean up 'corners' ... Clipper clpr; clpr.AddPaths(m_destPolys, ptSubject, true); if (delta > 0) { clpr.Execute(ctUnion, solution, pftPositive, pftPositive); } else { IntRect r = clpr.GetBounds(); Path outer(4); outer[0] = IntPoint(r.left - 10, r.bottom + 10); outer[1] = IntPoint(r.right + 10, r.bottom + 10); outer[2] = IntPoint(r.right + 10, r.top - 10); outer[3] = IntPoint(r.left - 10, r.top - 10); clpr.AddPath(outer, ptSubject, true); clpr.ReverseSolution(true); clpr.Execute(ctUnion, solution, pftNegative, pftNegative); //remove the outer PolyNode rectangle ... if (solution.ChildCount() == 1 && solution.Childs[0]->ChildCount() > 0) { PolyNode* outerNode = solution.Childs[0]; solution.Childs.reserve(outerNode->ChildCount()); solution.Childs[0] = outerNode->Childs[0]; solution.Childs[0]->Parent = outerNode->Parent; for (int i = 1; i < outerNode->ChildCount(); ++i) solution.AddChild(*outerNode->Childs[i]); } else solution.Clear(); } } //------------------------------------------------------------------------------ void ClipperOffset::DoOffset(double delta) { m_destPolys.clear(); m_delta = delta; //if Zero offset, just copy any CLOSED polygons to m_p and return ... if (NEAR_ZERO(delta)) { m_destPolys.reserve(m_polyNodes.ChildCount()); for (int i = 0; i < m_polyNodes.ChildCount(); i++) { PolyNode& node = *m_polyNodes.Childs[i]; if (node.m_endtype == etClosedPolygon) m_destPolys.push_back(node.Contour); } return; } //see offset_triginometry3.svg in the documentation folder ... if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit); else m_miterLim = 0.5; double y; if (ArcTolerance <= 0.0) y = def_arc_tolerance; else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance) y = std::fabs(delta) * def_arc_tolerance; else y = ArcTolerance; //see offset_triginometry2.svg in the documentation folder ... double steps = pi / std::acos(1 - y / std::fabs(delta)); if (steps > std::fabs(delta) * pi) steps = std::fabs(delta) * pi; //ie excessive precision check m_sin = std::sin(two_pi / steps); m_cos = std::cos(two_pi / steps); m_StepsPerRad = steps / two_pi; if (delta < 0.0) m_sin = -m_sin; m_destPolys.reserve(m_polyNodes.ChildCount() * 2); for (int i = 0; i < m_polyNodes.ChildCount(); i++) { PolyNode& node = *m_polyNodes.Childs[i]; m_srcPoly = node.Contour; int len = (int)m_srcPoly.size(); if (len == 0 || (delta <= 0 && (len < 3 || node.m_endtype != etClosedPolygon))) continue; m_destPoly.clear(); if (len == 1) { if (node.m_jointype == jtRound) { double X = 1.0, Y = 0.0; for (cInt j = 1; j <= steps; j++) { m_destPoly.push_back(IntPoint( Round(m_srcPoly[0].X + X * delta), Round(m_srcPoly[0].Y + Y * delta))); double X2 = X; X = X * m_cos - m_sin * Y; Y = X2 * m_sin + Y * m_cos; } } else { double X = -1.0, Y = -1.0; for (int j = 0; j < 4; ++j) { m_destPoly.push_back(IntPoint( Round(m_srcPoly[0].X + X * delta), Round(m_srcPoly[0].Y + Y * delta))); if (X < 0) X = 1; else if (Y < 0) Y = 1; else X = -1; } } m_destPolys.push_back(m_destPoly); continue; } //build m_normals ... m_normals.clear(); m_normals.reserve(len); for (int j = 0; j < len - 1; ++j) m_normals.push_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1])); if (node.m_endtype == etClosedLine || node.m_endtype == etClosedPolygon) m_normals.push_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0])); else m_normals.push_back(DoublePoint(m_normals[len - 2])); if (node.m_endtype == etClosedPolygon) { int k = len - 1; for (int j = 0; j < len; ++j) OffsetPoint(j, k, node.m_jointype); m_destPolys.push_back(m_destPoly); } else if (node.m_endtype == etClosedLine) { int k = len - 1; for (int j = 0; j < len; ++j) OffsetPoint(j, k, node.m_jointype); m_destPolys.push_back(m_destPoly); m_destPoly.clear(); //re-build m_normals ... DoublePoint n = m_normals[len -1]; for (int j = len - 1; j > 0; j--) m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y); m_normals[0] = DoublePoint(-n.X, -n.Y); k = 0; for (int j = len - 1; j >= 0; j--) OffsetPoint(j, k, node.m_jointype); m_destPolys.push_back(m_destPoly); } else { int k = 0; for (int j = 1; j < len - 1; ++j) OffsetPoint(j, k, node.m_jointype); IntPoint pt1; if (node.m_endtype == etOpenButt) { int j = len - 1; pt1 = IntPoint((cInt)Round(m_srcPoly[j].X + m_normals[j].X * delta), (cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta)); m_destPoly.push_back(pt1); pt1 = IntPoint((cInt)Round(m_srcPoly[j].X - m_normals[j].X * delta), (cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta)); m_destPoly.push_back(pt1); } else { int j = len - 1; k = len - 2; m_sinA = 0; m_normals[j] = DoublePoint(-m_normals[j].X, -m_normals[j].Y); if (node.m_endtype == etOpenSquare) DoSquare(j, k); else DoRound(j, k); } //re-build m_normals ... for (int j = len - 1; j > 0; j--) m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y); m_normals[0] = DoublePoint(-m_normals[1].X, -m_normals[1].Y); k = len - 1; for (int j = k - 1; j > 0; --j) OffsetPoint(j, k, node.m_jointype); if (node.m_endtype == etOpenButt) { pt1 = IntPoint((cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta), (cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta)); m_destPoly.push_back(pt1); pt1 = IntPoint((cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta), (cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta)); m_destPoly.push_back(pt1); } else { k = 1; m_sinA = 0; if (node.m_endtype == etOpenSquare) DoSquare(0, 1); else DoRound(0, 1); } m_destPolys.push_back(m_destPoly); } } } //------------------------------------------------------------------------------ void ClipperOffset::OffsetPoint(int j, int& k, JoinType jointype) { //cross product ... m_sinA = (m_normals[k].X * m_normals[j].Y - m_normals[j].X * m_normals[k].Y); if (std::fabs(m_sinA * m_delta) < 1.0) { //dot product ... double cosA = (m_normals[k].X * m_normals[j].X + m_normals[j].Y * m_normals[k].Y ); if (cosA > 0) // angle => 0 degrees { m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta), Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta))); return; } //else angle => 180 degrees } else if (m_sinA > 1.0) m_sinA = 1.0; else if (m_sinA < -1.0) m_sinA = -1.0; if (m_sinA * m_delta < 0) { m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta), Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta))); m_destPoly.push_back(m_srcPoly[j]); m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta), Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta))); } else switch (jointype) { case jtMiter: { double r = 1 + (m_normals[j].X * m_normals[k].X + m_normals[j].Y * m_normals[k].Y); if (r >= m_miterLim) DoMiter(j, k, r); else DoSquare(j, k); break; } case jtSquare: DoSquare(j, k); break; case jtRound: DoRound(j, k); break; } k = j; } //------------------------------------------------------------------------------ void ClipperOffset::DoSquare(int j, int k) { double dx = std::tan(std::atan2(m_sinA, m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y) / 4); m_destPoly.push_back(IntPoint( Round(m_srcPoly[j].X + m_delta * (m_normals[k].X - m_normals[k].Y * dx)), Round(m_srcPoly[j].Y + m_delta * (m_normals[k].Y + m_normals[k].X * dx)))); m_destPoly.push_back(IntPoint( Round(m_srcPoly[j].X + m_delta * (m_normals[j].X + m_normals[j].Y * dx)), Round(m_srcPoly[j].Y + m_delta * (m_normals[j].Y - m_normals[j].X * dx)))); } //------------------------------------------------------------------------------ void ClipperOffset::DoMiter(int j, int k, double r) { double q = m_delta / r; m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q), Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q))); } //------------------------------------------------------------------------------ void ClipperOffset::DoRound(int j, int k) { double a = std::atan2(m_sinA, m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y); int steps = std::max((int)Round(m_StepsPerRad * std::fabs(a)), 1); double X = m_normals[k].X, Y = m_normals[k].Y, X2; for (int i = 0; i < steps; ++i) { m_destPoly.push_back(IntPoint( Round(m_srcPoly[j].X + X * m_delta), Round(m_srcPoly[j].Y + Y * m_delta))); X2 = X; X = X * m_cos - m_sin * Y; Y = X2 * m_sin + Y * m_cos; } m_destPoly.push_back(IntPoint( Round(m_srcPoly[j].X + m_normals[j].X * m_delta), Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta))); } //------------------------------------------------------------------------------ // Miscellaneous public functions //------------------------------------------------------------------------------ void Clipper::DoSimplePolygons() { PolyOutList::size_type i = 0; while (i < m_PolyOuts.size()) { OutRec* outrec = m_PolyOuts[i++]; OutPt* op = outrec->Pts; if (!op || outrec->IsOpen) continue; do //for each Pt in Polygon until duplicate found do ... { OutPt* op2 = op->Next; while (op2 != outrec->Pts) { if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op) { //split the polygon into two ... OutPt* op3 = op->Prev; OutPt* op4 = op2->Prev; op->Prev = op4; op4->Next = op; op2->Prev = op3; op3->Next = op2; outrec->Pts = op; OutRec* outrec2 = CreateOutRec(); outrec2->Pts = op2; UpdateOutPtIdxs(*outrec2); if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts)) { //OutRec2 is contained by OutRec1 ... outrec2->IsHole = !outrec->IsHole; outrec2->FirstLeft = outrec; if (m_UsingPolyTree) FixupFirstLefts2(outrec2, outrec); } else if (Poly2ContainsPoly1(outrec->Pts, outrec2->Pts)) { //OutRec1 is contained by OutRec2 ... outrec2->IsHole = outrec->IsHole; outrec->IsHole = !outrec2->IsHole; outrec2->FirstLeft = outrec->FirstLeft; outrec->FirstLeft = outrec2; if (m_UsingPolyTree) FixupFirstLefts2(outrec, outrec2); } else { //the 2 polygons are separate ... outrec2->IsHole = outrec->IsHole; outrec2->FirstLeft = outrec->FirstLeft; if (m_UsingPolyTree) FixupFirstLefts1(outrec, outrec2); } op2 = op; //ie get ready for the Next iteration } op2 = op2->Next; } op = op->Next; } while (op != outrec->Pts); } } //------------------------------------------------------------------------------ void ReversePath(Path& p) { std::reverse(p.begin(), p.end()); } //------------------------------------------------------------------------------ void ReversePaths(Paths& p) { for (Paths::size_type i = 0; i < p.size(); ++i) ReversePath(p[i]); } //------------------------------------------------------------------------------ void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType) { Clipper c; c.StrictlySimple(true); c.AddPath(in_poly, ptSubject, true); c.Execute(ctUnion, out_polys, fillType, fillType); } //------------------------------------------------------------------------------ void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType) { Clipper c; c.StrictlySimple(true); c.AddPaths(in_polys, ptSubject, true); c.Execute(ctUnion, out_polys, fillType, fillType); } //------------------------------------------------------------------------------ void SimplifyPolygons(Paths &polys, PolyFillType fillType) { SimplifyPolygons(polys, polys, fillType); } //------------------------------------------------------------------------------ inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2) { double Dx = ((double)pt1.X - pt2.X); double dy = ((double)pt1.Y - pt2.Y); return (Dx*Dx + dy*dy); } //------------------------------------------------------------------------------ double DistanceFromLineSqrd( const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2) { //The equation of a line in general form (Ax + By + C = 0) //given 2 points (x¹,y¹) & (x²,y²) is ... //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) //see http://en.wikipedia.org/wiki/Perpendicular_distance double A = double(ln1.Y - ln2.Y); double B = double(ln2.X - ln1.X); double C = A * ln1.X + B * ln1.Y; C = A * pt.X + B * pt.Y - C; return (C * C) / (A * A + B * B); } //--------------------------------------------------------------------------- bool SlopesNearCollinear(const IntPoint& pt1, const IntPoint& pt2, const IntPoint& pt3, double distSqrd) { //this function is more accurate when the point that's geometrically //between the other 2 points is the one that's tested for distance. //ie makes it more likely to pick up 'spikes' ... if (Abs(pt1.X - pt2.X) > Abs(pt1.Y - pt2.Y)) { if ((pt1.X > pt2.X) == (pt1.X < pt3.X)) return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd; else if ((pt2.X > pt1.X) == (pt2.X < pt3.X)) return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; else return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd; } else { if ((pt1.Y > pt2.Y) == (pt1.Y < pt3.Y)) return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd; else if ((pt2.Y > pt1.Y) == (pt2.Y < pt3.Y)) return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; else return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd; } } //------------------------------------------------------------------------------ bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) { double Dx = (double)pt1.X - pt2.X; double dy = (double)pt1.Y - pt2.Y; return ((Dx * Dx) + (dy * dy) <= distSqrd); } //------------------------------------------------------------------------------ OutPt* ExcludeOp(OutPt* op) { OutPt* result = op->Prev; result->Next = op->Next; op->Next->Prev = result; result->Idx = 0; return result; } //------------------------------------------------------------------------------ void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) { //distance = proximity in units/pixels below which vertices //will be stripped. Default ~= sqrt(2). size_t size = in_poly.size(); if (size == 0) { out_poly.clear(); return; } OutPt* outPts = new OutPt[size]; for (size_t i = 0; i < size; ++i) { outPts[i].Pt = in_poly[i]; outPts[i].Next = &outPts[(i + 1) % size]; outPts[i].Next->Prev = &outPts[i]; outPts[i].Idx = 0; } double distSqrd = distance * distance; OutPt* op = &outPts[0]; while (op->Idx == 0 && op->Next != op->Prev) { if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd)) { op = ExcludeOp(op); size--; } else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd)) { ExcludeOp(op->Next); op = ExcludeOp(op); size -= 2; } else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd)) { op = ExcludeOp(op); size--; } else { op->Idx = 1; op = op->Next; } } if (size < 3) size = 0; out_poly.resize(size); for (size_t i = 0; i < size; ++i) { out_poly[i] = op->Pt; op = op->Next; } delete [] outPts; } //------------------------------------------------------------------------------ void CleanPolygon(Path& poly, double distance) { CleanPolygon(poly, poly, distance); } //------------------------------------------------------------------------------ void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance) { for (Paths::size_type i = 0; i < in_polys.size(); ++i) CleanPolygon(in_polys[i], out_polys[i], distance); } //------------------------------------------------------------------------------ void CleanPolygons(Paths& polys, double distance) { CleanPolygons(polys, polys, distance); } //------------------------------------------------------------------------------ void Minkowski(const Path& poly, const Path& path, Paths& solution, bool isSum, bool isClosed) { int delta = (isClosed ? 1 : 0); size_t polyCnt = poly.size(); size_t pathCnt = path.size(); Paths pp; pp.reserve(pathCnt); if (isSum) for (size_t i = 0; i < pathCnt; ++i) { Path p; p.reserve(polyCnt); for (size_t j = 0; j < poly.size(); ++j) p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y)); pp.push_back(p); } else for (size_t i = 0; i < pathCnt; ++i) { Path p; p.reserve(polyCnt); for (size_t j = 0; j < poly.size(); ++j) p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y)); pp.push_back(p); } solution.clear(); solution.reserve((pathCnt + delta) * (polyCnt + 1)); for (size_t i = 0; i < pathCnt - 1 + delta; ++i) for (size_t j = 0; j < polyCnt; ++j) { Path quad; quad.reserve(4); quad.push_back(pp[i % pathCnt][j % polyCnt]); quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]); quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]); quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]); if (!Orientation(quad)) ReversePath(quad); solution.push_back(quad); } } //------------------------------------------------------------------------------ void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed) { Minkowski(pattern, path, solution, true, pathIsClosed); Clipper c; c.AddPaths(solution, ptSubject, true); c.Execute(ctUnion, solution, pftNonZero, pftNonZero); } //------------------------------------------------------------------------------ void TranslatePath(const Path& input, Path& output, IntPoint delta) { //precondition: input != output output.resize(input.size()); for (size_t i = 0; i < input.size(); ++i) output[i] = IntPoint(input[i].X + delta.X, input[i].Y + delta.Y); } //------------------------------------------------------------------------------ void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed) { Clipper c; for (size_t i = 0; i < paths.size(); ++i) { Paths tmp; Minkowski(pattern, paths[i], tmp, true, pathIsClosed); c.AddPaths(tmp, ptSubject, true); if (pathIsClosed) { Path tmp2; TranslatePath(paths[i], tmp2, pattern[0]); c.AddPath(tmp2, ptClip, true); } } c.Execute(ctUnion, solution, pftNonZero, pftNonZero); } //------------------------------------------------------------------------------ void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution) { Minkowski(poly1, poly2, solution, false, true); Clipper c; c.AddPaths(solution, ptSubject, true); c.Execute(ctUnion, solution, pftNonZero, pftNonZero); } //------------------------------------------------------------------------------ enum NodeType {ntAny, ntOpen, ntClosed}; void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, Paths& paths) { bool match = true; if (nodetype == ntClosed) match = !polynode.IsOpen(); else if (nodetype == ntOpen) return; if (!polynode.Contour.empty() && match) paths.push_back(polynode.Contour); for (int i = 0; i < polynode.ChildCount(); ++i) AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths); } //------------------------------------------------------------------------------ void PolyTreeToPaths(const PolyTree& polytree, Paths& paths) { paths.resize(0); paths.reserve(polytree.Total()); AddPolyNodeToPaths(polytree, ntAny, paths); } //------------------------------------------------------------------------------ void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths) { paths.resize(0); paths.reserve(polytree.Total()); AddPolyNodeToPaths(polytree, ntClosed, paths); } //------------------------------------------------------------------------------ void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths) { paths.resize(0); paths.reserve(polytree.Total()); //Open paths are top level only, so ... for (int i = 0; i < polytree.ChildCount(); ++i) if (polytree.Childs[i]->IsOpen()) paths.push_back(polytree.Childs[i]->Contour); } //------------------------------------------------------------------------------ std::ostream& operator <<(std::ostream &s, const IntPoint &p) { s << "(" << p.X << "," << p.Y << ")"; return s; } //------------------------------------------------------------------------------ std::ostream& operator <<(std::ostream &s, const Path &p) { if (p.empty()) return s; Path::size_type last = p.size() -1; for (Path::size_type i = 0; i < last; i++) s << "(" << p[i].X << "," << p[i].Y << "), "; s << "(" << p[last].X << "," << p[last].Y << ")\n"; return s; } //------------------------------------------------------------------------------ std::ostream& operator <<(std::ostream &s, const Paths &p) { for (Paths::size_type i = 0; i < p.size(); i++) s << p[i]; s << "\n"; return s; } //------------------------------------------------------------------------------ } //ClipperLib namespace ltfat/thirdparty/polyboolclipper/polyboolclipperinit.m0000664000175000017500000000170513026262276023465 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} polyboolclipperinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/polyboolclipper/polyboolclipperinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/thirdparty/polyboolclipper/Makefile_mac0000664000175000017500000000167613026262276021474 0ustar susnaksusnakifndef MATLABROOT $(warning MATLABROOT variable is undefined. Using default MATLABROOT="/Applications/MATLAB_R2013a.app/") MATLABROOT=/Applications/MATLAB_R2013a.app/ endif ifndef EXT $(warning EXT variable is undefined. Using default EXT=mexmaci64) EXT=mexmaci64 endif ifndef ARCH $(warning ARCH variable is undefined. Using default ARCH=maci64 ) ARCH=maci64 endif # 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 include ../../libltfat/ostools.mk MEXTGT=polyboolmex.$(EXT) MEXSRC=polyboolmex.cpp clipper.cpp LIBS=-L. -L"$(MATLABROOT)/bin/$(ARCH)" -lmex -lmx -lm INCLUDES= -I"$(MATLABROOT)/extern/include" -I. CXXFLAGS=-fPIC -O3 -Wall -shared -DMATLAB_MEX_FILE all: $(CXX) $(CXXFLAGS) $(INCLUDES) $(MEXSRC) $(LIBS) -o $(MEXTGT) clean: $(RM) $(MEXTGT) .PHONY: all clean ltfat/thirdparty/polyboolclipper/clipper.hpp0000664000175000017500000003756513026262276021371 0ustar susnaksusnak/******************************************************************************* * * * Author : Angus Johnson * * Version : 6.2.1 * * Date : 31 October 2014 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2014 * * * * License: * * Use, modification & distribution is subject to Boost Software License Ver 1. * * http://www.boost.org/LICENSE_1_0.txt * * * * Attributions: * * The code in this library is an extension of Bala Vatti's clipping algorithm: * * "A generic solution to polygon clipping" * * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * * http://portal.acm.org/citation.cfm?id=129906 * * * * Computer graphics and geometric modeling: implementation and algorithms * * By Max K. Agoston * * Springer; 1 edition (January 4, 2005) * * http://books.google.com/books?q=vatti+clipping+agoston * * * * See also: * * "Polygon Offsetting by Computing Winding Numbers" * * Paper no. DETC2005-85513 pp. 565-575 * * ASME 2005 International Design Engineering Technical Conferences * * and Computers and Information in Engineering Conference (IDETC/CIE2005) * * September 24-28, 2005 , Long Beach, California, USA * * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * * * *******************************************************************************/ /* License: The Clipper Library (including Delphi, C++ & C# source code, other accompanying code, examples and documentation), hereafter called "the Software", has been released under the following license, terms and conditions: Boost Software License - Version 1.0 - August 17th, 2003 http://www.boost.org/LICENSE_1_0.txt Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the Software covered by this license to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef clipper_hpp #define clipper_hpp #define CLIPPER_VERSION "6.2.0" //use_int32: When enabled 32bit ints are used instead of 64bit ints. This //improve performance but coordinate values are limited to the range +/- 46340 //#define use_int32 //use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance. //#define use_xyz //use_lines: Enables line clipping. Adds a very minor cost to performance. //#define use_lines //use_deprecated: Enables temporary support for the obsolete functions //#define use_deprecated #include #include #include #include #include #include #include #include namespace ClipperLib { enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; enum PolyType { ptSubject, ptClip }; //By far the most widely used winding rules for polygon filling are //EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) //Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) //see http://glprogramming.com/red/chapter11.html enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; #ifdef use_int32 typedef int cInt; static cInt const loRange = 0x7FFF; static cInt const hiRange = 0x7FFF; #else typedef signed long long cInt; static cInt const loRange = 0x3FFFFFFF; static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL; typedef signed long long long64; //used by Int128 class typedef unsigned long long ulong64; #endif struct IntPoint { cInt X; cInt Y; #ifdef use_xyz cInt Z; IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {}; #else IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {}; #endif friend inline bool operator== (const IntPoint& a, const IntPoint& b) { return a.X == b.X && a.Y == b.Y; } friend inline bool operator!= (const IntPoint& a, const IntPoint& b) { return a.X != b.X || a.Y != b.Y; } }; //------------------------------------------------------------------------------ typedef std::vector< IntPoint > Path; typedef std::vector< Path > Paths; inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;} inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;} std::ostream& operator <<(std::ostream &s, const IntPoint &p); std::ostream& operator <<(std::ostream &s, const Path &p); std::ostream& operator <<(std::ostream &s, const Paths &p); struct DoublePoint { double X; double Y; DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {} }; //------------------------------------------------------------------------------ #ifdef use_xyz typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt); #endif enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4}; enum JoinType {jtSquare, jtRound, jtMiter}; enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound}; class PolyNode; typedef std::vector< PolyNode* > PolyNodes; class PolyNode { public: PolyNode(); virtual ~PolyNode(){}; Path Contour; PolyNodes Childs; PolyNode* Parent; PolyNode* GetNext() const; bool IsHole() const; bool IsOpen() const; int ChildCount() const; private: unsigned Index; //node index in Parent.Childs bool m_IsOpen; JoinType m_jointype; EndType m_endtype; PolyNode* GetNextSiblingUp() const; void AddChild(PolyNode& child); friend class Clipper; //to access Index friend class ClipperOffset; }; class PolyTree: public PolyNode { public: ~PolyTree(){Clear();}; PolyNode* GetFirst() const; void Clear(); int Total() const; private: PolyNodes AllNodes; friend class Clipper; //to access AllNodes }; bool Orientation(const Path &poly); double Area(const Path &poly); int PointInPolygon(const IntPoint &pt, const Path &path); void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd); void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd); void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd); void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415); void CleanPolygon(Path& poly, double distance = 1.415); void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415); void CleanPolygons(Paths& polys, double distance = 1.415); void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed); void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed); void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution); void PolyTreeToPaths(const PolyTree& polytree, Paths& paths); void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths); void ReversePath(Path& p); void ReversePaths(Paths& p); struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }; //enums that are used internally ... enum EdgeSide { esLeft = 1, esRight = 2}; //forward declarations (for stuff used internally) ... struct TEdge; struct IntersectNode; struct LocalMinimum; struct Scanbeam; struct OutPt; struct OutRec; struct Join; typedef std::vector < OutRec* > PolyOutList; typedef std::vector < TEdge* > EdgeList; typedef std::vector < Join* > JoinList; typedef std::vector < IntersectNode* > IntersectList; //------------------------------------------------------------------------------ //ClipperBase is the ancestor to the Clipper class. It should not be //instantiated directly. This class simply abstracts the conversion of sets of //polygon coordinates into edge objects that are stored in a LocalMinima list. class ClipperBase { public: ClipperBase(); virtual ~ClipperBase(); bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); virtual void Clear(); IntRect GetBounds(); bool PreserveCollinear() {return m_PreserveCollinear;}; void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; protected: void DisposeLocalMinimaList(); TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); void PopLocalMinima(); virtual void Reset(); TEdge* ProcessBound(TEdge* E, bool IsClockwise); void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed); TEdge* DescendToMin(TEdge *&E); void AscendToMax(TEdge *&E, bool Appending, bool IsClosed); typedef std::vector MinimaList; MinimaList::iterator m_CurrentLM; MinimaList m_MinimaList; bool m_UseFullRange; EdgeList m_edges; bool m_PreserveCollinear; bool m_HasOpenPaths; }; //------------------------------------------------------------------------------ class Clipper : public virtual ClipperBase { public: Clipper(int initOptions = 0); ~Clipper(); bool Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType = pftEvenOdd, PolyFillType clipFillType = pftEvenOdd); bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType = pftEvenOdd, PolyFillType clipFillType = pftEvenOdd); bool ReverseSolution() {return m_ReverseOutput;}; void ReverseSolution(bool value) {m_ReverseOutput = value;}; bool StrictlySimple() {return m_StrictSimple;}; void StrictlySimple(bool value) {m_StrictSimple = value;}; //set the callback function for z value filling on intersections (otherwise Z is 0) #ifdef use_xyz void ZFillFunction(ZFillCallback zFillFunc); #endif protected: void Reset(); virtual bool ExecuteInternal(); private: PolyOutList m_PolyOuts; JoinList m_Joins; JoinList m_GhostJoins; IntersectList m_IntersectList; ClipType m_ClipType; typedef std::priority_queue ScanbeamList; ScanbeamList m_Scanbeam; TEdge *m_ActiveEdges; TEdge *m_SortedEdges; bool m_ExecuteLocked; PolyFillType m_ClipFillType; PolyFillType m_SubjFillType; bool m_ReverseOutput; bool m_UsingPolyTree; bool m_StrictSimple; #ifdef use_xyz ZFillCallback m_ZFill; //custom callback #endif void SetWindingCount(TEdge& edge); bool IsEvenOddFillType(const TEdge& edge) const; bool IsEvenOddAltFillType(const TEdge& edge) const; void InsertScanbeam(const cInt Y); cInt PopScanbeam(); void InsertLocalMinimaIntoAEL(const cInt botY); void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); void AddEdgeToSEL(TEdge *edge); void CopyAELToSEL(); void DeleteFromSEL(TEdge *e); void DeleteFromAEL(TEdge *e); void UpdateEdgeIntoAEL(TEdge *&e); void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); bool IsContributing(const TEdge& edge) const; bool IsTopHorz(const cInt XPos); void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); void DoMaxima(TEdge *e); void ProcessHorizontals(bool IsTopOfScanbeam); void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam); void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); OutRec* GetOutRec(int idx); void AppendPolygon(TEdge *e1, TEdge *e2); void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); OutRec* CreateOutRec(); OutPt* AddOutPt(TEdge *e, const IntPoint &pt); void DisposeAllOutRecs(); void DisposeOutRec(PolyOutList::size_type index); bool ProcessIntersections(const cInt topY); void BuildIntersectList(const cInt topY); void ProcessIntersectList(); void ProcessEdgesAtTopOfScanbeam(const cInt topY); void BuildResult(Paths& polys); void BuildResult2(PolyTree& polytree); void SetHoleState(TEdge *e, OutRec *outrec); void DisposeIntersectNodes(); bool FixupIntersectionOrder(); void FixupOutPolygon(OutRec &outrec); bool IsHole(TEdge *e); bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); void FixHoleLinkage(OutRec &outrec); void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); void ClearJoins(); void ClearGhostJoins(); void AddGhostJoin(OutPt *op, const IntPoint offPt); bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2); void JoinCommonEdges(); void DoSimplePolygons(); void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec); #ifdef use_xyz void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2); #endif }; //------------------------------------------------------------------------------ class ClipperOffset { public: ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); ~ClipperOffset(); void AddPath(const Path& path, JoinType joinType, EndType endType); void AddPaths(const Paths& paths, JoinType joinType, EndType endType); void Execute(Paths& solution, double delta); void Execute(PolyTree& solution, double delta); void Clear(); double MiterLimit; double ArcTolerance; private: Paths m_destPolys; Path m_srcPoly; Path m_destPoly; std::vector m_normals; double m_delta, m_sinA, m_sin, m_cos; double m_miterLim, m_StepsPerRad; IntPoint m_lowest; PolyNode m_polyNodes; void FixOrientations(); void DoOffset(double delta); void OffsetPoint(int j, int& k, JoinType jointype); void DoSquare(int j, int k); void DoMiter(int j, int k, double r); void DoRound(int j, int k); }; //------------------------------------------------------------------------------ class clipperException : public std::exception { public: clipperException(const char* description): m_descr(description) {} virtual ~clipperException() throw() {} virtual const char* what() const throw() {return m_descr.c_str();} private: std::string m_descr; }; //------------------------------------------------------------------------------ } //ClipperLib namespace #endif //clipper_hpp ltfat/thirdparty/polyboolclipper/Makefile_unix0000664000175000017500000000170213026262276021705 0ustar susnaksusnak# 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 undefined. Using default MATLABROOT="C:\Program Files\MATLAB\R2011b" ) MATLABROOT=/usr/local/MATLAB/R2011a endif ifndef EXT $(warning EXT variable is undefined. Using default EXT=mexa64 ) EXT=mexa64 endif ifndef ARCH $(warning ARCH variable is undefined. Using default ARCH=win64 ) ARCH=glnxa64 endif include ../../libltfat/ostools.mk MEXTGT=polyboolmex.$(EXT) MEXSRC=polyboolmex.cpp clipper.cpp LIBS=-Wl,--no-undefined -L. -L"$(MATLABROOT)/bin/$(ARCH)" -lmex -lmx -lm INCLUDES= -I"$(MATLABROOT)/extern/include" -I. CXXFLAGS=-fPIC -O3 -Wall -shared -DMATLAB_MEX_FILE all: $(CXX) $(CXXFLAGS) $(INCLUDES) $(MEXSRC) $(LIBS) -o $(MEXTGT) clean: $(RM) $(MEXTGT) .PHONY: all clean ltfat/thirdparty/Playrec/0000775000175000017500000000000013026262276015363 5ustar susnaksusnakltfat/thirdparty/Playrec/config.h0000664000175000017500000000105613026262276017003 0ustar susnaksusnak#ifndef _CONFIG_H #define _CONFIG_H /* The mx class equivalent to SAMPLE */ #define mxSAMPLE mxSINGLE_CLASS /* Format to be used for samples with PortAudio = 32bit */ typedef float SAMPLE; /* This controls type of polynomial resampling. * * See enum resample_type in ltfatresample.h for * possible values. */ #define RESAMPLING_TYPE BSPLINE /* This is a constant used to adjust the critical frequency of the * anti-aliasing low-pass filter. * The filtering is done only when subsampling is performed. */ #define FPADJ 0.92 #endif ltfat/thirdparty/Playrec/Makefile_mingw0000664000175000017500000000114313026262276020223 0ustar susnaksusnak# 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 undefined. Using default MATLABROOT="C:\Program Files\MATLAB\R2011b" ) MATLABROOT=C:\Program Files\MATLAB\R2011b endif ifndef EXT $(warning EXT variable is undefined. Using default EXT=mexw64 ) EXT=mexw64 endif ifndef ARCH $(warning ARCH variable is undefined. Using default ARCH=win64 ) ARCH=win64 endif include Makefile_unix ltfat/thirdparty/Playrec/pa_dll_playrec.h0000664000175000017500000003162513026262276020515 0ustar susnaksusnak/* * 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 #include "mex.h" #include "portaudio.h" #include "config.h" #include "ltfatresample.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; // Already done in config.h /* 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 */ unsigned int pageLengthRec; /* The max. length of a chan. before resampling */ 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 doGetPlayrec(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 */ ltfat/thirdparty/Playrec/Makefile_mingwoct0000664000175000017500000000014213026262276020727 0ustar susnaksusnak# Use GNU Make to process this file. # mingw32-make -f Makefile_mingw32 include Makefile_unixoct ltfat/thirdparty/Playrec/Makefile_unixoct0000664000175000017500000000101313026262276020567 0ustar susnaksusnak# Use GNU Make to process this file. MKOCTFILE ?= mkoctfile ifndef EXT EXT=mex endif ifndef PORTAUDIO ifdef HAVE_PORTAUDIO PORTAUDIO=-lportaudio endif endif include ../../src/ostools.mk ADDITIONALFLAGS = -L. $(PORTAUDIO) -I. -I../../libltfat/thirdparty -DIS_OCTAVE ifdef HAVE_PORTAUDIO ADDITIONALFLAGS += -DHAVE_PORTAUDIO endif all: $(MKOCTFILE) -Wall -mex mex_dll_core.c pa_dll_playrec.c ltfatresample.c \ $(ADDITIONALFLAGS) -o playrec.$(EXT) clean: $(RM) *.o *.$(EXT) .PHONY: all clean ltfat/thirdparty/Playrec/mex_dll_core.h0000664000175000017500000001624313026262276020176 0ustar susnaksusnak/* * 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 */ ltfat/thirdparty/Playrec/Makefile_macoct0000664000175000017500000000003113026262276020343 0ustar susnaksusnakinclude Makefile_unixoct ltfat/thirdparty/Playrec/ltfatresample.c0000664000175000017500000003347113026262276020402 0ustar susnaksusnak/* * ltfatresample.c * * Copyright (C) 2014 Zdenek Prusa . * This file is part of LTFAT http://ltfat.github.io * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "ltfatresample.h" #include /* This is an actual structure used to hold info between consecutive blocks */ struct resample_plan_struct { /* target to source sampling rates ratio */ const double ratio; /* Type of polynomial interpolation */ const resample_type restype; /* First sample in block global index */ size_t inPos; size_t outPos; /* Buffer for holding overlap, length depend on interpoaltion technique */ SAMPLE* overlap; /* Overlap length */ size_t oLen; /* Function pointer to the block interpolation functon */ resample_error (*executer)(const resample_plan, const SAMPLE*, const size_t, SAMPLE*, const size_t); /* Function pointer to one sample interpolating function */ SAMPLE (*interp_sample)(const double, const SAMPLE *yin); /* Filters */ EMQFfilters ef; /* Buffer, maxlength ceil(ratio) */ SAMPLE* ebuf; const size_t ebufLen; /* Number of samples to be used from ebuf */ size_t ebufUsed; }; void resample_reset(const resample_plan rp) { memset(rp->overlap,0,rp->oLen*sizeof*rp->overlap); rp->inPos = 0; rp->outPos = 0; rp->ebufUsed = 0; } resample_plan resample_init(const resample_type restype, const double ratio) { resample_plan rp = calloc(1, sizeof * rp); *(double*)&rp->ratio = ratio; *(resample_type*)&rp->restype = restype; if (restype == LINEAR) { rp->oLen = 1; rp->executer = &resample_execute_polynomial; rp->interp_sample = &linear_interp; } else if (restype == LAGRANGE) { rp->oLen = 5; rp->executer = &resample_execute_polynomial; rp->interp_sample = &lagrange_interp; } else if (restype == BSPLINE) { rp->oLen = 5; rp->executer = &resample_execute_polynomial; rp->interp_sample = &bspline_interp; } rp->overlap = calloc(rp->oLen, sizeof(SAMPLE)); *(size_t*)&rp->ebufLen = ceil(ratio); rp->ebuf = malloc(rp->ebufLen * sizeof(SAMPLE)); /*rp->ebufUsed = 0; This was actually already set. */ /* When subsampling, do the antialiasing filtering. */ /* This is not exactly 1, because we do not want to filter when * subsampling only a little or not at all. */ if (ratio < 0.95) { rp->ef = emqffilters_init(ratio * FPADJ); } return rp; } resample_error resample_execute(const resample_plan rp, SAMPLE* in, const size_t Lin, SAMPLE* out, const size_t Lout) { resample_error status; /* Do filtering if initialized */ if (rp->ef) { /* Filtering is done inplace */ emqffilters_dofilter(rp->ef, in, Lin, in); } /* Execute the computation */ status = rp->executer(rp, in, Lin, out, Lout); if (status == RESAMPLE_OK) { /* All ok, advance both stream pointers */ resample_advanceby(rp, Lin, Lout); } else { /* Overflow or underflow occured, resetting the stream */ resample_reset(rp); } return status; } size_t resample_nextoutlen(const resample_plan rp, size_t Lin) { size_t retval = 0; const double outSpos = ceil( (rp->inPos) * rp->ratio ); const double outEpos = ceil( (rp->inPos + Lin) * rp->ratio ); retval = (size_t)( outEpos - outSpos); return retval; } size_t resample_nextinlen(const resample_plan rp, size_t Lout) { size_t retval = 0; const double outSpos = ceil( (rp->outPos) / rp->ratio ); const double outEpos = ceil( (rp->outPos + Lout) / rp->ratio ); retval = (size_t)( outEpos - outSpos); return retval; } /* Be carefull, rp is effectivelly a double pointer. */ void resample_done(resample_plan *rp) { if ((*rp)->overlap) free((*rp)->overlap); if ((*rp)->ebuf) free((*rp)->ebuf); if ((*rp)->ef) emqffilters_done(&((*rp)->ef)); free(*rp); /* This is the reason why it is passed by a double pointer */ *rp = NULL; } void resample_advanceby(const resample_plan rp, const size_t Lin, const size_t Lout) { rp->inPos += Lin; rp->outPos += Lout; } /* INTERNALS */ /* This can handle any type of polynomial resampling. */ resample_error resample_execute_polynomial(const resample_plan rp, const SAMPLE* in, const size_t Lin, SAMPLE* out, const size_t Lout) { #define ONESAMPLE(outVal)\ truepos = (ii + outSpos) * oneOverRatio - rp->inPos;\ highpos = ceil(truepos);\ x = truepos - (highpos - 1);\ memcpy(buf, &in[highpos - (oLen + 1)], (oLen + 1) * sizeof * buf);\ (outVal) = rp->interp_sample(x, buf); double truepos, x; ptrdiff_t highpos = 0; SAMPLE* buf; size_t ii, jj, zz, *iiThre; resample_error retval = RESAMPLE_OK; size_t oLen = rp->oLen; size_t Louttmp = Lout - rp->ebufUsed; const double oneOverRatio = 1.0 / rp->ratio; /* Starting position in the output stream */ //double outSpos = ceil( (rp->inPos) * rp->ratio ) ; double outSpos = rp->outPos + rp->ebufUsed ; /* How many samples will this routine produce */ size_t Louttrue = resample_nextoutlen(rp, Lin); size_t Loutvalid = Louttrue < Louttmp ? Louttrue : Louttmp; /* Copy buffered samples + update out */ memcpy(out, rp->ebuf, rp->ebufUsed * sizeof * out); out += rp->ebufUsed; /* oLen +1 thresholds */ iiThre = calloc(oLen + 1, sizeof * iiThre); /* Buffer for passing values to single sample interp. routine */ buf = calloc(oLen + 1, sizeof * buf); /* First handle all samples which need overlap. */ for (ii = 0; ii < oLen + 1; ii++) { iiThre[ii] = floor((rp->inPos + ((double) ii + 1) ) * rp->ratio - outSpos) + 1; } /* ii starts here */ ii = 0; for (zz = 0; zz < oLen + 1; zz++) { for (; ii < iiThre[zz]; ii++) { truepos = (ii + outSpos) * oneOverRatio - rp->inPos; x = truepos - zz; memcpy(buf, rp->overlap + zz, (oLen - zz)*sizeof * buf); memcpy(buf + (oLen - zz), in, (zz + 1)*sizeof * buf ); out[ii] = rp->interp_sample(x, buf); } } /* Handle samples safely inside. * ii continues */ for (; ii < Loutvalid ; ii++) { ONESAMPLE(out[ii]) } /* Handle samples overflowing the output buffer * * ii still continues */ for (jj = 0; ii < Louttrue && jj < rp->ebufLen; ii++, jj++ ) { ONESAMPLE(rp->ebuf[jj]) } rp->ebufUsed = jj; if (Louttrue>Louttmp+rp->ebufUsed) { /* Some samples will be skipped. */ retval = RESAMPLE_OVERFLOW; } if (Louttrue < Louttmp) { /* Next iteration will probably access an uninitialized memory. */ retval = RESAMPLE_UNDERFLOW; memset(out+Louttrue,0,(Louttmp-Louttrue)*sizeof*out); } /* Copy last oLen samples to overlap .*/ memcpy(rp->overlap, in + Lin - oLen, oLen * sizeof * in); free(iiThre); free(buf); return retval; #undef ONESAMPLE } SAMPLE linear_interp(const double x, const SAMPLE* yin) { const SAMPLE* y = yin; return (SAMPLE) ( y[0] + x * (y[1] - y[0])); } /* y = [y(-2),y(-1),y(0),y(1),y(2),y(3)] */ /* Taken from: * Olli Niemitalo: Polynomial Interpolators for High-Quality Resampling of * Oversampled Audio, URL: http://yehar.com/blog/?p=197 */ SAMPLE lagrange_interp(const double x, const SAMPLE* yin) { SAMPLE ym1py1, twentyfourthym2py2, c0, c1, c2, c3, c4, c5; const SAMPLE* y = yin + 2; ym1py1 = y[-1] + y[1]; twentyfourthym2py2 = 1 / 24.0 * (y[-2] + y[2]); c0 = y[0]; c1 = 1 / 20.0 * y[-2] - 1 / 2.0 * y[-1] - 1 / 3.0 * y[0] + y[1] - 1 / 4.0 * y[2] + 1 / 30.0 * y[3]; c2 = 2 / 3.0 * ym1py1 - 5 / 4.0 * y[0] - twentyfourthym2py2; c3 = 5 / 12.0 * y[0] - 7 / 12.0 * y[1] + 7 / 24.0 * y[2] - 1 / 24.0 * (y[-2] + y[-1] + y[3]); c4 = 1 / 4.0 * y[0] - 1 / 6.0 * ym1py1 + twentyfourthym2py2; c5 = 1 / 120.0 * (y[3] - y[-2]) + 1 / 24.0 * (y[-1] - y[2]) + 1 / 12.0 * (y[1] - y[0]); return (SAMPLE) ( ((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0 ); } /* y = [y(-2),y(-1),y(0),y(1),y(2),y(3)] */ /* Taken from: * Olli Niemitalo: Polynomial Interpolators for High-Quality Resampling of * Oversampled Audio, URL: http://yehar.com/blog/?p=197 */ SAMPLE bspline_interp(const double x, const SAMPLE* yin) { SAMPLE ym2py2, ym1py1, y2mym2, y1mym1, sixthym1py1, c0, c1, c2, c3, c4, c5; const SAMPLE* y = yin + 2; ym1py1 = y[-1] + y[1]; y1mym1 = y[1] - y[-1]; ym2py2 = y[-2] + y[2]; y2mym2 = y[2] - y[-2]; sixthym1py1 = 1.0 / 6.0 * ym1py1; c0 = 1 / 120.0 * ym2py2 + 13 / 60.0 * ym1py1 + 11 / 20.0 * y[0]; c1 = 1 / 24.0 * y2mym2 + 5 / 12.0 * y1mym1; c2 = 1 / 12.0 * ym2py2 + sixthym1py1 - 1 / 2.0 * y[0]; c3 = 1 / 12.0 * y2mym2 - 1 / 6.0 * y1mym1; c4 = 1 / 24.0 * ym2py2 - sixthym1py1 + 1 / 4.0 * y[0]; c5 = 1 / 120.0 * (y[3] - y[-2]) + 1 / 24.0 * (y[-1] - y[2]) + 1 / 12.0 * (y[1] - y[0]); return (SAMPLE) (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); } /* This is actual structture used to hold info between consecutive blocks */ struct EMQFfilters_struct { /* Passband edge 0-1 (Nyquist) */ const double fc; /* Branch 0 filters params */ const SAMPLE* beta0; const SAMPLE* gamma0; /* For holding state variables */ SAMPLE** d0; /* Number of 2nd order allpass filter in branch 0 */ const size_t stages0; const SAMPLE* beta1; const SAMPLE* gamma1; /* For holding state variables */ SAMPLE** d1; /* Number of 2nd order allpass filter in branch 1. */ const size_t stages1; /* Coefficient of the 1st order allpas filter in branch 1. */ const SAMPLE alpha1; }; EMQFfilters emqffilters_init(const double fc) { double alpha, alpha1; size_t ii, stages0, stages1; SAMPLE *beta0, *gamma0, *beta1, *gamma1, **d0, **d1; EMQFfilters rv; /* Check valid fc */ if (fc <= 0 || fc >= 1) { return NULL; } /* EMQFcoefs is a global variable, defined in filtcoefs.h * generated by a matlab script genfiltcoefs.m */ const double* beta = EMQFcoefs; stages0 = (size_t) ceil(EMQFCOEFLEN / 2.0); stages1 = (size_t) floor(EMQFCOEFLEN / 2.0); beta0 = malloc(stages0 * sizeof * beta0); gamma0 = malloc(stages0 * sizeof * gamma0); if (stages1 > 0) { beta1 = malloc(stages1 * sizeof * beta1); gamma1 = malloc(stages1 * sizeof * gamma1); } d0 = malloc(stages0 * sizeof(SAMPLE*)); d1 = malloc((stages1 + 1) * sizeof(SAMPLE*)); alpha = -cos(M_PI * fc); alpha1 = (1.0 - sqrt(1.0 - alpha * alpha)) / alpha; for (ii = 0; ii < stages0; ii++) { beta0[ii] = (SAMPLE) ((beta[2 * ii] + alpha1 * alpha1) / (beta[2 * ii] * alpha1 * alpha1 + 1.0) ); gamma0[ii] = (SAMPLE) (alpha * (1.0 + beta0[ii])); d0[ii] = calloc(2, sizeof(SAMPLE)); } for (ii = 0; ii < stages1; ii++) { beta1[ii] = (SAMPLE) ((beta[2 * ii + 1] + alpha1 * alpha1) / (beta[2 * ii + 1] * alpha1 * alpha1 + 1.0) ); gamma1[ii] = (SAMPLE) (alpha * (1.0 + beta1[ii])); d1[ii] = calloc(2, sizeof(SAMPLE)); } d1[stages1] = calloc(1, sizeof(SAMPLE)); rv = malloc(sizeof * rv); *(double*)&rv->fc = fc; *(SAMPLE*)&rv->alpha1 = alpha1; rv->beta0 = beta0; rv->gamma0 = gamma0; rv->beta1 = beta1; rv->gamma1 = gamma1; rv->d0 = d0; rv->d1 = d1; *(size_t*)&rv->stages0 = stages0; *(size_t*)&rv->stages1 = stages1; return rv; } /* All 2nd order IIR filters are treated as type II transposed canonical struct. * This can work inplace i.e. in==out */ void emqffilters_dofilter(EMQFfilters ef, const SAMPLE* in, const size_t Lin, SAMPLE* out) { size_t ii, jj; SAMPLE startx, x, y = 0; for (ii = 0; ii < Lin; ii++) { /* Branch 0 */ /* Feedig output of one stage to the input of the next stage */ startx = in[ii]; x = startx; for (jj = 0; jj < ef->stages0; jj++) { y = x * ef->beta0[jj] + ef->d0[jj][0]; ef->d0[jj][0] = ef->gamma0[jj] * (x - y) + ef->d0[jj][1]; ef->d0[jj][1] = x - y * ef->beta0[jj]; x = y; } /* Store the partial output */ out[ii] = y; /* And start over with the second branch */ x = startx; /* Branch 1 */ for (jj = 0; jj < ef->stages1; jj++) { y = x * ef->beta1[jj] + ef->d1[jj][0]; ef->d1[jj][0] = ef->gamma1[jj] * (x - y) + ef->d1[jj][1]; ef->d1[jj][1] = x - y * ef->beta1[jj]; x = y; } /* Final all-pass filter in Branch 1 */ y = x * ef->alpha1 + ef->d1[ef->stages1][0]; ef->d1[ef->stages1][0] = x - y * ef->alpha1; /* Add output of the second branch to output */ out[ii] += y; /* Normalize. Would it be faster to do it after for the whole array? */ out[ii] /= 2.0; } } void emqffilters_done(EMQFfilters* ef) { size_t ii; free((void*)(*ef)->beta0); free((void*)(*ef)->gamma0); free((void*)(*ef)->beta1); free((void*)(*ef)->gamma1); for (ii = 0; ii < (*ef)->stages0; ii++) { free((*ef)->d0[ii]); } free((*ef)->d0); for (ii = 0; ii < (*ef)->stages1 + 1; ii++) { free((*ef)->d1[ii]); } free((*ef)->d1); free(*ef); *ef = NULL; } ltfat/thirdparty/Playrec/filtcoefs.h0000664000175000017500000000054713026262276017520 0ustar susnaksusnak/* This file is autogenerated. Do not edit! Generated by running genfiltcoefs(4.800000e-01,80) */ #define EMQFCOEFLEN 8 static const double EMQFcoefs[]={ 5.7517185398529978e-02, 2.0593303150519190e-01, 3.9220443469999550e-01, 5.6933878325357445e-01, 7.1391142834802357e-01, 8.2295835652084259e-01, 9.0427015365586971e-01, 9.6945815394314838e-01, }; ltfat/thirdparty/Playrec/genfiltcoefs.m0000664000175000017500000002765413026262276020227 0ustar susnaksusnakfunction genfiltcoefs(fp,As,varargin) %-*- texinfo -*- %@deftypefn {Function} genfiltcoefs %@verbatim %GENFILTCOEFS Generate half-band IIR filter % Usage: genfiltcoefs(fp,As) % genfiltcoefs(fp,As) % % Input parameters: % fp : Passband edge frequency % As : Stopband attenuation in dB [positive] % % This function generates coefficients of a half-band IIR filter % consisting of two branches of order 2 all-pass filters. The coefficients % are written to filtcoefs.h to be used in resampling routines in playrec. % % Note this function uses code from % % EMF toolbox for Matlab version 2.1, % Copyright (c) 2003 M. Lutovac and Lj. Milic see the halfbandiir % function below. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/Playrec/genfiltcoefs.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<1 fp = 0.48; end if nargin<2 As = 80; end do_plot = ~isempty(varargin(strcmp('plot',varargin))); do_check = ~isempty(varargin(strcmp('check',varargin))); % Design the half-band filter [b,a]=halfbandiir('minorder',fp,As); % Get roots p =roots(a); % Sort according to the abs value beta = sort(abs(p(imag(p)>0)).^2); % Write to a file basepath = which(mfilename); basepath = basepath(1:end-numel(mfilename)-2); [fileID,message] = fopen([basepath,'filtcoefs.h'],'w'); expstring = ... sprintf(['/*\n This file is autogenerated. Do not edit! \n', ... 'Generated by running %s(%d,%d) ', ... '*/\n'],mfilename,fp,As); betaString = sprintf('%.16e,\n ', beta ); fprintf(fileID,expstring); fprintf(fileID,'#define EMQFCOEFLEN %i\n',numel(beta)); fprintf(fileID,'static const double EMQFcoefs[]={\n %s};\n',betaString(1:end-1)); fclose(fileID); if do_plot figure(1); zplane(b,a); figure(2); freqz(b,a); end if do_check % Allpass filters beta1 = beta(1:2:end); beta2 = beta(2:2:end); A0b = [beta1,zeros(numel(beta1),1),ones(numel(beta1),1)]; A0a = fliplr(A0b); A1b = [beta2,zeros(numel(beta2),1),ones(numel(beta2),1)]; A1a = fliplr(A1b); % Reassemble back A0ball = A0b(1,:); A0aall = A0a(1,:); A1ball = A1b(1,:); A1aall = A1a(1,:); for ii = 2:size(A0b,1) A0ball = conv(A0ball,A0b(ii,:)); A0aall = conv(A0aall,A0a(ii,:)); end for ii = 2:size(A1b,1) A1ball = conv(A1ball,A1b(ii,:)); A1aall = conv(A1aall,A1a(ii,:)); end A1ball = [0,A1ball]; A1aall = [A1aall,0]; A0 = freqz(A0ball,A0aall); A1 = freqz(A1ball,A1aall); disp('Error between the original filter and the summed partials'); norm((A0+A1)/2-freqz(b,a)) end % % % As = 80; % fp = 0.1; % alpha = -cos(pi*fp); % alpha1 = (1-sqrt(1-alpha^2))/alpha; % betaemqf = (beta+alpha1^2)./(beta*alpha1^2+1); % % beta1 = beta(1:2:end); % beta2 = beta(2:2:end); % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Allpass filters % betaemqf1 = betaemqf(1:2:end); % betaemqf2 = betaemqf(2:2:end); % % % A0b = [betaemqf1,alpha*(1+betaemqf1),ones(numel(beta1),1)]; % A0a = fliplr(A0b); % % % A1b = [betaemqf2,alpha*(1+betaemqf2),ones(numel(beta2),1)]; % % % % % A1a = fliplr(A1b); % % % % % % % Reassemble back % A0ball = A0b(1,:); % A0aall = A0a(1,:); % A1ball = A1b(1,:); % A1aall = A1a(1,:); % % % for ii = 2:size(A0b,1) % A0ball = conv(A0ball,A0b(ii,:)); % A0aall = conv(A0aall,A0a(ii,:)); % % end % % % for ii = 2:size(A1b,1) % A1ball = conv(A1ball,A1b(ii,:)); % A1aall = conv(A1aall,A1a(ii,:)); % end % % % A1ball = conv(A1ball,[alpha1,1]); % A1aall = conv(A1aall,[1,alpha1]); % % % % A0 = freqz(A0ball,A0aall,128,'whole'); % A1 = freqz(A1ball,A1aall,128,'whole'); % % fresp=(A0+A1)/2; % f = randn(128,1); % fhat = real(ifft(fft(f).*fresp)); % prd = 0; function [b,a,z,p,k] = halfbandiir(N,fp,varargin) % % HALFBANDIIR Halfband IIR filter design. % [B,A,Z,P,K] = HALFBANDIIR(N,Fp) designs a lowpass N-th order % halfband IIR filter with an equiripple characteristic. % % The filter order, N, must be selected such that N is an odd integer. % Fp determines the passband edge frequency that must satisfy % 0 < Fp < 1/2 where 1/2 corresponds to pi/2 [rad/sample]. % % [B,A,Z,P,K] = HALFBANDIIR('minorder',Fp,Dev) designs the minimum % order IIR filter, with passband edge Fp and ripple Dev. % Dev is a passband ripple that must satisfy 0 < Dev (linear) < 0.29289 % or stopband attenuation that must satisfy Dev (dB) > 3.1 % % The last three left-hand arguments are the zeros and poles returned in % length N column vectors Z and P, and the gain in scalar K. % % [B,A,Z,P,K] = HALFBANDIIR(...'high') returns a highpass halfband filter. % % EXAMPLE: Design a minimum order halfband filter with given max ripple % [b,a,z,p,k]=halfbandiir('minorder',.45,0.0001); % % Authors: Miroslav Lutovac and Ljiljana Milic % lutovac@kondor.etf.bg.ac.yu milic@kondor.imp.bg.ac.yu % http://kondor.etf.bg.ac.yu/~lutovac % http://galeb.etf.bg.ac.yu/~milic % Copyright (c) 2003 Miroslav Lutovac and Ljiljana Milic % $Revision: 2.1 $ $Date: 2003/04/02 12:22:33 $ % This file is part of EMF toolbox for MATLAB. % Refer to the file LICENSE.TXT for full details. % % EMF version 2.1, Copyright (c) 2003 M. Lutovac and Lj. Milic % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; see LICENSE.TXT for details. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, % MA 02111-1307 USA, http://www.fsf.org/ error(nargchk(2,4,nargin)); [minOrderFlag,lowpassFlag,msg] = validateParseInput(N,fp,varargin{:}); error(msg); omegap = fp*pi; omegas = (1-fp)*pi; if minOrderFlag, if varargin{1} <1 deltap = varargin{1}; deltas = sqrt(deltap*(2-deltap)); Rp = -20*log10(1-deltap); Rs = -20*log10(deltas); else Rs = varargin{1}; deltas = 10^(-Rs/20); deltap = 1-sqrt(1-deltas^2); Rp = -20*log10(1-deltap); end N = estimateOrder(omegap,omegas,Rp,Rs); end if N < 3, N = 3; end fa = (1-fp)/2; x = 1/(tan(pi*fp/2))^2; if x >= sqrt(2) t = .5*(1-(1-1/x^2)^(1/4))/(1+(1-1/x^2)^(1/4)); q = t+2*t^5+15*t^9+150*t^13; else t = .5*(1-1/sqrt(x))/(1+1/sqrt(x)); qp = t+2*t^5+15*t^9+150*t^13; q = exp(pi^2/log(qp)); end L = (1/4)*sqrt(1/q^N-1); Rp = 10*log10(1+1/L); Rs = 10*log10(1+L); if N == 3 beta = nfp2beta(N,fp/2); p = [0;i*sqrt(beta);-i*sqrt(beta)]; z = [-1 (beta-1 + i*sqrt(3*beta^2 + 2*beta-1))/(2*beta) (beta-1 - i*sqrt(3*beta^2 + 2*beta-1))/(2*beta)]; k = beta/2; b = [beta 1 1 beta]/2; a = [1 0 beta 0]; elseif N == 5 [beta,zeroi,select] = nfp2beta(N,fp/2); k = 1/2; p = 0; z = -1; for ind = 2:2:N ind2 = ind/2; p = [p;i*sqrt(beta(ind2));-i*sqrt(beta(ind2))]; z = [z;(zeroi(ind2)^2-select+i*2*sqrt(select)*zeroi(ind2))/(select+zeroi(ind2)^2)]; z = [z;(zeroi(ind2)^2-select-i*2*sqrt(select)*zeroi(ind2))/(select+zeroi(ind2)^2)]; k = k*(1+beta(ind2))*(1+zeroi(ind2)^2/select)/4; end aOdd = 1; bOdd = 1; for ind = 1:2:length(beta) aOdd = conv(aOdd,[1 0 beta(ind)]); bOdd = conv(bOdd,[beta(ind) 0 1]); end aEven = 1; bEven = 1; for ind = 2:2:length(beta) aEven = conv(aEven,[1 0 beta(ind)]); bEven = conv(bEven,[beta(ind) 0 1]); end a = conv(conv(aOdd,aEven),[1 0]); b = (conv(conv(aOdd,bEven),[0 1]) + conv(conv(bOdd,aEven),[1 0]))/2; else % [z,p,k] = ellip(N,Rp,Rs,omegap/pi) % [b,a] = ellip(N,Rp,Rs,omegap/pi) [beta,zeroi,select] = nfp2beta(N,fp/2); k = 1/2; p = 0; z = -1; for ind = 2:2:N ind2 = ind/2; p = [p;i*sqrt(beta(ind2));-i*sqrt(beta(ind2))]; z = [z;(zeroi(ind2)^2-select+i*2*sqrt(select)*zeroi(ind2))/(select+zeroi(ind2)^2)]; z = [z;(zeroi(ind2)^2-select-i*2*sqrt(select)*zeroi(ind2))/(select+zeroi(ind2)^2)]; k = k*(1+beta(ind2))*(1+zeroi(ind2)^2/select)/4; end aOdd = 1; bOdd = 1; for ind = 1:2:length(beta) aOdd = conv(aOdd,[1 0 beta(ind)]); bOdd = conv(bOdd,[beta(ind) 0 1]); end aEven = 1; bEven = 1; for ind = 2:2:length(beta) aEven = conv(aEven,[1 0 beta(ind)]); bEven = conv(bEven,[beta(ind) 0 1]); end a = conv(conv(aOdd,aEven),[1 0]); b = (conv(conv(aOdd,bEven),[0 1]) + conv(conv(bOdd,aEven),[1 0]))/2; end if ~lowpassFlag, z = -z; b = b.*((-(ones(size(b)))).^(1:length(b))); end %------------------------------------------------------------- function N = estimateOrder(omegap,omegas,Rp,Rs) N = ellipord(omegap/pi,omegas/pi,Rp,Rs); N = adjustOrder(N); %------------------------------------------------------------- function N = adjustOrder(N) if (N+1) ~= 2*fix((N+1)/2), N = N + 1; end %------------------------------------------------------------- function [minOrderFlag,lowpassFlag,msg] = validateParseInput(N,fp,varargin) msg = ''; minOrderFlag = 0; lowpassFlag = 1; if nargin > 2 & ischar(varargin{end}), stringOpts = {'low','high'}; lpindx = strmatch(lower(varargin{end}),stringOpts); if ~isempty(lpindx) & lpindx == 2, lowpassFlag = 0; end end if ischar(N), ordindx = strmatch(lower(N),'minorder'); if ~isempty(ordindx), minOrderFlag = 1; if nargin < 3, msg = 'Passband ripple, Dev, must be specified for minimum order design.'; return end if ~isValidScalar(varargin{1}), msg = 'Passband ripple must be a scalar.'; return elseif varargin{1} <= 0 | ((varargin{1} >= 0.29289)&(varargin{1} <= 3.1)) , msg = ['Dev=' num2str(varargin{1}) ', it must be 03.1']; return end else msg = 'Specified unrecognized order.'; return end elseif ~isValidScalar(N), msg = 'Specified unrecognized order.'; return else if (N+1) ~= 2*fix((N+1)/2), msg = ['N=' num2str(N) ', order must be an odd integer.']; return end if nargin > 2 & ~ischar(varargin{1}), msg = 'Passband ripple, Dev, can be specified for minimum order design, only.'; return end end if length(fp) ~= 1, msg = ['Length of Fp = ' num2str(length(fp)) ', length must be 1.']; return else, if ~isValidScalar(fp), msg = 'Passband edge frequency must be a scalar, 0= 0.5, msg = ['Fp=' num2str(fp) ', passband edge frequency must satisfy 0 1, bol = 0; end %------------------------------------------------------------------------ function [beta,xx,a] = nfp2beta(n,fp) a = 1/tan(pi*fp)^2; for ind = 1:(n-1)/2 x = ellipj( ((2*ind-1)/n + 1)*ellipke(1/a^2), 1/a^2); b(ind) = ((a+x^2) - sqrt((1-x^2)*(a^2-x^2)) )/((a+x^2) + sqrt((1-x^2)*(a^2-x^2))); xx(ind) = x; end beta = sort(b); %------- [EOF] ---------------------------------------------------------- ltfat/thirdparty/Playrec/playrecinit.m0000664000175000017500000000165613026262276020074 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} playrecinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/Playrec/playrecinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/thirdparty/Playrec/pa_dll_playrec.c0000664000175000017500000052417413026262276020516 0ustar susnaksusnak/* * 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. */ #ifdef HAVE_PORTAUDIO #include "mex.h" #include "portaudio.h" #include "mex_dll_core.h" #include "pa_dll_playrec.h" #include "ltfatresample.h" #include #include /* * 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." } } }, { "getPlayrec", doGetPlayrec, 1, 2, 0, 3, "Returns the samples played and 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"} }, { { "playrecBuffer", "a Mx(N+K) matrix where M is the number of samples that have been " "recorded, N is the number of channels of recorded data, K is the number of channels " "of played 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; /* Resampling plans */ static int playResChanCount = 0; static resample_plan* play_resplan = NULL; static int recResChanCount = 0; static resample_plan* rec_resplan = NULL; static resample_plan dummy_recplan = NULL; void clearResPlans() { int ii; if (dummy_recplan) resample_done(&dummy_recplan); if (rec_resplan) { if (recResChanCount > 0) { for (ii = 0; ii < recResChanCount; ii++) resample_done(&rec_resplan[ii]); recResChanCount = 0; } free(rec_resplan); rec_resplan = NULL; } if (play_resplan) { if (playResChanCount > 0) { for (ii = 0; ii < playResChanCount; ii++) resample_done(&play_resplan[ii]); playResChanCount = 0; } free(play_resplan); play_resplan = NULL; } } /* * 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->pageLengthRec = 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) //always true && (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)// always true && (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) { clearResPlans(); #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; resample_error rerr = RESAMPLE_OK; unsigned int dataChanCount, playSamplePerChan = 0, recSamplePerChan; unsigned int i, chansCopied, playResPlanId = 0, bufTmpLen; 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); 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; } /* Do resampling if play resampler is present*/ if (play_resplan) { bufTmpLen = resample_nextoutlen( play_resplan[playResPlanId], playSamplePerChan); SAMPLE* buf = mxCalloc(bufTmpLen, sizeof * buf); mexMakeMemoryPersistent(buf); rerr = resample_execute(play_resplan[playResPlanId], pcbs->pbuffer, playSamplePerChan, buf, bufTmpLen); mxFree(pcbs->pbuffer); pcbs->pbuffer = buf; pcbs->bufLen = bufTmpLen; playResPlanId++; } else { pcbs->bufLen = playSamplePerChan; } if (rerr != RESAMPLE_OK) { mexWarnMsgTxt("Resampling returned an error. This should not happened."); } 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) && // always true (pcbs->channel < psps->playChanCount)) psps->pplayChansInUse[pcbs->channel] = true; chansCopied++; mexMakeMemoryPersistent(pcbs->pbuffer); pcbs = pcbs->pnextChanBuf; } } psps->pageLength = max(psps->pageLength, psps->pfirstPlayChan->bufLen); /* This is only used if recording is also performed */ psps->pageLengthRec = max(psps->pageLengthRec, playSamplePerChan); /* 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; } /* Use the same length of buffer for recording in the same page */ recSamplePerChan = psps->pfirstPlayChan->bufLen; } else { /* Number of recorded samples specified directly. */ recSamplePerChan = (int)mxGetScalar(precDataLength); psps->pageLengthRec = recSamplePerChan; if (rec_resplan) { recSamplePerChan = resample_nextinlen(dummy_recplan, recSamplePerChan); resample_advanceby(dummy_recplan, 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[]) { int ii; PaStreamParameters inputParameters; PaStreamParameters outputParameters; double resRat; 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. */ checkPAErr(Pa_OpenStream( &_pstreamInfo->pstream, (_pstreamInfo->recDeviceID != paNoDevice) ? &inputParameters : NULL, (_pstreamInfo->playDeviceID != paNoDevice) ? &outputParameters : NULL, _pstreamInfo->suggestedSampleRate, _pstreamInfo->suggestedFramesPerBuffer, _pstreamInfo->streamFlags, playrecCallback, _pstreamInfo)); clearResPlans(); /* If the sampling rate is not supported, try initializing with fs=44,1kHz*/ if ( lastPaError == paInvalidSampleRate ) { lastPaError = paNoError; mexWarnMsgTxt("PLAYREC: Device does not support selected sampling rate. Will use 44.1 kHz and resample."); resRat = 44100.0 / _pstreamInfo->suggestedSampleRate; _pstreamInfo->suggestedSampleRate = 44100.0; checkPAErr(Pa_OpenStream( &_pstreamInfo->pstream, (_pstreamInfo->recDeviceID != paNoDevice) ? &inputParameters : NULL, (_pstreamInfo->playDeviceID != paNoDevice) ? &outputParameters : NULL, _pstreamInfo->suggestedSampleRate, _pstreamInfo->suggestedFramesPerBuffer, _pstreamInfo->streamFlags, playrecCallback, _pstreamInfo)); /* Initialize record resampler(s) */ if (_pstreamInfo->recDeviceID != paNoDevice) { dummy_recplan = resample_init(RESAMPLING_TYPE, 1.0 / resRat); recResChanCount = _pstreamInfo->recChanCount; rec_resplan = malloc(recResChanCount * sizeof * rec_resplan); for (ii = 0; ii < recResChanCount; ii++) rec_resplan[ii] = resample_init( RESAMPLING_TYPE, 1.0 / resRat ); } /* Initialize play resampler */ if (_pstreamInfo->playDeviceID != paNoDevice) { playResChanCount = _pstreamInfo->playChanCount; play_resplan = malloc(playResChanCount * sizeof * play_resplan); for (ii = 0; ii < playResChanCount; ii++) play_resplan[ii] = resample_init( RESAMPLING_TYPE, resRat ); } } if (lastPaError != 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: doGetPlayrec(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 doGetPlayrec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { StreamPageStruct *psps; ChanBufStruct *pcbs; ChanBufStruct *pcbsBoth[2]; resample_error rerr = RESAMPLE_OK; SAMPLE *poutBuf; mxArray *mxRecChanList; mxArray *mxPlayChanList; unsigned int *pChanListBoth[2]; unsigned int recSamples, recSamplesTmp; unsigned int channels[2]; unsigned int recResPlanId = 0; unsigned int ii; /* SRC_DATA recData;*/ 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 > 1) plhs[1] = mxCreateNumericMatrix(0, 0, mxSAMPLE, mxREAL); if (nlhs > 2) plhs[2] = 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; recSamplesTmp = 0; channels[0] = 0; channels[1] = 0; pcbsBoth[0] = psps->pfirstRecChan; pcbsBoth[1] = psps->pfirstPlayChan; pcbs = pcbsBoth[0]; while (pcbs) { /* Check for valid buffer */ if (pcbs->pbuffer && (pcbs->bufLen > 0)) { recSamplesTmp = max(recSamples, pcbs->bufLen); channels[0]++; } pcbs = pcbs->pnextChanBuf; } pcbs = pcbsBoth[1]; while (pcbs) { /* Check for valid buffer */ if (pcbs->pbuffer && (pcbs->bufLen > 0)) { channels[1]++; } pcbs = pcbs->pnextChanBuf; } if (rec_resplan) { /* We will do resampling */ if (psps->pagePos != recSamplesTmp) { /* Page was not yet finished, do something harmless. */ recSamples = (unsigned int) ( psps->pageLengthRec * psps->pagePos / ((double)recSamples)); } else { recSamples = psps->pageLengthRec; } } else { recSamples = recSamplesTmp; } /* If there are no samples recorded, no need to continue */ if ((recSamples == 0) || (channels[0] == 0) || (channels[1] == 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, channels[0] + channels[1], mxSAMPLE, mxREAL); poutBuf = (SAMPLE*)mxGetData(plhs[0]); /* Create the channel list, but only return it if its required */ mxRecChanList = mxCreateNumericMatrix(1, channels[0], mxUNSIGNED_INT, mxREAL); mxPlayChanList = mxCreateNumericMatrix(1, channels[0], mxUNSIGNED_INT, mxREAL); pChanListBoth[0] = (unsigned int*)mxGetData(mxRecChanList); pChanListBoth[1] = (unsigned int*)mxGetData(mxPlayChanList); if (poutBuf && pChanListBoth[0] && pChanListBoth[1]) { for (ii = 0; ii < 2; ii++) { pcbs = pcbsBoth[ii]; /* Copy the data across, decrement recChannels to make sure * the end of the buffer isn't overwritten */ while (pcbs && (channels[ii] > 0)) { if (pcbs->pbuffer && (pcbs->bufLen > 0)) { if (!rec_resplan) { /* Do just a copy if no resampling should be done*/ memcpy(poutBuf, pcbs->pbuffer, min(recSamples, pcbs->bufLen) * sizeof(SAMPLE)); } else { rerr = resample_execute(rec_resplan[recResPlanId], pcbs->pbuffer, pcbs->bufLen, poutBuf, recSamples); if (rerr != RESAMPLE_OK) { mexWarnMsgTxt("Resampling returned an error. This should not happen."); } recResPlanId++; } poutBuf += recSamples; *pChanListBoth[ii]++ = pcbs->channel + 1; /* Add 1 for base 1 channels */ channels[ii]--; } pcbs = pcbs->pnextChanBuf; } } } if (nlhs > 1) { mxDestroyArray(plhs[1]); plhs[1] = mxPlayChanList; } if (nlhs > 2) { mxDestroyArray(plhs[22]); plhs[2] = mxRecChanList; } 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; resample_error rerr = RESAMPLE_OK; SAMPLE *poutBuf; mxArray *mxChanList; unsigned int *pRecChanList; unsigned int recSamples, recSamplesTmp; unsigned int recChannels; unsigned int recResPlanId = 0; /* SRC_DATA recData;*/ 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; recSamplesTmp = 0; recChannels = 0; pcbs = psps->pfirstRecChan; while (pcbs) { /* Check for valid buffer */ if (pcbs->pbuffer && (pcbs->bufLen > 0)) { recSamplesTmp = max(recSamples, pcbs->bufLen); recChannels++; } pcbs = pcbs->pnextChanBuf; } if (rec_resplan) { /* We will do resampling */ if (psps->pagePos != recSamplesTmp) { /* Page was not yet finished, do something harmless. */ recSamples = (unsigned int) ( psps->pageLengthRec * psps->pagePos / ((double)recSamples)); } else { recSamples = psps->pageLengthRec; } } else { recSamples = recSamplesTmp; } /* 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); pRecChanList = (unsigned int*)mxGetData(mxChanList); if (poutBuf && pRecChanList) { 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)) { if (!rec_resplan) { /* Do just a copy if no resampling should be done*/ memcpy(poutBuf, pcbs->pbuffer, min(recSamples, pcbs->bufLen) * sizeof(SAMPLE)); } else { rerr = resample_execute(rec_resplan[recResPlanId], pcbs->pbuffer, pcbs->bufLen, poutBuf, recSamples); if (rerr != RESAMPLE_OK) { mexWarnMsgTxt("Resampling returned an error. This should not happen."); } recResPlanId++; } poutBuf += recSamples; *pRecChanList++ = 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, 88200.0, 96000.0, 192000.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; } #endif ltfat/thirdparty/Playrec/mex_dll_core.c0000664000175000017500000007062113026262276020171 0ustar susnaksusnak/* * 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 /* * 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[]) { #ifndef HAVE_PORTAUDIO #ifdef IS_OCTAVE const char id[] = "Octave:disabled_feature"; #else const char id[] = "Matlab:disabled_feature"; #endif mexErrMsgIdAndTxt (id, "PLAYREC: Support for the block processing framework was disabled when LTFAT was built."); #else 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"); } #endif } #ifdef HAVE_PORTAUDIO /* * 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) // this is False all the time || (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; } #endif ltfat/thirdparty/Playrec/license_playrec.txt0000664000175000017500000000227213026262276021270 0ustar susnaksusnakCopyright © 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. ltfat/thirdparty/Playrec/ltfatresample.h0000664000175000017500000002143313026262276020402 0ustar susnaksusnak/* * ltfatresample.h * * This is an attempt for a self-containded arbitrary factor resampling API * working with streams of blocks of arbitrary lengths. * * How does it work? * * The approach could probably be called hybrid. A simple polynomial * interpolation is used when doing upsampling (ratio > 1). An anti-aliasing * filter is used when doing subsampling (ratio<0.95) followed by a polynomial * interpolation. The antialiasing IIR filter is designed such that the overall * frequency response have almost linear phase freq. response (less so close to * the passband-edge frequency) and negligible rippling in the passband (one over * stopband attenuation). * * I opted for IIR filters over FIR because of two reasons: * * 1) I did not want any external dependency, which basically rules out * all FIR filters already, since they require FFT implementation in * order to be fast. * 2) IIR filters used require only a handfull of their coefficients to be * stored (see "filtcoefs.h"). This is in sharp contrast with e.g. long * sinc kernel techniques which require storing thousands of coefficients. * See e.g. libsamplerate * * The IIR filter design used is taken from chapter V in this book: * * Milic L.: Multirate Filtering for Digital Signal Processing: * MATLAB Applications, 2008, ISBN:1605661783 * * The filters are called Elliptic Minimal Q-Factors (EMQF). They are derived * from a prototype halfband lowpass IIR filter consisting of parallel * combination of two all pass filters. Both allpass filters consist of * serially connected 2nd order allpass filters. Using a simple procedure * described in * Chapter: IIR STRUCTURES WITH TWO ALL-PASS SUBFILTERS: APPLICATIONS * OF EMQF FILTERS, * the prototype filter passband edge frequency can be changed while keeping (almost) * the same structure (two branches, chains of allpass filters). * * The coefficients defining the prototype half-band filter are stored * in "filtcoefs.h". The file is generated by a Matlab script "genfiltcoefs.m". * The header file defines a double array "EMQFcoefs" of length EMQFCOEFLEN * defined as a macro in the same file. The coefficients are the beta * coefficients from (5.36) from the book. * * The passband edge frequency is set to FPADJ*fs_target/2. FPADJ macro is set in * "config.h". * * * Copyright (C) 2014 Zdenek Prusa . * This file is part of LTFAT http://ltfat.github.io * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef _LTFATRESAMPLE_H #define _LTFATRESAMPLE_H /* malloc, calloc, free etc. */ #include #include #include #include #include /* The following defines SAMPLE, FADJ */ #include "config.h" /* Just to be on the safe side, define all mandatory compile time params. */ #ifndef RESAMPLING_TYPE # define RESAMPLING_TYPE BSPLINE #endif #ifndef FPADJ # define FPADJ 0.92 #endif /* Here we include a generated file containing prototype filters */ /* We use elliptic minimal Q-factors IIR filters (EMQF) from * Multirate Filtering for DSP: MATLAB Applications by Ljiljana Milic, chapter V * */ #include "filtcoefs.h" #if !defined(EMQFCOEFLEN) || EMQFCOEFLEN<1 # error Undefined EMQFCOEFLEN. Check filtcoefs.h #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* * POLYNOMIAL INTERPOLATION * * * */ /* Interpolation type */ typedef enum { LINEAR = 0, /* Mere lin. intp. */ LAGRANGE, /* 6point Lagrange interpolator */ BSPLINE /* 6point B-spline interpolator */ } resample_type; /* Error code to check */ typedef enum { RESAMPLE_OK = 0, RESAMPLE_NULLPOINTER, RESAMPLE_OVERFLOW, RESAMPLE_UNDERFLOW } resample_error; typedef struct resample_plan_struct *resample_plan; /********************************************** ************** Public API ****************** **********************************************/ /*! \brief Initialize resampling plan * * @param restype polynomial interpolation type * @param ratio sampling rate change ratio fs_target/fs_source * @see resample_execute() * @see resampe_done() * @return An opaque pointer to a struct holding all the resampling parameters */ resample_plan resample_init(const resample_type restype, const double ratio); /*! \brief Reset resampling plan * * @param restype polynomial interpolation type */ void resample_reset(const resample_plan rp); /*! \brief Execute resampling * * in might get overwritten by a low-pass filtered version * * Either Lin or Lout should be fixed to a required value and the other * one obtained by resample_nextoutlen, resample_nextinlen respectivelly. * * Note: When using Lout fixed, the routine might internally store more values. * * The function returns RESAMPLE_OVERFLOW if it could have produce more samples, but * Lout (plus internal storage buffer) is too small. The overflowing samples are * discarded. * * The function returns RESAMPLE_UNDERFLOW if the number of input samples is not * enough to calculate all required output samples. The remaining output samples are set * to zeros. * * If one of the overflows occurs, the stream is reset to avoid problems in next * iterations. * * @param rp resampling plan * @param in input array * @param Lin input array length * @param out output array * @param Lout output array length * @see resample_init() * @see resampe_done() * @return error code */ resample_error resample_execute(const resample_plan rp, SAMPLE* in, const size_t Lin, SAMPLE* out, const size_t Lout); /*! \brief Get next output array length * * The number of output samples can vary. Internally, rp stores a sample * counter which together with Lin determine length of output array next * time resample_execute is called. * * Use when input array length is fixed. * * @param rp resampling plan * @param Lin input array length * @see resample_execute() * @return next output array length */ size_t resample_nextoutlen(const resample_plan rp, size_t Lin); /*! \brief Get next input array length * * Complementary to resample_nextoutlen. * * Use to get "compatible" input buffer length when Lout is required * */ size_t resample_nextinlen(const resample_plan rp, size_t Lout); /*! \brief Move the internal sample counter * * @param rp resampling plan * @param Lin input array length */ void resample_advanceby(const resample_plan rp, const size_t Lin, const size_t Lout); /*! Free all resources * * @param ef pointer to an opaque pointer */ void resample_done(resample_plan *rp); /********************************************** ************ End of public API ************** **********************************************/ /* * Functions doing the actual resampling * */ resample_error resample_execute_polynomial(const resample_plan rp, const SAMPLE* in, const size_t Lin, SAMPLE* out, const size_t Lout); /* * Functions generating one sample according to the polynomial * interpolation technique. * Function prototype is SAMPLE fcn(const double,const SAMPLE*) */ SAMPLE lagrange_interp(const double x, const SAMPLE *yin); SAMPLE bspline_interp(const double x, const SAMPLE *yin); SAMPLE linear_interp(const double x, const SAMPLE *yin); /********************************************** ************ EMQF filters ************** **********************************************/ /* Struct for holding EMQF filter */ typedef struct EMQFfilters_struct *EMQFfilters; /*! \brief Initialize EMQF filter structurehttp://github.com/ltfat/ltfat/issues * * fc can be in range ]0,1[, otherwise the function returns NULL * * @param fc passband edge frequency * @return structure holding all partial filters (and their inner states) */ EMQFfilters emqffilters_init(const double fc); /*! \brief Do the filtering using the EMQF filter * * @param ef filtering struct * @param in input array * @param Lin input/output array length * @param out output array */ void emqffilters_dofilter(EMQFfilters ef, const SAMPLE* in, const size_t Lin, SAMPLE* out); /*! Free all resources * * @param ef pointer to an opaque pointer */ void emqffilters_done(EMQFfilters* ef); #endif ltfat/thirdparty/Playrec/Makefile_mac0000664000175000017500000000155313026262276017647 0ustar susnaksusnakifndef MATLABROOT $(warning MATLABROOT variable is undefined. Using default MATLABROOT="/Applications/MATLAB_R2013a.app/") MATLABROOT=/Applications/MATLAB_R2013a.app/ endif ifndef EXT $(warning EXT variable is undefined. Using default EXT=mexmaci64) EXT=mexmaci64 endif ifndef ARCH $(warning ARCH variable is undefined. Using default ARCH=maci64 ) ARCH=maci64 endif ifndef PORTAUDIO PORTAUDIO=-lportaudio endif include ../../libltfat/ostools.mk MEXTGT=playrec.$(EXT) MEXSRC=mex_dll_core.c pa_dll_playrec.c ltfatresample.c LIBS= -L. -L"$(MATLABROOT)/bin/$(ARCH)" -lmex -lmx -lm $(PORTAUDIO) INCLUDES= -I"$(MATLABROOT)/extern/include" -I. -I../../libltfat/thirdparty CFLAGS=-fPIC -std=c99 -O3 -Wall -shared -DMATLAB_MEX_FILE -DHAVE_PORTAUDIO all: $(CC) $(CFLAGS) $(INCLUDES) $(MEXSRC) $(LIBS) -o $(MEXTGT) clean: $(RM) $(MEXTGT) .PHONY: all clean ltfat/thirdparty/Playrec/Makefile_unix0000664000175000017500000000211713026262276020067 0ustar susnaksusnak# 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 undefined. Using default MATLABROOT="C:\Program Files\MATLAB\R2011b" ) MATLABROOT=/usr/local/MATLAB/R2011a endif ifndef EXT $(warning EXT variable is undefined. Using default EXT=mexa64 ) EXT=mexa64 endif ifndef ARCH $(warning ARCH variable is undefined. Using default ARCH=win64 ) ARCH=glnxa64 endif ifndef PORTAUDIO PORTAUDIO=-lportaudio endif include ../../libltfat/ostools.mk MEXTGT=playrec.$(EXT) MEXSRC=mex_dll_core.c pa_dll_playrec.c ltfatresample.c LIBS=-Wl,--no-undefined -L. -L"$(MATLABROOT)/bin/$(ARCH)" -lmex -lmx -lm $(PORTAUDIO) INCLUDES= -I"$(MATLABROOT)/extern/include" -I. -I../../libltfat/thirdparty CFLAGS=-static-libgcc -fPIC -std=c99 -O3 -Wall -shared -DMATLAB_MEX_FILE -DHAVE_PORTAUDIO all: $(CC) $(CFLAGS) $(INCLUDES) $(MEXSRC) $(LIBS) -o $(MEXTGT) clean: $(RM) $(MEXTGT) .PHONY: all clean ltfat/CITATION0000664000175000017500000000301013026262276012721 0ustar susnaksusnakTo 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" } and/or Zdeněk Průša, Peter L. Søndergaard, Nicki Holighaus, Christoph Wiesmeyr, Peter Balazs. The Large Time-Frequency Analysis Toolbox 2.0. Sound, Music, and Motion, Lecture Notes in Computer Science 2014, pp 419-442 A BibTex entry for LaTex users: @incollection{ltfatnote030, year={2014}, isbn={978-3-319-12975-4}, booktitle={Sound, Music, and Motion}, series={Lecture Notes in Computer Science}, editor={Aramaki, Mitsuko and Derrien, Olivier and Kronland-Martinet, Richard and Ystad, S{\o}lvi}, title={{The Large Time-Frequency Analysis Toolbox 2.0}}, publisher={Springer International Publishing}, author={Pr\r{u}\v{s}a, Zden\v{e}k and S{\o}ndergaard, Peter L. and Holighaus, Nicki and Wiesmeyr, Christoph and Balazs, Peter}, pages={419-442}, url={{http://dx.doi.org/10.1007/978-3-319-12976-1_25}}, doi={{10.1007/978-3-319-12976-1_25}}, } ltfat/INDEX0000664000175000017500000001224513026262276012370 0ustar susnaksusnakltfat >> Time-frequency analysis and Wavelets signals ctestfun noise pinknoise expchirp bat batmask greasy cocktailparty gspi linus ltfatlogo otoclick traindoppler cameraman lichtenstein ltfattext quadratic ambiguityfunction wignervilledist drihaczekdist quadtfdist plotquadtfdist operators operatornew operator ioperator operatoradj operatorappr operatoreigs operatormatrix framemul iframemul framemuladj framemulappr framemuleigs gabmulappr spreadop spreadinv spreadadj spreadfun spreadeigs deprecated convolve gabelitistlasso gabgrouplasso gablasso gabmuleigs gabmul framematrix iufilterbank iunsdgt iunsdgtreal tfmat uwfbtbounds uwpfbtbounds sigproc rms normalize gaindb crestfactor uquant firwin firkaiser fir2long long2fir freqwin firfilter blfilter warpedblfilter freqfilter pfilt magresp transferfunction pgrpdelay 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 projkern 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 gabphasederiv gabreassign gabreassignadjust constructphase constructphasereal phaselock phaseunlock phaselockreal phaseunlockreal symphase matrix2latticetype latticetype2matrix shearfind noshearlength tfplot plotdgt plotdgtreal plotdwilt plotwmdct sgram gabimagepars resgram instfreqplot phaseplot blockproc block blockdevices blockread blockplay blockpanel blockpanelget blockdone blockwrite blockframeaccel blockframepairaccel blockana blocksyn blockfigure blockplot ltfatplay demos demo_dgt demo_gabfir demo_wavelets demo_imagecompression demo_audiocompression demo_audiodenoise demo_ofdm demo_audioshrink demo_gabmulappr demo_bpframemul demo_frsynabs demo_filterbanksynchrosqueeze demo_nsdgt demo_pgauss demo_pbspline demo_gabmixdual demo_framemul demo_phaseplot demo_phaseret demo_nextfastfft demo_filterbanks demo_audscales demo_auditoryfilterbank demo_wfbt demo_blockproc_basicloop demo_blockproc_paramequalizer demo_blockproc_denoising demo_blockproc_slidingsgram demo_blockproc_slidingcqt demo_blockproc_slidingerblets demo_blockproc_dgtequalizer demo_blockproc_effects 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 wfbtclength wpfbtclength dtwfb idtwfb dtwfbreal idtwfbreal wfbtinit dtwfbinit wfbtput wfbtremove wfbt2filterbank wpfbt2filterbank dtwfb2filterbank fwtinit wfbtbounds wpfbtbounds dtwfbbounds plotwavelets wfiltinfo wfiltdtinfo wavfun wavcell2pack wavpack2cell wfilt_algmband wfilt_cmband wfilt_coif wfilt_db wfilt_dden wfilt_dgrid wfilt_hden wfilt_lemarie wfilt_matlabwrapper wfilt_mband wfilt_remez wfilt_symds wfilt_spline wfilt_sym wfilt_symdden wfilt_symorth wfilt_symtight wfilt_qshifta wfilt_qshiftb wfilt_oddevena wfilt_oddevenb wfilt_optsyma wfilt_optsymb wfilt_ddena wfilt_ddenb wfiltdt_qshift wfiltdt_optsym wfiltdt_oddeven wfiltdt_dden filterbank filterbank ufilterbank ifilterbank ifilterbankiter filterbankwin filterbanklength filterbanklengthcoef cqt icqt erblett ierblett cqtfilters erbfilters warpedfilters audfilters filterbankdual filterbanktight filterbankrealdual filterbankrealtight filterbankbounds filterbankrealbounds filterbankresponse filterbankfreqz filterbankscale nonu2ufilterbank u2nonucfmt nonu2ucfmt plotfilterbank filterbankphasegrad filterbankreassign filterbanksynchrosqueeze fourier fftindex modcent floor23 floor235 ceil23 ceil235 nextfastfft dft idft fftreal ifftreal gga chirpzt fftgram plotfft plotfftreal involute peven podd pconv pxcorr lconv lxcorr isevenfunction middlepad expwave pchirp pgauss psech pbspline shah pheaviside prect psinc ptpfun pebfun ptpfundual pebfundual pherm hermbasis dfracft ffracft fftresample dctresample pderiv fftanalytic dcti dctii dctiii dctiv dsti dstii dstiii dstiv frames frame framepair framedual frametight frameaccel frana frsyn frsynmatrix frgramian frameoperator framediag franaiter frsyniter plotframe framegram framebounds framered framelength framelengthcoef frameclength framecoef2native framenative2coef framecoef2tf frametf2coef framecoef2tfplot franabp franalasso franagrouplasso frsynabs base ltfatstart ltfatstop ltfathelp ltfatmex ltfatbasepath isoctave ltfatarghelper ltfatgetdefaults ltfatsetdefaults scalardistribute mulaclab ltfat/COPYING0000664000175000017500000010451313026262276012631 0ustar susnaksusnak GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . 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: Copyright (C) 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 . 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 . ltfat/lib/0000775000175000017500000000000013026262276012340 5ustar susnaksusnakltfat/NEWS0000664000175000017500000001100513026262276012266 0ustar susnaksusnakVersion 2.2.0 * New Gabor window generating functions: ptpfun, ptpfundual, pebfun, pebfundual * Introduced Mulaclab, a GUI for editing time-frequency representations. * Included new colormaps: ltfat_inferno, ltfat_magma, ltfat_plasma, ltfat_viridis, ltfat_nicecolormap Version 2.1.2 * Improved functions for DGT and DGTREAL phase reconstruction: constructphase, constructphasereal Version 2.1.1 * New function for computing higher order phase derivatives: gabphasederiv * New function doing the adjustable reassignment: gabreassignadjust * New function for the Gabor transform phase reconstruction: constructphase, constructphasereal * New filterbank-generating function: audfilters * New generic quadratic TF distribution function: quadtfdist * New functions for reading and writing wav files (since wavread and wavwrite were removed in Matlab 2015b): wavload, wavsave (taken from VOICEBOX http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html) Version 2.1.0 * New general filterbank generating routine: warpedfilters * New filterbank spectrogram reassignment function: filterbankreassign * New quadratic time-frequency distributions * Octave package compiles on Windows (MXE-Octave). * Better alignment of wavelet filters. Version 2.0.1 * Included a test suite (test_all_ltfat). -------- LTFAT 2.0 --------------------------------------------- Main features of LTFAT 2.0 are the the wavelets module, the frames framework and the real-time block processing framework. Actual news: * Added dual-tree complex wavelet transform, general dual-tree wavelet filterbanks and $M$-band transforms. * Blockproc. framework now supports any sampling rate from interval 4-96kHz trough on-the-fly resampling in the background. * Fixed compilation issue with gcc 4.7. * Warning is shown if portaudio is not found during package installation. * Warning is shown if JRE is run in a headless mode during package loading. Version 1.4.5 * Added franabp - solving a basis pursuit problem argmin ||c||_1 s.t. Fc = f for an arbitrary frame * Wavelet routines correctly included in the frames framework. * Added blockwrite method for a blockwise storage of audio data to a wav file. * New demos: demo_blockproc_effects, demo_filterbanks, demo_wavelets, demo_wfbt, demo_bpframemul, demo_phaseret 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. ltfat/DESCRIPTION0000664000175000017500000000155313026262276013304 0ustar susnaksusnakName: LTFAT Version: 2.2.0 Date: 2016-12-20 Author: Peter L. Soendergaard 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+ Depends: octave (>= 3.8.0) BuildRequires: fftw3 [Debian] libfftw3-3, lapack [Debian] liblapack3, blas [Debian] libblas3, portaudio [Debian] portaudio19-dev Java Runtime [Debian] default-jre Url: http://ltfat.github.io/ ltfat/inst/0000775000175000017500000000000013026262304012537 5ustar susnaksusnakltfat/inst/signals/0000775000175000017500000000000013026262303014176 5ustar susnaksusnakltfat/inst/signals/Clar.wav0000664000175000017500000020005413026262276015610 0ustar susnaksusnakRIFF$WAVEfmt +"Vdatak{@VD=m1Xn? !ymoym<=Kp1$bwoJJXR>b1XRXAV/9tV +63@'8KMZ5'Xn?19AP'^wNA/JPan3119q`;T/l{?76HCJq)q#\M1# N@mbV}Pw; ! / T P L`+s}?n 1Js9we}PwwCb Z+EX5??#0A!) T > V # ^ \ + #9fza<-0?57 ` {  / k }yNF)jtr%u/ ?}fh tKym-%&tnp~ hB +0ku8R F qR?<)`^uF  B  WY{0> k X}!Z+5x7Gz\y^L<;?>A=t>a0MtV3 k :aJ o>o uZ \  DYcmQ4kL `^|]E|jk  '   b|E܄4ئC#@ #FvnAda% u |773hf uv I7 Fm {N="6߯*Bsz9 : 1 Bge {ѪӴ@8 nH-B d$)+ .?*%5%"&"riy1%#?WI!Ange+&&!n "M%%""g>)T 9)_<ܹDcYML !ccy :|0N̰͙P;wks]VH9# {D>b#(.5:95,&."SvVph3P?~O5^ q <! oG"*-y(;"| A%(v'v!|gZ)eZHЙ/w6a HY_ g6Q|e؁{$CȥȃlIHwq@! zC ",37U:9#4/,T( f eKW L ]iG"!* %P,,'#$'j'7&&$~z kG4Nmփ)tђ֯޽M+ s>&6! uK?E%<аp?WxfjϿ6ل_ :#,5:<;_9<4%/p* 6 VTvg:l {! a&' #Kb#+)1!-&#%()'" F 9l|!/ցD5ӨW&EN# @z|~~zZwhhxNsAʶc9BܒBhXD ]h "3$*w389[=?:-b#c wVJ,Oi '/,$Md (#49-3' !'D,,&,> : s)s%ѴѹׄZ6q6@ HE_cަn-ɍȾxz^ßi0ؤ٨ߝ+ m &k-V/D26m:863/ 8o݋OnjINu $[ ]+&L*F-q0o/1#,:=q6+!%^-1- _G4 ҍԍw [8e #FۨxrǓŋDzȍȆ,͠aܔ(p'W&+P2V5g1R---G($A%"cV@0(>I w w ]YE!)" .:O=9.Q$ |s߳%Eϲk Dk6v!--21u,.H44<6=]8+$f+:C?,801)l"!#X$[er4"Kc|C Ny  @ FgߦPEazUz5Ӷ֘GdL>rW n* kݧ`-ރ i#' '4461b/2S9?A ?7V)(7FHB=/C&G"fC GL1|]kY2rs7)6a8g  0?ĹھeǻKþ¡E'̪c,x~)< Nr.Qui  .Ֆ i,$ $8@A?;J5'6AdG>H4'6=>71-)% aHe1 MMQ_Ur*w (]u3 }Jف%ׅMؽ_ӵSr" đ=#r_~ ]  L N"S+ #)c1ˢ@ l"t&r%%*0S?U:;$@@:2)%C&%!B Ln["&]Ml' 3 q D4?i%צԘ=-͸*b~p̴v Awy { e_~u_=ŕ:^ 1 e#(2:9z:(BnLLxEA>$:6;><62),!a##x eLaV^ 2@(]{X&ؼ+?ǚ@RLնnñj$|T j?mew _U sK=Iŗ ݏ4&U:DbF&GlEFhC E?GFW;599T44 3,\&E![ z#09ZG(W[]-/# s[ Bk>׶NR}̀ȷoͲ>4GS.Ă /ʲ$&G'I'w } v*.q ?SdҺƕҟp,] #,9GGKLLK9D_?>cA"?[=;731/. ($#"M0ERXH&/z~(?r.lpr fi9.]À(ȍ ,4j3s S*  ;YPIţ~! a * 5%#4l?HN{RPH:?:8W;4BAH~B5,+)& )9'H1،rjiQ0rd##TCˁθ{^CȀߣ+6ù(0Z6c2ݟa{sqst8$%`B?Ml͸vJ$?7 9!=#*S9C LQyW W\I_9V5;AfHJC2 '$#(*-+R \dxӤӀE`5 r""%# ؾ΋oѮCΛW^"*hY88DWq'm־ =#H ?(% h bD׻!迦ڰ U#h&$#').6DP\_\9Jy4*4OCN9PhCR-E)%R-1-z )1I;*ߗ%+ϩE9rPY"! $& (5%o5OttX!ϙ %xĭƯgl+  j {m3cV)[ {+?,(?+; AePγ"$ 'p$&01/'09G[d bV2A. )6GyWUN~ՀuXqM%'"7&( ) (G ߰^ϐԭƔ&x:?ħHPZE ɸň}H J +&O,!-%eh FE hھ%"**)/2.0=UpjEg\M<%$9XaL&$F30(x }Vע(3ͦ#2 `?$)v'A%'+Z+" &vÑR@ؼʙ5WŲXȤ~w)IR *Z+DP,J/#( ??"+yɪv$''w-37.k-5Ic1o6f^V?G4%&Eec<),.2*n %: @1}0c;Ofpni[H75+)*Cc6f,> H.0#  Rq 3̌Z@zͧ0*y&]K$-0>/X0{/+*G1ϚH(]ˎ[iVnqGlГ!w9 +49'D/V ,2-  R Ob͸Á ?$ '7,8rB7/3DH]p-m_bQ?0'8XYfkS(k%1*w#ә;HֲΚ<%mo 1)30@0g12/1$YwǐՎڵ߯Jy>x- 0Ή8UnX x&'6@03 W2/#2JpK̼k6#S (}*4:?:0.:sTkoeLYG6(1/AN_he_7]K/.E! F YjaAT3ͨϿԥ|%/51s1q022)aJxpqLmȞ݋b*i,rj2Vھ':% 146M)00+M ݊Oͬʼlw"&/.=|A25--4G`o7lO`)N< /-'|;]j1L" ,'0 )- l>n~!FPԖ*\+L012_3-/!?8Ojɖɪ]sп(Ǘ+vb:,(p9'7,5'w30v!N?/GćѨK')8 @:+,0@[n3p*fXC/4'i2Pj\)1D /s+. 1 %ڤU1()@+q clpG p*/$+-  \TjϪYRo$#.2 432H.R-%0m5"s12--aP P:W´-p$v' .= Aa4.8GKcql`M<0J)<^lL!' )0&- ӴT'i*rl1#G*0g112-0K$Hʼa2vWC)TMcgO#70$XDn#e6-#% 50Q! qś ϳ.U`(*[7<@:{/3 AYIoqhsZ|G6)2/Qk]D2,!1F- BA 8ڙΌyו6_\PM&-/0 4R36--w.B>pʪ4B剹[0jɿMr F mB64u3q01)9 ' ݮ$-Y3$&/WAMB2,]8Me?pEmaM;/}*>Y_jG T.1$o8 1_ <X4vC#2."-+234T4X0/!7tΞL6bۇ6b w.Y?bjt f+]*.k9( A ;. 4@0O hb糽Ȥ4f&&,6=.E :P,0B]oqjgWrB2&H4Svm8[/{".L*"g aAv{W<́Lx; ,)+2<466N12(GaK+mܟy?𱌼_O[EԞ^BFּ\S/)- w!:i2R"30-'cN02ߩ'%(7SE>..=PUMkrk]H:+P,GAk i=8 |V/. _ Kuh+֌p!j'/35645.:ɶɶeAިն񚉌"w0$Mj cbV# e@66 20,` xviD|ּ͸ov!##.A D 5,P8KbQm5k`!P?w3*=\MkK$# p*-$#% 5BEE?d-͇Ѩ Ju* +826467:3/!Nù}[$H̽⍕ `<_&İ/u~\xr/<( !-10":Ai.UŠݨ!*8>RJ;*/AYkq|jYB8*82Kj_H4!,;( k ͩf١KBO 1pr'1 5.9F9g1o/(>mߺRC߯:eU^:$PʕA S"6=3l$u21X*x 0Rt׫;˷6"&V55H>-+>Tiok]H:/J/Fevg@t+ .H.h yy&N"bˍԭXV5*$.!377H42\,uKǵQwπJѱ{ӆQ+.¡"<|GL3bKEkD893ss11/.m t8/1vB#o/xE~H5 )5IanohrhTv>3*8^V-mT*\&+#!3 % )+ q }T n)+u2L6N76b/;.$3꺴R۫׎n?:M&/!܋3B=HaV+=7,>^*w3i2$+%ĝ渝<ܛ7&+;3G;F-1~BZn9si}YD7`(/O ob4c:!-{)x c @ 4Ge^q؝ʓVeD^'05H:_92-3+L$:vJap}Ů$˷gʘ]zA =:3&p!3Z11)i 5ήZcHd~&$&T43G(B0-?sTho^m[`J<20CbIilE$9-`.! 9 ?;vʤӎ%wb71%b/367P8770Ğ관 ęϊ3EZ(O|ht«g3RsM782D2%/. Q" ݨݢ~:} d$#.CF46+[7JboIocSB@6*9YmR'- '!-% `ЩD= yг&}Vy8P,R37S9831$%#Ы|+ZzݢsǒԤD:cńľkۧZ|d4.=)u ,32#F951諿E~et?!)=J;s+/B'YlPrj[1Fm:\,1Mtl`4"P,(% A{lf]ڮK̇P )79'P27;k921s+a![[ŤӀ\Ⱦ%zŗRϐyZٔ~ZD !<3;?$ 482?*" +)~(zϺc!&6hIA%/,>S$iqm`J=1>/(BbhDd++\zVP"+?J9+2zFJ^nqhWA6)+>5Rno]Z1LZ%\, '=B` 7N3kX=d׿5}XZF _J)2u8>;9251)!𷘼Œeblul5Sy̽MǠԇùϑ_k'`(>q0PR(34(Z#ƴvܹW>':?MG?..KATh`nk0]I=0/dG ge >t"+ )axs&PVKFՈ4 y$07><{5!3, L޷Ͳq[˽YWꮄSYǚ[ŹܹƓV} lj"<7 UD2w3w-cw w=׫ZWB|%J5nLD1-<5N4eppSb\O@k3(;aoJfi)3*!>Wif-NRVײcV^a^sRn"m.46e<<7'60MŴR8Ϲ-|BG4Vr% D7:?N1k31L teóƣVD ${/jDG#4)}6Jbqr4eQx?25)L6eYurkV/(:(,A% + yԴφR#Ц<%:C 7,39:842 'V 7ܹqr"f|#Ӌm$+,*=*T+ .33"i:;Ϲa#,!V);H]8+3UFk\prqfV1F=,s1-PZq_/c(.y("J sd PͻG + .&17q<&;33P,ZFl P\ f%B16==640u.޴OJk+fX:ھďY.TAG8Y|;8V T4606T d^`ּƍe7 |$+2HD03*W;Oeeon`Na@5+,;M_oXMc Y}*,I#cCn K'ҲMbё:D q #-4<=7>5/"\Ѵ#<!H옴E薟4 r?ƫV1^8}57 j( 7;_12P2 =᳷@ܿؽYo ^!-EvJq6*8J`npe+UEY<,4UrX(u0*,$@,N]q]\7dԀΌٚI\ T!(*29;88\2e0%+wGڨ .VAU _ļA)jڸ `Z3X8 0?f+ -a44%avөsKi֟_X*z@NO=3*0CC>Xls|jgZD;+,T.EJpfg7v!+T(LT aɢR ۓ˪cݣ3  Vy(2a:=:!3e0*7^[P@ăXꋳ4$ ♸IDNӷbbRe59'?2'35+Cݨ٦ǻqYf'9fN?A,)+_?XSgqIoq_J@3,.?fnEg**K> )UIːdE>6m4/Y{-,ӫoCԘnjíُR?c|Ju Xk79132b $F!6-C©œ-FKi8+'6dG\jqg/WE=-4RnYm.:&G("w 'G?9)@Όk< h' )\2^(H?3.BinCr +`(&V3|ɻtyD+\vl- `%09A$@51. RIqj_R_vpĜInÉѴ(u?@ն"ʧb "?46S"82@61< ZV%f4aG$3$7wPUF/**=Orepprpd!PA46u,<_mVL!a3*($} fӲp" ٱ3 T#b/g7AB!961&GăR.e .OȄ[^Cb ;=]&ZaB1_3/4 RrGN!~I/ O 2LM7*7I^lntjVCk9+m4SoeY,h&T(""2# q- Բ΂Z"ʰ؂? #m s+4n@B=7Z1 ˊ]cףh~pժfּgb ~ 5B=P.1J5b#I^Ȥ1ּװ* /GjPF9V)2H\^mHtkWD;/!3ANna4J#)%^}iAS'!">}  *4g=@;#4/%!@WƢؠjI+]~Uժ+ #+=6T.?}**27)tQ"<*l?P<*-BUiqm[OI@2-DAkbi="}*&$G9T#ɍԨ NdJ'0:B@61}*ԯԻ1 ȓC>ppa>'ryпfol'?1{t&07J/7 +7`өv· U#9PfB/.+?Qd-mo`LAB7'0>_ziMH!''#EMzAX|́ԝ`|^Ϙg< 8#'096C(B82*> 6inuvpܿMzŞ:yN 8f`">>5l".2551 yŮ'Šlģ_@!k9QG`.(:M[`joaOCH:.8@YjN&'%W=3nԥ);ZӝʬNql a""F-7BCS92* ŖeܹϵϳpytíQ_0M,r[߻hA2R#;7 3_y.34t AqL%w c3?MVL:3d**7 JZ,gTnMeRD<15P"hTW/\&%2t \3jU}خ#QvV6yZ *4BlE;4L*ն޴mھzq&6񃆖*z]ywnn6m SN7<:F :-16n#:!VfD|Ak併;/tIN73*J5HYfngUD> 44;KQgZw3]p$O&j!zPw۞5Cpb˕4 xH nw ?)2 >BO=5+ڸS<ܮUۊqԤY;'xM: {4Du T4;am-X0*79'@z/aFxğzY,SE;Q:+g1ETWfnkXG>T43Ig`:(N!&#mw0 ӂqY@4d /M&0=,D@7-fkЈҺpN.0Ҁ~.ĕâ_%ݴ^(Rz |D"^-@<&? *;.5X*VG7GċѮag`(AQ6=s+1/EBTdmAk)Z5H@51/A2de?Ob#("tH Ik]^`]t& /9(BWA[7.%D<66{ݫŲ},Y k+3޺ h|rn*g=u, (/7.(w,t3 !4\O&>RA++,?OSbl/nw\JB8V/=`KjGA1)Z%2S `gً΃wշܩn+ f&#.s7&A A4b/%)dwۊT}3VϐZ󛢯&.IcuPXطlRe z 4/3e0u 'C$ :NF,*[=N`kot`LjDg=N18i[oyQX$*b) S%i XҚ\|fǮ#~=o  Z%.6&AB61\, k 6+wNwV#ھˊcY\~Ĕ(5 ξTwR w3:+.5&S.G+ţǻ04Q+ DN8J)0lE\UdlhVF A*7-3Fhfb<|$*$ $b&V`(cݓˇ˅S   (0:Al?7m. k^ط UQQ9ڕKvE^?K|T /6m:HX89-B16$P9㣻Ʃǵp0"6a*k-GhO8+0EVcjfUF>45 Le!\7=#9'![qPiT^~o!σ- : )+2=C>s7+@-oي]tƊeE&$2j1 :|Z(,5'5ba\:޴K a'*CNP8)0SESc5kg^VHB7D2lEe"b;$#n)#E"[n1ѻLRA1˴(s^  h '0K;4Bl?N7!-h~ڸH*كmrO8Ĩlޑf4w۴C.:# *y.7+pV%UŃ"JEϠS&A R=n)F-cAO(_3jjYHB8)1:?`dA`"(b#]45rQms8\ D?g&.9~BA7;.G"i@Mǿ[j#]HÄGě-#A@]$3,:'ye 1)-7H.efzun ѮP_S{oM%@VR?(L*,>M\hhl\IC|;19gZfIx"'"$ZE*'ؑJr/rTмNW 0%>/:6CD 9.#ܿطSɇτd8UޑO\Δms_In)M<,# &7,6B1`˺Ex "4 Ŀ6ՠ6m n EÂÑ:y9.¯947u,%/5$`)⼦]kY7U[,HP6?*2UFTcjmbi\U3G4B*7s1Ef`k9c]3$/(j!g`TlQ }C{ ˡ}"/%> 8< )2=9D]>'6,i/ Voݘ迕ŋׂqs٦ ] 3:)+T.7( \p۳|Ф")+UFQ:9'.fBQcmlXG@{5.B~ee@&!>pYmhFp>9]TOZ# -Z'g1=DB[7-4рADŽWݑĢ}:bŀ‡jƖ۲d^30;3$*-67+a\$hR\Č!-uo&|AoRx?+H.MB9P]0irk.\JDo;2<\dD'!pt-Кڋ+-9/Qiޡ3 <e&1/;CB46R-=# @*`L-dhC@›Dԉ͠`ְ$-V);}*`H 9',4m.9 VX‘2&$.?PA*+,=M^?jhl\^JE4 3OSh%} )-67)+^:UDg)CR>*.@!P`~kl<]KC81 A`YeD!%! a,RK:˜ՈM m!$`.<:BMBg7%/|$ǵ6>lvۊ[óÃ׎ ϠհhKR3*=-1+ ', 5-rdʅr4$=PAh,+>sNq_Mk1oaOIF^iJ#,&$u^1*1olA`OEӆ w)#-884BB60(ˆǵ8ìт󄉆ʙ#2 ϳؔs0e@ܹ wc )Q!=5!P ,282pT Z1' ӚʼUnt ( ]8^PI/*9"KF\ipfQIF=17FVjqS?*eM%%4m ;Dsd+bw7/гOc ko"F-q6BD93,\ǎLұHY:揩 [(9BSM:8k-04"up$%.K*Ի21LLM25)6hIWemGhTG&A66sNlhYi2 %O& M)q!2%=mz˼X،+  *32AE=6/xʦͲ_[o׽[ǻ,Ăj7l~ KV [72;>N+.7&~pkm#@,G+OB7)3lETblk4YJ;E9{5\Ie2^9]&$l( "@ou s3^@?pݙw - ! (2i>vD@80f>k"toۊ5wUܿ>OߣtzŚ@ރ7X1;,!%s+T.67)"nGuW&Z/( DS_?+,.@N^3jma]TK,D|;25 A^bhC O&!O7ӞyTv  Tfi'/ :C*C!9/"NʼƖUgnj4}"^M66MU?N+<:'A^ )+4+UjhsYǞF|$?%RA-.@3M][tfk4_LM3G>%54<YbHf% 'x"(P3L/3GOӪkl@ $-9CDF90%}@DBƩknc³4-\>D(e;Z1G(6ˆLºK̸ogqv;ķ % [q&|I#e<:35` )2!3 ' ;|ƿ w [ 9}S/K1/j'7HVfpfuOD?y4#4Pdj{XT.#"rZ#.A?tu*P%xJ%"y.8]DF;1=) a 56wӆ!Äē򸌙Xʼ?f"E o;7 UL*0>5"g 3-  +3A3G>5+>^Ɏ™΂q^$%]hŒ]ù%@ξzCl >67&A+%/5$5=>xyH{/KP6(2CO`lOlXJDm:3,D` ];OI#%M8BRhD)ͺXؠ p (1?FrB9-ZWAI}$K'ң@SĄ&RfCM\nl F39 N?*u,4'9Ŀy[ƭ qY5+F7O8&.|A!P^k5kXUFfB94A^aA_%Q!:"ϑ 1s(1v>EB8,){aGJ݆éETJğxğ7O\ŎrC{95Z1;!;(Z+5*)$^|Gĸ12O¦zs<:'BP=*`.@MH]nilZI;E<%5>\cjD j!/(x"ZӷKk ֚N> ^{Ct&m.:BCk9. "6a6䷧Z٠h׎„+B* Ùh2 E@fwFH~,&;'-e b),25-[JD5d_bV B"?3S[C+Z+Y;HQG /L*9HuUSbjbfNE@.98ZN`#Q>/2&#>D'\˞ۥ{@9!,8hCpG|;o/$w0n_@+ԧǯN3ىEhDJԻё0^e)" :N1Kf"J)11 Od}e[jɣpc S9PI.'L6FNTake\OE&A:97bLaV3v$"&f?#Ղ/K۟ 8~P )b<E!+5|AF<1'e.sùÕ҂/В'[xGlĈ(siـ-v0 vh9 3(03;" *&Ռ~/T 5OL3(Y6=F1Rc^ifRGD=7Fa]V7#"K0Rtm4 4̲DګM TaM+4BAH?2' ǒź6߉A@aĄďؚ9<ާ1˯j@ 6}[7%5# w)-3$Dj65;({5CP]?jfLSKGEe<5,D^X.9Wf%3$m2TIs̤gۯo'  KL*2pAMH@m4)ܹa|w񚑊=na;ܹwѴpcIS / 56(k-%5%6Y;eg ʔ=J0 LO7'0*CNN[ hhUFxE?8B_\U] >=#'2S.C?6ӌߛ%SIBs9 4*)1=Dz@46) fǻ0XL澡 gÙM¡l_&MverR37b)+#4v':bq2ㆿ)JnŊm+ISg=v' .=IXxhl[ JFv>4;#Q$FN+5+:zFSzcka{LAHAB@64OcPh,C&l"rx !skXدDEz֛ /I#*6A.E_9.O&o׆Ԛ?`ɇx _-0+v$ :#.+#n)1/= XٲSďM<:QCI{/{)6FTbm*f RIB87MaS1vi"!2O uqBb{׆?1Gؓˠ- L!,5A$FU:/^'.Ck@žИ߃%C!~$,[][Ԙs]ּ΀V< ;]82%1).2!L w/طп;ʽBcݲ4NL1('6DP[`~kgoRGD;4GkbZ7G#$W0D e + 5BzFq<0 )jʷFDm6n_ wΛa!rV" r% W77 l(-3?$5Y#>ؽn6%-o/VLPO7(2MBM_\niUiVJF=7QD!\X ;#$> &jϰ͠{6 y P U*Z1?WG&A5+[XyeͥB]Q]™ hϐR d3k '\J5P8}'+3&-QI^ʼNʯmH,GK3S<(0|AM)Z=im[IIF?46*= X]B j!K$ .IHҔt[d Dgm -s)Z1>FCCP8,ϧն п"m a~'`so]óھf˫?ExĻtU3Z289a')a4J).GX~հ>-ɾU b)GVR>).>JaWe(k<]jJ"E>7;Ta]F&!$2U/ MFyb? eN[+3 gN,y(L0=GFMF=F;+п˷ 8R_jÓKx0- Χ$W9$XX ##4Y6T#^'7,o5(*C%kGԮ@ ."KwP;X*1@KyWegXHE.?7O=TYfB&n"#nWmys?B߶t'Ւ  mw ;(1$@5HD8 )󾿷Rz ݴMۄ]^ Se]%NO~jg15s{'*31)8w`-y ̽"y^q :*rHOq6DBZ\U7n1#"| (AY)ͅܥ T,!+J5z@nF=R- gܹs[wϜq`›L(ǑDcdwSYNp%5#. !%F-/ ~ X ùDŮ̔W3 _6OxK-3'!3<@ J XfeRHbFQ>5@WUo;"#9!?#{51^:^ϲuڈ c d*3I@dG:?.! IŤslmLP0tjóOzyPy|DQj? ef 5.P!u $,0." EyJ!ߓ 6P LF3(2$@IV0c:bFP3G,D=7C\UR9l"W!!Y`^ϸ۠M K)<4U@FG?/.yܥȘ#Ƽ':)85E"WtMQp?5] a2,j %,/,! E/ 4ơ̭K4MI3M%2?J W d cPGF @g7A WUH:! %$0<؀M C T*ߣk }O *1O=C=>/""QɚUŤDӎZ"("rМ M`0Ej 2V/)K5%X*/" F9RZXʼnµ8_ 0ML6%T.2;GiUegTG.E=4@<U4Y?#S " Aٟ\E\y # x)}0=D>0## Pܹągcךʟ#Ϲ[mɎ5}02_\&J)e0r%hz-Y¼͓ũ7Զ S,HL:9%/.M<3GScgXMHG?69`QXC'!"FR>1^ /Ү)ٻޣh J O9'.ΰDZ7΢ d*GOq<9'+W;FSbxh}YG1F&A89Q:\Gt&$S@Yk֜G&zS ָ>u ?(&;.o;DB'6C&*->A8ڑ\􊒖Ԥ2vófKj]&aHoh .6AmM%7&/)"KGƱˋM 'DPz@J)+D8BN^f]JG?676LY-J7,aO $Y~ KX؆ Vr#]! +&.:DxE<:)!<WkH?alz8U/'|~ ,5%%&e0*RlfƮ4`%~B#Q[C**[7*CAN_g~_KGB:7KZL.2"K }صG.K7߀ 0A%-:9,D Fc;)-EcܹBW^F. ɪڕJ f%#*e6#M%%/--nw~vG|*v#.?PC+)s7BL][e]JG9DK;5rHXVL. d$ &F^Pٿ&bB NӢQgD T%-8YBGE:V)=އcǵ| xN٬p6-)Ct&5&g1#5%.-L`?wط ʿ0œJ :NE-=)6KAK[faMIvDW;4UFXO2S"h >yN %$6 `"D,6@;E;)١ƥaޡ̠ыCAǑJԞAV"t$uC%>5(wq "$`..UB^E2JȮ̡Y^~9RP~H0/(m4?IX4eaNH F,>5YBVR6t x" m3*&l"[ߦoъO 7* )y4 @]D:d*=-Qƃ/<ܐrǝġn^ɇӹzR m!c5+,H j!$u,-M A*9 ;޺ȤeAZ8PI1&1B=FWfpd9PHF5'14< FSaaFPH$Fi>6x?SR ;d$C b#"_a"}vl*rTF ~)u2 >Di>. 2ݲȄ?Ƌ3ޝ/Ð(0ªkG\1  39-#m ?$+/! !|ã m 3MK7'N1 ;vDQ`GbSJH?6= QQ ;%!#,!r[GrN|ueqbшqm (g1% "C   Pr}ؔ|+"Ei wZs(1=.E?.!_󾔺Q? PǕƏÂC* ;ÅU;0. I#)/3$1,"pWx)8 1KLP8t&%/:DXScdTGFQ>4:SW?#^!C m(IVj6t,>qϒ~ކ jX (0*=D"?%/I&źgx`WM,4P:Cɋ_ܹ0ǻqPΓ^q %a/b/# Z%%)1/# +&>vm֦1JL7Z%-;nFTR-MH?Ma:T(-:;E Q~_dVHF@8a:MUC("#_FU?lz^EOg' Vb` -'--9BA 5K$> +|!׈}=]M;(ߣ17WS9q D#w-g1}r h&'b/7&HbE *Ͱ_!m *G)N;%)+[7BRP`eWHG?68 QeYlE (,!# t = X] bFu r&,9B2A>5?$w=%h¼͹ݵb"_}ŗCrȩĚ;aR*(&FG g> ,2sm4$&/("K; 4/(p*6> L]MeNZ+IGMB]8N7L4YH5+[ "r A@٘ߏR&aNؚͮ6 gZf%-k92A@6%D.Ļe0aȺkТţ ŵX&ۃhU= w *i2iW$%.)vWp x̋t&BNz@(*5a@LF\d[JH(BF97JW-Jy.!n#  M { l/qWdVپB8''IB|%ǯ_G'xļY7ڛnj+Z~b} E#-3r% !U#+5+vE(ԻZ2zŽC: 9dME#.)3Q>GV bW^MJnF=6D7UpM3! # " IDuhEA>qI  blB9!)36=(B9)+~1UܣO4 ДSuLɰųA_G3Yh* ;Cr\2L* %s+, +^+ԥҺ\d!Y6'M|G/%1=GyWMed-PHFg=2?XFV8""U 3dס7M$h<ܱ1 )1=6C9+l"$Ȼܹ3[]k4:3&NhX>˷HܽٳY *$zS󾸨ԘsYɀW7 +g-_31$%.&6zph ˷0X( y c+dGO=(P,8BO~_fZIF>V57\OXE(G2!ax@f-/ݧ/m֗@8Ub ;h %-82AWA}6J)ܿ2˚ڄXU'mx|t…ڠzzŚF+c5$%o/)zt7ll09ɳl8YSsf%APB*5+7@J]Eg^GKI,D8 4JNZJ+n " 60$5ctU؇JלsZX#+7A,D9*ֱUݟ˨{@SA'ڡӜα$aX$9'6$J3g#5%/7,qnX΄*ȧɘza #*=uOxE-)5a@{Lm]vgg`IL5HC:@6 J[O0UW"""_FI -z{4XB7DyWR6!f=#G"]:Hf9Zzt6/'J * +3>Ee h(0t=*C=0% g ʼAѢި]ϐ58 ővaڡY5ߧa0j h1D27%).$#_[+M#hΫSs 80KpMw9&R-7BwPaOfUGF?5W;SXYWA% $#o8\(ީtX6# y V)X0~<C=0$^ξ_ رhɓs/ּzÌcױ/*S*xSR ).k3s<r%&y.)%C bm̰<1Ѯ +FM=).S9B?My]dZjJHA88MuUC`(d!#?BدhC֏]=  t&,9B?A4h&[oѻҺODڱ٫4~<ījT[߶rɼaI D1V +2=$$-&uZPKrHĿIp#(9D7OAL*)+6.?+IZd\JHC:46AHU7I-,!"SH6:\wn݃χD: b}=#f+7WAAq6+&0DÖ~ڷ܅-dald!׍I%ݶ?0u)4l" ",)G5&^" ȫ$>NCu,b) 3=GXd`MhID<5IFRVN2." MSI6c# B~ ,"d*y4>A*7V)&ŭ&ʬ6Ξҝ76‰ė\ʟ̇}uCp!4)nH !%+* E^3ź}>$^!<:5NEm.&Z1=rHqYOf:bdMzFCCa:3D4YRH4d!G" )HWݹ(+7eބZ9 H2!*3_?C8*Q!nɀ.MǮB)FĜg›w~  3.=Wr%)+--( Qh`e作nO Z)3=LI5+&J/0:DXSacdRnF;EQ>%5]>TVg=3$ "8?B*%  Msӓ6 L 3](0Q>D<%/# j"]pH GՍ›&ơƛõx Ĥ :D o XP3+ 7 $*,? 9t=FՂoƺ̊mku@6KH1'0K;`E)Tccd{RHE=4?TS;"Ij!"_cKqodaܢQ C*1=B:-#R GYs,yGj쌳n|kS`Kjh Z1q0% %(-!i [dlb(ޙ7fQָOND  ]`(0M)F-7@{L<]d}YJtIB :0:MTC* ;"mznٹz_q؞8+ &T.m:A @4C&q9W͜ێڋ e ,d %;ǿl V1 +3l#{$#$,h&+7j|ĿIY"BE'A5NB,*4tC9'*0(*@GʃC@a}zC!|wdC2 z! 3( x" ))9 *SZξ-56’ܤ!:9MG2'51;D'SadQGD_?7"?RT<#S tS]}%i?-҉%O_3 Af*2=CC:+ IgHkt~Ɲϭ&h4UGzBr0NJ\2-q?$ )+~X h?p?70&V |2J+IL6C&.96ChO(_cT&G$F|A84'lԊyhZ$§FԘfD*_ŒpݮD1;YMS' -3f#$+$5*Ȉ)l<ɗP'B{L?X*A+{5a@K\Of]JG DO=F99JUIy.dQ!Msq bDw6ٙ3Kg!i =i#,8z@?A67=) )>و݅l@ 9¸n,h7к>8T'25&$ggS"#+(Y4] ˓(zb# l T49- Ld&$)+& Vxkc"įi@ 6MOI{5)2 :GESbePUJ|GU@P8?HQP<&( @׳9ay4Q F(2=tC~<0% [ǻ܋[ؠ0pQ͸" +SlЭ1+ ^ >20V x%`(h, ZlhK0K+)P /IK:)/8|A3M\bVIH6C|; p%.m:CA5f%Rե·P|W6_DөD?̋ǽߏv{ L *<4HT"#+#(Z[MUnʗ"'&AOD/+<4MBS9d*KMyUDcq򸗞í jC "+ _3, I#`(*|1 tSM9e)ͩt8ڪ 25bLI5'/8AOa6f!VJMHAB9>!PRG?',! " J 6*reFyb %(1<(B|;."- :3 UѠՒ3}Χ꺏õ=, z7_pR 11Pw4#%*!u W8*Ly^-GJe<*-7@Ky]f[ L9JE<9 J}SE- !.CIZf~_dMHtC VEKkc0Ÿ’1R/TKJ;+28@Ju[c[ZsNKvDQ>;G/K?,$."O S!+ j@ӨߙfJ{ =)0,.6?IZzc.\VLjJE?:FMD.j!C !,3 J͸?GıENSGSʆX# P,:3OF2*18cA;Q[`aQGKWGWA7<9JK;)!8N3#|5O9@ V L!,5=?A<:n)uyYּܹܿ<#ǵ*ϐ]";įkf2! ="2(b9 rx"(( [ѳ:95ےH j!:9NHJ5^'.6@AN*`ncSHHCC:;IuOB*4   yiACx.ڰڻ*L) w K%k-:fB=N1 # 9(~Syoɍbų@ECȕ h +,/S"I#)"B) &) _0]L(CLA.#.3<"EVc_PLF?8BKG5\&!O ,BNf@ p.۳&Ne ! i."*6@A7' ;[Z٬(DžuܖϳIEQ佗؛\Ș R )2K3= &z#1Q3ˎC IJp "=fNE:3P, 4 ;*CR"bacSNIhCm:a@LGK8'![ Lknw|&ץaYm )y4"?C;+{Ȅpɼ͒ *”f?I9 l9#39'$  &j'i =CtX҆пͳlĨ+ffP8)NH8\,28AN^zcPUKGrB(I=L=)+!KI& 3yܫ37<9 1 %R}*H4>C<- "˳G#&`o?C'DǴETB1,G # '=));C;{K~VH4LK<+L06@EJ_\d6Z/K+IxE?;fHNtC,7 [ ,]Frbz܋. DT ; (12p$ 2ھPΚiԭץؔ:J0ŀ𷕣c-8Q 'P = `./8RT!$J) y,_qĤ7!n-GM Am.o/46=DVa\MlKG@ 9BKbF1&$! GSzbUWqBO# c ^ WR'/;D2A}6&aYoAoPԤD[Š=&w*1jɝF \-2w!#*Z%h ZkYʧS-)C\OD1+R3:vDSa_OJGD4 Is] i"-67@B:/(x|0Iq8n˘kĿ_ďÄxBӗ~!\>h8T DP 'w3"":h !)'?Ohv?]ˬ  1#;O?G'6Z+28@N4_bTKIEg=]>\IL=?*Q!z_a,i f^5Ӡݩ) L fs+4G?D<\,S~ּWɜճځQёȞ= jпsbɸǔh AO 82(b ("T(( /"hп0?xĊn5LI:,15i>OI\dZMKF>0:xEJ A-b#a/s<<jfӒ* N1+](2=C=%/E!fܿ:Ňѳ?,Icy2%l 'n/-/ '"%1)!? nN YȧҺD9-G Kl?1/17=EWkb\-POlKC$:AIC1$"!:s> -/Iݥzl.ܿێU1 X '.8 A?#4%I'ilwiڲԌ‘W_[ܿt7Ɲ]̊QUM+ H',30' !#n)!)qĘIJ·żl(CNhC1.52;rBSa_FPLMJjD9>HIF5'"xnވV='.YZ P x$-9AA[7$=D}̘ח9ypԞt}b.;n #)0JJ9!($Ujy^ɐ.ċ̟bOsh&?LMB515+30:n@uO]^COJIE<>IOI7'" M, m=$Շx0  8`",6>A9 (Si2Ʃ[̻آؑ@җݢÄ [5ϾȷܥUr $/ !l(C&evMھƏw !:VLUF25A+067x?K[_QvJIF=<.EI;(! ! d!2ݡG,  L q , 5ǻfξ ~Yj;*g|¸uȼӝOK?NR/.+ fiC X$'rgvb>ntșΑfǒ֍0fHI=,y. 4o;hCT^YLKGAm: AKGrB1&!] n`ܽGzԁLmn N&/9@g=1! `й_(ǺҹúǘTy9.j%7,b/2O 1#J)l"e?(މ Y)Ҁy%*.EMA/d*o/5=jP_^NIEA8;FG7(!W kANyUB8/QKz}]z ^ 8;"+7@?7$L d+ξ:SϨ1ɰY}E8•ƭ:OF.ۺX,Y7 v'y.|BC !'z#;1[hVϗ'?LYBX0y(.4UUܷ6iڪU} X + fw*19>w9(Gܿ8Aɪ{> %__et ֟(?I.y(y`  $h& 1/kQ'+n^ R3^JG:*b/2&;EyWe_yWLKnF>8cAH@/% YQiqfd {ݘߗ  ?P'/ 9U@;`.* }8>Қ)ĿΧ[֓0]Ä)?ҳ|lnh,+,' Hyr!+&& >SEA6K̴ȭ"2\IE7)/4=HY_UKJ=F?o;DI?,!O CPWݡ8 SOh +(o/8>$:-t  62\cFܿץǒAfx_]7G޾б.u,+{ !$'MX9=Xpjɠd5-EJ>)+)+09C:Va\dM JE?]8AKFR3#p,  uhin=dP.۱g   #,7>=3"kRԀ@体^٣wR*h컮f\&͸FR o =) / !(#9CrKčΗY:O&>xKB05+18$@P4_4_9P`K(HtC : >(HGs7'!U[N<85O%kv1 < #Nn)k3=?6&)۫]_dאιBU ¡ΟdԀir !03$# O 7&h&8k \j1Z(e3̴OCT! 8bLF53*/#4=L|^TKK8#IiHApI?ԶG '"H.*7x?A9)kle$˖ڟ˿›<Wb A0h w3$s1!N E!j'&Y1P0ţ# E!:ILbF6,\2e6?'M]aTLICc;4WL Z+y4=C<+Vg>k T5^*G;FeKm ?)[`(1B1x"^ W-ψ6KH]ڼӟ㥵<_*$;/SN.._ " ( !%0 $ŧ̲GēѓF,EjJ8>-0255=J\O`S"KrHC0:9 D+I<*O d$[Lmk[|I[Z3 )h 0)i2~׃| df.&++  %+&x o fӯ~^M'34KG9*/3;nF4Y`/WKJ.Eq<7~BhI@.#r0zJ;(ۄp) \ J  T(0:cA;-Y}]rBӄۘzWҝfv ץ=zGӸ;;N-- ;9!p$;( yFQdUūǁ"ƤX-&GJ=-/.29DU`D[NLFU@90@FA2& , 'pߚ ;/Kݞֵ߻G+ J q3 %-D8?=23$ 0!$řޑ*QB޲@?̏Yp *;.{tO !E'!tz"пϣ0T9' AJI@ /+,2D8?AQ^ \pMJdGrB:@GvD4E' $*4s@n&.mٜxpo ' kn#\,58> ?Y6%cdsKk:؇ihQѴAzSĩ=bݮ-d=ˊt?vPu 8k A%.Vkr &#1J?ΡZͰxW6M%=LC2)/6i>LM]4_OIWGB 9;(HIk9/( Cm4lֳAR B*3L6%Odt_ < G(08>8V)6Iˊx˶a?Ҏ3ھœ)ץvbIS+hEP,' it #%0' '/3 nřIy ʳd~0G|G :*\,X07KAqS\FVLKE*=g7?nF?e0&""(]Nx ?pGܬ { w%-B7?;;.^PΧʁ#ܼӊZW~0-o,õľΧrx|V/L6G:))ZM!Z%-`vۣ{ͪ )e*BGK;h,3*/5=7OZXM1L5HA:[=B:?2*M%[ EoGzA)ݟj T :") 5g=K;1 R ԫe§Bmܶ7Xܖ} ;"hr5&+,$ 9^˂ȑЦSң %?I ?.(R-1U:lKZZP KE,>L69BrBq6+&$MG[bf>QI*@d F *b)4=8>%5"tŒ€ȓۻ؝ʞ˷QAU&w>UXBt|  I#+ K&$!U YǶTЅtΗ &$:HpA0&+1m:fHWZsNGD@7i8BFm:J) NZQLGpQځڷi  F oJ)g19O=6$Ww-ɻdB2 }*~˱~ uڕAq9l+!31 |" "WZG^1KaWX̓˱ߒ "S9;KE2$V);.'6DXW^RIFl?o54(BH=-#f&$kI9d&kؚkS^ ^ \&.7=6%_w,O<á%>Ʃǘ颰c0ۧIdU_$y%)+'3e "$ } `f91$ZͮҗwDh 2GFq6+&', 5U@bRZRrHFA:5x?1F=,S"KS3-ޔ$עdq &-5;*7)@M>j/~oC&o5f;꺁§^X':'' ~ !X$POVc"ʩğ5/^Ձ,CH|; (O&Z+P26=mQH]YJIC90;HCC/"Qg 7V5%)B ") 3;m:..Z?("ʕ0ܢ^ɰjҗat=ųmY5`жзZ6$=)g9d(p$ 5^=`S$*@OI>, (u,2;LBZ6ZM+IC>;28BA2% E_50,v ߀+ Q (i2:c;B1w V^Ǒ4؃T@ܹQrAױV3l.=aom #*(!_2#9!RVvϟ}҇Ѹ=dy&>lKcA/\&f+/]8HY[NH9D;1T4BE8{)C i* @lr]U # y 6|'09(<4! Jfόيr͎٦_Ԟ"*JdӧBߣd) b) z#"fE' ʙD3$:IBB1%*/7EUXYOIzF> 55 A,D]8J)""iajC+t u e|'m.7>;4x"H ;|<ܨźeEÀ5jäߩG+?0)l"C "b#;h$Wƃϋ^ %5tI1F5h&#(Z+3AS[Q-JpG @5R3 ?Dm:b) _aeLtvgڳ-u  _%+4:H4$xe'̪m`abͬt$mq$rs'E'# M!" 7ɣ9DԲθܨ i2nFE5%-'D,<4z@RZRIGn@461>F=+! i8T/R~ )  $+4:c5'z?[>]ø-J=;֟{$znIr͉jyh&/(6;U#?hj6?̫˘/Ъʱ\ e,~BGE8E''+2i> QY5TIH<@*72?G>,"rltfat/inst/signals/greasy.wav0000664000175000017500000002703413026262276016226 0ustar susnaksusnakRIFF.WAVEfmt >}data-``0P@0@`0 @`` `` p ` P `@ 0  0` @P PpP ppPp `P ``000p@`pp 0@ P P  0 @ pp00P``0P` @0P@`P 0  0P@P @ p  Pp Ppp @ppPP```pP@`0P`P` `P0@` 0Pp` 0P`p0 0`p P@p`p0` 00`0@@ Pppp00p` @0 ``  000  P 0PP@00 ``0 @ @@P PP` `0@0p``ppP@ 0`pp0 ```p` P 0 0@`p @`@  p p@   P` `PP`00 `p pP @000@0` 0 P000P0 @P  @`p@`p@pp@@P@0 0p0`p p0P@p`0P0P`@P`P0` PPp`PPP0@@@@  p`PP0p@P`` p0 `pP @`PP0@ Pp@@ p``@0pP` p`0`P0 0@pPpPppPp@ 0P@0  P @`000@`P0 `P0PPPPP @ p 0 ` @ ``p0Pp@P0pPPp00@0 @P0P` p @  p `p@ P0p 00`Ppp0 PpP@00 !P p0@p `` 0pP`@`P`@p 0` p@pP@`@0P@0``! "!  @@ @ @`@`@p0`p``pP0p```p"0$&#p'%$0p0pp p 0@P `00@ P P@@p $#@%p 0'&($%##"#p p @`@p0 000``pppppPp `PP(( ,p%**+@)`(&%&&&  0@`@``00` 0٠ۀ߰ `$@-* )&`/`-@1p-0,/0*P+!0 @@`Pp `p` pp @0`P0``p԰`p@. ++"- /32 6p451.@' PPPP``p 0 `0`P`ذРӰԠp#p.&% 044= ;A@:;p0 -p@@0@ppP`P @ 0@p @p ̠ʀ͐Ӑ0 "`$@#0< BHPA A54()  pPp@P0 00`0ː ֐π0P`$ !&p@H MB@@46P,1#  0`P@ @p0  `00ppҐPP԰ @Ơߠ@@@'@1pIRM D 9520/%`0 P 0 ހ @`` `p@`0ސp0ҐͰȀ@`#p!@@0@8pV`\O=/.2058@-P@ @@ 0΀հۀ`P@ @ppPP0 Ȁ@ Ű @#0 `!@M_Z>@.&07P:D:) @@P``pPP׀P`p `@PАп '0p!N_X4#@#`<DPG :0% ``PP p``P0Pp`0߰p@ PĀ'P00@`@^FP@( SPTJ(*p+ ٰ`@ۀܐ`P @p0+ p 4S`b@)pR fpC$`8 6@0 0Հp ߰@ 0@ؠP0P̀@`03@@@Xa0  3P^0o:`,E4pߠ @0@pӰ``` P`@`΀Ġ-P+`P`. U]>`&pTiK 0 2 B6 `ܠ`0p`P @@`PPȠ P, p؀ 0BX K(`=0^Z05PP!GA00 @ pp``PP@0p@6$@Ga@@0$`0@0fS1#Q@@`p `0Pp ܠp@Pܠp `p0Ԑ٠׀ޠ,5@ppDbpG!AbN02@J`M PP@`P@@ܠ@P@ϠP0p p@0ݰрPԐ?@ư*YW0*P2`[Z1@$` p/R8@  P0 `͠p0ǐ@Ӱ@ 0ӰӠB03]J@" 0: Z`Q@*`'00P4 p @p `@pɠP`@@Р`3)ހ0\pJP$P  1TpQ0,+@%`#FPFp``P$ P`ͰݰP ڐ@PpPܠ̀Ӑ2P&ܰ^Cp40ULp$,-0P%DBPp 'p0000`@0@ 0`ҐP)@0@CJp(P`&HPO0%05 *!20D@,`@%#p P0߰0ְ ڐސpА݀  ֠4pC+p&ALP2'0/P'.<0p@#"@p p`ܐ0PܰP֐Ӱ`0ؐӰޠ P-7,&p@F/@/P3@.@$0082  Pp@ېPP ׀݀0Pڀpՠ `&p)'!0-@= 5/=3`&0"2`80@P `@ݠ`@ ߰pې@ ``ڀp ` $p#%P.2.6:0*&P) 220&0 `` @0ߠ@P`ߐ@ܠ@@0p  0`@&p-.).6+&#@/.0&p`P ݠ`߰א0ܰ`P@pP(-@-@!--%! '$0!P`P `P`00 pހ P0 @`@ 0P0P! p"P"p!0 p p ```p00P@0`0@P P `p@  ` @PP p@``P `P p  P@ 0  0 P `  P  p  `PP ``p PpPP @0pPp@ @ P  0 `  0 0 00@0` p P@` @0 P`P@ @pP @0 ` P@@ p@` -`P@ @@ P@ ` 0ؐ`P PPpPP@ @ppp @ppPp@@PP 0   `p ` (PPP`0 0 @ 0p 0@@P+Ӏ p P p p`P0 `p p0$Ѐ%`P0P P0`0@00`ߠ@ " p 00  @ @pp0` 00 P)P   `PP0 @p`05 @@ 0-P `pp@`P#7 =p @p` 00 @@p0P;ؠP@@ 5p`0 0 ` p@ 3`p3B4@PP!P@P&P`( *0ʰ!0`; Ppp@ `` 0 PP Pp @P @Pp P`ƀHP 0 0@00Ð8:`P)0 p@ PP@0P0`p# 0 "0 PP8PP  Pp!p000@.@p `` PpP PP00pP `  p@ @`P0p 0`P`@  @P P2` pP̠=`Pߠ>PP& ` > Ѱ.pPPP00P/PP@P#000@@)p@0@  p'p`0@  @ 0pPP `p `*(`P0! P7P30@0@ @*` ` ,`p0 "p0P/P.ppE0$000`p(pϐ@@0% pp` 0! ` `0)P!PpPې9 p`@ #0 +0& `!0P`p``P`P p@@p0P0` ppPP @pp@ 0 p5ڀ8p`Pp 0PP0.`ːA7PpذpP `1P.`(0 p'@ 4@@`` `'ڀPP@A@@+  !p*)0  ŰCP`@@?@NP0p0,0 @00 PP`p0@*`0 pP`P0` Pp  #p0#p0P4P`P (@0%3`0*@p=0"@ 0p3ِP@Ր"P` pp`5% р ۀ! 0 P0p` ` @ @ p"`@p P40#` PP0`@`p `p  /ppP0``0@0 %`pʐ-00@0``@0p+p 0P @@0P `' P``p @ "0/Pΐp+0  00 `pܐ pp @`  P@p@0 p  `@00  @0@ @@` p` pP p@@p`p0 ` `@P 0P pP@ @@``P0@0P00 @ @PP0`@p`P` ` @P@0P@PP00P p`@`P0 ``` `` @`!%,,*-1@+@&&(!` 0@@`0Ԡ@@`P pҀՀPp3@4@+@@2@R@&=?0("`74p(p!0`" ppހӠ@`p̐P%p p;2#&XP>P P'`F@*`*5 `$  P'   ` 0ހPpް0`ѐ``P))"`BB"8@&`+1!pp 0@``P0p0@0@ ݀Pp(  ';+P.0' `!)P 0 p@@ `0P`p`p# $P/&"+'# @" P 0 0p@``@@@@0@ ؐP`@!@@!`*p!@!*+&!@  ``00@ P p @Pp`P'P&`"P)*'$`0p 0P0 P@00 P@00 &@*@"!&P&&#`pp@p`PPp ڰ@p p #+) $"P"!!# @`0p@0@P0pٰp @0  #p+,P)&$ !@@` 0 ` @p@PpP@ P00 p0@%ltfat/inst/signals/pinknoise.m0000664000175000017500000000277713026262303016370 0ustar susnaksusnakfunction 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.github.io/doc/signals/pinknoise.html} %@seealso{noise} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . outsig = noise(varargin{:},'pink'); ltfat/inst/signals/gspi.m0000664000175000017500000000313513026262303015320 0ustar susnaksusnakfunction [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.github.io/doc/signals/gspi.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 = wavload([f,'.wav']); fs = 44100; ltfat/inst/signals/lichtenstein.m0000664000175000017500000000312313026262303017044 0ustar susnaksusnakfunction 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.github.io/doc/signals/lichtenstein.html} %@seealso{cameraman} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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']); ltfat/inst/signals/lichtenstein.png0000664000175000017500000131121613026262276017413 0ustar susnaksusnakPNG  IHDR{C pHYs B4tIME ! 8u IDATxڴ[m[vZcϽש+qٕ8c!O!%"~FO~C+O!HX (8ʋqSu_5Go|>sϽeȮ[Zs9Fz+zB bkl*H9 "Лu`&8r|ڥSN8$kzڣ ]$iD3v!؉$; 4)@In@η $ 0$FPBvPpP"fF`PD #rsISi\kWp+!C͸9.{G$0c | F%|y%3#5V!M"(>QDW-xN>#"DhyU=?xfglbP]:悦W-!O-IA}XI,?_#6D Szْyٌ0{]fjH#dnB=nєAN: nF#ћmnn{+\f;HaaȍF %7caKftMt96Yp70BF4@q7k'$m^?t _pZxc[>Z3V*Bpc%Vۓ$еֻ!NiF(@9\K/k,޼y GthB'0];`0%35F5)3B]CIF0 v);G#:) JGyH$c`y""i ]fodʸ@XfZ)PR  Z|p0 pC33ekc>1wA8rUr`="W@0GX_^Cb얹O;*{ylb>s0#`.|ƯqHM*l$Qn{?#G*9^{(45M$^zC6 .4/#OJe[^Q7!!B]L"ĝysl|2u7n?nurYde=F@KN-'Zם 0:#"ܝ!ĠF4Z^1en2 ]]34 ѵ*]׎2Bػm-[3#qPfTeZ+v!* K FrPhR!)Irrd%6$dKnEAt  Bu~sEm! B*q33x!# 4̂" a#"gTVUyP,gdm[ՇL(vh}|[|k"vP;~8gmsknEifV G0b"3ۨ6nҞZ}ه+=)TPƀasز̴967e8Pf_Бic1À3͜8/n!ԅ0ٚBAܕ֤8Z>/Q?WmWpYteMS~i]_fDZTOH*<+m ZrBYb$C/~]cKkЮQAFZڣa%e=ЕcJz=k\"XR9_*GN4tbs G&<[$,3_@=؅=wF0H "4I]}W' |̓ނu SsB]=9_LaG:7o~a3YQin ,~A$x\5Kp2ib rOaeSe'F<6 :@)G34N֚S3@aCnqc0fNVP|HPjId kPs.8 $I((A1_Pt,j=-fJ$tdnJHg|Bꃋ *=D.=C.52 V3`MPIep #Is="(9fC!@&pl ,%DZĐzż<0IHa3mɞ/X ' P.N ]2w2mK bѨF>X<^C7FZ 6&ݦc =)=4%(8cttQ/_x|pqLP ΨDb]Z' wG-|h ln- !y+F]8p5g6ǃ fFw]6ŀNd}}:/ *v̀S7O<8hsPKů0]h1XaeĤ3$f`9@nNu͍{}j,f) ehL"aT$)t *#5=9c5;Ah"XS)\ P> :eAX)`^;N5f" rljY Gh>H0pl#gV`*KP%ae@OZ̻G m4~~9ǀZRT_.P3vCwDJM "ǃskt7w$4 f]rNgܪ8\nUZCϖVAǍܗ|'OJ96>kq02+;<`cL;eeF2{<̬ ؂Fy z<"K;P\l&7&P37ъMJ]dCCCYҿ1:G3g_'QbqY{p*\ 79 1 TC2(jPrB@<4p`8e-Ǒ%^"^UJ˭4Ngb L˼_7cAY ʭچAw7lkaF{Dt,:ud‘~ĀFaqd/x ˁ&e;Ӱ/OT! EaňYX`-xUM)y@:\dXB~ HS ʡ :b"BltZdQ dqn)*t@c=7!L` L0`}>!ڼm~ i F*Js(Ԃ-YJ"^ħ//:p|t#НU Oh!*8Jif,@ M!qtV--hv 7k(/i؉x脧0 VRTouETHYΒA1,b%<-)xGpgDC+z(Dt1*?kd<xs:LJub1d׵`,%)cNR HC e"φ3S YV=dF (IñbhFu**iDs^Ys3)#{c 3lh4C]By֏6yzQsPn{ΣwW)gT8f͟|L $ui#j0ϕTWd7ȐzPK;@,TC fb@%s=PrT2^%Vd`^;,KːAc<)Tn{9e*3AP(<.\ڍ3f+RgqJX_?@z~n>NG]hbCj4j5S'}=P㐝bz^E׊yqeGxl 8)8BA:vFޱfdNDS`45Ef@)"}/yikE‐eA$cO(DY33evjWKDYRC^ͫA(<lfxilњܛe2EHFEQLJ"y"_]Hg;͂ ZEQ;uIZOZ%P#l lJZXAQ`e t{*d9jiD3̪gbB> YX!j멒 ]#ز AC$M8 5zݩԳX m Y :NNظ{o޾_m%"\I)n 1e7 }hOb-3'Dkψp}\Ly6ښ4$oP*6QSG\KJNMF!6% B*ӌuR3&YRGeB(U\O7@{ "&{}B\љf:&Vύ&e @hPx)AFx5m O5ְm40+QN6XFI0ozcͱ5\{k1ӱ$Cz pۈIRѣ nfE6pN+?]aZ+ѯ(SCz'cSC/_}'6͖ߡפn).ъ(ȵU @HP!4A@O]!u31P3V%gvt7Ԟ_l:sCK97vvNtRo'n!ZܙIL|鐸Jg]-h$稏 Y޳wfyȼbIwsAq< d2:<*@JuIR+=pq30, !IR4js]p0ܒVuw.QseDAGe\ L0 r :.eVvV6|fwʍؚb%i1,H-2$F7n5Wud*;Rڔ=ڗ಍vAI s؟ %-0?;.p!3d/T< i.qkb=SDv iNfluFR=Ŕ7R꣌<"l"rsAY@cVL$%ϓI5[|+-O>*yH&Jנwҕ6S#Ќd za̕MPUnS;LO(q %BfſM\ϐw;N5&ҶV:m,8c%ow٫_>'ʡM ̤Uh4!=SS86 NP: U>@ NGH*TPD}@;4<"""QJP$%φtTGurS#xP 1h&&$2lcy\XޔG?nY_<+yx'9|4vI-`  [)#t*چ`f8h|xKwi8p-ԏVt* h"-$i keR+ vUI bb8:n9k8G xδ񌘧ۧA= !w(2"E a72W:]&[:2җ,ƴ|8qE5Cf.!tD0a. 1Z 4c4;];nI!{V#}6DiF@Tfb(bՃh Q͹C!% dzX&;>&[٪w pf^Cv@?NffÑb;3A*QCz]]YFϞ`6%"O%j`@l:/eU 4kӴ9qƟeoiX5 ~zۂj2Z*K8UQeb|Zy@3z l7Rǥ9Z =rfڈ2:/.9Z`ӷ1Лdw㩓; B' ceygWh8_CpCMd eq0@ju5zSDRY8)h#?)FN*Ef}N;N' @@D-+ )\Yl݋?43vili9p3֩-sQy̮F2V=b *6nܒr\r-ZBc&/tD$P\ rI#h "@ٯNF-uTT\Q($SOVȻo&3YITJmlNxOOW]w.KـonYc-(NY{.ҙ<O/(1P 4#i9F)AIYN!lL IDAT<+W-1HXl4ҍVGs%3e^^ >2*{4YE=S!F7 1a{—Ck;IED7"h%ZsrkM[Zv8Lp@r![o>\S]gHGgV{0R>2K3^^yBHb͌PXt#=H*N "~(zzWzu2&=9CjI_m|ufK{gfu%2쪳HŚer*{a*\6!>OogMcN80@|A:Ǹ2<1 -mU6:bb,]gMRrC'~ >Ո`vţ R-8|ecl9%=&i%R7ޮ]Ox =X &wܪohbogDecM5z GPJLVm yb iLln-tLj,BoG0)4a&}J;"4@ e h%=,+y-l=ֺdT|6E2<_~YʷQ{5kJw[sMO}ЫWr90 3ZXd΄S<ۚ]=^ⱱ=}kIqm'ahHY:y'qڬ@`єOg{A+yģz$1-47/XA ;f?6kfټ]r\퇎MQMjnn[9 ؖ.XCI3LKc3'һv9m:*j΄D::`Zz`Ք(Nt[ Uʁ:D͖s:^NސS&lLMBhйsj=n{61 =1JpGRnaMrVb ^M1»qq:? muL{73C{t| }W?,x:+3#aIP)ϣU L3$VBXcpaTe]1\%7Jfu*r͉?: !{FHoPsO޳_I&F1m7C3G,SN?l ?Cs1^,A XTVQ-q=$3Z-#in)-SɈ} aG;w#{ k*JLI~qܽf/nkEf zag#1ϲי4YdWvG"f+X{6}o|*ԑi5LF4A1Vq!tc (c'?C؍guׂb/}=o0ҙ:,E`‰48}.*shӷKXg&uA]NYi5:)$h歐UP贪Q]kC)EG#ڳޱ+-ƙ͗S5TϗNvIWmqsY$"'Ɍ2*OYS @3AKx͓30dߊݮq 5zTq rdQvt,.7cZMlO6X`u uN,"fcp?EWFC;R' fYi}жe 2iBZp +vyόs9X*(n=֤ #,< ͗ 0x]c Ҙny?/)9]=[3#+{)0\@6d;}8hVJX5t %XSR⢘ά x<89 aYw&ξ 1.61B&0<*jpn&}^t{EVqA`aR'TuCpAeڳ8#eH} t56Oe 2VBF4 t6K\T'ݒ^BW<ƇL$k@3޹w]z`T¦ΥfrS\3͑z U?s֧,]<2BT@12!j!Bh; V'qV)x[/io; &X$Z\P8aՙX&iLrlgNKj#!#TC7NsS3:u1% 8r#?NyuSncJ1vz{ݫHd*JCԩ /ůU~|{nTϠ32QPw@| E A/N]qSB㉤gI'vl?`Rcg$=Ϭ|Pb{G𚊪^Xnhɖݱ#;rSgH4A]GMV!⹭1lɐ,kkת3 o{cCl~ It+ 5}b>΄Z^υ!A[i2 EW@-2^.;$UAjkrEȍ\:2T Mnbu|t?ctȷS{Sh- 9 H*^Ai$=]5Zmbid35S34O @YrAT!1f+ٲ8ODgϟz-HBMNrċgYpϤBÞHϙyLp%Re6mg9z=;4sog/1fY cP,Mlէ\>sQπ{ ̷'u`H(yiĚ@h p7Ee>i9qTBhꛭjisup \*RK{5WeSf!FC 5_u ؜{+7OrKFOG=NA 96 rJJ;9G<%52)io2B2v{ 4\vtb̍<"ŗ`T͊ >6Qp0#9IJ,h t(cˉ؅r }CkjBunYL">5 uŵwM:P3xǫn0Xgw\ᰓU#"* ;f&2l}NO4Yᦌ&pX{b`&t't,+|r<e 畎:&^ ȜӨ8ZG_B^Z g&ę{_-q 6A 1E"LӁ@iNC[^%䧠h&2ƖR#Ia%ot(ŴռxO6윎 n~?H~"|6l4!b=,= }d ^c3/MP$4]Ic=稉S,й銈 `{ݛC"ۮUko2 f8u~FkŪؕJ[t1kU[ǩdnt:̚]=(5a}To4o_7luMd=>U_|rʗѯ͵_H݈o;_J??@M>kAC{j]xwJ6L*H/mI%M$cq 1sTdOXwa"o_3b avc9-a=68]lȜen+SV+ޫL5j/hanbOѣ;r <ݕff] ;_\5zaPMVPvtxӌ30tqș]ػƈ45uxSޱs4{YW҉T.sМ-xRɇ,wke^{F^h-^5w#a}\.?vwXE,Q@l2%eX҆ڊL̪K+6ʌr/}{;nm}|W[qy5n{|{n]z>|tƒ?Gw|.o~K?\u?<q+CGzXG'A+gD Dpy?Sv>Tmƻ(ܼ+N;N@ܣ1abkjƈ>i5󨦋z${`^ki;1Y#n# YOxw7` ^Kk\=b\grR@*N9-ؽEǜǒ)$)3sxx<-{tXsrOkrSd9[ p6%%f.H e(78Cf~=)s䆪iVɀlfܧg8cISp#hcųSzDd YO( bmT`$&F{{XM @@XDDY27gcq<K!)NT cH=ϽuIW%2Iv2ȃ7OS֦f׌@ bG @ K91FTW6P\H'ii5`rgCFPfXBIr]"ktQ"!!/.ٟ{7}M|qU=; zjK;Ѵwjf߳~W.?OlOC_W//|f/:}cNE"v„=|jc]TPx4y>`hWm<`R4]7-<8sdE3OPVe/Պ>Qh ;Ѻ|/՝r|7QҌOb!SkRI+:{)$ۣp ewyLnn|ܬ9Zn%XK͈Bmkc6Nf"A0zEza哆:@zGs5ӭcaJ-(,]SM70PD|/Caf %JF8%@Aci,Y#'6`F}dza޶7Р?Do͛,ˮ)d rM- [eVFsC J^2"FO,ڼ4lO u3?ݾh^Rw/o~ +??~?~~O?e+]dG]ҔIz8iO^v{}?x/~[?[̿ck;|ÿ7~W?o_r;IF348f=_bfoMݿ0.ߗ<'uç)qۙ/>IH(4GϦe#d܇PfӔd9105JcחZp}07(J.XҐkZִd2R9g3SZFs!T2h(QpK1d1l'f J[ath,?y2Μf#A,R]J[&>ݩ$@ga/Q)cd/aN4BżYD\B%LfDNV3n_||]Ok}7?s?~w7~˃]|m戽'eg"nIduݟ: |ۛ]|_л_K_}7~;?\/}~+??o]Q؎d tIL9]0g]Ӎ%>-^px>-ӝ!ħ~ NFC+c*ѳB*j?P\DFvaϪ,|,of،[c+Cf0gr⦈ I$ݗia\7J˻$'9hrg63ýg(JQqN=xT˒Lj2TOM{Nz9p%y!Z$& 9vR ej -OXc,V5,Ѓ;-Qh <`$">dJt(-RXT0xl O!37&{w5zWOQ(>$tL[ܐ3Ànb|G_xw>;_}}kk?{|>w޻FWI=;{C{Ӎ4Z܀=<2^LG_gO~ YuַyͪU8^m{3Li_ג:[7,YH(k`7)-[rKۆl؀ 4@/_b?ynѢ-JDq(cY燵wD;d%a Py"v~O"޶ 7MGHx q<7BZF44RVD2Cjbk}s"Dcb +U uh ´mʂ捝9yt,'푏ApJ,&^|erGJW㓧mUNR>!{b?qZB,{e2\*TC BP!wQFI ׹ DsN%'IgN$rNPɏLØfXo%Ғ B4` ~գzΪ+fY:N 'N٩th!'5 HHf_o>OO{g/=a͠InNn)t,"' tGewF|dR1$=z_ؿg8^QQgRlxpb*C&*Rܻ_{{VcOݯ\6?w~•_/揿įͥ>A=D 8?Pa18g;zfps/*DNwO?s4P+GOgPZ%ĕkD~䕖6(R8aޕ'$̀ʣ B#193 vw2TrL M9o.83W8MG4M1/69bsPjt^(@bf8w"fF>VCncx"5ݤ+˴Cb)s%%  (D]⬔}{}~m9 ADUS۹'0wbras" T\Ra,?fvDᜬ0)y$YG8 IJ_<'.ᓿpw^-4($w6CJ#LEUDJh#WOƝ/_!*0ww;/|/ݻ#^x/;^u[[Z8x{EGm[^Α-}g9\F#O]^;Q٠QbFRv"Iϊ2Cs''V1Sa8T<FD&&:f_VXTK"%LRNՐ:[ g2eI$_P ;π4>fa2\-y'Ū-I>07 hxOb}L&B"},dFLp8qș9 Q#;sZyX!q ]iTd3rҘαH)jƀa>oeTNj)|֐ӏ泇/lmPu ,-fInQI(6: zj{ˬp^5TIVRvR{[=5!{!مwm wIfmo\ͻQ;%rh`6z$q Q,n <\UKy??*&_~iVٌ]x>s.L (fݼX/>З;ڋ̕$,d|']/]:?>`¿n`k3QS|~Q n NdrAҦ3aUL2'FCVdELP*\,0H81xaQ,4 uu'N[A7%ab;5 aT*u9 \ ՜8Arraӵ):p AJ5ID-@^a{^OB)ia:rg 3dߒZٵ/A<` [}GFɘ- 9TIA*J,@rkL B"Gi>)L0 ma'F|i_׮_+PZ$ԥ =sWO(,;1Aߝ/Z \6[PZvj$+V|h.\.CgqSݮ;R8A#>܏R8+C gbAЎXDK)Vh{rO` =f7WzHS*F@qO\w[/ow:;L+EwH8浣Kz/|;=gX} ;t=OתQɔXpĉyN_RC6;S'dL"!+b$1vEpqQ"."86.oi薘qx`ihLigC"13&'%syeOEO {R4"B22ZOعjfb2U*cX~S3˨XZ)usc8jkHugsw3nBcEYcD!regr$ o"jwbRQe k"̬U_U^;0M׍"KLNT=Ӷ~iICۜŜDR Ols}7ҚI $BJ *e;e_OINڛ_?c=wcjw(e^{ @ \ )ʛIfLbN6p'ɭQZ5G"C)c+#;5_޸>~_=^Y/O|쓇~hmyvW/y|lF#DܕW{gwG9G:{.e8g%`Vt Q*u Q[g {Z԰Pp@J%Ki}U;tz@bjfYӤ64A*^@qHxNvg^ S6pQVsSd,{)Ce8߅Nj.a.M؜yYSQ u@ىaR|<鑨#}ELXz-lX MC$L}L{sњ.5/V*F;<%ԙ"<HTX*I?9Q xHYKӌ`*U"anŤ'-M5֜ +8osu?"X [P< WVJƍٮY6hz8C#c٣"Q(q;Ei6o0zasG&lLn^y*&6O^0u4M̆xa rԴ vh`wwG݇__u䣹ر;+ˆG٬]̭oͯ-_y/j/\O~/mBP\wl>N^$gt[%R8x|nLW֏_YWiCOLx[57faeD8^dep%D>*U'mK)i17r gPL F@P6"M1UHGbl}hsFkܸ 4nzjo: G7 s8Sݏt= X*nw;DQ)+R@̤uUƨѦSSkP#~ lQ5ߖ-M{xb @42(lZAT#æ &T!!_3Kf$N$)L)AU#QSU8baTLeAE!)1t?p zQRXjVBYG=S՝ ݉HED%LXs8HEIWp2Ȩ⪂i},'p>:{I!$$=DWfn%W! vؙ4wrR)qڐܴ_59h&C}'%;/pГl[Rs[U, p)%p* ais$dfZG8 T~ؓg̶|r;q8:\o;bO'gȗ._}[׎>H#}{/#/}qK@BgޣHta.ƫs/H˪Sٶ=m'WKRC2S,) tJ],к 5bRBD;JgJͱx@0d* eqgĵB!w*E.RUQ;VU$Qq8JU-E"U$$J\,<1AwMZ{fKs˂]8d>O#4÷;xZNj&rvh"MPT^uyG$w T$2Ň'.V toG 洳 ?6{Htٙ-}_' :n)Xsm7cZJhurςN;锄86@HdJB?ud-ТI$G-.Z'|A`-&Z.U%BKhwE+D BȌ#Z (FJe<#M{"0UϕW©r.M`KNZ$}0֍###2 ]Xzim]>^*p l9u%uo~@؊[+<%T*;le:-P!*[gAB{P:,`vfָ//B`ՔXr)Fʍf<(s҈t#ŔCŏh*Ӡ&|F"J]+1'U->"cv$yf.H*"=^3RTr4@qKGJ-)ۅp7X+KDכۣp>;wN|ܼg@:G?}w]ZN9/&>M0@8I枓D8_Ʃ YPX&ކL+ ̉cV2.=XI`(2½r$R(B0ۉ56h1Hʪ2yqֈmަnaE(XPPYƨkb(Nf(N>!3Alb!kR$qec_BSWQ&LbAM'e ~@$dfͽLa$eʉ:լP2w̫^]+C&6CxULR`{lV0L;&oūG|A-Rxz#KDѡ)vȵhA.7˒"&`@s$IJNu6 TXL?Q[GQ 3><"&ʅGH"mjd(ft1:4ѰI*S*g"܋ DbD9ưĞT N0w,N@Q1/8" oieF~ä{N?wp_ʽi͇ã0V;#w]/v>+zyQ ԏew-=pF4VYhKtG l|¶SN-$iq4B :PW8Rk~Uegu$HHWB]M%ͻ&&He_n9y'^ddAH8A^s&/L)&-&+!ȉVTD6g'ip4xH1<%y!v" Hd~ýBr;ft;-RI3U`Cb:,kJCٍB̤mf9tkj b`8f&N6 i2w 1yq(1hQUJ*9qNKP\sN%Hۙ/Є()'bNK -59CarvP`=F28cCnRM\&D&6h֖h DM0o>(BGsɹ dL=ƲOωLu[4\sU`$/,q!v2Py3.*fq H[#y}uki"?<:d pΝz||R7e4vp}:wݾrC7r18֟}rE> iD|8++mcfF\`P:ߑp*: t,wuʃp*ɞ[e8HpmO3csi IDATm;PF0:JhfJ˘G 3%*ՌԨ+K!*;p%Lm XW&DX#>68ٱ-p]? *(z#e`v!Ҭ)`bI=M'0pnmI͉_'ƭ¤ZL=ճhBS[tϴ^`qkY+RcwK^)@VDf.[O0)ʊe30&}]5#Me mg:9[fow\QHKSJe4u\"$u7"fS"3 k!NfĬb6H!r˨p[ea>v}F LDr;;;D9:˾KeTu|pc.evAT_|?>{ d^Rh9j/n4a.iMt2N9N<'_=1Huڪp Lwފ:x*v:$,^I ('M&ՒR,$K9+0(E[!Flxu\j A"S4U)0@⒨8_Ɇ<LH1W @E76=jFX< өi[N,V%"DF9pu/B4/1gɪ\ rC$ GpfۦgcH^3325s*q,n2mS)\wy 4mtBK^8uj,u. K*_{ufI8do|}?>Q_c;`..@߳rߓ.v`hb./YhPej5r4+\S)JQBvVJlVpcG%`^y!U!$ŕ1Opucr%^J;^T:9s}:ל[&fg! jB;X :T)O">ɛF/I+Ԛ.:y 9`N%mDS>Wj:<$<>X"0t9U8'.D9/1Q |P7-y2.o[kP_~  ~pF,[!oV ֞! ⓱pHOPS|AOVxXBIJ`Sdbr J@mOAҲe>nj,a0"иJ518Xa'Cy2Q ƱH2;'Iņ#<\{P<&e>`Y`eX +e& bS1ltwW.JDǁ:@hlcG2]8(~hs|XŌUIH \P~^.I3ߧD(-Bi+C xR1ni-N2(fl6cl@KXRݝNUqHꥀY.e`!YGFdIe3 8 &Ћn 0#q>zg1g)(t:u-/粀)Djʌ,VJ{EݚTJ%NUX^syD*W7,f{UG~q,@,M[."C݉{>gɻhPr# BQ"w^+DXZN|Y+js M30lK*5Y~MOJAUL }25>QU],~JS3MUQbfU5T4I,H -,*$D xHainaž g 81=3Z:DMicAy;A~r y3WDU `nSZҫg/7zG|!2Xd.eIǼ!x\ڳ+o~*FKBfv"'.Li,&%S@T(NU?귿_.=;Y͍(Ub>ؕG) rt݋7k&],}::XioDI)9w㵊px琙4˰#l,X6,*l }5ЋU0^5g.BpEԤcLNӢXUC4 XuĔrU&R'I\ ;cM`2v8B.D {DnVɘHE(!}B?[̰<GWπKE_ pvK@jZlmh/e P(3OTj;1"ЎڡgE7n[2Oj Lء.+$8뎄V!Jb/~/o8-J5y퉫ď<7M](E/K_r|7]]]b22G3K¿#>?+"e֤BiAǬݭ[vyuѥK«’$vXDj<$芭mtN-YiyW3O_xt |>qXfeWr2#ډ)$+CXU Y6k7m@bΑ_-D*K6n䵟: 8oۗ9yrcY,x |K~bƛw}o؛|ڻ/$/?g^?cॷytݥ[~_G7O| T̻[אnwgحԭ,wүq;더ãMqWs/*M[owXN~?X"B)4!"$%n8^rGm]B.#wOxfϲYk%}}-gS(%y1x@̬TXqDp(ߦmkPkwê.=")lSP2" "O\as/qiauH 9ǑeR PշL5at]oCnoħ 1N;!m_^mYn2'WA,5\/d[Y. e5ܣhd{NKJ)ɧ˩.)u"U: ,MEz)1Zs*Y%"3!dj>ێ`f,yqU-1u7w"] qJ V 5#8IJu}o{+yI_שhw>S02D$;_|c?_:՛G3aA %ȱ LT)#RyQ0ESmqajΤNF<>ຜ6lɱim(<L)6wE"-Ow Bjm:9U1bgE__TfwbJ}gm 6TyXRr m =В&z}*BϱNIteU@=O3*c=aӮRukgT[zgr'֤n]nZ!5MŒKȦ@x&U2Ua7RVI=O8O8bKU\\-j['&Gu0\`1/|7ߺ?o)fstXK2}S'nbv֫/;?OE z^RRJ˯&({^LȖh;fq$mװE nnBAs\[=iOd <Q6Bv:zʉNhrr3j7앪&w\V7>+ćn^oŇXonn%wƭoP9vy$`B!)D>#?JJ]gB7>s+=H8.R{{8\}"^zFwxiFq<߹vc>¢%f 9uDˆTA'sNYk|<I0j&O@@>#ZɁҢcC" [N. 6q=0p[hk65Cl7E4g4WfHY"P\ n #9Z+1eQak6aqj_4)}Qؚ-K5:0K!eQ B? vV;`q )&iAPx_=LY ʔ Pn^L[3ِNaJD$&8TZ4BЛx|NY9h%8f,-ZjeO\-!iQp:7DI h✩~Ϥ`\Mc")>w执{.<#?yxx CbEu8˫oS`9[qݓԥΒR=wɧ܆~desy套"Lm,;X\^G7oy7~ƍ[/(uCSy[՟_D'751r/k5$Uҧ581abl9RPvOUH!_-$INn Ȣ1MfD'4-t:G>ƺ2/Kuhj+wԭij]&пcSx9r*D@l$ HQE(,ցlߵh @&HtiUFDϸ=& 7PU1'{b"g2 9FS rjF4W:(5g@TMkLIs Xf+2B]!y{mxM֬xE,} % ,vH3NX3_4۷u@D){Rwɫ_}څէ|Gi<*̗/_nw`^y٨IފpܥU>pl43>kD w]ulvV;;{n$1z} ]X_|Ӯv.t{Wyw30dgε_W;#_>x׮ю/xNұKY%~8,Q塞~4IGʁ=Db f)D(]YɹIs1 XPo`4n6E>dIliXL(v`Fn66T@HL+UN+8{UVQ!b+KN hh\M[z1O^:FZdPҹo: 4VN7OϠu`2C&,J`U fn Wuvi3uݯJ`R^&F'oP?O4:7F<`Z' >׮K IDAT>+xKoV_h䄣{ZӜ-JUTTmaDJ\S\#zuNQ[S-b Xc0QeIh,w/wNC^/юӘ;]@k7 w+/ %Iλ΅}2Z2et;/fV*xF_U\_{ 5car 7 V:nFUΪz#Ǜo_z;{ܻ]2{otlaF׮6{ѝ+dVwvزrͫϩ0 F *g ӄG\ djASx D;׶L-J"3ɠ"Be)Xa5%J'>Up}r^7IԭpLG`O’h7؈b4 $},5!52mqF^%^k Fj݃R@1DX'A4@3م/RA `Ѳ[cg9n6D,K?ޕ'ɲģ`läeVf}xh;@AΑ΍ᐭp {!" F]+.-珳 &F[m9Š!drMi4ץk-pjf)5hmHsx$T*a-T2\KIwL.Y(Cw/wͽqodDFFdo]Ui. !P !W;B ^4R *UUnNgF:&9{59Zsݜs#Ӧ8 eވ{>{5לc|kFSSCxx_6csbΒo3m'9W\I.\ƫ(9))؉E N9!"W$Yh d @S&ƷeY+?y`;PA,rj leV%+ʤ4(`I fI(#Dj5+O)#"Ry9DyIppVṷ펍mڙǜWV5.Nwy{',ʐ'^qG暘tp(`^eh J&]w86l4Vl :)SفUeQtxMA|1M/h9rf.Kw"*6ce66FV%jN`dD %3聽ڕD߃zDe4oO}Gpuquuy3{9Y\.xtg~0 K6GS!=,Q#j=:Jv, Byf\ɴ<d7?xngV>{28W 5-:=c氎T̫ s[y5!{PGaL o4PHso0f99't:?\m毾WO~yq)k{4a9Kr~5à~py}xsty[oxPV̪`l. iISb1r Nd]\6>NtfvD!HBw0+[QRԣn>dY_n615GFq"8` nB0H co^ܯ*JJ qsTI0sWᘈ(8ekV:y p1@ɦq$ T1ԲlCo ͬcR;0_[)nSO/(,Z.8n!v0sv[ߓ`6ϑ(d0Z&W鷰rWAG3zP6 ͚Mkh*hZkN~\լ,`a] 'ϊ <,7cb@O"JEtL `Μ}jދz8[̕5ɍ | MVAS ̸U+Ueh9 u|po;9"<jB&W ~s舶qqnQdF03z~JN`=y} ?j!pJe^6כ띺p ۀ5\k Fw~+_g?; g~dHȺ_uw[˯ыaG?E!׫ Gf$D@~ٕK7S^|?(hFYRП\ofƏA99N+z\F䟶R[rs%.< <3. hA}v"ҪZq:O(e}$cOmٌ='Õ=0Y!bånkŗ HBx: Z˶<ȹ5nTPmxQ"*5zaRtH iGUX 34 |H! lNJN7Ĝ2/BȂ053ϩ3kALEo5ZwCppTT]D-_3-/tYA֤xɍeIDȃ!{JR(uw ^\&+0!@qY(7dTn ;LQn6D͵P#9K%.A}Ft^!ϩ-qa>U/IeՅOQypз# RÜG^rP9 8O (}λ?Z/p0K~UCu2U"үM7c]5 :9Ŕ2\>Wn~o>:?'^8}2~?o}x;'i[.VWk?Li ґ0tPW1Bm c$?dmɖ]6q2ѤLeD *@x;F1YdJ#3*țf > E#K6[ ?e>ɽb\b2Hѱq)!Q_ GUsO暗^e!nghuh Y,c}jnpKv YkL4rb~6K1D#]265`f+1ilzf$y}77`"AtL^<8s9ø2>\'EY *b|s Zk'Ol4&$P}:(>U4Y\Zf!qa+_~: :@B/啑C^_)$ K6GE3wB[BJ)Bhr yJ⮦o}^\{曟ARmrsc*.EM_pk}[хt|{wfuMOH'sV]MLSCu?6w9H4 æS@2HLt'QcaҁrFyԫaU&Sw5 /쎩f%@ Ǥ82h,/geD;LɈ? u_5/yJfc3*r3dthZ:5W11 gͧ]E1ZNi,_.?l0㠤$e$):Q*(?b.%AyVGu5J36lD/`_3y< )\%dzp<m)EZ'J(M+-k &yU[>b/}(d f M?nQhwD̦DagƫͣO=xY[[Av]0'wUApWA\ C̆ qȷ&jv658 3FA aHW[?;_p-}O=|veʜ{0~d`̡ZibG4-f/56ЛKrG,, TDA8v. r!5cՉXmlfV990fH0whnS P+hscWkETa͊r!53̔M32l8 s8_s,ARaq_̅]#e. W'Wy7TYɝJ9.g*apSw.U-iΌz1Ă*`)͜L-oCfyX&Q0@m FVeZ>"Y40yΉE]%nnVȟw.+Z,Zg%ݟN' 7 %9s(h Kn&D~Go<"=psIЍd fE"]%\=zlFdctSO$S9@G49t;Nʠحםm"<;??>N7{Ƹ: ",F{굯D=۳gOb6]ؠ~+ 3s_ 6珵#֤bG>>F b Jv4f"d/bd#2Π 1&m|@Kʡ:@"p+)V+ 1# pv+>::.CSϬ `L 5jhiY@z/ku 9#Z|^^Mz;J)\+侍?}ӛf4 ĠTDiP5q~/"2@fՁ.!<%%MD8H N㐒o/ϾyH(Hg@͊Ð/Ĥ_ş6u~sskگVf ɓm޺к,Qak 7=6CO-5ZH Phx&-a2b;gƚ;(c͛H6D0u?;FB五MY5KT\ ݒ\&0D`yF-2@WZq4x[4ToOPm/&ָ9aZiF΅~'#,^sV!ɕ3ݬBgQrSZ\oB߄9z$SSJefmU{Q`A{SjTh5"-ڔAϛRnEVn?^҇(հZSBȿ+_a3wsphJ,%_{BxH1Yg&5&]q 0$'JnVre7Q~,1wjӫWWo`.Adš'&u.un4wvfGED!8%k|~\Tt2!v"ճG2!Ɉh( 8AʐiXf?T cJJSC F*)mRIZ&G6Kc#yZx[3D&f8yl__lÐnn5IݶOj$NܸԒ]ؘ]0ѪKs0\YLX5S/'vw0s^ #S{,jk5α;\ˆ3'>YMGe1I\XF" gP89l2*Y*uh; LgY]E 5~0cf%'7B GAN*?nCdSfNte9CS%]V+[f881yC&9;E TC(tp,i`8z) gϴ^㯫n Mo.`ĝs(Y8@Ҍmvbt}3jPW~b7$\ן tOI.7.Pߓ9|9QR}3}ɱK~:1{" OGؚ.%3sXY h5 ɲʉK;͡f9g3s.+> $k:ୗ IDAT`dy(-Dީ-`9ln㼿.99J-} 9 3ĶX3V} Ux>#@rP>uyov0o3??_㷝,ar`XE`ޱ8Ȕba VQ&gHpP`Q37$Ns#^UE,` Y`B!aP0 ^Pmwڍnuļu_}nI-#u:rzCˤ8䏗 i,zNΆŒcv6d4r[ SwgX1)ʧvYs*15ND0}CCrV7҄:\_\|#5Gs3@$jqRwɒ9@,Weupf_ !׽Z s)Uwe)%"Bbt(=!Vg^)"yvf{F"j zo>wm.6p&L`6e#Df|QM=ݑY͋W XSI-\Y۠<]I`suϡNI^y2`c[>5X5XwfB$\Cq=*9qFUZq7_хF9)s3(U4~ w]*V:A,+|LTY\ !LΫgfNn8lkkr %>|&4c#r׌CUb :9xcAI_ܱ*x z{jm/IdF"yf6z^:Tar#sxsWcO/IIAٌAxq f꘾/|USRK0;fK,"qlS̼ d|1YYnt#x'ScF~Y}(aUzܹbgg ;R2>^̧[c ߙO?;f6@Vv^@]a p!Y[yt +{b+fg"͞Jj,k'ym".6j38+e%8!9Rp-,ۗnu=giynEhtQ_A4$5rs&Ǐ~2cw?g{Zkl'?qpߝqT&N; cl`Az;KNq|_osZY ӤxyU6/KbNF=uѯ&#0Bᛋޑj"t]Ed +_@ !{dc ҉ZTD]XxAZ ["#b5M9cp LtJIdjwDdCR'c&m{czHD-&M$D@&/WMN>)Tn;}Lfޣ 8Nī ]jؘ7fh UU@ L^Op 9{ĸ9jay[-ӭ)KMq +6'Z,w)j>zAP;dқK!~qlrAem⯬u)~{#(ޤf>YR$-S4M0d7D6R4VS8mb@FI,dzPuEU`^b (0gى@BoֽuBJĕ4*SGl$D)墾c^,LʁAj\Yͥ܌yo,AX439 ǔ^I̙+T8ۺOThB/ V~%9Y0%xAg1FH6ʙD:fBK PKem@jڕ ɂj!Bvwp)P9ݠ1F8} 0~{j_#'D"lȾ׾ٯ=)y8ۈ>B=/ɜM&D~^r,dfh3iҝ &F*ӚGҝY\B'+A! B cŻIH$R‡f0')4_c\c 'jR KU$%cOIGmYöc]wg,#9-1Kg09jGc2XỲ:iu"7 2>ឰQja}/T=4;rbRvx$n£!&F/obpuu Lةw A:*p:F1KfHfQv)%bL 7t9d1F  $ 9EvH3zno$̳~ + fC~%q/n"Xr=6y|azW.g->;50Qݚ܂D 71CYՠl} @I@]k"qZ2 cڋЊ@Bz/YiMxMJ6H zyv un7d"I׿fGٰdas3!}3{^btbnd't(JP.3kIoOF9eYoqhD z 0H\:SrYmt)"X&X ]~RLYFv8q%0P>qЍ=pAw!'tFwyXޛ53_쨍h l9edԬ<<´35ui;@{ <}tg:x|,?nK6Ty$JĮY$1ں)Zl6 Au R_m;wf뺵jt#;zX#=ۮj @5:AE:;,'F; ;s0uoo?Ntg $2:"4OAVq!I)}[ [ApMLnnٓ7&}X»ܩLқxp|o|;?}c] &Uyozwwy㝕"伣 )pva^1 9i1 cbT4U{SO98R`㛌%35eѺʍ85 (!JɃ!CzGkgE4 ڗŝF=vz7$EjRb?; b9cxrW}FyG]ꦘJn&Q43,ZLfCq*OC'oD6yY r/S B3fGn?yOLMu9DfsyȻ8h)FzoS Xs0A4]f?_F1޽~ylp^.dހU֒N3Sd?1{8BT<:RGg0BQcR皬NM]C,E xՐ[ $b?Q·}J1ZaϙSA < hw-fdɟc~;?.|[,s/uS{ -(1p:q;7= Mӈa“XMLm\Y p Ffw 8$U935v#0Kv{Юv}33.@ܘDXkrJB l9ZH8$K 3d^:l>} ]w {bBO`d9t{%ff鋭#fi=KC"C'po6=\햺o_ q;'Ui.}ӎѽ<0"`m\; $!1Nv62j& biOn()`.aҊC⬟b,.2:w5$f5S ,`cyGމO@>3HP<Z,mP:5m_>vH3nƨ >^S\-UR˚A8 ($IBl;|!2'*A{͋@[zka/w;h;36D0lu⍙ĤLIz^_zՇԯ[vaHIj"a7Ddxc)sȀ8IPofeE :v''o\_]ן?W>:';f><`>5ق\3 oe5'vѺ`fRc<÷0] ?"8=|8jhN;i75_-(~yʞx;>jFoFw3}{Kzюk-bMl {>YtOp/p6in-oӈrfĬj͎9g}>Gz5O5h$w>{o^SW-Z y41.V:U% g7~>7^]ԗ^ ӭSLz2im~ݱΤvkNf t,ODֱ%oo9.}x|1jp?ƯE}9ڏߟE!}k4Czj>PX~V^Ӯ9lyGwSȇvh]GN݉(K$grs[Zaa터Z uLnji2 7KDHp\l.=}qbw5Y^uK7QYbeuuIfVUw:]~w?}LX91aj1ƫ+J1vb|կw !OQ'S"K փBr UqnLep4#Djð6{pSX 8aMgr ?4 ǹ8|ē[tGrƤ,%Uu3 w"Ë8ն {ԩ9g6G;δ9A.K ]~8Zx_"gvNgԭp =+NB3ۨm@i,杷3_V]OR@b$%_]֗9&Ƹc(ъ6V~QsVY}쨗ay;ڷ^q91pH% 5|6qAԙZe]_3(7VJ(7SroYv; jfNÕ|標.[ş:!{xvK u`x|/ZSxAcE݁uTv]uUP L3 >*H,T5bH&}ȂF$"KPM- &&gf 5t_E ;čv 7!/H^毗Z /#pCquGFǕ|W:<3cy;^Cq|_pƉ7v\i{=KeW%J|!߸l:N~'(&{ׯuw3'}eG*WX "ŠE0wx!Ռ|0pR39iu($] iA,QoFd]NUGMDi.7- y ꜃wdasCݝQ1_sK\=<\66Jk'I琹M_^6>qQ0<4*jzm,ǧDRuǞMYy;c8$8p68GK-f1io{d'k1eh.zr? :?Nn)14nfuCL692dz&S9s6dMTaA))spTSR {"_:Q[4qi2UipOWחu݃ךxaЎQ<_K9]KʥۏeAFPSHK܂?b$?8bkm?z m ,%=RG@Ȏ{L(Fph$Iɑ8XజmIxպ'K8]MaGU+`T&[h߰Xm4eV͵ffdxӿhx (x^,{3}%t@$]Efc<4b?jQ;y 0Lꘂ 5] n;lِçК&iX Vh Ov#Bvy;"'S~/gpG=XX`Wq2e XBPU/_iDu-Rڑ򼘙9doR3K(wCr|~w:x*KpwA:fWkwǽRt}}H noo7+'brUsWAa:qNG+H.o]~Ku05,v~W.l6i'f!ݞ_uHѻ0&7'Ü+8S^RR3'3;:͍=-PG83Nr'?2ގM0Py]. &ZA.BJ]KbE,;V离n l”RrfRsaHa]ѕO)S8 QD[oê=}a QS25RD`/V ns3MZ&ԫOҮl#ΓgٚHZ(iP4N*\#YxF u%5 .2BIP8mW9 /&m&xJ0jOR^</S Ef}RT7wKZ֠95<& ns#*,H`fl`aֿi~ܷ 'em*4q%B3m90FL[uK 4}{A{wt#vSaGeui:}w nh!'\WOR"?:u-Pt!ѻ[N35j% fJm`hiX~CΩarNDE R7"&,B*AĬ=0wAD)mJD,\+ z){D>Uy BN77KQj8;m ;vO'ΦmW%LvOGIs>SRRى['[;8[_YJn=($}TN A1l]ހt$]Pk pݚyj[? b/~B LPyFIL@ ]=V]H,r*뚙EƗslp ۄ⒪}t.ԳjVM˙A*ªf&"sfy6\W?Ovה DHy]Wk2wwYJIU%E @ :uWgү@Iuެ2/d5m29,QD܋4 mdZq`?]Y㝸L4-6%480*sAƸ}Guoڎ]U7"\w2[r,s@x:awoA&>G ǰ۞cvB~$DRc 0vr3Z֜ل{) $B~?Ϥ\Z5&NBn$9DdjEfjr緾W[exD1 _,WG)!TurwYVEO>YjD:1훘 =UZp֠~<|/p0b~wUUȜɹ2IMڟͧ>Ƹc\v=;,6/q>zlFZN_t }gN~=ݘ~:x5 c+c-v>yP[Wq>9Z:S}֕"F<gyS\"L$`~\w/=W҈'@̈ Jmxjr/ HhDLSȎ'AE_G痗KcMZQSőU7ɉ݉gw={^.. R,ZB4LFNJ&(n[T~hS{MyC$l)r2ꠟ2x]TO [4n#xʎ=U8'*`3 a_K %Lf>f):Nnyg;1wW",E>5~9csy$GQ~v38$ӱ\s~1 DMөI܇v9Q`vu"[(?(U`|_[K AXXnScDASJ}!Ĕ; r8==4 MHT+` sÇsWWWϞ~,N~ECwU. gg,69-ϟ-+U԰.5t+}&R%|s򓳴ù9zjm`d]؝sVs@]{};t;&ٌ -CGcd[k]hd ӱ">bu7+:lw8a4jyU &[oLZt~`a 0|z4o3:'rt>j9#Sns;j]K?[4SIfB]EQhkV$ˇo3jprL9'F`0nk$hT9b4Y)Qمo%8ރtڀFLU$,n+0\Ջ>YE!W>@gъgxܔ[̹tmKS+9 '(#'ܸ%KP)͜_)ud%نwX[Iov ch ߜ$̽uxH0 գL-Q[q}.k@ai>kXH*HUg(Eεj@)b1J TP dd$ rEƚK,Uju)\B:cNf . "Tfysw=zjdՕJkB`٬Z)ypc(o 䟏Ai q:GQӠ4?ӎՊ/uJpuD$\pqk t#<01H 3 ^(>+vqڞ~؝]> G`tQZKbo :xMcq9xcpN+Y`-0"+HBrv骁fNcBd wgSphSV<%q(REMA(rRtgI$-ZɜIs6c;%"-d"@^4ClZ:F4μ5jou~{`')؆֯켮&89`pemS}zHgmgxM?=9Yc`Z @]pm-dw'ӾT8dǩ|sf3BzdhnpG(]?3Af>8GF =5 &|C{;;'Z/^; Z Ʉe0f#ڿD {g2S9<#s7nLCko ,e a'7l(/rGJ9,jTCuPZ(`".x\oEQ1$Tpd ^D\zGogǒՌsU6g:XU^RW04B9>`,`Gϗa &\zrɧUOqz [Ì~[|tl@_w,w#=窧Z%]^Ӳ(T1ۜEptY/cId4t~=8D'W3Ҏ1@EҽS񫏞&%N PwkTለ9, QPu(!wjʭbqd{K!ʳH AR܉ k` N(7ĂzE,}&1^{P  'g7͛E=XĴ|.^3o 7iՉ zFfWy=cǹ*nBGwN8MM .X$.q:-6]̉O0N`8fXo)|l~P1խۍo~v%2}vjpg<=yvNz_+&XM=BMn\Cӧ˗?|_ _O`i6"E jmYA!ifSɀF<Dzj*!RQQg 1)nu=!ݑ_Wի1K7eȹzfC8;ˇ1ŭW+'- HBtJ|G 9bMW*uUkh󉹃})Գ1G-#p|OL!F}La=%Z){[P]moF;Ѝ4N.ี^Y vB8ǏNmEq&;9fP~UC"00!8e.Ț ZWGt>3 *ƌg2u΢]扈ms|&SOdJm6F [S2?;ޝ:?7گMA$`@r{" đhl@H))sd0r55S f Fi`!w.SaAs^]32`܄ݽ;/vnȃ~*wxu}M\VWE28wГpQvw`*R@s}P}S=Օ1Mo^ӽ6ѼD=|4 nBNhJ"}>߽Lsѯ|Qی9$6'#?P62vw^.k Qc 0ΤTک|@zwwԩ$ijegÓ?3kM)O=\_\U?Ͽ,J6]bfDB ! J$FlZ2WʼᔼL(Pq92(TUBX*q H~!}Nݰufפka)x5YMX#WF-=wPJ'Twd4qm#Soɭ{E+}-I~[D@5A}׺ӹ!F4z,8m|&8A}Pegͧ< iW wsn-+Kh>"O~ΣŃ~?EO{ß?;G='xw(VUYmK08B\)p$9ՋyUε[h 8uwnnVPҚby\yGy ٭O5dPО IDATFHNA~xhKݗO {EIV 5&`^ۉ8ͪёz[wߠh^cqGM6f+aKMvu/; 瘻C? 6~e~{|lpڅշ齷7]YqjNscP$;1}F8D XaqV {3UY@Zm|՟~ +ݝ_zǿg~e Ur%p,s"*J\e3a$0;Yɦf!H],΂dfCT&ZFnEQV-ʳ˪Q15gq!R 5ꥰf͔ܘvRxPt'~8o٪Ri|㎉Q">:Jڋ؛N^=0Cm@FK݂~z0n{O?3-X.hmV`7~V2]-.4ҏm}ԍGi:^;,bgnMhݝ:6FN @"w30(xJ3mq!BD+?ůWL橃8Kq|Y,'Tog3Ui9 dbwVc@TLQd̙BS$k Rỏ-Z@U]]^ދERRsI]gͩbL 2Ж%np۷.7Dbn_-"3)lVfãᛄ/nON]aW!2'ļg4/ [\)vG#'^WfF~$X91H>cHDۼl8-:_kpx`MOQkY;B g|j*2:z7n  ~͆I怙݌fibW?,&K"lѲhEޯ|_ NC|2K{ׁ7]p'{`B/wz 7bpnKNڗ1t>Nm;9C(*d8YuoQޝ{>`YnEh;u aa N nIsL2-Bb&(Dc{q'y葚&"5Afя _RQޅ~7ߩ>i{o{ZD7RU幪7eJU6lDfJzE,e$CpwK1KXW/o}R̈́ q7VA@}vvBɉ _E . B* tG~oimpgH\km0͠Qb)E*$gGEئ[~;6̇|戹BƖ"OSWUq8it@ sJM 'Ϟ- ԊP+SchC-t7lmݐva[Qp#ًf}+lFxێ0kꛉsG/]yޙK\x vOd*ig)ۥ#M B;?ίZbb>~}-Eb!lO?-oDl8J?",5)E m D.E(X4 >FR,CW@D4fI&mtOuDw޹sclnt5 V_39+mQ1KKUfܼ];%r1!y1XxZ6?Щ77w1@=w[ q1?f1ļ;#r&N4_g'=IL'i߉ټ[1-e氼ml͵Vj4&&cxwݯ*.Wo~x ?\>{sԉ}7׫c 5؋"JC(A3%Ih,Q,K"RjS59٦B"'3Iu 2-: ]=*PqR\ՖW+43RM]gL!1txs8O&,6^؉;Ɯ\(јA~07X1|?I=P~it(xtB\ `t0ЦN %bwKcC۞aރ<'[WnB Mj^Zg_3?~ޝ/y}wuGRz5$GGi~oDZl/9@\ Z\i2n)#༽K. as Ɗ)CJ]Br̘ȮLs}Nvž4#,ް'4r7{k^FvZB줰JTYtAQWp_TPZ>}ч<[|?Ǿ+W?zmc/|EYW=T\R &6uY^ SC%jqhQ1g.\=0[HNiT(ɏ/@.OųzO_>(&}٫\,y ouѳ'-㜵a$,`"1t:u,9YsRy&+#zS*U"uJz\™bٽ'_&W/*Q!(Q i M"wzwzIbt]ra<8<[ܒNy$"IoF! _''/UB ~OYp "#8qz,2k $J`||Wf,|oO |~u}m^^]>x_q//~{O : *2i%! @! ^q33S,17uZJIȔlbreiSSJWWŶ9Pg>Lנ+WɦU˳E(21ȱyuk=x]la4hC,Mvho7at~6$o5f|1% $1 `b+|C $g@􇏯>yqRofy哟~_~MRw<|jyu2m֖=ҹ8Jx_.רLA񋩊4,8KyJ.N\ -"H$,H̉H!f <~?T rs 2)q|h4]A֌޽{ِM7UӮvmOhj&ݙrɀϛ3Fora68p'}~i x߰/}:.h"߽"꾂М $n0s q7GG"gS`vÓ>=/Pܩ`q,ߩ .cqy (2Yja'2$N~;_1f^Ͽݛ?G r-1'#ݼK{_rQ,2ŲldɺqZgAdv2"VQ$f)Ni*F@ ze`׫d.c?y~}Ljnn#jt\};̤≪3Ul<dYܵV/+@ur<`Q{ia"Vfwdxz4ɶ{Kn?ɻrgȮ]hpUj6{04D ޓžZo#F ~Bm9ͦ{Q UB'ێo|}6,}cQ~w1a̰XTdA84Y{M8NcҀz..Ν ߄nĄ?T|nn"F LاC nJXYKO>F]3'}Z.ɧ1!PO`_9[\,pBS 1x컮 !\9ej]0HciSj#sԛ4r!\,B*%f9?{W77u]{2_JgNxwf,DXC]x+s%'ka^/;JK-Á{!00P7]kHjNv˿-i^׮x[v!]xcǡvCakڔ~t= Dwu6ϛ >Е sʾSPwܲ;qOLeo<[-A6P<:eСWrfMVe:\/)޻Qx]b9߹KL8;[HWWG gE44p>ȪVe\;& @j9MC(_.SBDs(WK5 ) u;??W4zɠB2]V |C'U,m\g͛63 @6&#T } MN^ؙWS4uS76fGGͮ'cz}6b@hH h)A)gIzA6ٟux>= R_sRHu'X jTW*mAvF5r09)T]OOqk(ܾA[ \ L5FlҼwB^IJ0&Yl~7z΀Z\YDEr^/bi枪Jf"u]*`cZ,;3x^UE$src!֕0j8%-bQիwn,/봶G]-h~sASÆ~9tDZBQEN33[珕cvc:F/[;i>Z4r'xIjqzĝf:HNOC})sΌatѼN?e;ez<VOu~>izwfr ъǜlLؕ077Ȋ !Z  ;Sh-R&"KJ>|@r֨ 1yͺ(c 'r*=9ó[QwW2`Lp,ifTWEYj(eD1.A,:n+222s/=)^-7<Ю A M65!uD~qQM7•(o;o_p吃վEs["h^\:~e@ Orxۺ--߁ j}u;/#2oɏ CޛФfµ }%}z3W'l{$d݆t $ Yj-50c]Uwct4ט~ZisSդoDGAw͆N_0SFprf 3 ɒ,!$3"a)כe\$kNUE W"UN= %kr7 ,TY F EQX$jU=[J9='bxrvSW/b*UiS bq|rV^L/È$VBbV TfI% Ig:S]j[ 4\Y/A}P3 twܘA &Kq"9Zby s6j|ldb~}ɥ I[y'q{~p>+f"?‰~M阾yD%11O bBSXD5S)QyVpD(J]$xʠL$LfxND,J\RrDHEĨ\rX Gl$LjdN"Aԍ\ɲk.R6'prc[6d.B Yuɤѕ+N+Pf񊮌mhJ#56O>\3H|zl8}Q|O[ӌΘ,o=t9z(xj2C j2b6'5WG2+sr:&'OЛ_;@=d\u;i-q{M::uNW~,j7Z@o*>ZfnL`Dn*wM`:`QJ)4"yQACdH3M!gn q3f!D&Ȳʔ635)cd ]$,X7‘`Ţ vr27%GZ)5ÙaF)|{9@V>qqM]./}|.#Z1(FZcP:m>M:Oġ!&v?v M }5>d"nL! IDAT%Mux[ikf]|[hi_tήcOt~HQ=N|M6"L!|:-8Nb:Qvʡ2 [hr4jnֱsW*;;޷B3UCoV>tH0yg)߿hIv}~gVІ AQ &M托W߻8:WU&g/:PAdJ`q 45eF,qAD9"HJ&&FjS`6Fl (5`^9QM, lވ7^--2pJ!=^\Fg|pnxr%5+-qg'X3kf0dڈNF|i(Fj%z`kOB(#P;oYT=4m!4z[b'CjA)sg{[2ߌvi-==EZ\ѣc%<wǯ{:w Z]UQ6Щ-Nd;޴N~ |V[& F'{?ȈѺ.Z?B;que)6Y8uDV88!2JL`/A Is94L e%c ;fBjAb.DͲi&u7ڬk7RUr'g:7fjͺ^+U.bQLz46qQz?zOzvj ]MYSJggg*n*z_޹\m/wˊL>>ZG1n62g}#bojCX=4qtw%~rg">qƅb_o6Jmbz c Rx9ɼOfd[nޕ9&"FL7ozsXoc F+[V:\[%5lAà)Yi@Jb'< A!u3c\sT̳6P`*l"]3\8DJ-ȴLFKpp/RaIk|=<\_IJP$rJu󞯗W n& Ldm> .&g89)S~}SJZWpf[RJ f2SAA!rXlhT JTŚdE]!ƥoeL@1g:hQ}m]ųhEV&^25:][yȣs5L)gnEBEEQʭ\ϋFfYm{!"͝'utqvܕf.Y]'#$MRpN~"W|yނ J7|y Č:-7@yIpfmüj[)*`[' } pg/_>9ٵrw }tzsmg6dQeN>I[M/lj.i./ ,,}^xߨoO= l.DDawv!34) W! eXy:j1-Ds( ̌B&1 aX[]ݸ˷<?\'MgZ!ԘSt\%DٝXk&l1iN0B`s[;h^gմY;<:i,`s2])ݩ<77eJD {`Y:ldVխ;ylM E eILӖdp֧?;vm)dG(d4D l47޹2q2Nfe֭ |{֐yZ{-lQa5*Ow>|t!¡ Xb.hh/هl f@*YT1eĪL̲,ʨ$X\SLs_,8ύ 7EqjD@ʲ̲l>;Fb14:|K<>-vΊ9y([g4ϳ !_yמɌm[/i٘K9>9'$4Gg3+<=>(>-\ t~Ft?[5\@oyK TN,{+juߴ ,Kd,h;7lAVT$˭Ą/2! =nՎ<$zfR*jIFjSC*T"37K?@qgUQ2DvX#fWGQ cTT*BzPTM̄zwo\Q>==;D2PevǰDUy4ǧ9Cj\H-I"`l37n.oћ[oGE* /|'?ݣ9\?s?c Iz&[g~MPo~emKv'bX/[?B~$ed?-f}.`P!#fkͺެF;0PTƋ/m 4leX%b3[?u/ḿ*Xnj;%#a/BL*ՏDm6V$j7u8i]|]dz+O 5!k%)r|E':JjRYunuSlu8)BiMU<ii:Ѽ67詙jz0ElN F]Y[o5R`}Ź I0>G 2c6,L%r%R@ R2导%rWH*R[)D/T%(1JEŌvj0E1;ϽSLʲB3&wk>PfVzr93T1#-0Db>;>~?N/}mg'v4N`\zc4thзY$X`Xai1dϔvmIϼ E%>ͥPYc…ѫT5#OmS] `__)\/\QOA z37`=(E}zCњGZ Z~QjH9tADE*Ab *#`Lm0! j00E0S dtlL,3 2Dt<|dfpZ y#s&:'W̘HG˲TFIeQ!ܑT%Th8 u\t8Pb9?>A;ɯ?Gg~g7|?~xPn6RRB-]LEl{ }F/eZPУ7@bA@߭vXlrFX= 7ۃ{eU"m ^'rye6K@ݛY gf&ֿX }SyRXjh{*Ld= aƯ|fs^-n3 q5wn )3UD@mrW;jV SM?F8HTS\5bKE˾Zٶu@IK&uց!1y"yD Q, (*,DeϪj ,%T3> !x#cYF P!,+Dd6|7?տ;gtg^ȝBUãǎ)8t7n77<==W/dj z>{Ͽoq?} KeJ5QU6c-ĻFޮ[>{Tt*/_)(X3{%LN7" m[@O$פLz-lKd{\Tk^ou+;l}oJ: | )YwAUmu1t*Ú^GC"&C8 LR^ܕd6h{7NZ)Id) > ByQ1ը:gA2 1*HJHDU*"!t0!s8yAU*tzQYVPe(22=SPUUY,}nYTl^af?zwku+7@;o}d]$S,ʉccu!kIDieڠ,X š$/J!ԚJCr:zuIN{3# 1m?%~ ڊk5moɩd(wl[;_f qt&{M>6EKͰo< BC=[,{U+ *$g4mYDfAK2xDLM͹,`FhpVLc}@= D)Üp OWdvl#vOP>?6}5 IDAT"Hc!vI$7BFkk"Y dJ S!XLl{w-}|V^^Z%ۦ ]^ >E|\2: n7;[lͶ̰Mv]:rz?}fb8H<4haH$q5z{pVmfzd\v"}'oҝ^+\N!3R22~`6wohΦ){1Piahf0 :f3"V5` KCD 2!XWUI} 5T|= F |-1cSDJ3#vNmADγaUIV`hiYU|ϘxGU9fvEQ,j}V%!I6f6`UB߻k3=1?TŒvv1tӍ& Dܼ5& SAm\mE.j c3)qοmXOPխRE@]mg۬˥u9 fjJ5I[pBڬ(ohߦXJyB.2!ATxjDP@,NDBmi ]H$,<;Aq>C j *`JD 6$g.ӳxy?ݝܽ(ʨ2U"^85+ehh+CC p8z~(sf蕗= °X,:.Ɓ!u%Nj\V2‰ cs7eG!8bPSb6PՠGb @;n1LN|fdLٱCR IA |7"o@@643E̱ RP@Ԍ0M-#` Rx?vLX5"YO~Kzlw$XHbFؠmvO֝sҩm.O1{fX&۔?|Ű]2ۘ{k뻰#!6ZƵo@T U6! @mıCjud=ݻ>pͦck ]>dbh$Gg# +l̈b 0 fUY[ !;߰z1abPbT j좍!0  "bZ  Dc9+9Y|Pȏc$>?3dI1jEF`HvJJ!(OᵳM#t^y fPW엖kQ[<JAr')puV*d*nf \۞< n1m΀{:[zVKc M OƵe_Ŭx/KB. C/g2ykFoosqw!ݭi*؋uoͥ #r̒ޱ[:Fu %_3y_XE( {ǹc# )zB2cS%21f$ ]ȦFVSe"UEU@˭p?zޯ\;܏ytw7f'gR)*<BUUZ,O?*)J59`YXMjI,ةۻl׮;,o}[mv՟,<Ϻ7TȞ;O|ޣeo^O.ϖ 'Ĭ/pNVӞjmeK6R1O{16rL!:la5u&9meo6LtȵGGjX7(>!*0+S lH#r`rTvU,SUfTQ%t!ݤ^[X,12GʐehhHFw_z`o}×^|;&ǓHlw/;99|W!LӪjH N JMMBn*~ ޛ}XTNJe^%mnK6idF9R`}܌#1C0rEC^o+l:,r7(c !@"g U!Qm3Tl ٖUR&felU-,c1?! ټl7U;tzӥv1Xc'C4 ر"s@.6 T )Es"aiQ3%v` f]cM\P<8Mv?Wgn=7~ӟo_+qtVe9*Rl>fj"GFҶaa}&^Rw?Q056;;ߪYTe\rh+aSA׀x#uaHmֲ %BmAkK4g|۸ATk@UadᢓiЍ\\lK@Pɢ[bj88i3nu.J@hi)mbՐHIՄwtn#(PPB-&]x T8 *P54y)Z-0Ҍ: 3jH*kVQLD*ATɍbGFoo]WNNRr7oLU],w?ݿ/˷_xh6_Ddvv~3@(u4gDرՃ֢rv5*D``ӑ}w>| f Q뛅M( ^֙ RVVɚ4L4 P(5K6iogCY;|*m,ţi(ÖcLzw|k5}^*OkK.R@in%h{7g}Cmɷ6MGUjҨY-/6Hj`u Ʋt J[#23td9@q?ia4%"a|L.\Lb]O_r!|FUU\H $)h\1TŢ(';RX&fh&DBTs`B H!sGҟٯ|w&+vǞ/eA䣇Go_s_N^- ¢X#982c[Ëf ẖw饃+ρ'u=L6V!3[_ROQԙivv=ڐ[r$R8\Opl^3jWo_dڎ?@/HM}i]aDk)n\:؇tJ=-Y@Ci9R㘢(o:@fGd}9F*0ʼnA#3 ̨eY{$R5SH&QUX(JD9 2);oS,/ӊ?;}Ν2]?ͧ_?ΝOٯxg9ؕRXB[c}lU2F)Tb/n^.Ӈo_>}1յ>6k^=]1\[qPR14$B#}*{K6rXQߘ(P6큝2@Ӝ nږХf) KP/ӳakV&N{= 6J7Rwb-96{;3zd ӫ+/d`B%p२VC8ѭCϺTMG~@r!7Zz"+×7`*BHD$,PŐ(Qy* 5LB@*T#xds?J~VTLJ~pxKkFW'/x4`Q>?>> UB033 "M`%Ɛ`T>g{vy7 #Se:!pkɆ@b`*oر_<0˻[SΏovD9JND wfkeǵ.7(&/{_?ɦV ?P]~/I4K1-ȕrHfd$H17HDΰa8>9t5"لY$iEf jmW;xڹv$04}btR&(4d F6Xj Pb5ׇ2? r@jU79T-WE `AE5823dG!&UPvL՞̈X%1Bf!96#[Wy;oݺu};=zzNoۯO+Ze2)3j</#bolHѵ-Wq589ʧnsSg)sΛ!!&i1iߊpCU֯;B`B Itt>iN3X):{YZnn3 Z"W^}$|MmkZ|V3; 55bՑZW7ŭ[k_ᖷ\,a.TԖ !P)AȀ 7=`1A1W+i#3%04~<) N饺ަVUj-6Eic9OkBD @bjjp 1EUD$PD "MX=\| 6W1f5SɔsADb=O}?ǣ~yw>8?EQ&h;v_7? ?h24TPD,CD4rL OS9炖{Ggo~P_tWgpjŋS'&"Q.uT^76+c׳CLK #+$v\}WmF$VuvsA#)x0MultECGFыfsb`l\ec_Q] 7aE^֕>AȂw@aYheĕTyU-Y  QH:CNr1b 霋_E$jDD!e}L@58[fV,w>3`Nw3sf]z9<9=̴;ZU-|>WuT][Ñ!i1J&k}LF΂lTXDUy}7oF<0mp)bSԢ9/m:9ORFWM'Aݸ:7n㎹ 3Q\;^@x1w [m S )e7Lta$G3kvd=tsIU ǨyaC{#] ԔҰU7C Km D*P̳`ιy"rr`U&pHL9:6B2$P谙#UKw>)R*gA :ޙ~s^G QuxGG%DP*aiIC8?9;@% #:}ErMjOk3?2.hce(3C$auV@7] uOS alsdX#gsal[(Ni}_H-#&"-MR+=Cl@23:RY" ( 6dYMJgÝ#4:bjv$ԯKֈjǂ4QE!zcNT@ɖ$TAD{$A,f"xS V9* !kijG#f$T9调 D̪A7G9K9@6BG]fE?{w2GG PDi$Z\RqNF@Fd;/MC(w̧9T4LI (D#٭@&ň`yc zɕSDDs埑q `$pۊ Ic=nDJ iGWXudQ#&鯅l颢c@ܿ;X6t_?hQ נJ]/B1 z0KZ^ws7lWYVn_ ӾMS euk_]&pvqc9k9:֙0%[hodUAdN]iuڃ 9q2JĢa-4 ;7hkT@G\/[SMF`;2 HQ, "SuHND X$s$@%xEJyX(P̏1̎ya>{嗕ONOh^VWv*e|gsF,{aY"BY}rN!~r-##SC$9Yٸ<\}3mGc26X( wyÒTG lc Mv)#5¡Bb|9i72@T0PD4AeHI<愻iEJ HkQ}@6n71nTVg&}*+B~rw=AXlsb͔6PiѣݺHR[.X5݄Dk5U74n̚(KN6 w>S>o0BdWcf`LޱA`vDhfLYUD: @ Ϝ!‘!9 cRg A4DhETr̸1sPX Tv~~|g,;<:T):9|;e"S}Njbww;;9@0UfPE~u^CP2#VZfgWşڟӑŢֽ`FROry\23Lbo<ǓoK%`]%GQ`dXUiIM (ťrתoȖI]{+0aQж/CuXMŵz%׳}Q̰z`7.a8A~ ֭:׍1,Hz7 S1̐ OSuNzG[#PQhDK$vH?뤑kd -c+SpvQ2ECP@r.W`]8S1;ŻQ͟{K7JU1{2#C "Č )j=%Bb{;(=>I1a5[١ UP/]BȲ Dl20sUUׯ\uâ0Y#8$0Y^5u9+ &\*?{gt1ByO~?{wWbo7{J`6@TC"("0 A*.ڥ1qQf6@<|00/O ޿w`nN(ܺlAG' O{ݻo??V9# i0w1.<YEPW?y|t ^'OX0=yw_s?'nq{zd:ɨ~t|8v oO\;{{rV \Pjfݱv,3z՟>~i/]Mt:@ hE.ό%+W/5tm#dsL'K= 5ZNR^4i%K⨖ʺhRO1aQ5_*f,jSO[s (`lO/`5u"|cMfKP~v?AdmavX,JԍF Pkl=:-Gm0cB&qIu ;8Ԛnk z @7ܢՂ5q.xE6$GO F32$*=#ee *ƞǏ>ޛ߹~h1켼w, !$C35 dYBFDDDeHDukv~~~~6Gn\Oߺq0{x~|^ʂPX8vvwz3/n\&WGp`{9Q(rq٘6' vOn\:Ko޼uc?Ţ-FPaR\p=1,mlvXؼQr@r=w}tsjգ8ڹ^Mn fK=أٛU\Ǣn]~ypk&z UHXV D0 ̌d"U)bYw\{>7^` L,>`D0j& D*ɲL-0E9Ddb3۽gcv+o(OMZ6rWo,9W~K7o_bɓy쳯;q8_ET.&>a- cO>#n(AQ^!hXVb2@-yGgƚpɰܦ^!oZFl#ssc.zxXѦd t1=P!Qn'Ã[C'pYZG nwVOظ]a;`+͚ܖljՀAot9v:79ND \t3R< LC(UJUcoZ!(1htO/,ƖyX&B&A !z*g Db.P ћ:1#_ѳ/NT祆19~h(H aqv'ggag wGg??98]r+;p F2F;7{~gP-bv~:&o_UUS矻\ᡉw~o zk" 4@ck@=U ") :p F+i@"# 07ËM`%SxZsжmoK%X#vc֍~Xg5N#ēV AVt[3~UTZzZZuԻ--;D_h[-ewkZɏծ% v KRoxT]еUnא\_rZ<ޝ}Zo<+$n~>('F_4E4rAM{_3T1b&v`\!',Ƀ/ܺa`r'G3J7Yɘ1#ZT!;'&by&"`jB03,1ӱ{<<.22xD J hg2>??eG\g愄@UP Lp?ϼ,^:;=파Ȉx [\\6uqCe3Pw?{9Un_gý< &&>COa(92*.=+C1z|rN2w;p?uLhB/"VDCGa=plSo+=qKEl~ֿ,shʳ˗wvn?/Α+U}c<Ow'7/_'uGx?siuRUg{ޜ|%{akrȣpQz H2{ۿq2~.# 3ikM['c^3m^7/i[뒞-qM6m$osyw?lŊ)/Š]VqC +[w_K_WyG? m֯8F&JmM8?P{pu MƑR, lI4 9&Ko_$GbwFHƄQ(#lgVr7JNojMò\0we/lc#/Z_TY^~)z|ilU7)GۯԗIwrYqNHˌ h/aSfnDùP2{)&8Q"MFb8=2=Sڦq\>TG%h c9- %zzf'KAxNu$ %g,ع|qƂĵ}͟ ?OU}m?~tv5Thj MXok_fK,Nk/&AVm )<x^ͯl囍Ws7xpRƉDXA'ϙߨwma%MyJ1jd2z0~vvsWA "# 28E9f^&4$L"鱉Q&Qau|ޛcSvt-r rъ# ǂ|vXy%$9BPy5XėF)rYQ>]?MfWxF?Uβu25*dF.%mdѣit<8<ýV'l57wgm5v7G'G?g l~+A07a;{CDQD4w[[ha-:vd3Qo~|랧vv@(:" A^ݫhNXwꝛWowcƳzLB{Ia~IƧ[n;SQ$"j/Ȳ +r($"%/O9 2Z,'q;[ 2nx"1e-\ل_lm՘R?s(Eex݉ڧ%Z'\3+&~lfq&rGf@ ms X-m .Kc8dCQJ)E4!9^y//-Rzrv!BvX9t8ϝٲzLack5eB'bEֱͭ3,MVk_D7~Ja ƃn BM+v=.ݵ7>|ƚg]Їi~ֽo]|ԎrL͒X5+"63a֪AݮTF#ΌG$s?}^fR_ Zk6>O'A9Tm7 k{I0mTe~ݯVnQEDž` 23Kmf#Cͼ|{9c* 68GwxJm,v7e_OetgųdL/=;%mCq/j/x]FVIFl/ ̅@ B K-Wd|\1ӀP#2/1 hoZ\$O3ZBRj,NgOώnA/R"hqsͫ;{U.VC+T* u_7|-IZZ7wkìMi+уu;Ȳ4=>y#+$ AI Yn5Rup#'DFD*bHƉLŏK=x/Yckkswς&F=}NZٽ@+G}rcZ֊<9x~Eft㾏dV^6n*ʘl;f ?$!i|s\7VT/gulQi F\ӊ-ţ}TI8wae1n\<+?ыe;\ñ!Y8"3k{k/;70w@#&t -rB B9Ix&6y9A.uAܘ9X8*Yw\/=R(!pŪ c2"BrlYu⊿*q )` Okg49OdLY1[lV_ɼ' IDATZX͍ЧzkgG~ۻ;Yv{gka(ziI_ago=pyG Z-J5=aC*+)Bvk*)'? uϾY{yӼ:CtXK2 " C̪4 yFYJPVyQC.]D` 3X$J\"#LOt_k7_Z-\rgՉ]%]'K:K@=ci4lW [VMqW ՜uǬU&~hGcUd]ȊT X5FFEQP Wr<l>n(vDsהdcfc& Z֤s1slJ182 B,yBRD6ȑ0Yى8 30B M$Kd8Tm};8O,$Ń,I\ђ9j57057m$vQ9'žFezuReiǏ_~_ݿѕZ=zyWTXHu+DBvӧqg#Daf>PtV7M+{L4z 0irMGy㟯]l&DyCAeClov:ϲ R VVKtF"3Vd"D圙ea|tj%K%@X-//`4h8#@\/3OwnLkPANԱYhRnrhqT֓l@7Ch4&!"@[FADRd8}4\`# q8|+8=+fGmHʩ,F2FFC^Bԥ_"ǔG̡DCB@@'1$@$IQOڀ ,sVkbr@BҙcOkD"+( BsrҩWi{oL$@ƈylw LzmIRvN =+y' ĥy&[{ Y,WZE,WHvD" &Q\a9v*$n$ɒ"P XEh4&vG#X5 D -pѲ:`rY+Z{]DD#@)OsV)yx[Dd $, ժOĄ*瘔1FIJDJi{8$D;8 (eѣĜ=x^kU5A}6[MS'Fݯv{ݨs.jH.hG93Y4La_Yx!K~ƃѿanӔ$ͻvk&Yq% e4xJ0R 9AzHrH;V=ϫjځN2tR'OWfcg{csnt'T\:̢~lF₟s/$NlU_R ?yv\Gk_Z `3kfAY57;y?t2D_FI9|;x9c7K  Zr3歟X,KsZrݽ 21 y!sdNjX"eB/qKܹbf NF7O/7T 20H@ Xi}c!(D|^&xuFS!)*lDɠjݳO?\ Ym9!6KbynMZGJ+y&:*O"wSm\_ky6[v)8ʲ(8g\C/I铓?w,ںo+i Q?eƖsX(FSy (^X57\$o)[=_T(%C0pre+3;_U^+7m%HpIq}3@HE 2Fe7;AHFe9 [E0~LRe.Rш%f:maUXTI:q !h hszkY&cXXyEY;c&!V٢0+ 0,RZFl` }^4L!Y?HlLC^kj']q@*E0gn?>wӃarmr Vk~7jaKbl6m&}8\ERuYB6"Q*=3!;qj:>l?ww^=>:>;;yu{޺kt5u\vsw8 jCPqyJXys9{WڇҼ{@MOrkY'ɬ!KiՒa&*G p pBlb9T/@K2NK?v.Aj:SdY\Vˌ{o?jr Ӱ$fQr[1.IPZQ !'l/$=KﳋqvPQ őx1fhALh,^_p4iB9MB_%`-:f.0-4kC0sD@ ,Ƿ_}ʼnshr> 6ac6~D7+v(]0Ц{vv_i6E#H]:isz,(IypZKDuݫEx׌IRk6(ƜŊ1^.:]0Mȹk윲Is)$lmO{ ;w??}> ֟yN 8ʓNwo7~ $92)רjmYo0jdV2 $ĥ0>Yۯ=GjSˤ~="QJ 50 &C6(f!*D_p!$WKl%+ #s8;49N2W~-:3G2k^LX q~&ʚg:PlKap/*!WdjF8WFA"WOq. We>lb*`:H.0^)R2H$BP"Y c "2сcgs{kǮfr9ksDZ8'V: s$a X I%՜~; 3zcI*TA}:7vrBU*F|/ؿrL؏H"oG?Og'd6GQVjVhϾ<鳝+{,f̶\q.+ak&q(R5*AW)`>Lu&h(z ? ?I$ovZ|_[}&Y)@QnUm YSIjE;&GMkL+dy6dI(b%` hG9LX)5.BxݝW$,׆8-8Q^͚.jd @ =V< GD͡4(0 oy8fΪ\psPb ό ׅXp!`yg ZShͬ9s8bWSZ Z0^%!&O&793 1)AFdpYNAWM4I=sΡVy5O\?g'W(nZWoCgہg2b*_>&=ɰ/ +;7JUZ~X1v I{ҕ,1HZ̉e։j=؋y$,L:/==~vP SڸU΢ ?GtXyxtz}b?鞝U&={rVқ GG&ܸhc$źL+͠RkyX MAye%:Rڿk_IE}[J=$O z dWY}pI9 'y(ep ȓ@Q _i4nE;JU4&j&3#fe<#%Ix,ty*(~ 4QPP@3 A!(p%8 s t ʤ'& g~x[I/X:w9j7dѦGt4!bGvYG 8-g#w4Cd? <A/?Uǣ$(&$`axrVD,C"r|0z~5CX\u@kOD,aRHZ0";h=:HO7 $X&55X嶚e(c|֥]A` mpd."9 :rr pp2qzXDW .YeOLd8 E,'/&_*aA[:/s*ȉt !!y~; [I'N$KV@JsBDDpFsDEDX8HK< SA4n߾$M?&^n^1SjsF˷f_:*l}O{??= g闾UϸժuO\T"HC0ϜlLg,Ym5 JdT =ϨzrG25Sz'u <=X5Q?Yo*a@_wArу zGQo^߿GXim94x[[W:_kT87~N{>zi*i ><=;$loݎ5ܲ4e.o4*+CW!q>ZJ g-'6Hc ЊA3ACENE\ ̲ `qBxIqG_ZM `.rߗ3}yj*x Ur+4ʒR,`5FgD!iHkgsoeQ9'"X#&ƊK(""`c| wyOPW`6YX Fy^bC='hju]&t`4"sHn/0#)38|0M2rD㑸k?dq(Cf:RO̗'g i #R I$J)"v8 Ia&("hH  (4T6/klJر |/cA<ٹ0&QX;~y4\z# B]5jS*3;N[;[AA:j`I5[Z~e ۯkꞂI)o#KzF:Nwo}[_hm6d>>ܫͷfq?K:Atp?V IDAT#&qjkvt^t{~_Qµ+gt''<ͳ?hR'ZmP~lVf'ZXu9QP ݏmmU޾k?|okokg3R r%􈡺׈T1=6~-C1ER'se’~44ۢO@ ?_acG9nȌ3*zlPLmFc +Pa<al[THIfuJKeLNLlm9aꭵΪKw_zrڣK_z-VlXaPש*ʣp;&Vzހ_SgZP +"(i <$\ɷv@H3k?hth*Y?"Thunogvk/^|UUgY~tp b>T]GkW9/ +I>6o8UAǂ8 kqnmrNG?iv>;=my4#q&H, (0zq^m/BL$GR"c5nPո]jv58?rR fʂYЬ]YOx^Ĥ|1e EeW,RWITGQ(夛ig?y_s3յxWjGhvU "ve ⊚cE):Wќ'z3Mc&91K^6Z 2ҍ,2\<0]N/8^J5̈R Ѫε iaJCI˅ =穝春J䕜x 9`阋/f9h'\Dbf&R$"ZVd;"$"yH&"'yr:5cY-)hԫNvfia!$Ib|XArh"# <śGO=ڍ[&ܬ(Qy \W͵-+Hu:Th7ެHmk*ϣa}]ahm^^ƫ6n~˦I68b%OX}.ch2jͥx;~u>ZJFscg7r^UOe6YFE0=;x^%uIAj2 s"yyb<=;:l@Ja.ӳg qfZMǖ ?V'\ZZJuI%dyr<}ĐqTwuZAU=SAZvo~JV+`ewc&ykH?ȓd瘻']*R BP(,y <};2Y1\ha靝*.K⟲b`UƔ29q:T=9ל-s ˈ/,,貌qUz*X2uVf|L|¢TLf %en.?wGMK ]56!,.BZ̵y/}Wډ,rmaE3d&NJM@kYbk-(Af7F(s̨A/fpg D,p%ΓOx^ DiϐoNwr!&uNT i%O~:{^@iyHwj*tR [>=9]S1{9gӃR{~>x|Zzg{w>]nؽEZ(JTW1i]:Cf1a:0z0jY40 )! -Q26 ;(PMaAQDiVڸuCNzS:d#`sJهOKUJ2o\[7yV$K,BRaVPa1=sJF:i(oY[[z&7Do5X ,[.RaEYW@Sm^$p= Rr&%:~}!"(0NWrfe,C)2~YP\ʎ{]]\pعѴZ߬$quφ@L *8/PJh0|gR M M,E }U7* 77nQ{RHy}j94(Yzl6}߫5qtj^0v9j''l*۾bH'2L0*b8p 6΋-HcWq Џ e5THrqtkK,4u9O4\Y\tG|%Diu9N҃[f6!\>z̍܇AdN3j]FH,֒, 1}cYl͡4!ACև c,?"( dX(["Es7cUuUV/|㜳q{_fuzYY/q"b^{y;/8RD@i? C4Ji.8.Bpnf@$b%"爜1@AMs/kxhT{A6N,g3uǛٻuw?ca;櫭Nkw42]Ζ2ĸm4[A0򭽰ٮ2nPomtɀZ 0tus8u)Cq288ygv<8NueG~|<3@6KT۱lߕ.rCE?_}v&<ڐF]WkڢJs#:[qX,Ҽ2ݍvB朊2ql!%vv8;:o6Buv=>3AvO{|;ׯO޸lmy#CG:r'EÛ Cp/+VӽNͲf͌DʷWDB(/gs{/1'X|Z \'s65xTi]U~'>V0fq >@Ȗ7X^cU%JVxӫO"NjTDsI!d<"),q!=FCȀ3/Mamf񳓞kC3TR͖w`~*c lͳ?6'gVb[~o;ʓGh4nD$tYԨc#t !GęBJ¶|QWnQ:n`VFvmۯ1KEI7#/|V-ma8ILCIA- FҼ7ۧgFdmm>l??|{:b2ȫ ȄˏLr_'mlèxh8a| _N(3" RN-/00ZGVq;88;\h?mq=*-INÃލ_ɚuy-KXxUzĪ)=%>]|ӲT ");>lsd1fګ ;NGRJS\/S]E|' YiD 4ҡ6)(adxQ/I6ʹWT͈2u%7<% \kL7_iw2Be;Z28粫f%#&9|eݺ(6F!ACM8c19~!c ' a5`. p(Gh4R9o6lWc{Jn+LYw-'({6wۭ?|/[w~$m6%Q6>@ݣܨ.uƭ։35Q(VqOr"(&EVQgOL?ӻ_Q3kh9XNNZ7 gxE i@,QbF5TTt?f6$pCǧZ+pGp(-U+ _N2͒`|>Q:*,- \-{0!daG70ͦ:|fS{xz [8mz5D HUiy).q1E&,Υ"ijq$@[ FgITՐs|t5Ov*H@#Ck3yp>p4YJzJ3ޘߕ&`&xZb/TH83e<,Τy%W[sECLn3#gΌ1b-7ogn</VO+w%0.4ܹ@\09Uj" -ff('0s i,6%Ai$3f,ng9?v]آ٬cNܲmepkv w /gQf]]/~~7$b\8UdZ5ט0-V0Ƹ<nP;s~)Q%Ha8[K׵^ðN8:x=|O (F?<JeCA(κQt0qfJ2&߼XۺտNKVc@~8e{kt#F,FV^ y:rܲj ˩n>ޖiu?;wvSL̞~+u.}z?^_A)+;sqph˭\;bVa ۬)7EWӳ!ss|y5y]o/ddrJ= Mp?xun1tcCd1@k3Ff&N3O *ˌ8G"`V;ls{+QQ߳l[=|v*s2u08B;~<̢3~{'?x<e= 0 Vɸ\m߭QW`:2sl˸ؐY=݃"g_z(@r|O>,}/xtW^ZFgvv6_GiqR,K4pHN:in:ELXM bg`Wnَl2 (\~)4ǧ'ҿ:~ $87X~YFz4%ZiIҔK٨Y v~1ܹ LO`Nvcqsⳍ &X0,lw:8S$" qx)ȕ\,<8#P:-(]€\NSyLdݳ"ӄIIȡVk e:^CE9BLY?9֊ T}?*P\K׶1Yy>+YIo7_;AȘZܐіACZm4 Xᆁ*'FcmJDZʢؽyx~)kz1-h<UJǃ8Q3XG̷p\Ib*-RedbV#aI̟il&'kޟ8K3*ٜ1fJ=+*cI-ePU~Z^X9~m"@\"Ӯ 3k)s{P'f7([C WtBBaJU "?ljgpr?Ζ僖vBqI!g.qsƕ@#BsFqiنrm $%c2m h D& A $ )8ó O[7[I:4g'Z`>zf{˯mۚ9毾mYQUShiYK~g󚴱j>F1_,u4$h rc`A9oYUfvP i;Fx0 Nz'! {uU붑ܑae𝭍,cm(GeΈh҆Qy>N-k:~.8̀ c/NW, 4hcág*/T X8¯JpqFVqul7g?7|l5o֦4e:IF gQȵ-M#3q`&4?3V@Y +t):8^;a3<>E`q$mB"nhuzuE%< mfbCyrɨ z2y5} |bDzy`G$clGo}J ?>f;Yg2@YO,7Xܖ휟 `snB G IDATM`B#drpd9S$B46 ĥ΋1ΘcpɵINv6n_iTY*DbyQDą-Xe4ol5y@ݳ/.vv6LA?>ε0T,F%HZF┣l4jY 63Uh<JJBX"/ɭu̳x;i6&7wBBǧ,uG-2pkeԕak>D066"[p}?`~Qo4DGc!Ft }C&Tku .Z'gC)jOW^k/V3\:Rfo4eO{\Ny%hԌbF'G/ʋo??+J85˶2lmƇfbF45Eth.iOGU Nv^\Z\Ĕ. .YOT ef32) C6}U9OaQO٭FW@@+Kt?.\q x铠7r߮MK3ZCCOƸQbRZڨXayG>SKٻŌ D(1fTnp ˲ ADiԚvJu}JF()*[eYذ]El. fv6x3zy{};ŝnQrn4im R1dR(, sGu:~Í-#2Kk{0 `aEy87Za6l]}rA;G*6r~4jpR˨2/\R%IZQv2{76$ixaN"OF9qԜ"yf\'zTW%ȜsFܠHcXp(b8?7^ؼhGҐlP)]9Y<ˆN[2OlȚu_#Y"FGFc9uYBuBdI:oD` g>@dydf"hdv~nlTA51B2f7MaE" cd U*T3n4φ!z^2\AgZU9cHD` JiB C@axr4x.(oިo, ƌ%]C"# D6" [ML|2QqBһ;7d Ǐ{Ý]gy&5˭lw'}C/ N3͓V{,m˪YpFFJ'ql׎<ˌ G*MSٽ~sWtg<lV"⣏+{E:,$6j["-+DAqSb%FHNqCP+-G0Gw>/}2vG.,FXRp`(06@ !Yl7I2x-:W OZK/‚ 8mJyQI5S94jܭCIsId#4:3aPdc$$D0ASsO F_Ԟ'iՐ\7eu ͩL'} pp2. +C,[fS|t vyr ?tgH _QESjcaAkp4cLZb)6%C 1i2FCݤIF~a'4RHȘF[ZEQض-Td2f7|˶eQ[_c6Da)JƦ466w,v'l_-$*\j$] YׯZh"k۵e9$#QZ<'E6t,a ;g0շ^kNY2ۨC0VpGa@ǣ)u{m)i3nsF(**Z 3J!h!c0C8gG"BH1^nK2)WB**Z%h,l;I۵m NTƣAqKeyQ`8JRa]uJ KŰ,0w~kM|dasUQ-hiy0}~xe8k9o(*=;w idc=KOj.>a>wә D)Q[>ŝ~]/ RLfȜY`$7Q[$6d :ٜ*zCfHUe եgӾ#v,f^|ټ}9ulu`*]S.1;؝"q͔6dZ+ tN42r3.N"e>+:;۾z{}$ĸܐqCvԕl֦<ƨ8 L'A__Wy{0ӪMNVGn.+X$c?ey'wV+}O"GbuDʔe&N4G2d*ZV@b*"_LzljMepbvAr@DZ}+,*+*q~y5x-NX lox+_׾u/u/pA+.WޖK*&ܲUlWֵp g;ЭԺXEnLz}cIRu&ƲqyRUf]!qyUOZa"^.2WFb%vz]K@[ָDJ[K%VftHi*R%Z$BNi dَ={Xv5ͿmaxueQRl{X mvT,7uL2 i&x5EՍ(e^(!8F4Dmn]O8k6\v{c(μ_FQxA$9q ?YVYAX@3rzYp 7Q}ɁMGw~p^WHےx{{g0[\*@~txJ 9  9Ι&y_ecJi(!F.yPgE>'y3lrתͺos˱ 5|fOFxgw{?Ͼڛމ^F 9qGZoOFEv|xk{u/.IVekm{wU$3:|p!,׸׮UHWB,z'Ϣv?].|IX hi7WϜ . -X}G˹tEɺ+FgK V-+*K,VL3֔H,we:LqfiYB bh MJe  ݳ`p׏IfR ؎ mΑIB\ږ(aݖ:YwZ l8 7=/,if^#PqkeQy!}"F\  ׃GW]qfY#6Zx8Z<hŷo^:0+GwNϲ=X1T*K΁q[Iƍ*Vs bRlwAovF-ZHJɠ67ܼ>1h'=:;4VsY O>u:$nk&{2{fǮ@;di; usGP:KYP~Eh2z̼U֐MvY a+?槔jK<E +4oS h4gYu4<DucQ ZAX Y=:V:ӪF䳏ff3OJ 96]QĀ%m.-ASYLH& ȹ0D *@e xJpd10W\$%e,qdu/xm QCa><<vZ(fY~9zF4 f۶8i<.8tG#m749%eW7o7`2I3,?x{xsZifY#dx4Vy*rdxӁt~[=wۛkM^oԃ+[c{tſgM`a0p!&ZFDhp3dK/8GbzHxn R.۪$Y%rުE܁Qs;Tŗ hA0y!];Z(pibv49Pua&6```gvhJ҇\*hQk,l7(6)T *tIՔ_?՟ u~j]\!\6X[~h7(YFEVt0fRcv{[Zsn by1<::ٽzO6nq}m0FslT5Ď˭go'uJeWCGԶ}?xP$F ST`l44 IDAT4LvdlIyl,AnI*3Kh$NGAVnmnt'ʔym7^F;_}u锭m!(d o KyF1Ga7_DE̲a4,kA{6[fJ[ģS.HYύo/yf;.Iq6AHq~?ZI2N<.<׵ sFƸg{4m ӔeۧwUv~N{ٵW^~{}{Ϻ8b3f|^T(sS}f4\sC!9]M_,hVE3Fՠ1 , d*42A3+̩JL{~1HcYL҅5f4ztAMLP*\\]Xq+#y<5o+;^>d9-ܑ.M26)n2|"cDHd1BB(6@o6hL%zLgA-{dfIݼyieY9=}T\ [&F'nR2+4!*ꍐ)e#ú?Riތ8秇O_ɱݚ_\׵xT㱣}?vmo] mvPB9Lzh4*Hi?||E1gdeEkۛZ:z_W/|[Zolop2Z%2mRDΙqjF/#gj4va!Gp.qR0$~z1H4+ۿ?Ξ{W8 uWۮe$Ȉ8*M0™c3i݃QՇM0JF#o߿qEqv Fv͔o@DSqqW@Dfx4{p]HZ*&"XK9=8;-d$[t\;1x.Y5cVLWNI&9-4RN=m_9-\Qvs3lhqBd?" z+ePFΕQ !c&8-LilDz8S|{ϵC'<@ad9?OqgjtVyf;KƥUVdc±]I#ٻ {5X ݭ[7?_wAE`G*+ <#lG$͊ӓf^oֲ"#8c㠉͠yHKҁ*)):(aa0:/f^?GOv^˟ `Llg&oL+xNh @s>Ig@h^(h/$D 'b ,PwL.%3瓊3%h~?rѐd9135,h5d`QJQZk"a[11(5Al q.U6^o7[ASU6pcnřgeA[c-qsۮc<ÁDkօ9iTl{Z($wv-,ْLb4IiPyE6v^z|}F <)xӤAeP"Dht!?߿hIB6#42^)P,3FQ樂kZYp<HA.upɼz$D=VãQw?ڻ~텶)we<x{{ܓHrFixcjhp>4wN s9xuP5HZJI[KR֒ZYd\YU*'iڦg"go6$'.~BYs<*X]iItyزvYs^s Utk>I8^X`[1~b$u@!XnunA @d*ڬZ^%o^RT 1+&ӭ,|*T5@LnVKBJ7{8VYVz`9爎ȱUsJ!8c@9 bYBFَ|2-9g"4 ϾW 7)wt&E2㌶fF%<՜NkU9 C`ZI/kͦʲd}BzsX*ߗa2iؘN'Hpڵf9'QqTy^ץLHɊ2~w& Yh qc:$;w+(F<dXisik8㑱 ==پx89}6~E^p;`dnU28Uf^yG=?TTi!ek ցpf tWqR Ӆ#턮/5ϯX[|D]<<.Zt)C%Z#n.lUj]hE,f5Z@ /Ҵ4oX/D3s:V [9V-=n.AY@0R0GN2cY-Y\Y*ik,aH&wnԤgkQGHt d76Z"K?z>ʘsQ\V)m̓u?22{Y,R-* iArFkVu^MvVS6&L(9ZM=IC{`Su%qCMQ<;GcE6}w_¯|Q|~7$=D*Q9p9Ǫc{BH.C2t$DWןvbtO%ZЊ24aiu6nwmug)8ެ g/{_6*9;9@z1"眵[Gx{g:qdL;dB]M;EU(IB$)!''_8&-56xz3w?yx%+˺| /II 9hA 8.$dCdRO^{zrOJ!Ȳ,jcN'ޭVɓz# |@q靝 ,mȰ=qŐKMW*to1_^0^,#d1DFZJc6F{ 9\pn1THqG`S0`068Gnl F}aީ{!rjoL&i;C;N7o sqv d lnlCa$ K2 7fQvcg0t#c2F>GOF'+Mݳv69R)iz eYNԨ71Xi6 Q="5"𤯴V9 ΁c%9@P0 #GH68"@#Ҏ1\cKp?d8M7~Úҙ Px~1Uh>xwV-̭[_D6C^dxۜqY.wzѳףsB@/"Rbcz(̵!Zw6cmt;O^,q`9ZJ'IdsWL/!A/up_?K/'.6 War\&}YpNa /G,U7z*YY-eEpYv $hpiyaY2~I_T]¬*8Npg0\4 !%$㌯MᜓCr U,xڜI+2'➔a$q,nGj cɳN8흤C79QeܮwOnm6>ZA U{|ͭ(0x7ƣ4L&ggǀdgw׋"O t8ng !sFgDG&fq- L3ONaT鵼"KLVF^u] Q>"QD$ũ*R rw~A{7Mtޏ7n7YFXso~{1wsd}X,dZL:ۭNi^5,o9d4yjQ .T`KR/iyb78G%kRtln4FIyi·Ofk|7%ؒ1X:gjOS#JsIZ2՗T6U: /1$:Zp%V]řt J2'M^9e ^gxn^Cpѻ%Lswo/|Z [Ѭx.0sdJ\ Ɛl%%pKY70<tB"޴8%|kqزBa63Z;={؜FXƑ Hȡs3<R0G dc{;{"F#d 'ain [4M f ca\ko44ߺJPo FeVcQfxwoyqRz؏@!ٍZ1M4.xjlcYQLf}*~ qkETak,ݻVm#T8K=xg;yR(Ko$ L&9j?04HQ->"~?n\"qI1gGs Vo,Ri:ժyO}6-Lva҈:,!(BUye(.ӡd&3^_L*)UaV<?y(Ύf1ܹ)C@Oԟ"c/E~d( cӏt́RU`3 QEW[2eb_P= V].,i+ [kEݼԹ]_vrIDμluV~@|](g;kd+sPd ۵٘²+ʊ}w3V揳/>ůa-; 8N%BvGU 9Db 0w.%!r Cu=l3 1߾uB ?T+šfkیLxq FpJq#x`YƘWy- k^{}[[ݣ#UXx}o?"w.j ;?j7nE>;U*Bgu@I4usiH.|bwaToO&E}=#/&EFʼԥ.OOf`'hwl{xΦaMlo'{ψ{pٽ[OifX*u񕯾̈́&2nq- -qH#hstXळ+$#F(-ȪGܵlBc+lJsts' 6NB14}3湜UUpsڂ/|«*L~'Vw| p^FŊN-DWpΛ..9bH*Ur=P5@ba5 yiL@@ $@B j ekǛ䮞`ɮ/i CFxta~>—75DpIDr$%'g,萑E•Y(y Rr%44鐑U%1yB@YZaȲi>AFBz!, FqԈ㳞QBgx٪ZG|/KWaf<̗yJi6q[YZ%"~7S{yP\o|&? ߼}Woگݺ^(v6 gYGTaZz#-e{Nӎ.IRd,# ̇=K#'7^TYY>M޽LZin[QiD(i d8Ѱjx0TEGCD / 0Y^;B0^ɕha1HR_9+=EaYR2=f,4vӖÞ&yNaTF9c,"GdR7NSDfX 57cB4ßx[AWB_~9GdpftCY2,K`| SKI2`e=os@Pfœuѥگ@.v9mwΝ2+^}V ^aŘ*i,̚Z=;1p래jpi; > ٹ'Ş/X"tc_KU -gevwH@sl9")#)C!_?}|N@5ϫx(\H̦KŘL'XxqBREA،"1{0 )ګ$E#ɀ! {0 vji2<9|ϿMV~?{|21v`ss1fch1Y| Ξ=j%UGiZZ qv:/hpzm;$1gl^v$ɣ!XD$_,) 蒣, DOs 됨Ѭݺ7 0j6b~l޽~7&̌YyƄoZhi`k5Ozj>u"{PTmIM$6^#kAY&W^~͍V?$FTo67jq ִQHجEA!8FƜֺ2νgqԌe^P#a\e{ӯ. 3u9n֣9gZi]A臡ՙ' "2Vsp"$c9er( @BƐ'$jK^oD.3U`QTFnl!b:̦c(t !6}Xͅ 5I&$۝(=FȒYʔ^o6jQz//DͰ'wv(0lN8GLZf\o~tk('X[ϩ^nqfUڟw@Z(+ʸw]aC 'NKWYt^\ԧjU\38Xsnmc>a{yH%=!C@vx͋BZN[ʅjNIK1y{ `afqsW8hie 2GuwP MY5qsn~+G?qIH"̗92"dl$rfSyq5 Kq7r>NIZHyFN g(͵qsV&lӌk;r^Fca<qH 4E1v̳Ti)vdĹE09+1~?;YsE^l"IXelۍtpVj?=5VF-D-2[[@)C`\ZpMYk EFp*9/"KB6'3[pyl腜 qPe\0+ɖȕX8fEyp/LzZVdf<t:4)iȕڔZ8h&q/VK;1*Lap8;уq^{seș }cƝka5e-7\*Hʼn,ًrXh/ĭk! m?g>{_TUx9th7~ +^E|,tUM[>oɖWsLNjƔ/M^fYvyRȚΓ8J"͈.|h[0g>ʌϳ7-`X $`mc@@"b4zW7fOrFī(!!:BG_B%R7Ƙ1,c9»o߽qsrGH'"jtYZmgU:M;a͡ysMumzEyVH.jQ<i:VǏwnO>}8n5"5g?}uДȸi3ioww?]gV^g]N4'I15 k;5gڠҙfB`E1t8̗ Y:MaH9f!rq !0\y !"RR8k l& |8 zW3F͍9-'";q6:sol]+Kƌ'c_ƣI~kRT"qVƘ4A[flQt05d)]e -ˬЧvi4pZ0nq+nj 6Z\Մ?8tZs$pDi d>bXeݤ ]!>-\u&X4ق]V+T߫tP5Y,I0%pX$|!(Caz5>CȱlTsöϖu8 aᨽviu"-!ͪU2 J .h沽!cAGBKF#"$$8*J5'ΰgIlNCM:9?<t6w6saZ6^-Zo71kju,bƭ1ivT"tMz~|wvT_lZC T"H]iixVvH"IX^8 Li6&A/םqotI {BkݜEܬGbם}L3, C9kqD@sG9"8@",À#Y Y(@FAmRq6X=UV3tʺ4R3I& V*|.}BM5P1FI:d5 aZd1d-k:'ΑY2, DJ`8ʃ|Omڈ?~ٞ^z^{xW}-dyh(w U!J16qapDžhfm5\*e湝]Ԧ< U&9WtK**-[ Jx-uu8pX3ndUw0U[fKl*}:uDiIw3^\X ./T3Ca͆:}u>$jpV W缟Rڞ *մzFĠ.Wz.<`s=e͗jGF˭#`֙yP7:V9@^}}Hq'"MN 5iު?c!a )A:o66,+^sW^\CF"O'ORwR~iM;e9;^^&6ڛ2?:~}3̓1=T}e<"Fkޖ>"g񲜎t@bO (n7q#؈grv2Ƶaggs+TA+𰹹S'4ώۭm'gA =ԳXYU:!`>gP5$5΢ua~UfcY{A0gֵQYQ$ϒ3(\8bW|%v05D+k8ys&y za::3FE~+B%L~δD^]Cd2~q`qei9oK &Dal@*t̙bz'ޠ{,0 96v4+|AT'Q絨 L6ɸ2/J//A\` qzȑ*o CǬEEd2aEv+wt==vm_}7>wZȁ',4\t^IaJkssK?W$#O:(Bɵrt. YŔEFoWϩEkUwg~?]9b12/ f) a+\ 茐-8:+*?.I i 3'qje6KOh9aA<{/5Εq CeĤuy,uQEhI2!a4&npe^<>z?KlmƃpϽwNg(FZ5䬃Қd2iD- K0wV¯\Ej.2ؠ|ϋC  C>ZuZy9`]Gׯ7;Y8j&YӧIZ6hXii-Ӣ,BRA-3d;ӝ+u`cM_/xT|=P/ Ϲdlxv'S`fL;g#PD@JN+t\"OIN-4<`Hā ixhRi T7i,9wz1GfUݨF&L4ȍd2- o\ɴQ !hr9||㝎{DdV2<ݟ?ot>K2C]mm{ EkVJYIZE==; $F"g^ }8& !22" flU 6&H_C\t߿f{z^kiܞoCx cS+w`;+72JqYfx}a 6kCU-}EGҐ6Y]arF$:n׌jڢֽto7x55 wd@d VWŰkySXƫ:Ȩ%乌9Rd@|y]Jt:)Hbqh4Z,f-]@@M|w?y۬7ftrP> @T ˥o x nXurس!H\eTD1/;_E@ߕ`dž $68ej ˭`9`\H=b]<}?ڲVV&-4OWJ+d6 F;]udb : ^z!cȚ]]ΧpPdY ?3myJ%I3d0u9^*ztHe»Nd,@ʶ$/صm] yhj-*!UF}#DBjs>"Þڦ+%- +Q)&@(}צEN= U$O{9I4-/:Yix@׿m.sOT"p\K|ʣ{mݿYpєױ{pDτqcGᇵIqkln[ obݷ}|ouF nu6v)x|՜33:i|@o9x3[J2MIyoc^$29AѹGZ>nWG/rh;Z<;^F)6df5lZVP'6yǛ)A"o%M|ָǿ/7!N_i>vr0c]0#'7Wo6uB⍀|}<jޫaw|ZA` oŕ-qd !FBHcRi P H wAv`8LAٸ?xE&8wyqdѦ_AV9;ŲZ̖˘%9!)fEcAl()Z )Ikf&I9wt|ptt2,'EvRzf];!v\Xdp0zV{ۣӣ45Z+l'ף^^ Mӏ" b(-WJAZg=UJ/Cj1_+@Q~]/01L%,SyjCaBuIxGvP6vڹi3JuGumr]ٙO;R!pkcSׄcs!k;] Ͳ$H麹Da]*#$ ^H-C(Ţ I4Mccu_t3Dn-:M^ؔ|5n͛QA- MzUv@{wV+ g5DEd=iyw;t!<ԝ T~kUÉk+7]:uyI(| o?[%|׫̛[_vyeXm~,nggϋĨ,G D *#vp!M]G ;fIR2<2QHM~#.ۓ\.93Ñ8<|k6 2ûm$L{)_ "kz]dEHRht`ʒlgk]Nfڶ25{xyv"w {Wb9K0]֋ČCl#Z"Bq8!Nm:ۨ2zvw%{2CF XjUZY.;,GsTڮ*o ;:TբJp9cjҤ\`OB@#uGCDj\o]t(=9'TIiid)nZ"SKem[`#,4&u6]GDdB`AǏpwXKx+bs] H\S6ޑsf<^w8W̭kv5k#ޗh=>`+ jY1z$Dl=>1``15iU &[R {FH-U]5^Ll( // oZ[ցjgZCңUR, ^1JMUV^NLdJG[A_IvZ i)@MWwn&@K%Yt/i/E/MoT~_٪J3/wB뾐 s>jѣCDBI0[GmAY4u25NK *zpGy+@ Phcf6YY 0t$H>G|NB1}m@Mw3J] 7njdSY0S.N~wE\Sÿ>sb}5%Qs;;1p"kk'¨!XDץn8 A`i# #+ Ql# @f!U5 Ҥ{O|O;خm5H26#B(&sdbd׵O?4~./!J'}>[UY5)zRhA]ZQoZΛO12٧iGgdFR08\~D Ay,]u<wU$Aý~o.\cp9)41ɠ)=G@ІN^TNgugB&tmHt7+,KyW1`XX"gy+ZBK$ keӭ0ڍ8+4#"oZw\Sn@gf7rj\Zʫ_*ZBtxϾhWmw"npM 7-5vlk7Fn|0ko"^)X0UuꛨbH\gb;1]aA p!B鬑ȌDhsf"b N0RJ+Xf`ADBF6?.ǖ.t<:RBRR8H ddz63#a]&IcS ɺ#_-fiSl>ao()O Fe$UuV6[%U*h~! Ͼҕlن. _?{ì+%Dv*Kcs>xc|$K;yIEWv@H0U*s5E |?/^ ymE mA\o ț?~U] `/:ojP{7^#'*F>gI_o}X{7xM'}ݫzރrA+v%P̑W1+}p(H+f1ઽ9Gdɀ@Qx***2 _2?o1g!!L_/cIвs9X+mX ܖ' @Ew՚Pk|S-HM9 AY5uh['ˬaPVՔ t)L*fȱd8iƶd鼵־|vu?1~ &jWum|Q2$ϟ>~imHp ΏN&GEt'GĒ8^a:Hr]h3L&mΒEӜ/~N_[h?,3%ʺ*w"KŢd_ǿə jfY?EvT^ABe{'?ɲ3A*pӋcsFUl!|N]h+VxK:=9? QvXбbe{2((lmJQji]hYWij)0$K[kUG$ bbpKDވx9#2,s@˵ł'o[>sL]cBf x#ċ 8k2aM?n)q]Gx#47o 'X_]e&}-o6p=^FF7Zv&}{8Կ>2UCCa)|22l]}:D.'vyw\yz^`;񰭎'UԎ]kֹ0z0rAte|B@J)$YuҴgEU z {u &ӼHCg˲yoA8ON϶vs6>9?zn}:Mngɴ1^a+f7Ӌց6,d6j8?{2KDӶ" 4e/E.%O~"/fa Nfe$B2EGϿG&޻:~v'_=?!:7Qe|v4Ȓ$Mg׿xqںm^~l}tu88ؓ+gAZAtMhVb6uGC´j/d JE׷u=gJ}@ !Aj()QIrYEVB!%Ţd )8Db~W׹11`sN+ׅ&ZkP-?ZE]6=_׎~ %\^_nЏߡ`!_[]u7ßѺ9sm>o5n0k L =2"Ū},=I}Es|ut-©2׿^?Cԙ_('2<a:,ы{Eӕi.l{x$V {묭fdF4m w ~THHeFں,LC$mQDksUDLb9Q%JBg["2 HJi M)"SC"@)ɲ"\VU?>|AuMyArE٠74Z0$k~V}[(m"H||ƌ6Tsuc! krY7ůz[Y}/>]]XOzۿO/\>.$D$ёQH#H y$;~t>&Z2JmjW,JJ4:2`9B `4#΀Q(\HB`qwuF`߷$$2kT#_>7qhr֍NeUZC|"c| pݚ*}<.'YUhg7i7ו@+n>0k]Xf/źI7 4^N/\^!3XJpCWbWG!_&8-׋JVr~f̖/Wt#zf^vyqvv|]J%>BmgCe5L˗/^4j nP[tm lo'sABP$A 0T$}"QomIXl:CRրj#IRֹwm[1JS!`p49gʅe:^.?~WHŌ${- IHdHI ޅDC/ ]e᫜FA~ݔ÷Bu?rps7̰=MT')};:q' wJz\b ?d1 oQ@ QD@W![BDȁ$ĵ*^]gZ/^'9K}i%эH6Ts_iًJfuf57"*eɗ2[Ώ&_ i}bka.j>O¦1S5]>3{?Z@}Vh!2E)WODbjteoUWًL"JіYޝ_l?z˨r=,_" R9=H,:IWʐnTaV}`aCcs8;ڠ` ϟ=xwo LgZT.N)ɜ 1$m(LTsH2ieUF*K{g/N?OƏ cL,v[%TY~6hhGzE\,M"sV*I?|t1kZ0y&A1_W;t٢2ɖ^ȕsFovBQ7mIY:_mS"d4P%teO* %TP-ʶuVL'-$hksj!1DCNkޢJ!T&%eA("_7FIOɛ|7[@xC+ęc㵎^'D=fܿ  l.[ |e38kWBw% ^O8Z~uX!7B;77 " |ڊW.ƍH#uݚ= Xc&hpf|΍=ľ?F;eY&:g4mӺBvН;u-r+do;iV'1 zo}]ׂw:'품B`/Be5K򭶩 _JٶN,Mz!tMg#Nrp IVt/=u}Ve"12FZ纨f[[;J]POP: , :D!8 \%`eMu:O,hF\L!I A U3u #1ݕ0nuU5@TWKu> AW VF`bMcXRW2 o"u7wqݫI}HoʗƵV5'+ Q7-CkI "b-^~mL? db(uX,[uGz MI #?kar?5! ]*mʙuqӟ|L%%VX iU0Φ.Z!쬛c`ŤaNzNS]ZNNOG[>6R 'Y}pzZRg{ϞLy}\MΏ1^ŢѣGd6iPިԕӋj~ntMRP4~Z/]@fF"A(ifB*#DHQckr6+ %1Z%֎kr^r~1^\Tg>p0潬YiE,&Bu'.pmJh1B`&5KIpumb #x:"2I] ţYyɀB L.2`9r$Hn?z[7O~{v:}$ !xTv=k;k֭V Z\g7BJTJteVZyRR i f#HeBDVe*F!^qW@o%\ٝ6s%z!Hxwi p]@L:PD4`{f\1z`m5XnjXe9 c+jW$N6x_ƽuS;{|+-齚Wx82-nU#C(ci#7+U>'fiW , -Fp9,gٶub8fLDmK(W j0 ~PJwu@hlQ[o _ \+6?z,VI/6IAZzh[_hF0%"zGe!0'JC H#zG$H rsX[֤tղbV !᦮n:HP !YmZ3}ұYa{f=B~𛉍ݗc;+{ 2>*MהEbM]I.P6Qe/wyM^fE:fU6vbV$s lm&\p WExBIc2J'== ũ"n^UkeR..:VAbUC9W奝~Av2<\9~x7~vz^;2Tޛ=&˳P^$QZe!tU,U'G,'I!LJDW7Bッo=uWg!MD.-pIb\4ˡb :C\rXeE= EOСxq|vy6A&'Zޠ$YU6]Sfn>Ȼ.lt7%9Zw|G*cLDf7ܲv@@v†4]F t 5$MxxӪz"lF'!uMM+d+կ2mVS:7+ w O=畅5G=zH\]5Ku˝ۋp/Xk^U2f)3?Pjs|OP{K ;sEЭiowE-=il$Xj;nFHhW˯]2L4a`|Q%z:}1.F6z_Gnb`H(*n\ 8!>@)=ަi˓|uo l]~-f\tRT弭h]{tr0Qr6O``,2TPh2Ϻ#Ro0jj4M`llkg_yAm{x r2^*ӯwRí|K{LembDn],P3Ѳ[J\S[Xt]!Z;CtVC+wqw+EOMdl.wa:Df [T#Y64H eD^JdBPBR>p[w֗W?8rFeNOxz6.܁:WoW+zX⮿8z\ !SuR[Fn(ubۍZҗgX"+vv Wi@394TT$[R %Dl!u!,h?xK} R"VMMA2R ";c!u.#Zzf9OAuٺ<$iٯޮuuBVlog_֨Y p/W?Ugâ$Ϫ0Md^ (l{\T;l aָn[-÷|pmSGgc4LR٥.taYw>RA(/_o|8)G1""!xH P֗Ų P*RJдm*&R޵mW! ۺnoKgv1Z{16Ff1mӄ_2#шU(HPRcAڶHtTu18fvycƤRT@gyl6iӊbd$KZ,ɥD"ɜ@`\׏& j楍Q^CkJk_>l«_,$?tsAI^AQy k?W+}_`wN]7ג6,# r)hdb]Hᣭ)Hщt"YRL"JR|$DL/=y@d)#oZ;Uˏ=b癄l' ɇ'SxIhn'H)&e6X_W2$n)AVVS^=I't2Eeeٙ ̟WbA 06 Hά\^}?e!<"3$H$.gwαs\u<?[z2]Q|R,7q<&T%$&Xƞ ` X|ЀY-o;6}s[6ggރ.N "҃$Fզon]׵b\̻FuGYS= x23hC#7.TfR!4ʂ-lKY6dx &uF"#:~/c.pO`L@^08zY+T؜Mf Jb')c۰f(M׀ն]0ƅlz GJ)s\,Ao3N2^^3i3Ql ӴYpzx$uQlc:.K# |9J8MW4*Ͳkf0M gsȸu-2hB0!M\%猇oS,67ESZ.x`(tyx;vo[-66tx, ΅Dg'ŭS.X16 2X^?>JAe@>6wT\"`]=h\p{uӴgCG@\J @Q`.2qy!#d F#j^[BguLJy{6`P|KH Z#Py?Jt;w;eJNz_nww>;wབྷu iIJst׆ߋ\o 9E`#ٝP5t#E8{PaЛvvoxc`W?z _+VɣL`,E*elʎ/t0iZy f<>L*\t\H"Eř:?_70'#y/?R3̄<gf#)ƣrqϗ*ޅD/+j8,8֍ȋ43=$é1F06^m]`3uqǣ>9xsvٶ(,]֞,-rM\rCđS1 .4hlUv}o^O+k@p4eUb%Zx8eex4o_yMf0RomャO{ó*ȊOpZ,Qp<݌.bQ1<28c1km>ͦFFQt/ Rm1.Tu6I#MUU˗뽃C<BΘu.J.Iy]$x7Nimk)ٛ}uxl0+]ԛl-W1H)׫rjM]) }ӈΘ(XmyP@OĹ0EւsnRJo1[,2&b6{]!F8ؽ7G v']qe7xMUT(pzDf`l{=?n8 }{AA`.VÏ-oO\:7;'qg0\EeY%:bʗM['Cw2a$Kd5uq yt"+'_#6;׺؅,ϙ[~o_0}I>Ϧh]_,!vOCuޜCFޯRl Sͳxǿy5bqJL8+:{pe[~0 .pnTD'A竲ڨdPUMh$I^o8t)YM }[6U`4<؏b'oO>}صgLv2I?ʦlqxփ#%Pm\!?} Y$V8K8=qLzb7ęD\6=1~]EH BDH̶Xy1ΑCʣ)A+oC X/irđ zG=>VUY!߶bE2k: 8|3v<o5wH8ʼ@9-C7eQƘ1i22̇EqLl1If=h4͎˦{v. ҁ  s=" !fdВmPpo8cu!\88笳$B"d( Ԅ2@`9!nP 8 G΢>;\~0^ڴcPCW{y +n׉p7~_)F@s2@N~#Iݸ4sOm7N, ?rrPf|=9:П~M4l̘(d4a8>:ˣt~fz7.kϾxÛ@m/_/'+8]f2BLn޽y=Q6ҐEzDB$[Sm˧3篫'՗U NO_ۯ;3e߻OePKj)18~Fg *ŸL#L:V/^A\w~{M  s|K a|rf EYq} `l[x@Oض]$5i+{8b(ƛ{ Zk8"j}09"p.Z ΅ִZ %vi$umr8Gk h1sU_!?_ӌaȝ֣93x/{ n7~z w玑Qx^Cc~خÎuMq>x/~/6CZes5ȏyh~48Z7C?^r1m4׌3wOJGq} G#ZDIxp+=N&КFr$I)8(qyku۵&Rj6Kb̲p:YnBrX;/߾-yg_|%DFrw "-B&lfɀC$O[I\SWKNn0ȥQ'mӥj.X'|2fgoK !L}r[JDy~!t̵pc޿}z=IڮLkcٶ`(':?geyvqtb<<8xw~v)׭N:l.!x@ }Fl8_]f1Pdz'p[w M$_:g v  :!ΦQ# .86}ׯ&1΢(a!BJQ\z猩"wbS2 !x-, Gs4mLzoPpήvvV)EL߂?xóe2 76LWyOwm@Ct^ ()[b!~n ͷ7 Aw] {ةoǡ*^ҴKǔ"h7 ˺L7%Qp8 ׄ,byhE\h~6@A:ݻY)MDyI (~*ɃX~a^?N$妭<=yg,I bV[o~呴ZRm뜲,Kom:p,ߞa9ˬA4b|ܡIr=v4O>{YVk(ho2Q۪#Ofpd}]8@hRUhrz%zNVq\,.̸uk]PpZY<# Xq(|u_m0{ˮ)WVj=|8yߚ~<{ZjlWMeHkGruDrg 0x2̲h8L/e¹·Bz( >i+$q".&Zgp0m%EAzî0/x܈GGp]JmzkaP˝k)~|&ۏ(ƏBI] WqsVuWVJmNWqT%C@jS1'!nǣI.=<{̦3q&*8cy"VZ2.!9gB4I()<2B q!'DLQ "95J`%Bҿkw9?Tv O!՝k7>BLmʛ}n3(oh>'|[5`%!S~#fnTukqouUet|ny2LT":8  J)4G#B@ZJ)LĻ,whYdף0(L>?l~bɘђ"3AY G:X+5% #Gnʪ-6R70qY烺I#W,I)j7u=%ZD"T ޮV6O#Ǐ]Vͺm Sj4<&Ӊ3ӓ\jN'_|\79)Jm$Z`ᨚɣQ>jUidPTIMqUUQ+iM?!4~+ɻ@dh1u۬Rޚcƚx q||ptt~~l8Hu L'Bt8^5긨I#%XY]]4mKý+gDu=c>j88YeL/rNWͿog_l6c/_֋kK⤄X^EzlCֻ)J쵌$#ܓCșuʮrv]O8jyyfMu=Z!"g<9 [1}zcO8c[jF[4\cz! !Rw3nprٯH/pǹjd.tx(ƕm,Wo91 L%2IlW0NPɢmX0hŢQ9pYuB%9 JBחLh$<7=(~S,@h4l(MBބ(Z:g*ՋG-]?O/lĴFi-I*<]8&ũ@{vIG64(Q<ԛuMc>x8ֿ ŻLJ+v.pBE6)*Gȡ* 㬒zOlz>gQ4m &d2TyzM^=и >gbp9\JYt2IB^bݦO/ޝꟿWo;TsdR2B; A AjTR겜1b dPr`h@RJg9,*Aq!GD:D# ܪ_ض  7֠y;S0E:Qv 뢊7JV[42n:'@p~nkn,qU(zl\=# ~i~vxGxD@Y7Y=D_䓈X9_ѨJVr]&XfRPRI<4bȳaYº~ddwp7/_H?x|9OW Pl6xrլ.DQɅQΕrqa-S+b=߽)$scћd"3g_H\6i,]J,U7#bI L/~[,\MYX/kp0W7_'TU5SBt$@?~, .~7JރwOhrtp?i'CZq$.DoG|9zvՂ3&in<]yO]ȴ{ogs-#ݚ>M9e0@h{g{rk)7}UO%>Hbqٖ<,RYq|2=O4c]YeYVMS .)&A39FT,񺪞;Ӵ3̶0,DY6Yt\j20@G}c9p8Qp%="yB`H3q 10VowַM_W 8'oÿjn=9[3o۴:o,d "`BJBnJ) (KwYo5-{!lGO⢷[L PI""ȸ 6W[MDQA ]~s #"1D[z t"GB~i מ;"ݵAMvn>p IUw9m+wճ^nEoVa?v]#Lh德vc~NƖb]V vG$oޜr*_x,ԦRƒ`~nr|)+]>Ca;8hq~ʂYݛZR է_5|՛5Uu I%bSUϛ.4}۷tN{_G{LK}Sg{&4zH;)BӶ@LYӺWg 0.8J||h<+//|$S,8N[2蘧Y$C Lo^YdI\4eY7U5}ˮQ4@7}ST$3%8t$dD==ɇo;=)50|:f+S鄁n4mL,&ls}Mt0'Ox#^]De߇v4$ǹL|s&';]o΅M L4ם)n1X//WΆ1U WAZjp0˛LGu՗k8y6ƸMa@8!0s֘xЙ yIUnVmtmZϥ{mv}K1Mٺgý|4?$6NF*,綵r$n Cn4CWN_ S2(%T JCәjFBghr0'Hr.MZ,k;ßfQS2KFoW d'ӑgb*X3e m`<ˆKff]#Bd}G'oW_ٟ}6Nb) eUoMճղ[BJ@G*VZ7 wFq2LCwsްFFt0o5"`=pWyy%OMϲ<HCcL)B0ӉV2f\"@dmfLq-(}U1I >`m>!vֽ)卯yȗq<ũ7[72$E>huID19^vюիn--X~q:}ekzk![oX@";p\fѯ2b헸+@jAܥuwW3 sTb>X\\*:Lmuς7.'"EAmfñJjYW4Ŷ,L,,selj~;4_b|s-t~i"X6Rb2 dqUM=U.7 qZL}UmϞ///30m%U"Wy: hyxպ}| "<Ã^2㹊/_=iYnʲSۙt,Wl#0գ,0 ǟ2g*ec)= BmS!#gH3dз]k]\̃*Xuiti.?PqbDQEi6%y{y.EӘ,;g`2-r1{rQEC\i Ҳ{b{c6?d2|d<Hg_Ηe{+;xs#32b,vm% -0`Az2 =`hhգnMvM"37g;č,p࢐qU{ojt{{}DMhE(NPRH`*dQ1JBc;+6s.8Kw\kn/_xo#J&Q:zGᐫt*pδ֔R@RJ:~9=;1h 3Z~,!lc3*ZIZY7,NJ3!l%mqF;eQz{DbXIEtB) %QDJW7d=q.UL# f)rN^tM*Gׇ?prgsap zƐ3 @R%@ $ HN'!!.od LsX,<2 PppF# 0DVyŻU9kZ$0ɄET2{1q$ܖe]]ckѓ,E/ z.&~7גv]5־ʲwv'ml1^M;ZĶ(f#*r]@f4ƀ"Rewfj Ҽw=VB]O_ڃޏ~x{ 44mu]Av̵i|$qw֦m驣>~4Mlg4U;:|(Ô /aR0L|j rnuTL+;G> nMQ.a1믃 a<2hEYn Lo&Wg77 MGLb]Oo&h9N"vN_Z\8"n'{{ivϼLPQݡn2[8F:(03ޞu1n.·;A0U%b(29 vvw6]K8ig3 S@ѣ ׿ɤӧOϿ˿j lqm:YAN'x{scۮGi@! d 2!2aDi0($`Heˉa+. lW7~+$YO,wWx9Awd9/ Q8$@B3HJ"d@Q@9eDP0J  @)%QΨpH <@9F #(9t%CWYͿ1WV2B.Z5G4e49u(g6]SO_ $7$Ȥh&Qɍ@K(( \)n<4̮g, Ku4Qillm- ^f[$lZk$f M>;}^*b"Ó7G~~+"'p2_ĦfA@԰ktFDYTW4u)E4#g,Ho:۹ %hrBlГHFų*NҨK.LH)$f8A\*Y.m 8$J@mqsduKtDr`sn^_Οߦ|'u1BI0G8h$6ӁQ2juLQ贗LUGYFag t IDATEJ3ܼd+7d ޼(ygsBFp*֣&bյΑyWVq $4vD#0>{s-XrEnn'G\*KDDS]犛Y45jh[4d|3y+%́ `q"$SWdg2.ͮ__3<-f3ƘGv5$ 'M]^VeyfB8T'(&]~?>O<;#Uشr^Hý,Y9a;`bU9q{JJnˮ.Oў@enNqPBJe1q!!MqTD9 `k]'Ħ` !a{Qr 'W-nϻB{e8 Y,bu?ϓ4BκVI>.tk]a@;օ E녇>!~;\]]̦Wn+hw? @T΃bl( ^0 r8bqyYgYuHj<)y=lmee!Ga=#ֵ#Z=RAy`hnvV g>~$Q)j.YW7g 8mP59銒CSg֚GGڸ7۲ŹWFq<$qɳa޵,,*^xqu~uqqRYʅ31mK7MDQUuOJ]S0u=\JAg9l~? X0\eaֹFko-/oR|ǭ`-W ʠ:@OMf250'!^8&BJ;cQ.0̃FE!ESW]$O۶Ս^eS6Y^ J#<'aN_~vw0dTX1@ʰ*lg_e c$q07բ T"Bf0@J2JtrE[Y>EwfW/JfIș`L wFai,cy7W~]W)r>uΔELOU|8sɳ/?}Mk KG`W][We9N${AvLa+7o& Np J8> ælEg* `gO.86O\XY>0.R. m:D8vM =qrP3Rqt1O@$0*:*;WA@N@*PReU )7J Z8K knRt*$; ^j#bJ vD_%x+_V$rg+[w:'X-H#,; rkzf;#x:xBnJ7emhd5/K3bl^!֡+{;!Au޺'׊- ]5z}XAZ^ [H/ŧ#a`[&LRݻZoå;::CeʳN97wŴJT APKC崶{)1`(RL2Z~dWgW`jf6vE #g4Ejt:0UE^=FZ> X[{!D]胃vo^(b?:UK%mu2UAЋYrΥy޴M$UQkm@2k֭4McT@]OӤx8 \pGo~|=A<^y]_|l|3/L3viLüwTǜ3m[5I/⳿HOf$˓ _OWU?֖YFQ*UsQI{GsXJ&%e f ?3{ppύ6gW/l;1S/s;ӴmG/)bSUcu=2LϿxh8AT]2&$͌Ԧ5}Υ(`'z@Q NC%uWv{  N9G,;' 5uŴә5z>_Mi,$;m(zcxπqZ!8,?.DQ.j $Q~ Lz|kDg}zk_3͢ Ȱk]YUUi[ѓo3tq+]Uxߔ*˱ۢ X 6[6γHx 邍P-p{6ָ2ƵIJ}m(Zdض#{1n \+lQ .:ty z@C?{sX%<8˟`uz>~1%!rJK^Dbͯ9v  Q̴zЏlG T[9 B%B__O^?j;ݖGjV'x{}y_gLFƘ,B >Ōsg ={y$ږZ,Oƻ77 1ߍ,々 LI LPWɭ~, ⶫ۫qϿ|_!Yx?圙afEo.NogcFu5d|uy1>;|}8 )]a/Cҗl(EOhq&='a^[y";\}s:L?ɗ+odP7 =mUUc1;|rr'q1g(nY$-hGGFm%+ ^{DY%a&$ַ8A!Dv! Fy[*PI^ct:!hz|v^,Qo(rwQ뺪.=pBqA pʤ`R2J-ز={s3\E !"Ya8xa6>-g_;9FGhW/R,@YӵTH$ԃEuzo$ z~/ +ד3.~K7i2Sօ]us@?NxŤ4\ԗSmf>}~#c^^iZ[$D0p*n@&AxvzΙGn`>݋ My48 efDQ@98*7CN`~C(ZkAX8x,d^K<)xo\ٳO_͊xI"ō̼<}* TXk겨m`|f1/+H~Z܎uތǻqSWW;;xC+B''`mQ&qʞi~U()]!iýz<{Bc@ XƘ\ c@((z#*ʻX o> K,_!+x<尰e<-tge!GOnpmX[Uzw;{PvX/m5 \XY+"a#]+_g_/d3`K'n[-9eu%SڜV9e"ׄ24'@>K6apu}wӭ$+wTyiC,lek|3tKQ:-Ι!"`'x(ϯ3)zW٢ ďJWz?ڽ_N^JÐ7sq4T*2>8גSJTiUA L98;ofƱVh4He T;ɵy%F*+Bv ^]fÝzQ8 spFW B\j )#1iqPw?JcX$SB2 㲜\^IL9TwF2 X_|a _,JeU^l6 o8N>bR־9zyxsDlT.G14ᆊ|*{w>?pvqv9#ɋg;<~).8ig/_ƃy?E{7{UQ(2DDER@nRyn.B(i3MrT J3$]UJ zFHxz֛ӂǏF H03(!R:s[3a BG:(!j*BB#kk)1!1]DRHT%+{f 弥w1;e,œ%*BIW+ZQ5&w`'r#`ʷb=da8߸<íEgYMz`۹: yXgvuDma;blD1xt)[U7֡l_oYad6ޱ"y]7-': nwЗ뵢Z/eit'ǣ8gGȫA)0W?zbn|5KY1,q'ꪫLE3S>PzJ"P=Gbw-\ADMAlI|np7'L:s IDAT<{}B`AzQu`oz|{p9wΧS1 chу]m ڃH|so179zg3xUyӇHT0Σ_t:4YssETptxd6ΩPf)%E(nQw]ѳOBh ,p|}~#g5aLMhM5'ҥAk;Nu]qurYW׺.QjMI͋yxv~Vu0H2bW7hsZFaH)5Ω$QLz,c9cGou{S !XDυ1岦!#;އ!_jR7t)"pYo` Ls8c<1csozp-xal풎o܍;kҀ]^E$r_6VP%nCÝ3l]ZG%oU0>;B{܄2ރ2x^rVΞB7ilo ac#ޡ_8뗋2$?èW_?|p1.QkÄҚ kKqR=o wJ28Jm]qH8]W+]-bÇAoԶÇ_ NPuڶ0"huP*R =yD9AF2*WJ2.Ej&@Q0,yBV3t$Mbe[tև@tV N)eXiJQ ̯B̹#+Ɍc7zM+F`@ zySiChtU)0B Gؼh>:JBV) h #n=P P5M)l5z* ԡs]k Y΂6r)\ftgwBagYvau'8?G?Uba< Ba*k8 LI֏0y;}[ A;r{u5]C9PNxSFЋIT^@-!zMA9rt5MMWsPw< (e9.^TYu<ơ162 1;缥^5[ڿ+wL w$}Mm kd$t-/ kҚateF<-mM<0n KlQ%|uoON6eiS֋p/yܷ(R5D9t[-l pB8G,6%4U5LA̞_{Y?O嫗9ONyzr8zT<^,кWuIv~: An8I_칮4o9]$X"FXp~';;&FOꭺ6.Hw?p%c s2[NN.J{ &/EL:u.V)Rm/_嚽+ż^wv⷇,Y B]-g϶}ۧ6~{~h䳟}Ug2WLJ_|{?:`o[5_[A\+ OS̲~GzH"R7zf'oG 4Y.3Lc4RK*X̦$GEI8$MzuSK&SVIΰ7 B oT;Ve"zg%m_.6:]P LDQS  *K!Bjs1XlonN@$Ik-I Pz1nnlaD;7l֌Εl0,4M;aeSE>NF $J!E$h-AB*$ᜳ, A""1Ia0FWϞagПtĩwEGZ 7bnOgfsX4GBD1^"/!5(_^Ry#  JF%Vay )[*@)@B5EQt0\ *,8k$HG"_+=ݍ%>nG`nK]n{ܽwsNn> ~ *Q,g |j 2oaI yt Re>d~{d+55۪Lt6х(Lufw?Bם4 M⋫djznhgWHZ ۪>z;<[ ll|݊c69KyOU,ҷ52K|6lPIӜwS}vN3}7]ǣ͝ϞJ9xGO~M??}:'yΛݘ~dC79A1Mͻq3鈝 0edJ: uvBQhT.>Z>Љ+)!uh0a3xc$!)8PJ%-,K4M4eD|Znw,?el" C-$2BkkkH/XpIvE6R%Ce^Nh['-$:}6YRi*TQSmkL#`crLQUVUy޷& Nw0MYHy>Q/bYX;KQk,6&2 u5.@ɓP֑Ɲ;Ԋ¬3O$o*%iӼ( ʲRjd۸̶u%=d{!TXzl\TewؚRIZڶ]>Zk( Duۇ8+?PݡG!_}H֙2k-CzU7;Oڭgȷu?~bAZ὘ D? *r{|+CfU|/b]LܻW}_?GǦgiNG"-xK zy;HYxEiNy:f(^/k_.?8(*לj_>%(NFI}+֣𢭿ǩGPӍ'5(Ӏ` 3CYwG_$ 6UHAB{Sb G D41֘ޠ\8 'ǯyɏW#Hy@2ԳbHW3\!zfc +mOcYhl9__zQ8LGQcOFSv3hϋJѣׁQ !Qxt/CnxtBpQБ"4.Fo^v:|50[cmBm[laR" ޣ J`dGD yJ -$ ij-4K2 kYe5mآ` GGi'K ]۸heni]hY U[N":FRHopdkzŌg ٻJXh@ %{t|k\?~Ϯv3x,?%5b{-3)h5o{aY]?x-W^`M})f}!D~/H3;uG:BK|DJ"ͮ 4~5ZJvl`$`7O@X+J.q gٽ)[[5|jh|Yl+dc8(hOL]ymtkOƅ̾7NN?{YӴf<>>yŏ뺞{7Tۺ U|6H9p4E՛Qs~z1<8_4,.?ވCvay9GO+dƠ0wZ*/LL袜L~h&ds=3(q{k벬;@sd֕Fʕm s^ }={pЇh؞6}`\l!>C7eM NOQt>c?ۛ]⚏ύ]>s ڞu>{=YWNt>|Ut=Hfԑ7nw?oϒ(!9x$[oۢ77nTUŌlp(%<mu:瀱m۲,tE!@OIR n"G b:?mg}ob0q5c@Jt:1;B8MVM'@+-ID$DK:jc)R#Q_.h=4!ͤMŀ4mmfKD왽dD!W׎wmBxl oha[.k-V:ʝv IDATʯM/D`m4żXOszy *Tp۽M55jpÚ}|z ]jV ÷ʝT).=Ha^$fI_n_&ߜ^<nfS2ӴOwŜ72Jjtzz45^Af|j-z[u,aUP[ct1)d:EeiE*d$j -lK;(|evI,&I sp{rtO@(hDbh0Żw֋" %0/cSl>b&i,(X`vaё*E7JE8L.K17 zTZ^ w[{{O2&'m7Q}u[c`=hmUνȬubލ*W$bˬiw`^X"8!:=04NM2/KVi A F"sKlc$&!"!1vB;O(UJ0{1zzp^xۮ no~w/4O[5ځM^M- TRݵc<%$%:Wh4tgnR+ oDoͷe{uɄ`x a+NR%V; k\o$h}LWkV _[sZ~-ZWu=>|s4(h(0觉uh2g7H)0W^\”9oo#M8ؤwIɔg}XQfOß~4lUͪS1xt;W/!̲,lr;DÔ/mF7!UOaY#1q*qyNލq >s7fGOJc*cȐ,ۓ,t>?^˯w6?[ZNOŤ(P퍝.lð4MƣEDȎkO.dU׀γ Xk@ 'uU8dv0ҷ^tLiLkiF먓'Z.+*tR}X52˷ZEY/oj."{8kmTyO@Goy>/b,74ygYWEBa[7ʸiMS$1UnsaD"/<2)e4Aٛ7GQ孳.p--w-`lwsLD:Yn`hH(gJ&˞-(@(k*' 8@@<׌:T+K^ d]C"̊2{/A#9:R_k E,PTGldH<[Z,yJ.9s=amxoKcpGz%yব5G  tǏkCXJ^ok<QڄKί|p6J̄DKދ +C%n&<ߎ;+ 7YqiUi4FxA6ulk3ٺdGw7CA[?޳Yjndbw6tE,4:-˭'V<{Ik<;|&I J@JIƛ'G!ei8w4=_t'h>b 77n;lTkE_÷1ޓaѰ\c|mp븪^c}ztTl]95'?7@7E+CH~vƪZ< %bw:S,~qJ7%FFQle&W5e)a WB=R[a/ B3fY&9',@G79*/Y;LNwi$SY,lqQ(uVZ&)ϋtлLvva%Qg{kmeLȤӬWJyb )J,.j1sN\,0&㉔ łZ똹 ^ʋE|'d v $qӣt=z8qWt C,EuB6,;6N19pd笣L#iDEHwˤ(LzCT;Y+ RB #@x3 !Df$;@kyn h͛$Zwe \f JAtBݣuWݱfiq]l!!mG@yVŏ <yn1"p_QK##Zi/ʭm7!kh3xs7Brz I?ͼiݍXIɻˢ 7$VwYلUQJOfUј0cQȟ_Ύq?ݞMM[ǝ`^Hd6,l<ҍHqk|rp"(N:Q7٩4~?iw2r_ӽ7o~W?;\Vͷ^HD$ũNѶ/;obU@t2:Yt6^T}ƒT82舄TI-oenښ(@Ⱥlm;bDODx[ T^.HP]5:#/gjf]ﹷ8,HPƶ-m[i ԪO)M%;IYW:P*;pl<bˤm-B%kֱ"t8Y8v=ID I\\Ǘ^o8lۋIT9jc­@3 ITn޶;$O-9w 3Za~.D6SfC&AH4LJBP):HR5FIf\GV+^`)_XC,OPs[2qiq`D^.=v$/ΓDloDНtzQM=R\<>Wh]]I&*j͓wsw)7RcmS5{,JMܩe5'($Y1L~R4g'3!oX;P\W_MIt|%<d^ccڝP课aa,*ۦ)50>*)/faUvށ6zX/۲OL)JUnlFHqếTnB9ƹڒںy E-}몬RQ:3Ng|wwwqRIG0),jۖI(!emPR9fo*0Y(eq1_IP/Ɲ4Fk<^z0읞\Qpyjd {g?a^o\[] gM]d3kO1K $qR )LL T,MQJVA)ΙBxеm짬F;GLAp޳p 0 F$<"Il=2:u7 UZ !#~\;KY)mޣmkAcpLDyfsZGތgúv=XܚX^fmX^_?=_z: CYU|~̭R*Dʲnۤ3<;ڪnmrBI [DqÄ2Z^k3C#{jtk[k|Clwȼ 3ssvZ:HM"z*M疁[މ;10Q2&Lh'O?LGW\&7vv,DGtc7UEQ0:{~K@>9Pu3~xo]]A7p6-|y`k,O :xgˉtRqՋѐ^=VT4vw|xqPb੻7ݐ,ӦJdkE_O;>VR=@]:C)Eċ̴&&ǩ5حEM~D ,K\ kC)Rx lMz6aPEml|9要VPֹdȏ-l+{BuGiY˲fuXǓn*,؍WuU(A6Է>޽<:864LCH8HI\kXXxS2+㦳I=~}qj:[^g/ţuA˼ t-]!Ȃ7E* W yu2nw@biٴ׵ْd7_\Sr\u̒޼ɡ|VOfEpZ4PN|AyVͼe+ʵI@T4uB(V֌ޑoheFyɮ$n/[QLڔlp#a붮[B_.O.X&tcoH dL)R:$H?llEY|rc3; ~qo. _ b'olsc TielBj+7_ccz'ZS\:{$l6 HjTRPG^(l#ޱg 윧2$q %P*[Z=0 dcZYnyZj D&gƴed!@e ^jnYrk1yvF*z.H)ATB#o%!+q]^&/_77۬{wHoヶOz2vuh5ۖ ܕX-Af{bZOtX>rf-_Sn|}x^ ? n{ĀB N~vogP_N˷( O[2TGGFaǗ6L#U`WUX.fǐO;۽iS͹,zmdWaH"3ѴhJyuɊqa<:\vv2HS^C,&禣^uOޏ߾<e``0QEuFfQɛOz6#Ytxr56 le*YXO.Y>[xkbut~d1+fs7YbO> '+ئ?/{8>Ns37vV IJk dZ&IO'3ᡗd(QyY?P̦c`&yUu^-gASWQ:uO2UT`$>w\k^?lƵ2PK,$)!yy" hZ+ޱ ,*^z3T XgfV:d$]23cX+ L:Pz9k{B B@Lal8zPJ-ߺmU FѶ5_կY{#?({%W5Kj?et_ IDAT㗖 =x?^9]g,m?fVW[hw3V*^ ~%{ϱ*2H{ɲ,K#4n.CGY%gz0͞C>$C$ _f]3]ӥ+U ZvQa2"7>笽wg_]̜B\ndxp~姻3N;B[tsmtFܙNy[}crZ׺M՚2#m6gH`4gƳ`:ZrGL v8^>y}g5U>0͋rxB^s4={'qNv{̡/iQo7%֪8,t¸%[M]R6ڎ8[itO#[7xBW)%+]׵T4Pde}e*Bn N=j1L0iwh:nג22u*Nk=JoD]LRBCFJ08J]:cz/T&TqLEg|m͕-foJWHZڕL5L RFޏ8@<pJ%Zvǩ0lr)ãl>ŰkX7{jwAMT(%@sP&,ʁٚR=`ըE(c⩵0bFΣw@HΈw"q[ )@1J';k6#@{8u;cRFe97@_VKc )&?w>+upi}[De/G\ZfrN*T߬“oKwp\zWt a"oL/ʮ!;y$Q̱|C Ho>Sغ~>:8<,QyŚGRhQp(x 4L2N(J# 5@vn5WHQs&]/(lJ H>imM0jLs٭fl6|;ctgٽw*89;E~<8O&#?8z1k'*HQG8dQY^#*[5$^IEgYG5#AEڻ8R 9:TY9OüE(Eku"ȁV3(y~U{.y1nֻ R&oZ*SN8 jcYi[Nǖuҽ9EIfoqltVtlRʀ)l. .JU9j:LHYlwL ntEVLafBKwQ=obqË^W6, ]\Ֆ/^'2?| Ȣ K}q[|VáiYQgPk4Nf01/?o5ӭg}QW2c a*4#QVN޺]IK3M~ t2Bڙ/cܽ{:gý4߾3lb+?"MXҬ~j6N5C+u1S;o=ߟ';uɸeLYx^μJ9MG,L:m6:Ɣlƞi>?_g?x§ىRDTp?0Jb<{OesV3*ZɘPgm9)6'{-J9ʢ g|wnmwb:-‰HY[|^<[[ѩw&{6~v?41 =RQAYfy筭>sx3DQE{k+g'#YzYE |I''R`vcF ƹj5"zwwFIMe{EuI n %,«K\0_-m@@nv\|K7[/5oεpeѫW 7}EWRg" /-_/׶bqh5tَA%^'be1Fjmm%JTRgwIwx)YIX+5L*3AzM$Y;"FNPD fG{\j9} C1uNahheyλ޻_%qy|X˰eqeٴx>"y1@u6!Σ h4Aø8>>UJtӪL(lcѳ˿_=z;\y`D=Aɐ Os" ~O~ҙ&S֭f;yw۝EWg_XB.<m8yJ5z\kvӪ,H^<BX杷o&Uj+uT2)ˀ pΝs-c0d" J^ey1Z]jzw٨ЧI;]+(䌆q}=ERFEYESʔupx8@gl\i\fTZEYv;:TD4up3 #Yqfӡx^)oݺuR Nәil'%a3z{zz2 J|;q[_~%oEyy<Osz|{+}6Vwvx.hY?+M6N~LjﯮSBF.NnF0Z7g[וQ܌y6:"{)g9/ su]T~ٛz[<~|~ -Tv_H>ӓ<+~ӷU읜ϫ9 :,0.+='P-8]mN0bFItN,j'EQN[p` x ΁ !P:b ;0|.RRw5q݂tϹP*]=²},E'қw`1 $_Kťj:B .U'Y.8/,JٷE_ڞ*y)rSLqC.9w.Y/H\٣xtݣB ^]Zevz4 "VIRŊ+%@1BR<Y@̠]6Ɠ'VgۏFl}Jt(^7VzD,R*GLJ&Skz3A[2;B6t{Ziyݽg%Nj aP\hp4# ׷BZS:>zCJbLH@!dR ÈJJjAzƨMi8t5b~sccγhQyS͇Gl8 g8QHY679i-Ee%"_W t0pP (.'$b2"0!TY!g]Y++ݢ(ѓ|5dAI.Nôt}֘I6 fs<iA8<4B E)A#i!NR̦i3e!LYq+p<8t+mr>-ʒPI%/P =0eRTQR>QR0"յHU(< ΥxU AERFVvos$>CeAj@X:#$Sf=}* <;IѠvp8&b2A&`h[:tw7~ڳP᧧`ڞ{͆_OΨ7-"p4"w8JNOi^YzϧOh%Z2p|:!f;==>붂^gmcɼ<!^ >Fzt|gwmu}tE5xE( (MTJ=)Ťd IlL5_k0H)A魆&$ G^[-$i@-B| 0B* !ma5DW9yMQqL9vNsKGBBz BӴYW !3A'7fYVNN4U34MBӃcc&fGjV5us~^I&T*'?ټJZ; D pU3%C=課gJl6ű;N*9NvjHRJOO˲gEںulhOO%#^e>JL6nmF:4"6;SյUB\ <B)emsJRfBpFjojPOWV{qʬDz::Rx=zoac"XN']QaH0WAUBrX!\+p21v]@ r}1*?:dmҊW+ٷ$Sof\ہBӋ(W`NsܒEwǫs5&uW\@PFJ(  Z%@ &\MAkBIQ#82wAer 4 t"L(ZE; IDATxx:[1 g'_Fٔjaɨ^ y$NRbUzyF&[Pvr:̓ywۃqOEPni˨1tER{:w(}{]=3]Yɀݽ9K{}Veꪦ*hqI7oSgu]y6 Rɀ0H۹. %(Qio;m]UJhPO(qv },5vQsL TaBP=Aj$r3 aQ. p)D!:O(] "a\;^aHFLXХPc՚\rۼ0S.J;%8j3B(!R{/Ѥo]8BK ˍ Kמ^ƭ0|k_oƯYݐa.j͆L]5C4a]v;[ {11}1n򳽝 J,;i[zK{pΦF'IFQUgY˧FY>u6(mmGgaPթYGϞyпMQ˵ug,M%9+zrXhmZeYzB$juiv+j|(n[]&1PU:;F@\ma0RtV䬮 qI":pmk&E>Yk| at6VIQ'ѸW9]otW'g=TlprVukUUx,0ZE4*HüQ ޒ\<{$[w> xoϣ7 z]8ι2H\答1m6Xs54P!^%cOpQĥ,Zglۛa$zKJ @%pQ$ R)c@ THF(<HPfjLgTQJ꺢LXˀH)`3 (E,x\pG/^xe/ @Z^cUPnťF<{yt^ C/alW!N{.ҽd{1qq! w/+^s`}ȡ +mÝgêiLﶦVH9<5Qڲwv OF?WWh8:=ŝյnG+׾3ldiR}wl'4ϲٻS͎^Z6;=JQ~ppTO Z8]8+JIgݣ߲km//?=9w='WL4oՃϿxov2E_/$ +f+zn_wugO>iN&hRXη|/PO zsjcurFnh ¨~ lVlpT7ڽ$T[ғ' ۷{D9%Ɠah6{og`0HV+r< D28 :4&}8\[e(EG}\R"kɤ6JuJښRF)碮|6k591RJF+*N¢,NB @\ z$F)x(R-`/bf*k q)=a1F*ۺvO9r֝+pAxY.0O.&2<ד.x]võ+l^.R鯝հByedċ }/[8j2hy\/bQfģ; a2Ʌ &&D⼩R E)\\)\Xf_d / y1"U+eˢG"]u ̝N-uA'|u ~pN/:uU&QgSMګUk23qNiYjVkդӐ۩6tZ4Ҏʭ,UgO{%_>|3qΏVV_F&jkcw>ڨoqR!v w[ѓo5D&F{lO5SeΌOv*PIԌzv:R*htѮ&٬z˳Hvp|7l~wg?/?oD+?nq{ӽbm}=yOoїOr|^qPb~"&v68fu'g5vxZeieYs(<g>&>HU;`8vè~$SeQ7`xt[֡$C$jˊ2:ZGQs2;ʲjUIBWA$1{+ݴfɗ{ݿϨ?}xH}/|w i=}/7R hy_4[?έᤠ f<9 !m@ YK:4LW4lkmGZʑaW6z}m\B f8}d<־k &P @V?j,ጂ)Gw|3*~8NNge2= {40BmqrܳS*u5 ]ҺȲ2+9R$0I甊XoT!w뺮/bY+}_^zӄ69|A"(@(k?\*EDǸ8?rhpz~B%5LЦ0AuF(ѯό1Ůe1*bnJź[ɆMB! Pz5*Q< scB16hNrP*Ogg]lQttvSк<Ɛ\k8ͺk9FYsJ-;{r=K]m{d:Qoש_t>_e{0vƷEϜ"ſ?>Q=Bl1nM/%]:\t9{v1oRS/O*H8ޘ]:mx7dK^kiFkm]1 T C;^NBQ7R~ZO~QUsfN8;^ݭIVUYL6ai Fn8gBa2Nl|2/1FZ6P_콏/MEo8*;DbR ܖF΍;y[Ӷ?o܅z2m|V?\ijq>b0vy< 0ouW[(R1 *ʔbplꉀJ,n~-9IĥT<,5b pbpθ"s r[OPJyɽ_9l)skȦJ K41&FTd$%Z[@S EYYZCZ (ȇ" QuxuNSjLjefÌEzyzd荻UYz>ޘҺ3Zm-:zE6z c Զ7Ix`g| =&ј^nmڎ=iU,t~D8um3 F{[zOzٗ_|vr2XS'?'Bjr~3&wzkww߿5W~GG~?/e'lΫE?F}yKI^k/u-|ZoZ'M.L A/}&)N#"pS-ZIzQM}}8z5QVsM뭃&(Bf]]YxW!b/!:yFPA5V!i RҮ S dL"iH!hv( Ia@ԙ#cDڃ'?gJLrYk_Ͳ/T&ʹipt F2ʌr<I=ƃٓ.obg2]v|al0Y;Tô߿֍?O]S6.'}yz/Iҹ믦QݻNO2;e•4풻5ӧAJ;_}:B[ jO|:l7NpXڏ~aesYQ<0~ӏ\Y;lӪQESj蓟ǿf, g͖jd>,lZ~VjYezٴW1O|6uy?l|b}z0ֳ?{n}=\_N$ *e<ޝ Z6V_LO ,0˓[yb&$I ^/Οڲ '1z@ "_Rq_9Mq|iCfMeJ $mF;oNS;JBj#` QzbRBJ8g,6mkmƐ!a,l-Pb ',C牀%H , I vQ8 ʐ1&vLA$LA<02סs̬zvhbdNh^*Vֺ4@i~^ڔpѓd\Jlg2eaSy/ycOz~P; Lvpg\gG|0RJze\{]эѿee3MF_^m-e{VaYR:ӅY]s{l {|{h'Mh[s[Zg/+R(OGϞ^4곿|PnݸuU~÷j=:;HQMVt:\z>~[g^i/↑+ؾq7f>Y>Y1!(FɲYN^^7w;7JNOΈs3g1Dyn&aԛ/yQSwnZDώox}u`Vk;i3~ΖOQbWŇVYM[ww=ubU.b~q1sxwpzl~~<'ӷ.V`d3^F$$s911IaQZmKb߻њ YMR!$aH]̳8MScڄ66VAĘ|iY^AѤ]W+Ru E!(m3|0Vk!ܥJE}ZLwtk{]e (JdJ[C_&=oQ2f?h+]^$;c.WGΎ.vv1f޹ ~:r9*|HY%`< (@jR<ˊb\>}n8ػs綏Y<GY X374\LۚFÝ/O'8{CHT6oL3~ٻ8??wtٰgVicLA?z2/糦Œvgo:t]"(2vˬ[gQBOSdggbL('=yV ׷:`S.g'[[ËTY"y^_>y{ۓ;nu#Q?VGO]*)ƅAkv-yCTѧHdDD)riCE۶usyS,R0cPsۇJm2XtƠIihh B@i&("mmmBY1>vhNh2CHilQ~_)5N;h7?02Lm _w_oٯH^ H5P^L - *ڿ{ť~\|'s6w HONFB֫,}F,!j H+ @y@2- 'MPk iH 1HJBH]} if1C1|VUv;M4'H }PJ|El~oDǰ~tww\}P4>l\?AOv2m\Nz:Y3^? Mn2D4[6ʅ-9+0r֜iwOmP|Ӣ? me.8Rm`$f3!%Ѥ۶{s7n6KB9:۷ndxr`eyU5j PH ޽O9 A˲;6ѽGicdڙlmӓӮZ+DL)u[`{oуb:я[st I Ķҷu׮91*j9K8!"NS\uM%_dۻTU J9X ҮO.>GN8cMMlDBnnuP@$TbKz{/"Z"BDb$2L]7"lET?6ܾ} 2&c`@B"E* )riiZRdރ@^_cUІ)er ާN267j1D盓w!k 7$yaEDxUCwNW7U8N0dk7+BF^d_xѺ;#@! ^TfV"BZAl#  "$"i@qI+ 0pa%H(1Rbdщu$(LMH#pL-br!NlR"Z5*N)D6+Bh6( ˁ ,u=B.ĮW;#h B?wyCro}iWCٟLXlUά,kOVI7Vi{o:m t<_4R>,lo˭|sz'{7%6 lZ`|\oș~nmMfϗ룣s?ܹ\"+첪%n1?yD“SPɤcNzu'Gbմ>G哝W̙~>Wz8y0mWݻueȜ~oGu`0^f5ys@L)'\"vzG?˒?xro.f3 Sd+䏟 ^4RryuӧO./!_Jb I.Y{tYaei0N71/W NBџ+`BUlh۵'@޽{}_y~H"_,첼uH)E SRAiA)chic8;cLnQ+FN]PSlSm) lMz8E}lj̚r0DQ m6uץSN;bD2Z+QDH2uJl۵Qy~]JK&|eQ$H((6hSɦ쥏esuM6[ -p{^W^&ǾwMi rwNk唑BZ?]*)VԱs돌?:?<9X=H伒/u?=vf9T)qp疘p}xt|Laώ?{4{[hhvNޭ7fel2VkHob͟>>J&{dE|T7{<37M[7֍;?].m]W еAD()_Ҷ:cd,ʞsV&QU/WO,bXWeg][c ~7|H15H)u1j0z~:}]w~wvn4OϞ~}MrmBm|2Y sڳ_TbxO?W.Ng3?|>߂٥FejRuj9O/l;VymM^d=;ېژjvІooǤơc?}"(ut(cQsil U1NSg{cb>ryAD$\,WJ1Gb c4!j1]ͯiM+P+%̄ Mv($O*}ByS6ۮXIEʲ; $IZIl$5%AHsd _i^S^F-U/:[py~KhwoYeط C" g6D|o -Y**UTᧈYe@ 6~XVSDI^,LmD<5 jC`P]˴>"V H@pħ eQcQb$db "">f $E2 1Fеhe1"RR5h1i-&ILAAHP c}Ba: Y C/]ל,o_V/VXʭqv9K4NK|AqvcDy8VpluGƒ(onUlUom:{`1mn|O>O?jWr?S="sr|2y|llx2GGAo?g.7y%vU, ^_*les8ÃrZqU9ɰIpz| Sjosw8o!_ܹ}޻o ĪϿ|Roq٩RZ+?=jVMU lm1`^u1Z@T8 L97l(O9{=s" ,,+ b&֑@TJ^ߥS:f.H1&igI)t:2dֵmo4)eu圓!XB) >k$/J9&!˨;gz^U>hKI|CB%b[[jHƍR)og{We`KURAJEtCpCBe"; DBzckK n݁V⛳_/f}"axх(J&=h}ηm 8n]/P!Os( Ā@"e#$1& ]5Ʋ"dPB Z* HL>ƐUۆYi@)Q"Uq@ŘEDR Hb#Kde~1!!E@k(Dh(AenۼXͺd+Di|ŧGguEknflgnBVEQ,[)WdY)b c|/?y2;?;?9؂Kɇ)]AΌFYQ}i]^^i1V'?~p"mUUİlݏ>öYƓtpy3(Q9+?x?&v򡩪m7obv#267WD~^Ovخ)HB^$@'Rc( ٟ1N4]*b6뚮tEq(tq1_t6úiv=?ɸ흝mE;tr&{w"3ۓj݂.~UB:VYf}5rc]Nzy4sYf\x?1:=)SZ ڶJδj@TK$"DF:DA"z1[0 (6Vp8Fb9||R2uƺ%@ AS vw63+3W\STd%)mn` a)EκS QXH)V4uu/Gۤthq0%Rg@`N"Lh/|]")Aw"L)pJyd!l)2Ε%]@ 8ab;kNrw\nn~-%ڊRČ%J$q'|U=` @CQ%$x{c۴,e֋oFHync7^QSeXXQZY ϝRGƘKv-zde3cU+2s9;=Guڎ9 t(~ #iPJ[֦Z;MUl^իf9*C+6"$FŊVCX&+l9(! *M8ab!  seb2ʐQMӍF# ;y*eC[~Y֩XQZ&n2BH UJۥXNDMh )E{LVoR:D 11brdj1l61sB۴i3^,戊PI ZNI)28gE"TwZ;$L/(yNl7HLje$ZzQx M|5ݸJdNxeӁPkO-}W!ba(ܦ Xy1" )F"VHX|+Ⓞ|b VˆH䤴"cQ$|ADD$ZTI8hm E$ps,Jwb 4b IDHȦ)1HDStcK6,J!$B}Ct\ *bDiL )low[\e AENӆ}( i+1En(Ya(@ILo~3 7M|[鳳/'OΘ:I;_|q?/ݟoȄR@Y\:?CiKж(NΞFťYUs^ON|Gg f ΕsNc2$mS)\^0W0Nr2&s*&;:U\\ (qJ& [wvպf?mcX.+5[#sAQb_?:;jR4!FI 3mQVw~ a_>w>v|9Ukmugi;nܙΖU[[8f9)T`u^8Ulg?yʲpNO]źe^/.DW^)207ue>Z/yfVof5VZK*Si Y1 M1OZ6Nv5wA9DЮkcd2ɬ2F̬W %7M#¦Qyee45'aa$IP"fI$rL)a?BEIH u.W)Ej3ͅ+7@j@,ӳ(F""=phKF]YD 'Dj$"dYF9 l·댵1"!2 z @ RfP.@! !0b8M;bDBkHKWB#G)Q)SR]c˜RrYƜLNi PmDDJ̜JP)y)X@V96t _b Y0^zb 7ufXkى'&vUF1R38./K\pͤYΗ/^/Ǘ+4m%rVV!ͷW~ZR Aso9/w|Ç^OR^>_=?]M>y6~~w Z]]~F7YqȐ7>n7G'Oo¯?z|2OhTo.99_]zaOgaٞ_8cUSwjUS< fkE :M^xx;EM&c-m :Ϫ>}[_]w}5aʞ}yh6!bGgQ2u5p;o|gG'铏w޷>y8냃E]-./7767n9}|sT^̼7:}qVfz:醤*l'7a|n//ti $T5%y!*I%WZ_>WU(4mz1)\'mUTz'9e*YӰ1Dp3<:fZ! 0D&>Ǿ:8lhUP"@WZI)!QRV2%.HU D9Xe .kV^c5GsUCCp fTDRAFV FLp_MώՒH 2˵gfvSJ"bjEU7+EU @k`)9VU;o)s;(R?3tMNV"#Ѥ$Ѳ>ޛJ1s$V|Eēgb)aU5|#_\)%![_K2= *Q0> 18R`sΛj Evq$)FREv$#P J`ώy$#DPB=]|8_h19e*B<:Y l7ㅯ݇b)VSYΎb6j| E CXqNC8)Nfh:(4JgD0-f??i;q>}ܜg?R˫R"٬=&'?9ikɪ q,+0Wm(h>y",d1=s/?uk*3tSPr| )sELQ٭W2;'K56UKӶHsAf@E 35fc.2j7L$20ZR1Ru !3$!xUm1fΫ!cj5"@M P7ZAVdPUe6d  WŴoj+ޔؐմ)uL3!PjKH {S{ ֝0;;BOHX.D 1F>ǡ!>rˈ$`қ EˈfRT#" 5PbT:~6 U$D$ Zj"x{wnD!Y*YI)K. $5A`+Vr."R/YtV4Τ1;fA42"PMMDSB;n31t#QTi{혘9\6D)8By!gL T=/ݮY@}N,f̝;ӠǷ4m&x2~LfއݔZm0 )9&t'/]x'?W7Lh)q:^L"c;/sVu勫]_$Q>^Ks󨭨:\[wWyҶ㸞-"j]7lv9E;9:< '"C3t]\:D&B&Z;MS8*|yuxxt H$Sҏe-pgwaY C@QQU%dga8ી-a(cJ96gˣiG=+o-gǿ<;%/_y睻e߾{O>}wH~dxox`1#i3|ӲB VWbQ׵u^oܺ\ٍcw4W>8<*%zqZaνo֩Fs6{nfꪯ|ɉL}E;nu1QZf4Ӌn2'xt095t@je;k+-@քuTuЫEs(y׈'$0Td! %(`y~TR^{wӐ XUm` @EK.Yy0fœ@DwSPSb*`H@TZC"Lw1R$yZ r.(LXI"*Q%P%S"3ˀ$j\ 5uWsPDB`R*d$F0TŔ:'h 2(H#uafF$FkۊTTu2(T39rL{Ɣs.L(r-E\!E\Qh목+c8맓gD,Vy:^'jlƥ4'Qɇ׏oߩ=u|6YLٳ'I}uۮsKEDŽTUh=!=ywߩՋ/wM]'-fn8\Laz_nnPqBtv߼ni{0;rհ:[,~reW5"3L]E= t:4#ރ\]*G9["jB8?;?/gݶ}v:o|RyxWUGyɛo-4fpw}SjqvWY Z"u~} 0agi7mדm6^|Ew㛋O>?gow7`o'[yy5]m;ʛh*LS[!":SM)cwOg񍹀Vn7s Wk ɭXp[Q; cR"ԺmERQ uFʋq1bjҮ߱"I$b7`&γȐTW!v|x9 'ʹlם_xjŊZMSdڴvwq:TWm=_ެ;fdSU1~󣣩|SvѴ3+Q wn*:'1*S.$ eSL*4* & ̖^0C-t)3U{.2g-PQ[=E "`H__Q ̼GRU4bdLM!R0&B@Tk+!8vjbA"RdD bUd`dR:QLKkK2L 0*#!bCUQIf:+BFӢb EqA PY(1"'bt*Q)cQ; V5):v_()'&&$UŜ+%S MPy_LQ23SQ34E5!Pܷ+#""]`'bjאp@^PEڦ6&VW>lQ*2Ѵd1oz̷]FM?G?k^PwWO;+38raR&R = cTDbP`;Y,O]GӳOc<{8ᓗOc,&ՁsmmN:67|\R޻RG)aCWC/ǿd28 g=8ֱBC5/\}C>cDɭ,iw/yLj†q3nV:ԝ -RӳNQ3>4WH VH 9HTGe 37[_86˓g?Թi7z_g_2nbLF33 40 Rrï{O~O8_y \rٴޥb˩C$q*8v)m//ի0| rm6d1-Nx#WmYPݘb:TJaDŽXr6՜B }4hXP[vBSfT^u<Ռ ْ~7:/oݧ MUQfrr6lWQ]׮2+LY:}zhXHծn)f7 l:\^pk''_wݶuw἞0201gH6hm#9_R\4oq0M7}c}am_UHtt5=@@v笫sΞA8;LzP#IfM_}2y1jC4]Kri1n;`p,ZE"j&4?49-(Ģg4ŮGxb P14dSJA{t} j#"5-*%!;2DDl`yLRР1- (bUA! ̦VD$fPv+x")]" FcdJExouWUjhV>A$# @Ʊ}֔cFqDT92PaPu~1ZZxd@r`ExWUMJ)d M ФbLf&H& B1D%4lT,;`Ղ,~/C$Ep5d$/ڠXBD2H`r86Nۺޛj7Rzj,;󶞱k&I kK4D)R:UƝjIQPEBܹ圽Ũr: v:[M v٭wɼ_୻7:û~xͷ2ZhUfݍ;OϮv8CԦSֻ?}>Os4+̦\/7^@/nC}ݹrf> e}с$d93NZfugg7=8: ͦO0蠹{gzo|`&vj~lԷ~|G7)dNgִ߭K.vA,vžfЮv1kb#0*D'%3qEb:2)9c=ϞvWYN&mUmTC𮔌ZDh3B.vݾ7 qTf4mwu#5{#9"Qp0u[R6ufO齇&g(Ğb'/#UU hë/Th>_>4zsUJs9.brLw+8!! #ojIŘ4>ƌ9i8 +hG`%p>8ՄcBs6DeG&EYF(D{oّ mqfVfDtdM" LJ[k+j#J5co5cUm!ĄLd&sMMU4"rM/B`&DU&PE`Bs"<΅ "FT(sj pXJ9@9̚sbm7g"9rz}q bLGǷ`"s<=ԑEI*U9%tybNjj*ʃ>yZ]3u߬g׳m6[|Z4д trvÜS''o޹/9 7o8:s>,#:"~6Wnץ5䝣Rd)4iud6R@ɤ:)D ˃Ì=~DVފb~[*}>02CV49d$6@bͧF l6 -d?pL}~7f${?!]׍ P*9S.E>!L!:i46@o =(,v;r9c*(ޅRLC 8@]캍wmkwF$jЁu//cڣz9݊qYp1۠M Nq(1YeZUM;k|yxXr&ۮêogZ_x;;k_ms eߺ޽7~cLO>oVW!H/8h9v}Z\OfI*ŧu*TyZbLC~>\6viӆ֣d-zyzYW[b8<^dm77ݮh-"11 $EX4La[yh7Uv3NIBYUIcjBা^.'m+ꤚnstwujuޙfܸsr Yw]I*V@bb("m(dv1.vِ<5u}=Ug'7xWrBR_|T4B'٭7CR&Yӆ\zD&bLW/._<>srA LEs/,_w.n8h*".*nXmzPiwH!dm~P4N{OIv{RC?\vg`Qyj]MoRo>,>y{]>~oӼg8ucU{|i~w\]߿P5ϞZ懇|{Mk(yG]es_n?Ծ8~qmw=9&5{7)_bL <^ms)CPw4V1p.%7MV4眧iz85ͻȽiU<#bhRN0H:[_G4x<2,_n.blUGDo4UHfxٸ݇wӾNϿzvO/o޾xC:#AA㘇ܼ|xsm3Pji6X 1&VM-K(uErd Mhǩ:{Q`Q81 z"(.U1C"!ۮn%&@\&ʜ0>F3)Wu,by:mfZkĺ="īdFP`6$3HUSʉ1%&@ZKV}pVQjK;SRP@QɅ826x'293b&5[ΌEUAU گKT# E9/k%b< x"K(1eD쑢Z15LՅS4)33:830TtkRK!E8{5/9P!gZˢCCt!z ܄&iå9/OaCUSw3w J*1F[^K!R`bfP,,I LMCmJv7 H*nt8ɲ)"Pƛ7q"ś7duo^21_u~Nl42n R}EA!5Ċ-m"9O1ۻ2NΡ]dmۻCNO7ꋳb=h4Mj5n~_<5gdv1_{88BӬ/Jj6gi]Ji/7Wzg8t_GW/<&|z|X9O?}޶HlVjw/_|s)aD$ğ;;W,1j"V#*Q2STmN Ȝu7}פ6mJ1_2;1ݤ cG><Ի\ PTLz]u7it,T|Nn;p/>O7/^ DDh ⨫>QCEABS 1Um&Rj͵R!ČaĀJ\rۨz0v/pxc۵B\Li Z)~tI)%A4"Rͨs7 BhD 9g𕫪T)aO=(&u *SC] m(Q1Ep.EAD*HnbMPD0IŨl89C6 2jZJLI\! fb&Or.F")s`# bE]86,9":Kl"+ NH!XeۅebyZ*bϥ4MPӘՐI (M!4mɵ:\Ŝ Qch8x AfwM] "UO#}tù!bdNńl̔RSCc6W,' [26ۇfF8 ~u~}φ??~.8őP|7%[y0B\J P`4CӼ̯UX56x{Պwmo"x mYmp0UqF IDATMR7}w7I3rso:!?Oѻwr֫ٗOͦӡ)'s1 lյߖngԯ6>]F]CԆ2"8(5!u]s~of0Ę 'uL)R4kTgǚ@JKǠҬUZc"cjIT!DfTLc*G-WL^R=b ! d.NK>Q*"(Ȭ&f"`ud_\6)J 摩,Pw !; T@`NT`uWFvWTcD[Q$2S.*d>TMQ%ƈn y$3HQb 5'ah;qME.F3@p1T ILvlꀁ璁9H1 lZ4"4܄@@PAsB`s]fȨ1 Dx &F 2q<~  iNZrW"}z^ηfN%i, ]!6Ukۋ؈yTyVB:t4z 1qlƏ>^Fꛫ:lgD!~!CjbL#3Ph6*"JD%\ a3Nc,!v""JjZSM)MEڶ=;_ndAtw ":Af"H Yc#ɲL!*VkpSQWED֪8(F̉8.d;Mbjh"s :@"HIMRJ̉]2R$S;<֫<&4 q "M&@"Zs.&VC`Pe\ 4T%"6M"\HVܪC YiePUjU͂v37e\  )!H"oPe 1Tc$FS%fb\ 3U+й;q) eU!SL̈Nf8`@@@\ܙ9Q,f,,@Kڦĩ쎵@ Kuэ&lVo;0jۯ^W:O/mo޼y~?(PkEƇNy4lL]׾&qPS|}_vs=?agֱ "8pQ9-o)"l  ?CX>3qX".fQS5G 5WXU?RS93Y5eb5E31QTwZ?"BnD)DWsq TER}-\S]EUU *5Qĥ>)h ZӼ><86|o?nާn94i#sVq*C\u5񳴽 C{uw'^(z8{r{ι\^<nOSwq8}77fͩ ,E<ѽn/9߼xiN! Zy5mbʦc|o_E@M1lVbCO`ak#Ǧmw_|q< p5Mo\0/ð~i˲l"-L#(VkRK`B.9IsdU?"n-sjDyoK=0F<9b{T&}wg~ڄM\E%B;M-hmRaXCTsQAJcբ23-ɏ~GBqsbhqJJA++1b5rb_f ۡrzoPD۶1" "|{<&BG0Um/JYĘ; ϓV1`_sd0 /jQ!OutjKH &5>r&FtXEf1;JYcT&!j`tZ2 A1 &ay2LM DDfLh[SXHm Tl*ĜbX ?~"-MWD'bD ͗U11pDUq$Rה_ݑ@BSqLhҤXVZjVRAеH".LJ ,2W7hn)EkQ۞ j%pr%13KC` `܌   LKgiBi93ar"'6&bX9:Y֢RIծ=~vC_]{E }mPŠh۶bcɹk3[:>|wMy{:i>MmGNf=/^^? n.~3O?x?pӸA]ϩOHԉns1è۾y8Ο|9Mg7u: ]\r>>ˋ__߼*qmbC1'Oϟ~\yWHϕO0f9_z㋧ۋU4$;pw`c7/#'>M |'G&Hɳ1F7T` ڦ'!uѭVjY[~/;,i[=;?7u5Pq\'o:0)y?([׭r1hTM]?ξjvso'*MK77T0nuΩma͹~򓇓_ϯ2bhb׷Ӥ% ňlhEgpN=RT`'Awm2&R[i·뇶kۮJZQJ-f=)Y-ystWYGOc% 9cn}ZCaJ:M)4 Лs!1W@AT RөcFmjC`TbjVMbI3A* M-Ei̳(j #Q)0""R]MX!\DU1HUcm"8x'ZYgNfd98QT0sTC<_0H.fC$31BW@0UDCrDRZm9O92.g73 #B,F\ i%tPl}i BL5f 1acb̡*Gx; Hhb+(WSgS4 o`n$ H Llf(p)j۳Vv2% [w^:r L)2X~;I1û~v5N5OM38l>ٜmcۛ4QeȁSI-?9nsn9O>{?o mMZhp{͌m9O9ki6]z=_Lqۻo]Jvm>9;tNwWWc.vk}xGaǏwZffݮ rh{9D.O8?"w?#?9{oeO8nnO?9 1 p9 }{5>M$b)YIMԜVP OǓS0T z* .ᖒv@U:anU h!֬fdS׷j8ۍƀ6N1#"fKE̐HeJL UAD1v}8fmlNZ+#G&&6wd9@UL-8 3RRľBY* !2QqԤID4NŔ=ڬ;VqDcfh)r\]MM }R`.b*\ y7-`m: @FKIQui@tE*ʼ|" Mr ׽*ceI )@DH!*!.œKֶߏnMlL !@$tC70a$t!:rpPbVk]jة@T-4\a5Ge& qUiʫ%b\ PĒmSm+O|o~?M =9>_>e"q>u !6p,1z=(xZ6forcf" #/C 7(Jv \ֲcr\Ma_뫛ɉ_7az! Lmx| JBiۦKqho^ĀM#>p_}\0M޾{'/N$))8u]j̴[}9|{J,L4rd?wl?.Rq?ݺyeon?|˿[7ߗQ-zK]Y1gRvKRǤE} T!K?|楖i7w~0~훦[ua/~uK]c&z8uj;)]g5K. @L}o *UJjd ZklZ:3U2+cl|=gŁ0[IDkM;x-cje6Ŷdw8OS6Ųsd]Xri j!a!^S-7fN4)&@!% sZuH}q9Z2<Pc TI]< 4nWZ82&# VU3Du2" j+`Q-&D̮VW>dfQud6M P/8/bY"JR͝`y1@;#1 #s-%[" 1$S50W7r# R#i,HL!)332Fi뒬Y CTe"2 KՔ)2E7ȵȱ]Ч X0Q@@!TgFT,!*XJ1`3T@teRB?l7g#yw'D,*9n]i ~>,xddMRۗ&CFׯ<&a՞d*M^0+_h:D|ﯯooo@r~rvr:Ix9}+l_w&]>MU}zp*OSF]8֣܏@1rWM/~˯oOj՜̊X9ܔwz7e (6"aϞ}2S<\:"@ I\ԙ,g8777fBţϿcpEMkyz70lڮ7+^&Đb?pp4 QD(yDDX1ľM!!u16m@~gG`_RJxwso|hVqt#Gb6P"xl5.=ytw}f>%U\|<YeBڬ7۬ IDATV̢\b A,Γz ?n]>]no3i?t~w)'7G"blM{v!DEu37 UZG -`q2x*Ԯ x ؍\6uqITi=W_F8Gc>5MZ ybw"U%dHE+ .|jCbD6@G&R`D jH DJ~Y  S4$U ǽHED @jNdLQՑQEk2W#`P>R(h*bqʥ ̴B<1 RCY2":䔢;T@[YB St(mN&6MWP ytJ]kⅈ,o  L&գVsBvBdUD!HUd7J E*mb1ݎM=FA665ۛwW?m oP,c)L~cfշtJP>kO??G{5ٖgzi>̶eNf7HF+QR(҄@mcje>XjWg2}^qNUvf}v!61RsWunW=/)/^<5r?ɋgwÙob~կ i yb{2yӬji}_]"r\ [Hsi\ t~O:Q0_}5 =Ԛhյfz}Z 1D;~]Ʋ&Bbl0 U۬6!6; B%jD .x_xLD*;tSǓDHU KUbC$ !xQB*UcFE I+9*R.g"@40,U>-ZeK-V92a.][uj9с!T ,OTkf@ Hwf *9rV@EbfRgrܰ-yyB4@@ؙoy.SVS(I{]/hB 层*cV<&FeGXoo RjjbO^\ v٦ӹXDOa囜jUKv:NÔSuѻZ}j6Wk~gdxTUA_Tf||WXu{թbzZa` {9<x'~w{>KF[mooU׫xUxJγtufѮmz[TՔOnjwzqdͺo&z< + ˴Zuʨ !4_oLJ4 ?~&oΗ^̈1dBq=~}&!f{y<Hj_4]kA2;h@  ԚExrJ*\0)m.U$ռvm+ex]n]4M kd6.P|Tbn)|}}sx3<|qjntSB^=܁al??~w2Ss޷0u I ?OSʷ>V]v^j##4Z ѳ2Pp0R*Gzi2ϯM o0s9߭VI|>Btsƅb \@EaP\vؙA'B?fl qT՜K4\_ߌSC{dش9Wp>OWW>SwO)ƧqrvW~g^s07w7?4WK1cMsVU.RGh&Tl'e\]8֛i#'smmvúnHjM=6HmmaHR{w ]שj,%>xNU efDvdK"/Kf "lj:i;LecDZXLsm0jT"9 S2:f2td`T̔HgMj`@ yF'V"" ч1-|)OH\kY \\G0`G.rJM,@@S&Z.W, ((S535jզ\)LT Dd9%gλcRJHsU{&B./{ pKfXw"8 ԡCVʜG"F"Z$B9'"̹.H%rY"'ǮKX 25Ϟ=i^b-ÛWڪ[q'&*mM`\woP_W6}2 v^զimwiهnۮWkȺUssK@@5]i}I׷UdӔUx:Y|h ]Ztkiu9y||Nj.zB_]T9=k4:=m#&0xO )M#E0\xRh7Res@(bUhy]~u^orS5xxxp?TPR*h?i`R4&Č.ñkfBdԨ\<&Ej- S{_79Ϙf m}ȥO߾6t5sR~^U(cMY$M|4LiJ4 Ͱ#@3#4l T@$*RE ]$Z1~,PZeL L'fPE3s^/H("d&HH *siV_! fҟ !("2pG"Z-%8nHU ?9&B5-@U1Zͥ.m C%ƪ@̵j%r"p j* ѼDDH& &YUU#EMo` =3$j!>XRr9 񡨬͗}- bMh<mݭֻWS,%sӘDT%ԢssJje]߉J9vMyņjp~4iq#"Ot>NiLZmvm0k17剘CRiTk~xx|Û<wWYU M̚Ux\ͳϚNJoW7}jUu{aǷ5Ą)O"v 5M@>yq7}˷o^*ip.S2JIsIsP !MZ9FB@kiJեqĎ۽}@4On].aJHpnS*s .FM/L"hb7*f*4OᅴNύ(xV-M+z)G+v5N?4a.:?|xi_iVc*C\?qUi^DAݻyi!' iʎLo|!*i\RYlv*Ķ#d0D &SY0Jf`n6\ZĩHߓHEw!Vӥ$,&x"̥ E ̄,!ZJL%d9-H4 = SDUR#2re }T""1!b]64@DfrRlS1{KJTy"E.OCHLVMjC61DءhuVPur_BO~b9_>櫾{ի<;o^>}?y2LNisZ$2]&6]7c;E`Z < TWN$McۭirhӐ|i%8육 z?ID i`Š]7OGDW+p#&9,unCWARB ZKJSʳiws}{1$%粡I)< ??O6̃%b>d1v+i~cǀH̬93;"2R4ZkN_K^ ZBF*3*`qiU]Dp>u]$y>~"0{U>wnnsO!^ `JZ6j^}W.D_j2k=t<#:zzacp7o 織,_9ŏܶi85MSj5PBH`jɫ ojK#\tѲ83ȩzyxdhĊhj='U˗˅ݛw!>޾}~__)6UBN)v-j2׶9evd߻K<*)/Xj1dXRY.6RpJu>Z:+è}9RC(l@Φ|g&Tff^ "4Rf}7@RjB%s.:0V4{Ah5STC}&xUjӐd$;xڬwyv'nC$ Hm+1 .&ƶ-ˁч1{@\.77ÐBGzWH_oLWb6{dtnWۮ"(59>77i8o;bΫip^}dx2@bfrOTx:>.KW WnB'Ao6׿p}sڊV߸sUK>eB9ϵ1 *-&HgJ\Յ5y.!7T"pUs@ ΩIJc&C1HQ-D,iY*G)RJXӄRf"lU*9֒ @Uc }"REhL;p) 3` \ cÎء߰(1 (/F/}Ϊ P*:U9fV)8Jĵ@tyOXDjNDT9'*pf&ĆΊT".ZEL&cNZ+5QѢ*8D4uͰow>FF*XզO瓗|z<ƭS~tQ~UwbjfƳ3雖g~`Ç8!zc8)LAdM96;߼;M.n I1'_f]L)<~3˻5~ݰ~Q0{r] f٭Ѭ555OR*ճgDv809XsCiqg#7o=: !Nǜ\͢k }y&ĎSv.csM|:q$vFM4&"w}?]E4UTa9{cUY>@$d&S*cǝgS&F=:牬֊`fl˚LXڲ!R7bT33UK`B H HEԮo5  "2 S))P=7^Yn/:rpMhapΙͫuos ?{gK_9ĹP޽cڈ*w^[8vqKiLs ti۸{rCZ7]ׯ@mZx&UB r*<{d?<&QaizS$ 6כ~'i繮y-c"4>"}tZ<ޏ-.T]îY_%ϿMG7˻sz*MDҼ^AE=R*i(5K @@ĥMbfq%O ؅bpƀLX@@phmWcdFGfl D"Z94a&t%sQDiV03r.`Id@]TaΥ\2e *ё¢U*;10TQ"3ڂj6"r!VDI5GW*33 U*hQ`J<*` VU Cd=;T+"NU̖cOD΃XEFB#BFT"V0EN _JR*fEU(sK :ϩ Ty.!"Tb B2b@Ԯ p*B2 +#:ߝ/'4g'OK% Ziկ2xƠ]AUqL\EwjaB4yprJrJ*!4C:7Caծ|tΏ̎\tx]Q):Ox>EUo_< UO>z|wl'W0<'vw9aI0cCl(χ8ɃU<O^~{W&~"sK-).qy`?o~z?~?|80n`slfI)0\q VJ=g"/4oOWkLn]]3MiNZcwUhk"]w~G_no^lbCCϧ%pc/RRBW ٙ.MMnoU@$Fd@f13躵:$}Qρm' \7+xODD(&fKscOCH? #"#:0R0%' @  <3y\ }ʈRCcCv}[KZ˅\nѹvӍYͶ[aLMhetM^? ^CJB`TC$jWmJTJmIo㧟HR_c?ܿ[mV\; p4<={vs{{?zqss= t!61 @ȍ:paF|<_ -38W͓l۾}M`꛾mg>› J'OOC2 aRepz}[UXJժiqvZEJu5yipηt0/Dຐfբky,5+_w]ۮ.PUhwu{tM(5ytMq{47k*}C_ksZm6s{}sI4ow}(xBsdfZhD:gm\DkvMK͆.eqT)*2\9L8WeɁjGBNxU=X1%%4i åj&a5Ab3VTfT#b"&t.+ `9!cȼlP`fR{ TQke$bFGpK5j@j]SH`DX$#0 CcjZ@+؜w)tM i1@T\44Bc"4$pa!~*q ARUEB rDnAQ# 2WQD1D"ة9'&GĀ/F: @Y0}~{~}s2TZҥF&'1x8\\c9blx|AP&@Wo>LcMZ@:fiۦm?70#9v4n\ЀU ?{;1V}۵Y5Y-ۧn6yLhn[1)@7Ot:Rk7.KW^Sqp>]w~:_r M#\]oб4]WU~;>}zt{o9 ~/Ӷiھ#;vK? 8Kͦ꧟n?ti^[3 |:> j+i38U$6-;;{d%vp:gy| Л.O^4]=y[nW5v8O ٍNͳf{9V]^}uu#~Z4B25=S]&\Z3]c Ủ:αE?’sn QJixvlLV( c爳{%3sΙE0stMCǔsbfbO"bJb 3WeO̲.0f4L4ωT T؈4^Liy , KLA  lʠryY5É쪲(ˢt5Yߍ(9ڞxWJ\~1y% 4:t9MarqS3%3Dm6U#4+HT9'yx<}p{zP^CLJ4(4gūsQUd)ɇJꪕ$ˢ,gguSiƜZ)h_/_bewGU%t}b{y:پ84uXm"]7ř㌈ЏcFȞ4Woz!*!T"B<8.̠nO~~΀@HHŁ=b vz3^e4d2Ѳ(~lZ卤9dqp^> '-zLj:QLj/ @)Ϳ7ǻz۷grh$Y*/Dpcg$EE^E!MBe%FTs +8uEH&sHDU͈Yd5YTUT58_xD0d*؁)#0Ę$sF$ !4焤xQ3$! rvC@mjƒcCKK /;R[ٜ@P,[FG99BbPP/eIE(0rȪٱfG?G@\֤?+SpٓsiXxqcSJ >Ǐ@X@S_>S~sl!Mp:Uv:MUbݔK+hVUʓI@tRн1#UB|<Z׫C͗_>?=8)4-$ȶj6zV8:y9:Ezoy;EP"R[R7ia呟=߾z}3ulVXn{ Cca9) P/V.ɮ hOa'"q RNyV}T)hM(qVq:Ū ; |q,ׇ9wo's#̆7?;uXkf xX9%Qufz~jv$$Qűǜ`J@J~kdq@߬+\><ʜf#433T$N 5ywEڦAN%MQ ~l-~.gh cNc(<3v;)*2h ?O<xP'X.eN`y/j`Γh* ĜES T%+eY:L` {@0 {}IYW1-',.M!%+"Y]Ж(#yr% 0"~.Xb S>Bּ )!f0avy0\W[ϛi3Ǽ|/s*k `9)[s3 U#/3ȑ&dSESEaxځn߽x:}sVr'&iI07aUF!ǨB$MJwa3E\(8"4Uy^B O?|.ݾ}=U2'X |~zx}g>IYPȆ< + {z:BQ~()JUn/i׷ d:ejP7WoՓZ}x{جV-*;_'?Ƙap}S><&3GٶUʲtDzD0ʤl? 9)~[_|}ܝIOyp8te]]]VmےwӜ../z?y_F,} e9N301Ylqo)uˎU뻲,wW) 9K^qD"{ZoVn&g58y뤴(k?Nip\ة!üt}.^ϟ^?if%b#"˒TɧǾꪊ$!x(E 3*U=Y܁RUm9紹xz~n }|v>h7\59ͅcQpNlT Չ 2y#:~77a"HbC$DWif$G{0lj'7[t3q"nZ-Vm{v%/~,l/Vպyu߿yjwn7⛳'7O߯՟ٯ _o~ԠlE.nSwiժ$&޳w nyc/u}0O3PSu4Bպ3H"ʞ궨[(ƉW/ DUs+KR0B9) STARAgˢ¢fED4<;F1Se5 gYAd0 PQ@Yy"-e[?) :5i""jL XByP@( ɑ9dFhq攅ȩqlfU rLStHT8g! "fH9"FP7P4(QVP@#fLFL3!#fFCdsX1 q-.CCɂta_)"%~GH0Z?t_?ᷧT<~Q\8AJiqpiJ/r|qʣx¦(4% ǹ/+ݮ8M]ҙ\?>}z1 qN/^}uݔ߽e>t?eٮg=4xt߬64<]aߜӇw4<}z0,IlWp?~"DqUeݶ09ЁaU՛ UU @jOn'_v,6g72 "C<{f(N j6' "<ҧ88]m븀ȩsY 茶'T3h  !KnJ֏o)7_\?yTOy=CSM]֛SwLqJtqqPd@%?>ŸǢ,-gs(șaN1\\@`UQ ݨ+˶YW_3&jW0z7|׿9=]yr5LaPC})ȇw0p/xoWqbf9[m]U޹0vacܬ%;~Jf,XUUY妠Dmn)IMȣ#u[eɣ bYU b˓mʳ:1c"IC`QHeUrqV79[qr3xD hN`8OS,ʒ92[Yz"TyojF ) 9ӐHNr,Ps L+=y@r@U  @Ae\(DC0L);ǀgd$$Ȟ Ɍ @41;Dv#-%eti-#[ Ii)F$%\L2+r锖w&,BPPeGL(UI T @ lҁ4}55 "Ջy(,|s3y͋Od# 38:2`"_x@S7iY|JM㦹5yFxql/|dHYܼ38ot!NySVuA5اOwY;vWOP24 1Io^^z}Ff 0C,)gYJE4Ƙ\ٶ_Oc2ơ)fI<)U/ B3xW!OCpxuqVUg)؋9mg2E n`9(YQT v8vo1EMR` 0jDpiF >Dԇ>4i[7/^>ߍ}\WiWպxY uwm}~}1 9&h)~*CSMۏDԗlu~~<") CڪIYS.FN)T;/+&v]/]b;3x 1ZL4uL1+حV(t¤Y fc$F*hHVQAbv$EU:$ - B9Nq`K@3g9V-2NgO aFPl9k"b,#T1$*sј*^O7ߢj`3ꖻ4e ug AL X E "C͒ܖ!QM;r᪺t*ĬLU13,_VUTT35 f`UŹyhDY buJgv YM@x_V4S0KQWkI-+8O?qX*@CY66)ƈJb9FMS:|"l.W@}םWO\~o?OUذ4O ~G) 4xGlt{{cuLActy9K6uSWK^wٌǹ)}U ؼ9+~Ng9ue0qʝ(lrrMU8h#9Y KYںBc?%PTMTRs4˪ZR pQb@CNB3й`(fjsL0~+wŦLD /gKɘ2[N b ҞejLKE09*]D D1G9f 2 @B32@b. ;c&|HD]ALȤ0CXܙ@n.Ò{@r\R(-/%dlw""wg8*sb{5Dd P@U(/<lYo対~|1q_4)&ɚ&#ҳ~04d̲,C,izFYdcwql{y~w?~߾e(_<,硪م0te]} .Nq8霓 ԧMKy2H9Os2CpP!TO+4uደ/([4F{1njot^ T藤Z9M?sEVM1&İ{蓦O=i…g$U),pmS!>>08M;W8HӠAgyb&a ~8s4GpĤ *SrV3Y„H 9i9s(P TD2s)b>x@B LcH_y@!Q\ĩ,-ɒ WJ2C#~Q) h@Ĝ"-N455RMY `!(f`@5AT3ldf `.0"23bLF#Z`Σ P)Ҩ5g5aٽ’I6FVŴ1F@@jF@͈@@h1Q,YMCt j9eȚcF"'H$()ͼ U~_y8uSOi9{8^gK߾8 se(%&6T}f pfsqdL8uYLS\]lm~83?u lϞ_U%M>݉x(qyrnjxx{|c_+iˍn:fA^|/bX7aAQ`sb{48QŹƱ c?dfR[i7O Hd.Wqөϙ`0NdAEJyvyi3P)b9LjbuxM]{.fy^xvmf)%mʢ(]7엎[x:ycg8Mا8f}zsyw,7vc:s?HUnd<PKT5UKLΗb:Fiy}/x{T~H1Y0š`sVUDUYtmhs28tn5: դ^5MU=LS9O$S١U1#`4Ķsb;bKq ].FU!gYE} ŨL(DL "!xQQK=12(rHEMEr(I>3QECtyrV[;*ޓhgh-WLH PUI1!҂uYҶW~TEb4l*"ψEHDޑi^h4DcDeF@GcLb3х=8͖, 9 bϖ*b WsY{PŻjh\+SC0V_mn~=0;ޗ˺nU$9i'\yS&HM*ʊ$~п@_~YnNՓPXm]ix~n_<}ӡ{8ƺUlԯ/D?a8;?/}T'!Էm=#>>bRQyJ.\(y.xߟy8Q3%158Y1s9KYYvU 7_u ޕbe )j׍vIiҘLKLS.ϛ/ѣW&F@RҪj@TH ,qpP;͒bL9ԍ.SVa1UemԴeQ8F{|ܧi˶ o^}Pu(˶8Wdeޖhjw}}woOCYBY,3: ȌFeY"bmC{1qPI89ޯlIo^MpfuvwO<Gcq O9uj?<6U՗çqNYoS?o*m[# ;+jcUi&o1Y18AUð?ʪuU~B/_>Ô"OQqD2%PHcN*VK$PS(j@P8$YIdrtdiﰮ&fjt_'dT!,H"Dcy: =g@35 MŅL M=1S 1få Y3IѼ#&~YF>+?h HHŎ* bju;G"e1,T3{VԔ3"ybdò_ imH__?}pܟ /#"=u 9iBFBͺUݾqS4L)a{ǩVwޕ.ܝno뇸?= #,2K6up؟:Β\n./x\o<m ԍUb]%CwW5R^]q2CS켬 BQynZ^^TY#M33眷 "ơ(J^!!9?}z| 96Euݧ0PxmxY ŜǦm-yG"qf(MlsB k&`98U|BD_b MNUub{㧦 9Ncw Lx<{eYawl;@CtG%g[VmU mY4t*mN33>{v=~t5,sO(h4cnc[UвXiخWLAcs;Sh4N7,Il,w\kަ{0P#B H$@ @OIP鞭rnguw3Éjq p)8D17£D vTlEf\*$(CRx`w=* dh`5)P-DgXU(̔s^j Be"I1F4S!eֺުy"DUMDsd$\<+ssʦW+ KS@Dcf%ZD#9$4Cv @ :PDha:3@Y0-i*y~8~^\U`eDh˥EU0S""Z dfK4 U3`UN,?<?,<w1xW~OqM`OX%yt1,Y!327WڦHJcu8>iX.OeK*(]RC:e:yTz;<}8dAۍj(cɵ ݖk=7pBKIC6u˒fXr9Xnnw]7ֻqm6ArD߾Ӆoυn{9O׻OHeuW~ڼy.ؕ~<<!=>?=><<\Ηp|汫mծwZ4U cyyo}7f5uDf Qri_6sE]@$<ٰD  JQ̤dZ>T-SP5PAZd"yGZQBul04T8|=R`YCQEᩦ֩&眔j x HF"ZDe1x]eB'P@4BR5 .=YyK^,ETdX X1-DZ)c,k1$..U1FcGP"( 42&qTo߅W]5Qa  C2؏ 0GLD.Աu wզ<<#$b%vb}OO/h)0v]ow\w9Xt8<˛59* uN2u]]$kJ 0OcCGf T?}T;.N ~sSUE1nVU[sĮ]}P럿m fM͜oBUXj|4t:^KNIՈ_~Ep|<q}s;yg e*P 03ucM[i)i*z:T>_O]p8!m8ӄU9πy z5i{\`=U_]beozozՄכo'?˩op8R:NxvNs6es)$Ww߯>mƽonPaUQSsy2(UC7? 4M <)qn,nx?z|S?uU9@%APrqLp9SuUW^d6\,)Dy BpVhg{d@\` A D3_x!VUt`*f#IIJ!1:O &30v HHB1!. Os#B0r.!\ygٸ4 LECHD7.c&XSxHg ((!:y *?slKg Q MmiђUS&"4LO0?c#rRIGTGؒ+S)e. ѐP`) 8PTiN]?VjN9&o XdjMCPBpHju_W7r{TmńsV1aެcpD@m:C4lx0syUB띁H}`6#cLiaN]PԮT=(?Ͽr2]mSqw1 \s>E8I`ׯӜqxj94w%8fix\橜ϗ8ӹ;z{=ι$G~]o֫ "|VjTR),iWM]8O}cUN 07srxM b⪎DdxqA7MuSJ3 0_l^ܼcw: pOS'HdH|OiftCw~;G~mI'ʎnnn wSnu3sBqW+~wt黻çϗ{yݔnk$Mqm44s<%U,S#WŐ#N'_?t~>0M Ia6 իf\f7%) 5Sw<|)O9:_rB0agltG"|6eɂn&G0fI 5"s.LU%e'fCM9圳y~fVjWMSDfqɅ.S?V]|lV뵊S\˜B`Dmiّ.}ɥTm6Wnowx~OIPV _tcwcTKucn3Q]?|]]m.49 :zz:~xwbǮZ׀PU89;&bU 4Cn놞W`Vng-nSBl߈ t +j桉5v&YԸTj 5gS4109@$18!$# yDMUEy2! sKR٩b ")K[k^eU]-0();sQ043"2 E̙wPrv,c-df@a9֋ -!!E =1/]E˼zY\ aZA6i1"!)`aVL/$65!!j?h \ !-&$"%@`NjErxʈ9gEDprEy  ձ`S!9jBp_+rZ7w#( 9-%MjrR(jV՚|Ȓw xVR&D ,bއ*?orz:nNrf݅x|짳rٽzHc|8\4L< 0d֛͊8f^؝N-V=1 2Aj|m`>:5[94M qT~ӯ/(Pab}<˿]?~eC~?v8 ۫_ } sKr*ꅑWnCL!nXo0']֌Bj-bd/ݰj7;viV͚iVU] 4MM .O'2- *sߟ<cb.T #<o>ҥmXKUP):͓s\عXWJ=4}eBWW8;\#:]RW;$$f7ŋϿdcSq99zx 4t4/WVU 0W+Ɉ_^8?yZ_؍S?wV.aT\ݮ,l6Vt: !e(^ ШPcn)),;hfB%/qSBh G 10T32G  e!#h)H$H!8x!JQ4ey"_0yLZ `h]]آ"lK8h)%Q+Gզݴ͊chUK4$cE&B*<Sclӌ #itI3Xq:2S4V1^_ߨДb "o}wҔrӔ+)<\mK)"#xAu:v&꽏.:i7fj^o}Y/!9v_UwB]Q!DS.x$rT٫_~:zš!m㯮WblO!#Ŝr:7[~&Vf#64\ooc[+X)$tDq"&LKT㧇HTt8?t|:J|8;m.^__N3 R ~FGPMUWCpލT3Ly(erH Z<}؟s47v ƽyspӜ4kionn/O6~ݻ/Mx<nRh?|/8 W~[@|tFUNj֍;6[~8 #!eQvnqH6HC7Bs/@ҟ À4pj8E1xβ =Oi662sb1:2@ Gj0XEY}HS /Ga8C4EBbD 9QBT5PM)DL)SiZ9B`ǎ<EdNJ&*L\t;5-*By'?cCI&=yTZ uY0sT;]Y/'rћ ȢA9/\;t df4=sea[<{L=Se٭H@fGesˎ? 0%po_<Η7wy<܏niǃ&d z.3 @ v]]]UUسM(p8'K(ˮ7H^bsn/]EiXeJh^WŻm+u$sAǧ)ǛUd60Γ>?T u`)7WݦҪMv]97.|^7~R*m}drUS31F2+D锇0G֕ӸnI(fõlYOO3;"9U LcnV)圝sL甧)P" sQ놉Hrvq! 9ϋwg%})%4#)!";hG H<Lb19EM 1TR)eHafrԔűeM Tl:),3?[Ho*HpeN j({0!b\VUay(-зa3 y0"!Q)E|XleIp/ީezw٫Ͼz՟|>v 0LvJeNcє,#S4ETC~'ɥ]U۫uU"s1iW4R5@Esܼ3,F? CxyqLÜGDmv&j*j.Ny+A9_Eʇn,HUks1c]p;OHOO&v5ɚgmZU~lwYjk7@T+k~|r۬ע_90fދ)Ae 4շ}w9uιΗsMl?{w#`4|pI|< fMISJ)jYe$j9/^^5m|*\W?Wu>(!66=0NffxNyr hanӮ<Rn*3!: 1x4U. ݉UxTE~Ͼz5ctǡ8\$wǧ;=o8v)My89fA57xtpJOWiLSqγ2\48W|כO1riqY b p}?8M[Ye fQSӄG4"SŶuY* Y9M8r,h&RsngUsޙE~G@U0Sv>vK:l1QU RB΄@!h萰Sf*D;) Q"K%n =bq h1%f[H圉 EHSsyV3]*HBZkff "4S201%&ι0*017Rm&+@ sd" 7*BbE培9?iմ77۸ +c.Ӌ94gB7dGVdN%3n;TmB'vPW.y/ϿfZ47?O~mwUj{yk~I.$&Ye牰nc*w?ŏu5OC?W7?'y#0d7A,#y~YMy$"e!bMնLj sp.͓CތP6! }7bju͛ݾ}Q5U'ͥ A'\5PyTb秧;˾YW_?>k/>l`TDYڦYW8mC{W0b}]4I& !Tm觜gE9]5LrF8s͊J~=zG05BpٵElozmC,U /_曏d@R5*ZmۦF(YU7~yub{9Os"zxYqmW|t_l>=ɯ_>]?|1"*ps}+enr<(L$7B.cw!b"Qfë/?jdz_\_9uy,ZciJ&"a TZ4M1:h>,)}7}>iQ5)in4ϓ(P0/e=,d)E Ϣ {9eQ[*ƅ P-J  Y LwDh!c`<9'@Bfyi(0%ץ([LsˡjWD)f< D9!=6~0bZ X3eamXs s~!>/1w5# 5S"&r`*n !hBT3)u IDAT~z軡 NO&]fHn m膇9F{@&?<֛uBLUX.f\q,i,g'r ))RTU~sU^-)Pd>U0nHu<hdE3:G@ 2Q(A=gYV3< ;.สkC@V %kA)J{<@̌FJ 21^(=esыe#!x'y8`f1١z(DGHH[=Hd9͠ޓcTŔgP;rޑs(HT[> 203D{p4FPbDA@ ^YfLEuIv>K6P @`0eCFF. f ;dg^J Sy=*>=<ͪU0iB]O#eqjz#CޮW-97 S mr@soVOۻNl2X)4H|뺩KGIϟN|Jʧ{Z54ۜ dfFN4*1Owݹ/%2]]òIWU6e*c?PՕSIm]ynM4Z^74~8@1~w~Y/~TKy< z[w81s޴Mެ5vZ5Q%Н;a||"y:<(Pp̪q>sH877W,c5+Oڃ# gM"f])TH@"h1J*ѹR YJ% 2@]K\D9_b3zLlg(s/{^D@0υb`1!U)#0TU0dv "-sL,FUB\dVPc"`B~n=-e=X䘙ٛ**!fQ@Q* 21(VydD7೶ri)Z."Q|$Y. -cd5Gj20Ģjd`@$FF"RB0;R:x~`5ޭA6/oR bBM[$ޟhl/S?ϝ'Fa9OCSy]tCM]i58JJStx򈯯^H<"p<9/3[v}4O}aʐJnnnՆ dYM5|^>V Emh_x:¯߼5+tVq1ԝO&BɤytiKKΩX*FYlKIQ  ɅC8G eUNh@$e! \.gTU2+-H:!YIi;_w8ztE*P6hvxTLcԴnbJ_fnj7NC4<Ʃǧ82 :Mtrڧê]KwƻzRUcW ~_mJ[U{)b&5yxyֵ~RYio\T .Fc*&"R|)Ȍo*ۛK߇"ٔ'2Vk@ZSE A:B PȱSbQHY;XKOr I0]9)˜Պs$ C4{/EhYZjgcB蘵€3Q"BK7~xX%s.":̎$9&OWYU v(RDcM)jn@JwgqGB0Z7Ήy2ҼÔ=j pަJDdB)1$*:#:g.)Y2iT~3&2Zi$,L"(ĆRM"aϕgE̠I2 0l45+S g_Eª_T9"CcG1o(qWgzROX,eL*0 p:njݻۻ yXSkQʺȪ:ɐh Ȫ)f~?0#!NY6iGYV4 !2ɧ1iʨ@8!oݑH{(J^74& )0cΗ(+m!XKT/K a;rʲJP~}~?;voo$" w}Ç[T}P7UJcVg]~ώv)a RSlͪ*˫.\Yy eFŘlQ/cbf\\=Y qR~BMRIY)!2\v)RD@T _UbA MAEQ VEo>|-?rx\,׫:Ŝ3X뫲aRpi<\9zo~ëfiRB?,0 + !j1/4.׫4q}mJKK DÛo޿* f hܬM"朦m7H,4eGGQF_=HuiQaE ]]=:2r,ŷG`%iL1B&4BQTn5; K29X6D)iҜrED11`&c'0 a4)`fU0lRY3ƙ8oAfbQDɠΘ93\|fie$3}:3bYfE Ys214531KdUDUGYe6s٤/f5fOgsլ<'f.o$@$ w Rraeo^?'ˠY Ŕ1g6جMMU[|8SOEQ~,qeaLf cp*\^}rٱ?)X^z+w1u*ɲ~x 1&4E9̅{ bلowM } ntSyUoֲ&tLV੍¼׿Kfsqulee-7kQvjS땪۰JSd,Ulo}'Geŧ/>ǻRptp'?;O6o,jY0 }r~!Dc7IIeiY!$0mQYAa(^,bSL!Lah[~X6  bQ:Ei<+i:D-֫sN 5:kVF$+)ۏhB H qTp1LAh/ñUa dI .VSP԰ }rJ.dS4qyaT%GT9baΓ 0;4{rNNQQ)(kY!OSRE"0lT@\Ubr*b +S$"T2Zcg'$k0%( fUR֌H"d!C&4Z1$V197 "R'ƈ4$ZjĜ%F62@@`6䄪,Yu"}?Flyn !@I44}Ɉ"La6"d0ePATD(52+!L0g%x O]9`\|wYBϟ><ۻS`EMqz.j$ǣc}>+i E] ! כ H`C hm)ri:; JUvx_eES<%.XUUߟq1+Bjl].Vn;˴4MLJws4ŔUۡGҹq캶uimQŋ:IqƜWeyu!g73{[@3USΡi}?wEu?HdGϯ^={p:wSHg/ *&}]^^1) ~hZR0UUbLc=NНզp~R 5Qb.0dwLq8˚$wՂS?O#YQ֧6__<ߟ}l>o )mݬO/^?zv~(#e<<vw|ܟ0|ӨIaZYcDcmжB\)3yHl548eIR(l(ݭhlVi嘒BrN8t47բm]xzf ŧϗuzCMrjCYxbSv ]ǢIy~R >\ɻvۣ!2j=Ҹ2GiЕ[9qSˢ *;+oxFf,#U$5eD4LưqP$'晸9dT%gT|rw|9'"I)" QF4"U(F+D2@"ưRfq;kD, 9K4_p"fÄ"(0lg H ;K~R rY"<`?̀9D E΅4RefC,"~ÈȌ6vΤ"1&sC,I!}iI53l2ϑ$1 ~׍߽9_7զlz?i׿ C>?D'@^^4)}v:}9 W.eܞ)v1LG {M *- T1em@,YWvALEq@VQAˢ}ԋ*eC91\,g.4G v[4U\kOk 8MSRbIǏUN>N}b\ǮbL*GajzbX6(?m\ma-R*u-,Z!EfV?r][M(?4}\tXB%02Aũvumg0C1@DՌ4c8.=!9r{ 2(zjRbtWί~"ۛgr3 a EYJӖxH#rƻTUa{ivc]" إm,JfZ>%X֚1`alcCu١O1bf"6֐)*k C(YC<1Ć)<\cD s bHDW YV%JUL)"1;73SΚQ$JNh,s,4jsNX& PT@#)~|tbΙȨ*"$9)x1ID(s@Sk|М@=5 "d-V6D*jDtNQ -zIh˒fЬ09+[MmrsqvY:Qc4A8%gOEQZ S:v֘q WgW\`9K1][|yIǮ/:?0ݱʲ^6П~]T\;-d5覆}-пןyU]{v?mw[*h*_\_؂]Eղ(t:զf#!^,2[Cn.qVS2BS"FljCr2HwɊYlv-1Cȱ_5RkObqK<m\iH s 6'ʫzL)K$O`!NKds<a_&EËW__Ounw hdQ9M)Nt޽oWL޼|x~_ًgLJކ0Zc,•/>Sxx|IueA2%Bth\T58"TeUg/*lLd-˦*1GI3CL.DElw0LC7R+b\=x] ~a!mJ_=`g ئvǔb3N{?pC.^вq:,Vzye!J:?Wwx^w$q]Qxkv{BCxM 9Ų⋫(}zqS8tX3zqn 6'B.|avr볱=-2[}|xCfd@"*ˋtPD$l {ѓ%g!$"48k`pbR"2ֈ̠`AB̩(=OjùZHd$c\bՔe$1d)`fI")E';9iYF<[Y$ea&TP r)O*9(̼oN)8k Hf/ M1"@FȒd-BY !0Y)T O[JD&(xQԒO$ &D hd" Tt¼ }$yAY@uVf,迈V X\GÖEqo~ч1j; q'UeKUEsyݙA1&7aL7eb`ega8Mcwj)WUU䬐؍9H˦t8r _)CY6z8$I7B*)Lck,mf {.KW^wS 9W8S= ?CmR<;$Y /ͳ?%.ex(My8nۺYo1jFɜR>v9 { UyVNC(al;Γ0O0{{;u]U:bxڕUE:'[Tզ#u٬Waίi~7.GU'yTqƹw/caci_:19r߿a&_4>~,Y/VM]ݩ!7W_~[2()޽{\0umwq߲?q)|\nuh6ZDfiwfb:vaFҐ:W0Qraљjt #16zS6uOqH|Ga4no>>4CgY3Ц(t6പ0L'eQ~hۣ뜉ɻlD p?䘑 +S;e –AG5f`0s3&AICޕƺsJ<+S΢stUU=Mc,EҌ1'$޻͙D\-0ƲeN$Fs2 ƀSV"$<9'U0EB1A9dP6$3)DfdєS$]J2cD)kYZegۜ|*Y-H** j@ ᬣ$2 *Ƙy/EP@< L3Hs;0cJD krl%C׍þkuvۗ{8m⠨Z_&—ڸxys}~y[Ԝ$R b(B)Bj ٦YVK6.NC<$HLʜ)$$Icưu0ۇmrd :EU S.tuuńwIR^-SVvZ}ןRJ}~ej6KYX]Xgx8C$ChKwз; 'P0BP.~շ_|ql7^~UUs"QU|o~?/6a[㻷~W._;o~<?oOfMiOs͋~O>$(Oo`tz|C8MY,_~]W5{X.V2coߝ$e?lC_a `IUH"b)xpff]?ES~uS,ASqpzuLaoo8i2[VPAhNY)uiU(i ڶЇ)4(a2 U)e\T`CuS0heMLQdQÀ)j%̬a !3h03EgpFrQ _ڢbtE˄ s@X2E Sd K9A2 1!H&- ZgA5/ARA}kKLXb"6@c`F<;g|"UhPB#Ok!+)!fH@ Jǡ0YbdADYqIrs9+ ƁBb@&B0F0$'B0@'F`DDHf1,_8@I@S)dBw0EU_)F DZt%8C{:-ՋW*or!:aarD(lU{S єU]-edӾ Q31!bٞ~R 9SQn) MrrWLX݇w zss\V`s~6kz:Eo%0NW)N1H6[.e eÆrNE)ˆIW+ 6M]И'hw7n9+K{{ ®q,*SSe9uMzVb,4>x>>nwfOM41TWthhUm-;W^,ϯ/ch7?lҕ޽o?o|1o@jzo>Cg˯±]M?A8m-ʛprU뿾{sۛrh]kpwv(˲OՍ>Lcˋ3b c4MW)0LeQgV˅fǑi O#Uٵ l D!q-BWgMs<_NirS5Js&lKo7fɐX֮LQd>MԷeQl,$9(ON΀c }PEmC\MS0 oxS*)Gc<+Lvc@ebD91^軎+k%y8&k 152Q""f,[d(J(Y"29Ir2։*fA&lP,̔sT9z?g e , Q@f6s33PAs* @Ī>tg̜"6l͒E8A?04IU$SpVM5Wuwn}l֑U"ZbZ,jU8<nUI}$gx6ήVb;&ȬfU0]],sL*CWY;MaYBTc@$~]]/i$8ws̒,iSitSMYc圌A$ зmbз]?N]ME~rlutcw%tb o!,LӬoooǸ^CH]ۉ"1?$n\Uw~h<WJlFԡIq6 ,Aj ՘8nn\,uۿUX]!Ǧҗ6^\A=EVa0WW!Mӫ9kvK{v^WK&BX4^4,88ka[vєHa2蝳0qH)La(9ŀJH [TP4b`2)FZcIbQbQy/"3"͒!b ԜA@iJffYz g>$1Y]Ho0 R]ʀ nCRuueVedәqkc,Kn^ z)ε7IbS BPPq"VDְaĔ$'N1h9'a6@$TĜafPJ<^H 29hb8e~ eIHJbzML3Z/Sx@͆!0:9Ŧ8Ӥ4jHIATD,,yJ2b #[ks Ard>Gd1jƪrn׋CH]Fl9/D.4H$ddg6Ms\.cRQ֎'aG X:gٙ$)4t=oA⬨Ai~8Nz0@ BNcJt\.&ce^_.!1dN".Y5nׄibq ڡϙS5c&5rJꝟ/19njs>ֳfoo߿iǾi.d1|8<Ҷ*g~ۿ]5[󐪺J@C.gWoqYe߾Q.XΗ-]9Z պ*+Yr+3 XcV>!Hn&˯ǧ͛?}_8>}Urz}uz}{kz ;_])9WAr.czݗ߼o/ ;)4$V_6!;tD15/}cr}zJOcev9咒ZxX( UY껎 !f!5Eɒ!EaK vD6+@Qр9tD\8f#Ō8\E}hv9kNh||އ!3ü20ԳdHEiOmߞms9q$ rmjY_֫յ-}aG1p]>tWآ| !eIݱOvqgf欳1UǟXgL.lgy\A"zƶ˯~;n^z`YlWۛJ|nk8KQ4Hl0vcKʢ\Գxkʲ?>b1$rR֖Dք(3}~?ٟHOw'L`rn}ƍw؅8X62M{z9F85N&>gFc=4**aj@QPV!j5 8P`"BdT% sT6JvĘUUrb9KN9*(刘4P2B&"iQbM)$؋*L "FfĠQd0fIdH@%fdq̌ O@LirJ;9FDQLU59I(Z0&.yQdPE} @Γ. X'0;k *7A $ HN׾N&~DYr G8O@ѓ{uuBD1ܼZݾ?~tl.1! 1<1[)Oa;6^+åkB1b>_̫ s} L~ÏCە!/$TC/iy) a,} 1ʝP\zjUǘ1B7tޓՄvϱRJ!E@Ѣ,Zozq voGG%}]!зqR-z?}t}wyus^owO!' x>?(J1ǔ|Ytׯ>>]>5ixJ;>?|ҜO74駧afA^$RZfs?`a-~ʹ_~y\dط"c{vuQ8dJtnڮH\n-]G9ΊrRjV!IRUNrt C1 )$WPϭ7/ |p]l!)RRQZi b s$@n^f0Ք8H]!EEbACJ5@"X R]yƉLl& (a ٓH I(ix9 ZÔUfTT2S@ (m 0l A UqHi `PA I b%̘%[g@nCP 9g>ŐJuA-WLN6HrNKfd /AL %QfC/ ~A" :Z0HR%D-3)Lh_-c8. [SL&J3 e 3괻Fi ɉA aØ4ºZ̗~_.gO'AMcmg Eb9zs}Z/g۷0ƾyjŘS 9΅/ ˹&̗)T)ms$ᗏcmO>j,N%R:}[WÐi^y&:O)خWf_]ȀyX\"caksuCYV ]nm4y>>4yެ"2iF犛wt8DZUŻwob 8嘔?MiC׷_%EѫWۏ>vM{) [/n\V8O?l% xM Q <"8cwfrR 14Ҍq~hI1M#Yqx+;KPj} )W7s˯ǟL\uMs|<{C9u BcHY~xNtL9!jUf?c^v᏿;j֗$?ϗYs.5WwUUrn7 H܏#<:_vK aVtg*-ul·sbQU KIuxNES*BLˏ_?^mS҇~[T"2D`3uT!s3(!pms,SUuvH rLeQǜ41A q*JQHbNxb6Feks 8UUX9ŞxpH)xアLTL1 a$fQB6@!c,)h"&b1f0g Y  ub<8#%f9Jqc^2̖s9' * L~AKJI^`:@AdDYW ̯;ZAk,O D /TA S,DLyAA[#I""Z6Ŧ.[t.1cSYY%kLahc&z1_L9fCZ|׶m[|)In6ۡ"_t9P3Ƣ-xWVl]\].-x<5K4"cL)1lr3I2Sy9D79vФY߬CDege]W"@ I$r< Fᰪ?_ݩqL쫢]+Ϗgo g2*PLYsnϻv4(1S_|yt(IG͹Oƙv) r]Uׯ|~8>zӟxwwWU{b Cpt|{< 2)EU?7sҜmmǧܞ櫯LQWUS )WcR]x>67ۯb5+@nH'b]yIZK;?<YC۰%%!]FΏ|z~<{aaXH6l\/󚙈u/ x:neUͬ1;G(z<9GX_~G֘ɆQa Z%Rgq~{ͶבOw!b*ql| G-Wxytr0 $M e27tʿYW ԏMC$ ")cLY bb :5)E lVa 3jVU!9A͹ @DƐ!1p %3W j8Y4JUp)R"!œ03+6 AE&'#+Ĩ), bwDGdkRa<)|ehI *yJdOMb$bL2bA9C"@'!*`FB%P1(9g} )N5'h8I h6`CFAo2xvZd=TxFt^]ߜ.4}Т%d$Ilu뺪,T8FfsͭuriO٠B7J \qvYJ*˘aPQJ}TzdB?0d K\ :JBtxC@̭bFW,r=4'dQr̊u=;#,}0jq}RY"ت1oVp>uCR?|T?-֛f}n:ԵXe}Nްؤݏ}|xyHE.ozLC<ӮI#?%8C&}Wflqj|<cLEvqh.MmsyO.!'j>\S"`1Ch^z-~\sZ_u)ox.g(·hĕI&_~i4=]e)vh?RJ.ȦR0ZYBc/-Q?&;6C Do.%{:@.KC 0l=\,|{M3BqiaYTǑ`/(9_슬VB;2rYZ6`r׶59JWA`Jr):HRn l FE%cB"5:X01 Li8Ȕ$bIU!'@!΄1gPU Cs 4UĘ !Uʂ5CJq#(H6$ $Y%kBEY&&DQ$Kji%dM1&@Ub.E\sr6df}YݐgkXN)l 6&N%~|ڕEywYզ;Gzu5[mv`]RUF¸]/|7mYUOSR>]6sW_}QZnKeUYv:p0|CT;*%W828aĜ2\.!gqJǐf!`NV|N_~hSfv{X0 rlvFS 5vǶEw9y5!)9@ &IcPi=hʳl0YsUSLIEDs 9 @c(E&ɈJ;k80ېJY P2E=#y=_yؼ|/`Qx"^,IB۟AsYz_k4&3dL!/ 9Cf(猷:H׶CرS}ۥw_|x~gƗC= g KL3]a/aw߿ܸͫo[dӟѡ=4ùO]׷} 6vwlo^[Ev֯VsoM{iK^o^݌Cv _a,W/*@?! ƾcܬL2͛Wzfݻb2_k-O1r17eDњ ?g`^zX*|7~zܟT %s %wc/ӢS<0/ӱpUUYrU C;].˅*`-5ZUvh$AAMߧ]|Q91#Bbכtn̺GLl„&||>=UNݥ7n׻ WyC%)"!H 9*b8`]1bQj !%s!a0#š*6B-ʢrF Y꺰 -ٔ3v*&%E8Ir` -AzɃf(C"f;o0@ryaDE,`ɆQSNsBưQj-" *R&k$fĔ4n/Eb~A3O9 wTg!9e攣1J AE "6 A +@,N.0b嵂DC@rDm 1(&Fa$?A? 2$ cN7zv{W3b}]aѪv:[0![زI޾~[zxu20:޽՛7Wuz]ytpliUEuu t_śv9ՄS5߾YleqqpUWcRN1EDvp6Ef+YKLC1ITr1'R$gcRK26q~l2wolpiKClR\n/ryz<^Tw>~~rsb(l/wY :@պbC]٧ӱ C˿-Y~ŘxtWor¤w~Lms$"WW߽rcp\Η߿Y+_gwPEW n~|t7=>*]aa8|||Ψ38kjBeIUa(ɠ]//\G㸿\*k8-TbV(,5Nvq )Yɩ/lV""J?~%bVUmUC,)ł\.,c3 IDATcԶ{f͌JM.D2d?4%..}YnnQrs{(Wǡ~*"%ᶱcTzFcbS8D]!jl?tc7zGC6\UE)&adLaȊȤRQB 1YD!OάSu+CF%0(AORR. $QŜ'c0 cQEPPs6LIFu~9eAH)gɓ`%l*jR:UqBHfU-L0 R 0YDW97kNDfQ@EAAEAEIeAb2/XyLP&"bRPDNUa&&$R6 )%IňY0#/$Bb^-۱ Zۛ>Ax>_|e{v5MoCbFPl ^Vo'3"E!I9+D!I 9D_>q.gUat˧|QlUW 8? v 8f *Ys8.Xb1!lkZڠbY7u>U9GEe1澻V0RS sɰm-oK}{# ?w̴X,5]? .׷\)5WonTm7|}uZx>0Cʡmq>!S7T?vHY7ZgBw㮲U{zc?ObVc E|1gIr r^|7QǾ;"_|f۵wŷ~t ?8}fp~:Ս#ӇLJ'bZmןw0+?t[ϊ|~|h|}^/K<[va!c]( dtV2(v"Lkp~OUQXSvmIQuu>G(9Qj"eI1DuFDSBTM)|L`>>?!<=ڰ}k~?Kt7?4yt}n EW"8樠hC./khwƐ/.1E~. ?+YH$H8kr 0UDu13&1l}̑ p(!VBҎR "aVKB֩ DU2*$Q_?$9f% &QQPkD 9hQ31T |q{Wd""E`&F#09%ɢ1AF΄Q1A I#Ʉ`SJNPqCKJ_cU$IkUU9*2*`3()CQ% n_u]"N|d̶4WגsQz)Ϗ}}=va6sKÚsz~?=coޝʪވ[Tͬ}Vua=c{<%h)rgڦ2mMۓ3VrF&m[J9]=#HcQ8x)&+1x}i XsWKLO/ na8pHmՌo c7?~^oO@bu䐜/W۱,jL ~LR+k}׎Mw67_lr4mbqȡE̯fWn^ 0vA@U !\.咒0k؞OMGáq/§) !69ӧ_DU;j~q( SƟ~9}=z=K(I xXoj/mV6Mh[U|9Z*6YHh\qSU*ϗwG.~$x [C h]`NK]WB]ٺ4 R3PfKeyaOgsNUՅFOh4`$hI$o(3I(@bwFuWUVUfdp=u@)n"n؉X4vmQ V{\~amL%AdSbkGէ5Y!t?V&l}v<6,+,5!v'n쟆|)}LGD&vgg`ٔp޷S\bh˫Ķ^jvNۗ`lΊOcwfu<:~ ]5KOmO=e<|E܏}_֋9;[;c4)’,ջ ڥ//09ԟmUز .ۋ7i,&Nc{ؕMsF$θ\nBLO!!wt?Ţ[[꺬"ln>}4t9YEvw!MRb gYՀ9q'KnllFEcveXo޿7N%o7B9iZw}ׇiҲZھ(pX TEU٧dGf?f9/7wnrܕf=qhYE3Ϟ] t-Oz5qQw޴cs՜5C^-!\2cYx1H @};ԑ(&V($lSɖPT +G2B<7I1U-FN6S6 JcmY{ U5 U5(嬈h!2,"Tf:JQzYusj,Hg+Y4Xfq8*$c AEnDJ(LH?Dsbaʬ@>,nf!P5 L()!w9D0b)8y!c$u}], G!H(,ASl{y{$Sv`_nW}yњ2h^ P^ ~w-'_ܬŢ>z@l֮iPE]7ˊadlQ/+4EE%[AiZB_e9 6iǛ8Ek|]e鎧=RՄ/xJ/>}˜=l1CK[(u8 ss]{7yEAF]w9ihׯv_}cw{OX;lSӔ&@iñ;1<:Sa!{hcR>:l/]\\Ŕv x{Z,0 /nLIB1vi&g~4mUWŪsڝo!W/ow{)?̟=ۮo7ݩ}v}?2*k8鴮O?QN۵}US]vOp:<=8oWwЏP/7@rV⪰Z!gpl-Qya{}?՛+{W13<_/SJ<NMS,HrJ1EaVOv X] .̟=բ].J k&Yg#qQ`0)`:@3H%c,mDU K)e"Od@Q<8bD$Eďj!97UHsdTESzd(~ 6A$3z"#HF ZyC,θTQD#Cn^J]hIDX S:( dD(UATO} tSQ>(gכSۧEZ#O>})X9YQuݨ$y~SKFʲ. o}휷EJdVeJ ;_L'"pZfZscʑUDHB#e-OsO9uؔKt&4|iY84%4Ut6>>BWO~bsSX-W7jWuYX/n|zr]E7EW_ǢCgESTprqeҫ/1ݱ%KmdV{ݢټ,pʝmϪ"{ B4j12b YixeN~K/:Sk_Ֆy+>>p ]&NSCt{}zȑ!4BΐX0Zc97M]˦,:u`LI(+@]8DUeu֑\hVc"0sMӨb@QYuт%,1(%D &D4M08cKRTCHè8^L$5DC\d>"zk Ra6d@ "E1 Ќ9(h,dkJUPɂ1N3@ E"˜! .cVTY5!JB`=*f09 -IȚy231JHb\g㧂`T]UvS!Yr,hW~  (S`Tg}7Mcbamy cc}Q5*mYユ3tUIoŔ/r6 "ĠCԘLpr Fc&-a^& "U X1֧ĉzȪ|a!r# gaunsmʖE"̜l 2I931gCfSkIʣQB% ,!uFf}JMfz~Ƒ|" =X$cjusN1,*nI"f_jdS}Yrp)e&c0 )۷wh׋gp|5_?=XּxO9LaQz!&;Ԗp|ZjY w!g8OHƔx||<<>>$uS])(Ƿ{<_o6r5~wpx:Wq|:-~eN]fq޿xb{4baZObHIT?ݼ8ZW1o~f5C~I?yv}]w4߼*f2ts{{q}e(?{~E0xٗ7on/O |8BJBgKb]L#vrJr)O-CD2 cNn<zԜ4S{LSalSIXb9i *9_6 <bz:?<D_Ms:IdmVk~5)fdS^ǀcaMfU?47٨AEb9G' Yb`!)kO##PM)e,sǑ6D8>A!sDPETdUQ4S ٢,43Ѹkל#1&P7 :kA`KUajsMyv;y6s8zyKan2!R<K`u?v$X8+%Pn!w#OŢ4 z}l5yw<OpܬVaz~0i$Ü'́s!wHW$Lz"DHyXSSxBjCРERm7&rᐾ}+C%S}?$K-l] Q_}1L㫗!o.L}Bc a>Ka8 ֻ,Xt7WgW&ꊪ!eiئq~<M}y^MD;f6o_h0t:_z0q=ޏc2wo8%PXԋaSo7ۗϊ7X.o|oz>w֫jjҝƘmVϟ~.x7 \ήW/duV>+ڡmOJdB[bQY:爘۲d$)9gQPb)'i\1{aȬGR֠RX*Qo_˛K| B2|!( OawOݿ?+lڼEEN4FqTZ4}?1h1ˌ&54ĮT)*Q[OV5ĺVOEY\}`m]70VY‚H(-4"RSA9 H,X4>|(E]K!! 9*yЙ"JFA٨:@FР2XY̊`%AP&T530*dG`V2A "!6L,+0| s=wDc`2:ʐ!R@ ¨%Q )eP ̳nRA*QPdQL%e0C]U?X /V(Le9 beY^OʝNmӬ:X'|ڶm,64WW];L}ZmEUp֚ݻ7~+*?>js~)10(_^l 0MUx[7oޯ7")7r&CvY-Vzs^\L12?;; !erJ,(^5*z8w/bE!jy"?F?>cjvuyz,ڽu\K)”bseΫN-We8v$z]Ji(LQfP9溩$B(+2- d8E  DEfLSNPT6XB E3FT"CY@ "Ϛ1X٣r5p 1)AQ8o-GCHXFPEK@ EEEGG`F1wk #ץY2g;4o3 9:|V`cmyNx~72d95s~t@"DD0"^Q@7K ;[pQ,*G=рޣ!UaZՠӟn _/ϚI6>%g9֜mkҼ{8I9eqzQvI^l.3W֚)8" zqt>4nd.l1)kֲ*LacN)EUWq$0(Y@eDZo'f }U7}A$w#is)$$!KjɖE}ME|fF4CfV7|)>px1ǧ^޺&5Fd8*)a%@Dz@`)e._,v*/?rtj͡jX,g }8,C:L%'=Na$BT*ZBoŭqsRcWeY>cz}*LJإ*ٳuYii\y EuyZ7pB21~X51KblUa5!NjgMsUfŢjQK譙{j,c"E:-Ybc ZZ\w߅Wh]Cc;t'|M c-jιD7WOI ,R 1GG4ĜIA$ hڧiwh3v^il ֐ f.Ty/h!)28K#)ks>"1&P`%Q!!9k!T@6މ+b h]լ QH2DD1&*A"E,%1 Z9cgn( WA@ę UAL01D@UQP""3a@wGDT`3* ¬ $ePCXY8""50_'l|XcQU 4MɈUUQ熜E\ڪ[Ao^lV_~=Z<ϿD`+$8Àhh *FY" dld2h?mS=8"`N?8T7 fڝz&aZnJoEy}{M;C UeO0ǧԋƖJ2&r.j(rU)V8uXE;v2p"y9eCXxJb]S@b1pwLtf鉆ˋj-'G\ڕFQdDgU5hEfOUEN' c"L09ȣ==paNԍOby^plO,ۗW3ay:Zqꐋ`9G ^E-īMSuZ1M1r9o>яElu)>!6HWː߾-b./K$z)oj͌@0TM=?;vWDf)g/7_ݿ'?zu쵨=ۜr]몪kZ.fS/Ϛa1YCq+EuIpZmYwVہ jxtr9[cB !E4Uʓ/4U9p1MN.%ӘbI6C7>%/^i:J/HRuj-jZx|%m˅UwBS 1hl'CQM- 9zQ[R5Ƙ3CĪt]ҥDLP׽/K 1Xd@8CxYՕΖn)eRXӠ)&DD3JYF$;FMW$,*͚S‰ iƻP&*\Jِޔ5YJBu591Z#3!B2 +"X!SHh 2~DIrEx 4p1gwΨs,qTTGsI$)1LB%U̬3,2 +*HB$"0s,b5ƚ3PU"'//8~bQNc(sF󗗷[Լ=_?o/},?kkJ_վtC7 ԜmL߅8e_m9kU-e3Cw~x˲|)>ߞ-0MeYC!L *\9%^02X_B k+STWR$<v{f=8DIqý?ƘU & hԒY[O&UoԫZڤ&E$B ̌9ӝ{Ep?i\iSi9FӾgMٖ"TM'jDOH3PD%&ǘs:)8k4yIĠN}mp .z}6MQ[E!1c !#D RNId81$CAESejYmzzGd0o|YU4yMpմl{vwtu}MQTc?Ue_|˪(K}!E=GUI{ӇSHׯ{?z}ōqa2Ϭ0diw=c?jO۫ } ga0]]7/9_:k-YbVДg,Sǜ]^äYLF$U[1FD>{c)qt1@H{xNu}?Nv1o3n4v?MOOq<ϖ,4fs,[fb9E>rql]q1!aH BJH<Ơ2g$r?㹪9^ȇZsň<(4.3J#-S 6q-7VeƋQ%IHD- 9%&Dr CDAj=KC( \x!#+d6V|H&tE z@p`n#MYAbRUX)1ٰI9EĄBRL1ZcX"l2Ƙ@ H)E"VeIA((*䌆Y2^~)eP#-(2UY({PX5͗}ՔRUW (I_}2xR |_.C/ Zw9St+nƏb6ha $㇩SSeTM uHX( CFH$@l"©RI$s| Ä̸^+M|Q7!t>۲) 0Y50eSX0P ƲH&iM+ *h%C }_rvD2"ҹ뉌1%@J)u(.&bR%"[Iز()/ns;]s (:lM"<*1GXD?%V"eaZ@V&N1]W((23ӏQ^ 2RUB`CYX$!\KgeѰQ@U(XkA}Wuc]&1:W9~~nbmx]ںmq]]DJ`uN[? pPg7ᢼ97_f0 4dUUs9Rb~:Ihc!Ch)P\)܏}w}gEiMӨ9DIu} 38!LWw??~޼ׯac^K1 iX^1iZSZ IDATͦ_՟'Ŭ/op4Czvc@k6@QY-PD뒪Bc$dp YB`(qAֱ%`"T:cK;*I9ޕV$ciRLAEB@b U;HF,njl&2iRUdYq 9D, $ 8l0xA# 2 S P?6mQY,T`6d$"]̆Yr$F TP5lr!$U`$r j6VrK$M$$Ys4b0ULCdl9"hڃ K #f/-՛Ym "؝:re;Sz(Q׋|d?)61k}d{Ebr\}ZkAf~:TՅO)\޼v !==<)IrrY۟}Ӯq-n߻|mC7gf EzR63A&ݹwELͮBtF(O؟i]-oiJ>)_믿9Ee[dA?Ph2n 7/ Y;3bdb9sVtzoWW-xj6pj6;4SΜ+VOeռ|yy7=o?CQD'UaL*?4w'_]Pơ-^}g3m5u5XI`)'nn)>mS_)ԟbDfø]\Sԅ8\L^RqUz970ścd`fqA]OܺZUS8a5`I]AUURʚb4y&1&B'^,5jh,_ȕ-mN90-gR4N0/_y0hLh ;hsHs$\F- rQsi:GKHj`fN\E%dT:BbP5, PJ h 3U$ƔDI3UҥL*@5( T (^ ASFØR"(Y-+L$Ȭ/gz&Q&B$D@%"d-@ e1BEPֈ&D99#2AdD؀!'*KC,l [g៻s.՟Er>u9ggl0ݛo=]W}0g9&^~jwgM a$ q Sqֶևp:7ͦ;4i6!&gmF9C}3)P-aY;!E"GIpPAɧΔe2ӻwK i>?/ŢW+JDŽQ% o{ͻ?ϛv1-}쭫sQT~^axD)ɨ&XͲmEcU?]O}qo5S?A⇇nѧLnwΙu觡o?=nka\E@^)7E\4EQ"(xOb[2 yGUU)cF5ݜ0${т4&PjJ4+`cXV[]afzYԏ50a&C>HΫ@H\M!̨$,Y$5 v(ƤȢJI$d f>J1)ۢj9FnX% DF$ks՜1eNJ-#E`Ԭ˵'gKPHErΒRp֌1)gFv (@f@%KHI#!gD1F%KhD"5D*#@6Ll2!K"H A2&`KV6Rec ]6 0r&\Uu-2OSq˲TŔe߇ݾToog>K[آN-LS07n|uwOIvi&a3]QֹSX,׶*o-(s\ys RqnW @ErZ6:b!2uP63c i&$\N䈟"}tΩĪ(RNO=%E$`8-lmC"UR5h-)(+yn?ræ4$  \]A*"䠎jJ9eAE$}_슦Y>>wa>zۮ bW7Ww|U(V!skl6rN7w7ɋ 0t۫?_\Q<|x:5gUSM2\_c*rsuup8uчTfBRө;rQeHu(Yui kA no߼}_ Qc>,?|]4%~_-$wn5U^~٧fߟ-f7|; |sU0ۻeLqi"S3ݼzwC7d$4bB CNU4hbDl.sTP\8sK "d  QYD.8#EEPҔ'0ƂJZV tiwQcd18 1Jfk!JA HYQ!c\*)aU%RUPu`ڲlZNz5>?=v&~6feHYu>!?|G?Ir!I߭OODn?|Ţ]+حn}A4IcZ n1M!m5{F.=XXw:mnV7Ɖs2LsΒq!ZWSeU` լG |[&Kܝ6'@$'=<iLMLSȪ)?|9tS Ĩu14u]jg36ZR bV1F *K A1Qp}sf~=O!p)νG(;.8aW׷7u]Y?xڪF6f>_Ę5 v*\"@)x>?Nӟqm*ի/OlbF3_i;qŬ?@`~xqFz?E5 SqlQE>ƘY8>L;UdvU10-Sww v㶟b6CMsɿޔFG'?/^*y+Y䜟6՘mQ4n7σtXkdžy0a.Ʃ,ls~۫Un1ȦA5}7vԥuΕѧc?HraKEC4)c/೘ `lY ) kTe0RSRE]J$$!K=OE .8y4 "1D̹ʡd$?459cBMPiȓ- aPfSVb"#eCа1!Fqhq)/xB8E28Ǫϭ,p90Jb6()ʿ!3U)%`Ƞ=^IE2hJ+.~113@FB YjV!Ԥ!%'YsDD"@ N1sEh"""g@7 [Ȱ?g_izqo,任[ ]WHJӉ?/W4(٪B:bLᜳBҲUv]eq>wL]͚ )Mj6G"`vd-V뫦糚 OW%`Z"ٟ5׷׿/|ͮnZ?zkfǠT̋)8ݯΚ~9b^Yuc90Rh1zP@ئZ4?tO[if{xOBJY4ƼeiGl5F3 2҆BeiCce<AJ8c6&}eU,  >ZSM 'ܔʶmQQEQZKk$EF@S16 SJiʦ\,P@gF&N1VAf4!ĬP\i{E<1J)(@%BΒcQec깼j A9EMrg)rQD$"8&'Rx2cTD+!bΪ t9#"rNCH9g&RcdEhRuhl>wiV~ũ˪yvwl1TW3?H'Zas״-Zg/څ!)UYeh (|EZ۝qb*YSc~x|x'I)]u?oo-Wٟw|1۲J1yRu!+A(8 އ7߿/\5lH~$KI}Yc%9&;3(++P|YŘjg4IF@MY8 i("RF2(1)fbMJ,8 |=l-mO1LS',.ߘ(Y˧Ͷ*vcjQO>dDl\7XVWs~]=)YXVBXX[gglq|\;<_/un|:SBU)պr&k)\WZ[pz}5H]]bawNn>ng_(O>UUY/~opQ0c4|} 1t>}s{s\,xolǴ}:\ϧ̵ܼ\o/޿~8~|}~yiNûaE01YWCYV!8~DT`3wכval}z䓱l-3We5oWW @II9lz?tc,m9)M[)jS9rJh{lt?G?t3eSnWùw\a}f8,[ǡm:<=͚v;𑭤TfVSA1*rB:FC,H@Y@h9.*%DBU413 j* 4%,N$ Θ,/JLZŪnUc74 8k0x?r^RR2B%#|nJ,c^bLL2z˥1JƘ"nw?]Yc?(DsBX7p޽|a'U?:.#{a-bY5 %cA;1O^O||9Ռɟcz?U]-M|^q$[A[s5,AYz_/q7 a_l61ì^$Qy~?CaTI=;ՔC,#Πe/1B\(afBYF]Scruuc[ȬpUQVeۜ! Ș4" [a@KC>nda:7ShZeiFETTACj ɏSFW QSCPSȨdWBcR@Us& h.)\əPj^UU5BY\9 X&BkMbҿU " 0g cQ&vYt<\Sُq2 KJHBd2A9MY@UAI1Wwnn۝#~*o>guF>ny*Bcʣ~()ß}&?m1/׃?>=m*hRa\U?4N>^VxFlfnwST!%ETHsNg@|}?0–h@\ IUj(\ZSzݏy [ͼZ̪H>Q}" P$ UHP.MQm}:n}UcPX% jT ^>N ȥ 9E!hQ8‰hL=>ɢ*uIRH[TIz<~x(˾f*%9).1svVMVCX:c>z^Ξ.m7wϔLx8?n@ɶ5! S;kټI> ))qOWoŗ_zKPkD IDATtEHݨ:,>.;tY0LADz۝^LFf_󦪧a||:[ŋO?}.!|)ŲxV⫯w}wrnb^t>_vOo󛿟ϥ|ӄ|Qj, [̈́Y|#,NqVno_kU p ?݇E:qTT* Aa+W: U%,t]@Y(G,,V)LݶJ6$+$"UE2Qu;D$*KBْy8w6KL""uY(Y rJ2ZS5B, _D1&|Ѳ.xgBe$3 XFGI0Y(%hgְ1^B03IdRɛ E1A2() 3"8kHM)%@K Y J.<$CsVK.|($eFriba-2;@PA@p~~asdПsv_}ղptss}sqOНd/mdliʢ1绛@g~ʪNaʒNzBjΪ ` 8Mgu=4UTs*`fU6o߿;uNjHԳC< qWYY+~cŶSWϚykؔ%C>8k1!cc4})gB U&%MY XHq< xg#D"fԆBhlS(k2 Ķ'LDYIU3>~HMYniTsqvBƌFz,޿z8߷f9 #Rb }DsJz} V:yUM~&)τAt ]7&vm*SH2yUVqϜ(@ "Q>C}>KDr":>!F(\]iVBB9a^gc !BA+$""F1%'ON< 3J΍,1T),2=R1[-. C5v{vXgSZ-槫ܚD !hj}phNOWbŢ2H1^^\ rz}f:]q,ˉ8vYQYUټ} I!XUѩD)x7\gF%";xebTOW)'Uj.B̻!vGY]3120 ^~QʄL"3zKV`lC fdhQ6]׏CgjE_#&w.a50ښ@0!mHQT<0&N"4*EjƔxưҀB@LC"Z+bN, やHa!  "Pbn-"JǙ! 1 m1V0"d&F!BhV XRգ~^qz @dјg'!fqhj뜛Nʾm=F@,Myv_ܮKpm]km(p\̗s>^\] Hf2$ ;7jňnm2ml?$%|'XE^Cвg?r,gn>*1F')k2`)mnwXO;BePduCG 51&?܎P@!4'~uR_y>D/q= )"$$a`Pu."z" x_[Ikb12u7QbDVnM+yY՟>} .GgpݶB9iARqz7Y6x79F`"0yv8!e'OnxϪ|o?nn\V./~lTu>_Lt:Pd]d~|cd1Ɓ qNr,%Imdh m 0jETUU(Ũ$pDI*0 6 "d"JXWp"Rم"Ơր%E"^mnt,`9V|I!heO2X(E13(tzA2"31Xb`D "՟HD `"*?[X*DAab#WfA$5nUwwnV)5 ,"O*u?};rs UadC1qQ)ݙLt:5a+EQјBuq:$MDQy9MJ\@ UQ 'вk,|2(zZu)0&f]rtFU}}{'@V]H bHA@PhE(BRDڐM_( (I bB@JA d s"!Ѐ: 3' 0a("(9 I | _tnSX|H#HZ#*f24ZkZ/"4 'fD:Ji,'Ht|UEP= ikx !YTelbN Js2,ѻrֶj."u]7޾~{1V!rb(̤o\mFX.jpۯ7''bNwM{ׅ $ALrԆmshػy0$)2f>_,,n5UVw!Mߪ+x:oZ?dI)"10Ą AK?0DAb8A}IIQDi_lZy0# MgfY0H n7 #h73U|f2+BI1{j"bU` ܏i7]YfBnbێ߼-xr[f!))mf/,gyB4mo.jsyuqioyu~vÛS5>^2w!S"w]Cf`ٗHw͐ے]=zr~1SYXzy~v1ٮ? k/r{{P=y_f{bKDc{RjQ( apGs#G2C1zƐ.b*3 H0$Vp:*x2J)-,y"DHpbaƔ09S"#9!qR2J)aa6Z!C8~=!De G RLBG&)0L e`ҀHQ)Iq%Hrc`Q\ecNկ qr8_$usӓww=܏]9` [ԍ/ꛯ{޸!u;=:#KUWy{C`" [,Of&a$48?vI=nq0xhtxQژ5(2Ps;C I $,bӵ"Ѱt]Hhq*a*/[# Nfmh@5pE`8ZD}oWDa\>LyM3K;YԻm?U$YN>xxZcp4Ĥ"KFVňI@DetANX5ձ_e#@D%0' mQ $"(1ZkD8 ^mH!thb5hł)Q"3eҐ !"IE F>V"Hʤ$" IIvq`T41$qO~7=49+ mO7d}A]^6?} z}Ф>&vZ;DN/~I1!)e\i Qι~h2L,u] !ʲ`L̫f$J$lud>>ܶGRm׎زo v]]&G1%NYC39bI^m~Vy>ABM_6$۬3>}7a:EdȐ\)^B@Q9e(Y9[sJ rƑ)] !0bDpw&ab"1&=ynC92GbJ WDϟ>UD.b^MJ,JM'KpwZMשVH򸸸~AiSv*/^^8vى1v6Dtzv2 ^>^$RJ7ΝKޙ3id\5?ˇ{_E_? %Ff)s=fue<c4F[#F2m6TŤcL ˳̨,_MRaEDYQFmeAЈaHAíj|MJIN nl2%'ejԨ$tj,;cm UlfoxhV QHĒR3pK֒Fk80x;2#pdac S@H 5Z+@ kAi"$ DcA{-Iʲ|9"DPJHJ(FBRi@@XXX#g DDf9B|XC9MEH$>gIkf T 0̖oCߎ!ĦK0jo_?|vJbzs;T|6KO?8qHZ~B?͛v@ߏZ&C8?~k}ۅþ=pv#jSqbz6~h8}}\>vڎ0Y2Oyi\'mijS/wDI?a; 7=HDl:ICG+_=6AS8=m0*DŽ*'\l4, =x;*m}1E^>]*rjYQ[h+8>˼bUX/eHwձ$:5/1xP z_G$s!2ǣ> @ 3]HguIk&>FSJG/Q2k@X3?hrX"RDžw?&ac,]ڰ$愘1/K},/AD@ #ݐkgbROona%yDbʔ$~7]\n[zr<ي0p:6/rZzLguYe]fRWYnL'"!t %76r90B!0Yw;صw|<7!7jy mf' ѐRPyV6}[!L|Qpyw# eF.X*F"AN V!%8M:VNX3Hұ bQMMqO 9e=n#ANNNʢx|߾yOoQO=}xxr1evдE5e. c(J)U׵1FGEJ|uyQX#?=l_Ujӧ뇛~hŷmy5ɭ-lZO_v,Poӫzu^ XJnlj^o.bgM竁ʽ|ZfT3_ ;ի~{7b옅g?{|lMr5n={[R+)zwz?f90դe6|&@J\Ψ;mbT̺04?V*Y܏/k?]CƼe(RdFK7ivF2"S`,VCAJ!n,"p\J$̊1kH01sB$! daf&Q(I ItTcDJ>Ak (Z14"HB`YV8qJBT1FE#j#bE<ibf竹Χ@0#~1` .9(S:9=OQf?412o ic3,.'ˮ6)oL! ,k]6tC|b +Ek82?4fg:7A]JZ|LR !HH2'rj߅Xepx(hV΂aۇԥHLajR3$Uys0+8N)!f$,PBФ0!0 h&Z`@iLFS"@"Z@M RU0(10 14nбaWK'통^=z\ tۛ2_R<|:q݉`瓺R,/Jj*Ӈnp|zlur~~ 0d]+%"!$_T8]u5vq:SOwo9Nk<֓fs7 2u!qi1/QT̴zvzd?ލn= j:׎K.Z ~.|pV뻇ݾO&6Agy:)qUnQ i8ٵ2ZNbTןpY׷8˵2pry"`ZuEf"[v(cJ 3[˜jBC} "RI(S~\Φ~ JU}vher}GRmRLw!˭RikE ޏ}dZ*-f0$`;1ShVi #CtcPDA. {[T`M޷;ߏj9$imJ}IimJǐ~]($MQj>Yf 1&uTqh2d 8gL5 ̺0ޑ 0r$@+hjAEF(xbIe4 4$fv pL auqzYQ/./x]_ϗW/,K*8aVog/.'(?jM6U]&]>uص~ӏoɲ̋kbߥ(JEjӤpq?V/sz̦GjQX./=dQOfs^~O:ۻ1vOso?|ȌMG==9/RG/~6n>S/߿}?x6O^i]L$i;]N'wa~^.;Mq썩[.mNgz0.WU9owUJpkPfJ4D% ŲܬSL[U"B]F>_~2F@.SL~!2w|HZ Y;8`(r$îu(& 鼚*tdk߻6^N|13~qtY.UGk@ }B"e*TǰNJ) BG1c$$A(_VH r\őJZ!`XBh1) >?)ARD(cdI ,xD11ƔF|krZj &Y!iY ``\ez:'`1"U AX$蓋F[AH./WWɂQ6&*ʼm8xe8pr~9 ڦJ!nױ,WrSLm6>o]߆ͫr2)Bu iK@ @QaIm{拓]9JeԴ̲^O$J)H1Yn !1boft:j{{A'PUT| l>DdABadP> En #(RH<O)jP@" $#ZT$A) Vw?+|O?|x.v]o>{'7}vYDTfl9a.-fRh >}pwEo7ap1$CN7a嗏_a !02C*m|(w>im֛]LHnfnƍM AgywuY nyl6)jjYZ,/2cjzybN"˯w^n(1Fmk׹Lr|mdB_~yۻȊoHWh2eBQJ`m6 &i}?}'PV(l1kޱnwFaoPUQgŰVҍ2ah>~O=~œIa=|JW9tn0U*/EA(>:An Ii,+G_uasׅou^Tnd*7J00JmwM )ɀyHi&яn TNy'ޅӕD߷=%=kCHe(q,Z{UGR!*BJQA2Dcs&4 ^iUD&ǾB"1*R򭎏Lj?1:bJO{gs~,B"" R!q`a? HkR'eQG̾<<^UoRm ǘ$0(B[fyLI302|!龜рԦM)Z* kbOK267>9kTF@f 癈X@Q)h@)Fel>?_'n!BUenA]2:3F,2=e(sUavP-WYÔ'%'\vOOFgFh4{?s?LBD8Eĩ-ۦZ>$EaoJV'~!pQ#@" #X P (Zcba-`IK?4<8Y8{D%ĈspDĊH%fn fAvݾ#ϮMQ0}{ 䦡ݦa~F4-I#۪9La臢(WM_|y1/tuuqgZ^ܲ顟i>[N[=;?y|x\aH̤;~ Mn**R$qʖzfݸ1 C4y}z˪.ɸUpAR0(˦9:RTg\ؐ{*rPTVEӺ1ZEԣR=g*&ή4ܻr;tiKφ}ynwqd^/Eg%"Z^,a,Y(f*qT 0)Lh$%LN"@F[BZ1`aNZBMh="hh8E}L`&aIQ!kmL Ř./(g3; +"-"1Z)BRFe (eQ@1 !B@J#fXEDuvr|нGLחnCxN)DfpvarddIyFQJ#7ʀ%9yўIvl]#ϨTYYQdBHeUXdBy13kfcKk۲uK'$,YDk45b? 0klY&bSũQ'g*Ӵ\y6ˌyOӼXü@Q IR4gh8 Yݶg[!B 1 LCEZ( e $^ )x )6m  9ҜR ~HˑEJ)&ŠJ~{7ooo}?F*_l{X`G"9oKe)[q}*8ab<~y7GGZ8'-jӀ&7㡟=/Vyá'<7Mdh6$!<~-eO>.\ww~rkOڅ M;/^xo70ngf`NBhE)ĘD * IO~(]g&h0D1H!D"N)rEw 2fd"Q!R7mzgڪn7i*n@UuqRЏ!4|>+r;8NݡtA (*0Eb" EƘ@eЏyQey "M&'2uyh܌De[ma q2:#E@{P$AB<&ԎbNiAPA6ٳ)2o?w#y$F` cD(>? XH"ZBD݁Rd uSǠ<ˊC?f6/Fe6xwwU/.E]ooo~;SD`vo^76ݛ $NA_udTEn޿ M\,f?7CL,}78"y֪Ew_.EU|?a??{K^Y#qf}z/~zSkO7o޾|q_3aӗ_Ga}LX.NfK!ԌD!,"EH1F4d1irdV$1z R' lFƐ$7F%a" ,"I>Ї0yeM)!T@(QD S]g>}lu>e$Msɻx}d)<'RbB j,$F&aQ@-Z[bqyf=}n nӱ h>9i6΢C7~.r229Cqf pnj:m4EV C#1@dA.6Y[ez IDATGU "UYt}(zuz:vQiM~᮴ES9^.Obr ᫯~ i^ԕ1FjrtL)qeQϓ\8tCWYw¨q?9@@E? P3"x EhDdfmL:#[de# h#J[;/??Y7ea%kuY.zvCSۏ>zQӦFcɢ~őVmw޾0(ED:{xxj:/tٳg61yɜOC_v}z=Won䕏 Yُ>i(:yzЪ|djQ_>y._:;;fFRcJL__a ~?j{Hgw6Ǘ/[kʍAml3% yQiҤVJn,s㏞c?Mn:nMHL|H^ @iJsv qYj8u:SIVﶻ>Š(|e} q&7;Eh"BD!ό!hdĉjmw0mhR ouo9ժH$x΃2@$\f4!Te?fU`LQU=NcD)LVif4%Q$MS"x B+཈pC#S0N)08(ڍ3"0Wpd T ;KfY5q?wS!NbUm{ X~\I0 xf:v{̠أ\ajgœ>yPCKa%xqU hLq'f6lWTVU5s+aqnÔP>=/.Oϊʮmpqy530㻷wg 80E] Tm׍ɲ\/߾˲6gv>1A).mU(beýPw kSaI?}/7wû1eYeq>|a )D&^,o~U}lzTytY"e<[4ůSׯ )i8lV~>bPbu>tC!U:+\azHgyUpx~͍ 噱Zήj OqVbUYV~x +SdVS=_~z1:7/nJb}R~8tӒ>~ަiWWwdQm7[?&)E!M6y^tanH!i1zO"Q6Ρ6@Ђ y{7GȌj_s2e:@\Y5;{ߴg볋!xoMC&SY,˓Et}m~nG?|u|W'׿:Z5. ue!FmUɪn&8Lㆴ,0%л0W˶Ե Y4 ]ٛw}W1Opy?Y^Q;={NE/˺;tZVq^oof/~W_w)̣Ƒc !e/nާ(OAJ81ɱ ˺ia}ھ|>Uah aq8 Aʕ&>wgW?ܾx ]S MjOɯ^<ás]Lcp9J#Z)5ZKySneR` 㗗]g"mjݴU|8RU˓k 3̤[e ú-vO`3Fel1CAa~} S@W9DagW,ؓ͜ƂR:8L9jB9!$A(<%2"!QxIBDJ K h" d=QI5&f`M^YmY5>Xh5HL!A $Ek08()-v H ~q_} _|]Cˋǧ0\OW'icGH˺췓s#&(˚9݃VB驿~izgMeluX4 Cgز.l9zPYN BRʲl\Wug6qrn. Q9>e" !"#(h8 1,E4R*zۻHϞatlS?S? ղ LX,O@i(*ku[TdNoo4eQx~:i~姙Ʈshã1t\^U#alu[*fYdv$8.WK]oV+Z.R-VbeӶYUmݟgMGO/٥X7b+f槷w~*g׿ۯ}bp]dD)6!P,ۚKaޱH^514M[0nn~*"pn :Ƀ ^S<;9MUmVj!t/9?_>~]gӎ߿vCX7x^4g6SL͛Fsnt]RSNk"w@@5|<k61DfN1yN R]psUEnD4 R"32KJb Ji "(L)2 ?׫wۯo ?xYݏ?BU(9r܍0O1QXDCbB:$q.EݮfIi֧)6{K$k8ت̑ -zOcf# >92Fm2tRAs\HkH hSh"_ !4@yUeaҫ3\[Xmv*S(|]?a]ICcN@ *B &A0XbR^؇`H""+DVYR  $fVDQmy\? s>$t1]_?ICGf9q}Qk]^]Wna4آ޿]*?ٟ߼/.gC?VOOßϯ]OVUp 2?8O97ʲgY֋fozvys'TdG]PGi.42"[SU`7CYd}RP`$"#*ҜRQd'pQd)&Ml #2yr-msTEݻe 綒JLzUna2eg6mтƼr#a.r^,tY==Oo-JHŪ: \z.F#3{T!i0F`@YVff&M&1<&2@TOчXD % 3juQ!J[ 5ƹ@(@b0%Pc@-":? H,3""l@ݭAJ "),#8$X 2 bF+0:ij BI,L8AG|D"ά"$e_|-I_,/>a aƄc(G__?,m!QW@R"%Q!@VIQ(I J󫪬<ϊ=Y0ysyyI`qj)ş_e1hW\mw, aJ]woJbYPY4rȊx|azy[^ׯ |m^yYĤ$W9>?|F Ϭu“w{fj6vKuYWz蟲:|w/_߿o'_#Z;?dY}w= <_'$ {x:\^~^ˏ/R޼1 zy}>Yl瓳ՋKJn ٬C i1!lv/_||wCgUq93&Ӝ?mDhh"+McRt(l\Ū(eQ(I[²"6RE(a1h@a42VkɇPr )3P 3"!`)"hNHD)RL)RQXZ)G?`L(6Is` I Eem 1 +sH)?lX"h`D$( _~óś7n;v$\~7ZR0F!4OϮδO;7)!yv'v.ٺnJǧPMQ!œ*R+ .cri-bҤL~qڸ1y0 SU]zb˲cE6eS`E71͊(&+ExquV/Wm,vqy^=?kG2Ҷa2Sš$qD1쉄!_%KkSJQ$Hn)kʪrWU5c(<庱-׿~c_z1Y-]7eJiyz#FWU+~y~{%*KS*/VwӳbD'fY٧JH좍n@9uP2cNÄB}o~97|&󴛫A9Vʡ1=>޼9`&?M;cd[+hؔw?z9=C7dfBAF7o57O :Hi\ŢO>jCL.R E ?9|)(&( c]DtȍN! AF"(i>bJu Y H#^o1ab@H H ZkF,RH$@"R # Z=HY|"L "()Es"u9c 1ZYPXY)R(J#|hRg/>9N! wv<{Ui;tc^eqy} @“^\%) QSFի벩in*sx?C'BVJ[SpS0J &b8V'py!SZs=SY=iJԡ ^@:8N3i"MDZVU] 3,㒀`7tOOO2 9 5@&L63yV"i7;Z.1cTJlCH)T UݶYwO~~9Yl90vg2S t6qBMB C,cYD{vfFi6,d~?gu:1:wrԝ,,8Nyp(ru֋SI\{xOvn;og~^dn}v~wo*rr=*WlW,,7!xe!xGд@IёCa_^T@͉gᄏuAB*'UY5mQzP7UY6w7gŲC'>rY޾M9Ftޥa>"Nǧ&3w (k,~M)0Vnp~^6e[JSSW,m]6%E7]={u^bMSmuHOaB=ܽq0GJd0Di}7\eJn͇ufqvu޾<\ź89(VA EA="TJya H 3ߔm`vwTnrwOC32$\і^iD2 p Pًg@D+4.O 5 ܄RJ>E!y#@B}L"(X8$HLG)<@GdJr\vEO11ChI)G IDAT"Ř81!&HGb bLDPJ"ZiV1 HQkךB"$Rǿ/??9J mwvvsh)@J0lVYۗ(f|09ﳢng",XmE!2ckˬ~ cB"e(+K¬ a0ڂ@? {0λ sʺ#o]^Tʚ9k̶mP()+:"hژy c,Ew]?s4Is0N)dNd.G %6>ܾ'J'u d=mɒ3;-C}"_JP`l396#4(UY/r+ƎQNL"Ύ}k-.MFPXqiܣS߹ޮ?}T<4,R2 !5fBdh}آԶf8Y.ArYɨgyqRV^?Ȁ kxLRUxTOWf:| 0Qg$2]2L_=UlUE@+qȲn5lZ6F +AXmVcOWWnM9$l\գm&ٲ `T'u]`$Qm*ˊ"aM} d> jeXT",7O~Tt@@%m1ȐRRR)'(,Scf-:焀QʣA91Ⳟ@2 $ODeD y^>?!EgPH-yt 0+W1RZ%NBa"R ydafVJlg??Mtnssc2lPO?xϪz Uf٪m> kBJB0*%dX͚͡;rHF$P*%]kEsHCmPZ*c6Yf'RJIIAV(g?0"+(%&F+%CC#zlZW7~ * TPH-և!7G׵nr9K1*elV뻏Z-mQHjSn^coP48J?l5fS%m6XłZPr %th8La$}놐F@+-š=:1?s's7lyyxśv;)B!|n#Z,˯yeO.w[-`7e---gF""3gYnR3-no@Ok{u}?M zΗe#Tjlַ^>l1Ǵٵ.!st^=>[wǧ?d>TUa{!SR_7Ux%jM)w6"gSjnl۷H|Qէa=-p! ߽x6!56UF?V*Pd6c]T}FKYe%@n]Vt7w.QX@/ 7H c ƓYeUpgMBt7Rh1Nܰ [hD\LK-e'KA:0ɉuqHcZ,e<7nlf&sHi$PNEDҹ~6RӦnwA 6ALb0֓FNT&ˈɻ)Hٶ蓐XLs)1He3Kt$)䵒idf(D0D'LJҏA`I֡ )Xk:FX V$RVtnwNK!D7:!$"(#IZJn\~[ɽ|Dl2c;@30~Juq7efnݟ^dV]_gbY};\\?ao=%Zsl>E|Uۺ,We@rمHY^)t:6J~oPjyr^Cpz^>{m9a_,Wʍa>e(UQHE!tӪkO~aswC*H*nV$Ԣ{M:OQ)0y%0v Kp@-5xrQBh$d%d RFfIU]Lnl|t*M*H eB* nZns]rtQ֪̊7n}H4J1m]WBz^E`J{T^(c`cN#"GHcpJ %H} DcL)j)Q(G ƣ( FJcR RHB8^Ffu!(p&y# PjT!їYG, %PeT 3/*cM;q\82/ k')Pm*!1ε,3JL)"p{y<[)l⁉ZM) (UA27Fno$, [0ԓ b/"+;L]#|r6Eiѷ(ATRL/lCVV.K2_~udy?3I[Gd( (Hd.d S) 5]]|_߿u.zRF>~rn2O?~廏wU=)2Tr97Wru R~h]^YȊz:YV٬2aszzb3oo6uU|B}Ⱥc"G(:\,ek[05&áarZC((7)bL|8WWWi}曇Ooϟ?^/xtJd^6M]߯ůMN+7?.cUrmoo>>$o_B4ju抒4<}-Nq>YFޘg M_]=|7W-D5a*'b nw%ۍl*g:1dUNs;wrv7MwC[St:ghrjwnȻ. ;탷Sw7jBln֙F!B=]߻BHbQN晔aw-m#^wg>4eZD/h/\Dw8jDIJIBdu,t19cV7hI|2nm#cr@%P )3ͥUZe%F VR#LwFJaI(@ ("dDA(JF udS Sb)1F &Bh%@ਵBhQ3+e8@RB$ĔY>z>0?DZ*_~˿E1}xݯTWUvr> _om|AA t Yph_L#p@ TVqYJ(E*i6yq$5JHF1ŇmG\eeS )Ū(B[.!KN&SF jPj#uc=Cv ޏN+ }8 ah[-P6mϦ j(uC߸ (;|"y0p躡sntH1ybߣT 3aHRju],u>8DwI@]<@l\o>ͣgn>ág.@DX̵ndzRam`֙2M LvߝUQw~wQ |w뻏ICzrr5y=IC"݁YZˋGgBf{w~cev 1;7/^|op|wdbf˿۫"㗗-NK@!fz9/8k+|2-~j-b 15y;N0/la̡q. Oj0 #М, ~V17e5p}\.JǫmxIϟ|)yQog:xڼwa{^di\`1hIa;(R,,HYZZ.PEEI#j,JQɧH< T)(! 2EmnȬr)?ݥB)IHJh!1%R1pD cԟ]6D$b F`)JjBABT B󁙀0HDZi5E(Df  G_rVCM16S˓eӶWY=7 RF_<:K8GeOn9}@BJ$Р%"l~v6mmDZO!<[E| RSynQ%H)dlc01TjVo꺲E>ڱ+mmiafkDlqvBخ= gHĔeVndJ1( x:|JBI7!ABȭ4~66WFtc;(RDb%$J(FT sc೧/z֯_;r7! %F%HYev!X4:w*effB*@T1rH޻@,21H\,l.VjB. L:cbOD-K jh% ݏm,l\J >qO JYظDaGwvR>ޯc##1P #d3 F#'ZN/.ۻfy躎JHd@ |ٗٲ·n+(幺_#%Gѵ_~}~~~X Cd,<em =<=g\Τ>Dg!,UWV]ݮ=^<QY)dY~{vc'^}qauxYcmXh r1aܳG` ~7Ni6E!*#8;|oe[TZW]&j&zj]I``@fF 1D:fMv>fsHcV#x6sYfj?Wnzr۸&l5]Vq8 Gb}P>,'4]۱kBUQcRncTL$YpHJ)UUfy|pT+2n*g3e& IQHADt#$VF PB$8pL$c9Y! ``dϝ/Z#") f1O @L.@*C2&Q()q"P2*_|h<[J-vf/u t1e0v^5~%fFe(RԇOLVծ [?0 s}~|DZ "Cݶ=D,B`ƃaUVIr6YM&{ϳ“V)mR;J.]2жYմ {?6RH\d*uCo1VEdar'G"2R ȅs8*+`=`:g@s6R"J)LEPfE^W"3'O\}xbPH-rFyfI"*\OΪ$b״VQp̴n"ATB! zYΟA:6&NyNi,,3zF?l9;}Yi5zGxO~el.onf)H3uVѓggVW&l~2$ׯfI=)lj՞GJbB||]ut:Eea ZU''9fwsrj?n\߭bZΊn;HI 0Ha2)QJ(͇O(T*- IDAT:WrҚöQ&]EaۓΞTQy5X~9l7뛻Roǫus5;Pt1)};ߛ\04kgTQM83YVYUdAR\ƍB[YV ڋ2{P.9i4Rj%%6b-N={FxtcmVugOjپCG"pw72cOzՇH>}ʼnv dB+(-.g67*&+KR8:i0'>C"2EtQ I)ۆY3{# \$1ZE$ B J P)% !Tq?0Fi-RH$" DG4BJC8j;d"R !:(B#BK 82 iF %EJIH bxIQH囗~?%)<=a}! G_=6uur}qn vDB402@#evxz<{@I4imrA!KlUN9UfUA}; `hcmzH!HP.x3k#s?*cHnJZw]tى.Pۮ:/"Kbd ۶u>F''PбLKgYj#H&79$d>TyL ATXJ)C c>pξ벪=/5u3=H_?nGh `LQAɴ-:AJ!64ZckH"Ӭ\)?~z}K1 E%"PcTJ.yR)*SГj>/Jɝc(dV5h_J)>]یpC)6OUTY$LEN|EѭoT|zR1_tFEaQRLjܐ<mRHL6?۷olY"ݧ䍵ʔe5T1wY jvMþ_zcTMܻ/g7W(/<o_\\~&͸^]_i7(ﳼX]Xd&ͬ 𮲲(/-1+h6+Z3b|^ǡJy t! a+iTڨ3ts9{zۙBN&<{Nf@8_R՗'rUiGPU phS|2tRf{, !,̳g kiRJOʥ I! wQ eD,B# p=BSD$5SJ0!J<^ @%1DU&?g9lD RJL RcI5#ϥL"%dBcB$AJ)gG8REw(KOw>df򲲓i>}|2NWooO?]w?vFn| ʤKQHH<"+%'(r)~i)dv5aDc@Aru+iM2IeM(~p b,ltRwk3#STR@eYcM!L&97;=FM$1*EbB)Mf$lq#"˪v daL](n Rc!%% 1)`# 2D1m{U/?^cb( X:QBZ`!!<'9l$!ғǏ۶b )uHQ&8(Ζv)2 )]6n6Lb,pE1+Z qIC qRc߸Pdp10a?{~2J-&IHVt1bHB2m6.,~&xqx~ c}c/\~O=t}/~pw7O(G瓪 ~lVk <ֹ/C޵O]|Otݭo ?3mӳ'Ϳ1 !8P̓/Ξ<{ͭt~,/'}9<J&J(AɈyQZ5L㫗gqa+ٛZ̟j_YVY ZjlC * )Oݸj;nC| ҢP&Pfq^ v5qx_y1ue-NN,zzUg٤7J]3U q`VMH2ȍD@uiI(#RS\Y@bQ&JchR$3E J$AdcdBω~GN))H+ ̂oH(hApfx,BqyB Ĝ(0H$W/f$ y TE5,z5[~aًWl6m?tvu{׎T0(ܚzRC`wCKkcd\Lm*D~3v߭wqi]Q[;$3a=1j)YV €IU= 8%Dnϧ!:Ik H MBA)VZ>TeILZyZ((J q"2 H'bcA(H(Y z>?oh}{pu1w뭏>N 0$Qebe ڪ}VOͫ/dv{zz68)m+J23"F?_̟|6?]q~Df=d`qC4Z_TL5=3cƑ15\I_j?ǡ3k :!@֚oeJBgU]Ov;5F % R^~Uuuyti'Iso՛gyztv wcs~vn9k8]M_xY'2m\He믄?m }<}f RQLIQ?.?m];뗯~?!Hh?f! ~pt! =>}6@IlJBigm#$\}\w&G)5qaǞYy`P?>lzf$ p6)LN^xQXHʼ,ڔE/JN,QI!ZBJz!3R gL"AVt#iQǧĜ@d " !$%J,Fm@2 D$#C<1!r!!% &RB |8yN)Q@AQ )X p ĘCD՗n UY3?}Jƛͮ{ߜ7OdFw7z(CC rCy$Bd1Cf/l67{!E@N~{Yc>Eyb:};͘L(>7+$RYrD9dv.8f,~_HCns ]U-&C)h-oɤޭ7œIfweIZBk#&̖ui`EEN;eA@med}JED=ؘM MҗOn.b+ݤ.O 2,UT"h'm;˓C`ȜcNbBD}t&D=&R!<=@YH0 ȥ{("H w1 (6(x|Q b" !I b " ן^>Y_~ [O/.}|p|m߾VU.gi Ef#xN8F-zqyfY4MӦ":πy] &R+soihC rBQgm]@&u=mZ['Do#A*3UY,j, T~?B"mqtYVyDz:zF LZO5;p `GBBdX!Oɺ"c"R'HA#-#A(N11$D-̓秗/,]^eCtcE"&.1,>pH&˥j>I:9\T˓ #mBoz۴Mb{?tӪ̔ϕCCJIʴ]_,ݾ6Jiw秋)-/ow1x eU*H7\\\zhb9ׇ&lw惷v<G r\p5mk]ȲIm7X|0Fi ;)ƧOzuo޼Y?4Ź;2Ѻڶ3&߽ 8xa~w轍}7u3'6dYphv{r~#1Obzn&I|8@Ja~qon캢..zi5/1c 10R~/b7Z*lʺktZ\>8WB 2ޮ#qGde]\_oj1{RF#DC5_lq[\)7+/u*ꊠlZe,=֎cJgmH)0TێadbJIj15NLA$:!}lBUdC; ۄ( F@Q4q8!2Ɣ4x?e$1 c8ШkmISLHYW&E) 2 U=-ҹa+aLYJRs׍0BJN*=z@ )S#T $'A<ژэMDH PFq^|]mT:J& ykhPӑZhCJf fsn~nhFgR#ӟr#kWWOI5)I}rzzqz[!‹OIe8/f۴1ź*_|:+s)N'&*d^M.$UFd͡6̘Or2LP~ۯ?ǷBfE1}$)vvϳ|~<='0H^?bJ$M ROcbGݒֺZ<ˤUUzD7[ӻ?W_˫ϞmwwIYioCY(Aѹ(k.};!#ՓɤTC-N >6Rgd86L^~ܴMbTPt!".@J?.XLB!2kǞ)n?v!H(B'@C1qYW8mvt$ww>t(2;t30iCi2ctUU;E"B1ye4-LE)۔b]#! ??D߽w)&$ &NG0҉& $HQd9ʣU|vU76E#T"O˧/>Zoׇgц")|z6)K:?ӧϭgϟ^L3~?0&`=J1?_-4[/<3F,tg0NeYY1хȾ9DBվ9'ߌqwwZwa9gsv"#}.RdY]1eRmQbRro6MQ|~׋t>Ch_Ňf%ɘBIfth[٭"@/_ o]9){K@NNgﮯO.'?zlQ~՟(ũJ*~oo;ߏ\LNHV"l*bz&MۜtN./Jo;-殍2}4}v~FOiӬâJwUh7?خ6&(U-0I95=NWӛ;?Ƀ=}/_]45{ٲa:g՘]/> (bbccnT8I͂z όw,$'Č{ "3F[ߴ#D 1) B2Y 1@$)")y䄀(I)IBd%CA!PB ]XHa  `4@t$bL?̄ >:ɽ~o>@ L fr9b?B]߹8!}#F D!:+S 980C{[GIDAT8ϤG HA(bIRJg9B!E&&z>lnBt%'{r2ۮ͋R"!&8E Ĥ"2X(% )y- 8 ȑb>܌(`H A"Ja/2 D*(A)]bcT!EO 1WUY&Sy!ⳫKS?BhYf!e} IȢ.Qӓ*/u×_}PQ<{|\(IQLIC"/"9M'T m{W׳jf.=LIg8=]޼vlͮ1դ֏wbAh,3U}1Rf4&` d à3&{mwo_| S?gOooYq}qw}}\좜c\ՓY׌1ktj|sIۮjz0Ӫ2alhӛ_}['١MfӾk~J}]sdeWa}qs3lJelW;c"Xe۴oc0tyepn=>7׼<Wϣg i%lP5 0%Y[YH>q?1Vˋ펝嫋tf:2cu/\Nr2aYv{zy*ePRbJ]I1'AjUԙ*0REk4!\nR8&,zJPq2 HJ; 7D1ϵ]d&)AD= 9:7HdFb#ۣC;&#2 `,TJ0{ÞR"!!$# c`AJ1EA‡ !r4J3,!ރ!!#8s)>>HG}J c:;]WXL?bv\?n˜\3Y1ȽFPDFCe, mI`G(l*Χ)&ec.LpNVeA6$ R#bnGi'BADL HD 115xl2# ЍcdvBBpѶfu?0- p:',f3;MUu_>~\t}o6֫,U=wUUa{Ų(DMLɌP]U 7ͦW$$MF6Ƽnoo Ãw5FR/m~$.>ɫ"&]ۧ!N >GF;Z)Dv2&^..*1:$oy&3 gO_>/_}^~_q{އom\"5Mwyy9$WcH 5N 3y#s"z `[!zI?b5p]V.<}]'w/E #JE{7 1i.yJ"]ߍI̩ T=/pxإݾ?dff#ƜMvżw= .N0Ǧb ^_OJbݳφWҮãm޽ fS\$ȿ?J)`  JA<=>F.m;Z!F||F kb>U6߿J!_DBfAjT@) .$IYv$4Lbd,sG71EctL#D2?@t\>1JQfd}ܞOBMcR+!To{aD^ $-4NF7)ۏ!,8_qd2BJ"%DBNHh*Ť G'\8dz ֛^EVrix,+c$ )x_k8PFOZ p9(uڧ*r:LWfJ #xd!ż~}}Gf~fYo?ݿn9ׯ>{9DĻ^`@%g'?<>>o!4z n> !OgpWE:PP7)ݮӶGCHwCb %$Lgyimnpd o% aRיκY]o./Olʻn>*iPdru2;I|o ̴ۼz}xv:Hz>YZb_߷? lqmO(Ο]\^\L|h|l)nMWW]SO!vۭ~,f*P8W|:e"B(97(L!4aZ62 RBNOBdID1F)ֆb )0 @$OD(;u[kG"{9' QLI )b DS1?WՁ$gRJ4؎>Phťw{?D H }wpH B@%Ԧw}do98.'nu?q @ `OB `REL8ZƘ|leRu)087Dkd(+@)DG~ RQJCDtb>xcJJR6E)Hk{k F`I?(C>lY y9cקp( /ʪ7?8{v2/?YKi1[AH@@ ZJ57dEŴXje?b 06Ǝ>FH|xryZb/qlwTd1 m $Q=,哫byr83!Q./b;HJm뇧W.OfϿxqǷoey-*B)׈<~69 Ri*Igh9iVՆ1*Qk)yNgyQL@Ĥ9h'P H}ߞ,"c~2!+jYh!t0_NauJr1_}^!evRZtF6ƀ&J7׫4OF;mmbٻpvz?>DƔ$R3aBdxvy;2TZTݿbyȂ~WNg/L^4|FOKOVQ%B~=GmZV0(ZWTB(E;uMV߿̓oo} tȔ.Ibp|(^.ř?ur>T3ȣ? Q^>'/'UIy|L Rft>a0$TQU9E^8h6!ԓpDHU1QYJT*O/ގ!qIk}T| !'` 06Z RDGd#IR"'t P6YĄ{8"#^A#91"J!P#y'IENDB`ltfat/inst/signals/ltfatlogo.m0000664000175000017500000000326113026262303016351 0ustar susnaksusnakfunction [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.github.io/doc/signals/ltfatlogo.html} %@seealso{ltfattext} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 = wavload([f,'.wav']); fs=8000; ltfat/inst/signals/signalsinit.m0000664000175000017500000000164413026262303016705 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} signalsinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/signals/signalsinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/signals/cocktailparty.m0000664000175000017500000000326413026262303017232 0ustar susnaksusnakfunction [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.github.io/doc/signals/cocktailparty.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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=wavload([f,'.wav']); fs=44100; ltfat/inst/signals/bat.asc0000664000175000017500000000545613026262276015457 0ustar susnaksusnak0.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 ltfat/inst/signals/linus.m0000664000175000017500000000303413026262303015506 0ustar susnaksusnakfunction [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.github.io/doc/signals/linus.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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=wavload([f,'.wav']); fs=8000; ltfat/inst/signals/otoclick.m0000664000175000017500000000331013026262303016160 0ustar susnaksusnakfunction [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.github.io/doc/signals/otoclick.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/signals/cameraman.m0000664000175000017500000000314313026262303016301 0ustar susnaksusnakfunction 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.github.io/doc/signals/cameraman.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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'])); ltfat/inst/signals/ctestfun.m0000664000175000017500000000245513026262303016215 0ustar susnaksusnakfunction [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.github.io/doc/signals/ctestfun.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/signals/batmask.asc0000664000175000017500000000625013026262276016324 0ustar susnaksusnak 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 ltfat/inst/signals/traindoppler.wav0000664000175000017500000114546013026262276017444 0ustar susnaksusnakRIFF(WAVEfmt @>data{>0Sib%: =D5WK%]D 00W Q: Dq0S Q% DK% ]+ l0!S0S: =qDQ: {0]i0D: : l{]=K5=WH 5WDDv Zq]DD: HZSKS%]]q5 !!]S%Sq]%x00{%K HDqgWl]!: =bb H=Z=: qW:  : iSDDDqK5K] : Wc : ii:  {c{6c{bHKW v KDq%b>c: b5W : ==Sq{: : bDH HHWiDZHH]]S=S]Wl]Z%0]l55b5D{: W  icxb: ]v 5  D: ]b=W=5  5{]=q l!ZW]0cHcWc5li  {=]==HDq5 DqqW+ ]v gHKH0i Kl : c!: W%]b560W00]c ]Sbbl: 0v v K!{5=DWqql %: Wv  HqHv ]= : : 0S]{=D]: + =cqW: bc{{]g 5q!cc{il]ZS {v + c%D{]D]]iH=WWW=DKi: : + q0lb5: v : : qxb Dv KZZD]qlx%]]HWZ]l !x=H]]i bKWW ]+ : KZ D: :  D: SqH lcc5=: =%l%{]D=K 5W Zq0S5= b{lHv H%Z SDHDDqq: Q]Wq]q%Sc]Kb!]]b] Q0% Hi0%K5{{a: x  !l0WKq  q: KDZ!=Dlq%]%+  ]!{ciDW]l]]!]q: QQ: q%x H=D5%Hq=S v : ZW+ 0H q]b W]Z==]]l!gD66D{b : ]: : ]]l]l%W: : ]v W]i=: x=DZDDqD: Ki5b]=HZZ%lbS0=K]]l%Z=0SbDbl]DD: 50%W : HibK5]%H=0]DD W]  q: Db]lDDKb ]llxZ%H%K!c0]!>q5HW: 5=D!l   =lZ:  Z: ]  ]00]S =l]5 l]] ]%0D%bq+ WZ!0!l]bqlSb + lQgDxx{= H>: + ZbDH: %iqlHZ%0K: v ]c: qWlqD D]!W]cSDHZbW Ki5: v 5]]xx l55+ i: H g=%: : WlD%H: Z: : b0{DQ5HZ*cqA: SH"7d*pp>Z+ j46Sq p-ZjPKpxͶdIW+ }6""c%]txZѐ-ddc%3-3JUG?6q%Aq"/oJUڝD*u]4yxZ*QضBPP]䯫ͣII":_:Zc%:ѐuH3~xZgU20"Oõ'q࣋-&"]ty0:aud~_7gDBй7"l Gy_uѐ GIJU~juu"xZJU 6{DyA}uu'/o~j pB: U2/JUuu/j~Ic%/uuO]HG?A_G?ݣu6jj/oJUZIA}H"3:JUPA]uu'/PpՏWv jp*]t xZ]tIU2uHxZJU'-_AO"]/oj>c%3u G~<uDaJU~3HQI7//ZZWc%]4JU/:]tA]]Z"-JU~I{3AuJU]B%c%7 /plQqu:HѐJUj<4d=qujJU/guu}Ⱦ/ GIHj:JUxZJU!' BqA_cuѐ7// G'-/&"JUuuc%~Pu7U2/ojBuxZxZ: Adڶuѐ/ GB%JU/oB*PH~P0 GPD bI_u/*]A]Hc%WdJU}uBА*cJU]tSuJUj'G?AҾ/ ҶU2v BQPI"-<q/ GQK S䈥Bо/7"/oJU]-JUҭc%d}uOdG?aA<]G?uZP~'--c%xZ0g/*HI::u]A~JU3U2qҏ-AG?c%::3"*gO-*d] IIS"U2/:&"Bu'-d:"jc%-HB'-Pc%*:u:~Pc%c%KupՐ*JUxZuc'>dJU:AZ q-":xZ G c%u"dyv j] c: ]˩ G]tHpc%7S6AZ7<:DAuujyAuBУIJUxZ/--W7c%ppՙp=AJU*U26]uA~: GjBpխKu/~/ 6趪G?3c%BG?Iqc%3]> A~JUuc%d Gc%uO/od'JUPZupJUu"JU]tU2涪ŭc%: *ѐG?d0&"'-Buv _]tZ G!6G?H]::ˣ_<4uAy*ZZ: GU2 GѐJUd&"b4uu*~_ !&"JU"BPdIHuuy/o/ ': -:/ uu: JU~I͝Du xZ&"c%j'pDcuˣI~~JUѐa/_A]H:7I_ GxpՁ{"uG?JU/U2A ѐAG?Q6Ba/IJU GI"S"JU GG?*"_JUc%4]}H/~JU'ھ/PJU]tuu /oIJU &"auuBЭc%:_I>ŵ鶪c/ojA]uxZxZ6S ѐu"3//j~&"]}䯹}/xZquA~A<q<6Q}Z: U2JU:G?:'uuxZy/>]ѐ5򶪈SJUjPqO'-~"c3 G?/gSG?S_ c%xZuHS~y~*pub cc%/]c%BDPc%]QS䶪ݐ*JUG?b: I'"{u"jj_c%W6q"xZj]c3v 3'-Bp&"_G?au-7~~7涪: '*ppc%A/o GIa" 6/U2' D47 Z*U2]B'-D-yxZc%؈/: ѐ'-jAU2]pB/JUAG?uB4_KHO>4AxZ/'&"H-c:Wc%c%uJU~j'-: ڸ'-IڶBНgPA6BQ /oJU'a&"Z]p]BНAJU/o*]ud~]tZ0Q6B'D"/ IA}H SpK G]ZIjj{OlDD"7 {JUxZ/}ZuI~A%ѐ&"JUA/҈ac%7ş6B/Acc : WKA]tc%Oë  G<: l6JUOéc% G/i 0]ZQ7ScBDAj&"3JUQͶŝQ]: _yuuj~dI]]&"aJUZuŦ_~d&"U2Qq HA~/o&" ]OuH / *] IJUc%-H&"j~PWŝ: 0gHDJU/od"c% ]]__]tI<]u}: 4b]6IjAKO" c%ѐU2/o: "]>*A:0͈ͭJUdѐ6d__ G G}&"xZ~jc%uu5xZ~JUu7!'Z G G ͶW+ A'ؼ'- pu5xZJU' lOU2IP'㶪]:_/鈥%7:W}D KO]j G6"0JUyAuأIyA*:q"}pa *+ {W&"c:B6ݱ<_ GOZ"G? G]JUdIc%x"cIB:IydA]HZ=7~I5j/6v 40Aj:<66q}D5c%p'-d~IQpSHuqdyc%p Sc%']Bi*BJUj Gc%ѐ3I g6xZ/oD""q: A"c%~G?} 4v pնa/Ac%H qPW}c%c%IqcBD/"˝xZ7P Gqݼᶪ4P/Z0:jJUaJU'-'-= BжZPv G G:c7:OH]/P]t<Ŷ> Gc%cH/d//ثS/'AP : d""B/c%]&"*]t*{ ]U2 SDI7/>}u"<~4&": Zu GDQ:dU2 A:-:d7Zq}Wa '-"&"6I:&"37B"=' G*pSdpA /6q]u ~~~G?6裋B]DPDڈ䯩:'-U2JUU2 uҁA~G?QBЯ*PZ/'-KBc%"qPJUJUc%BWU24&" }ZjG?dOc}QQ_<-}aP~Audy ]6}ȶ嶪&"G?/JUc% 6cIG?HZBU24c%6 G7-cjU2'ѐ"6xZ~P~~P u>+ qa<'&"6Aq]H6 G:Pڝ*6&" G&"_jJU'p"q䯶BA* j:BНa/c%Oѐ5xZ/"JUjI"uP7A>v G?Bu"]'c%PW6 QpZ6!IBlI43BеOÊJUJUAB]AU2'-c *%ABQA~]u]A7jj/6cp B҈"'JUyjc%-&"Bcc% &"6H}ȼjP&"څ 6u/ 3q0P7 0&"-uBНA_'-IIOuucI~7quڏJU~JU䯈c! Hq JUݔc%:  U2 BА*:~]tA:]/7B'-xZ'-c-3}JU0<]PgD :jHj xZjP7ڈ䯸-'<'-U2+ ]:OU2d/: OA{ :] Gڃ7c%:ApHucJUl_7: Gu7JUU2Ŕ**-ѐBЯPAA: 7c%]cAQDi0SqK G':c%qඪ"&"&"Ŷ-AAG?'  6Qݹ]c3 :  <*06Z!>I/&"&"Sҏv D0 *Q] BB䯫 GA*: BQc%]B5G?/ASSOù/7&" "S7:B'- G/4c uѐAxZPc% "/SqU2c%'v HZŝ: ˝'U2 >ؼ&"3Sq* GZuAJUdc%Z bcqSpՏ 4Aa]U2ͶBD63 cZ0]: &" q H5]5+ q6DQ 6 6c =]W i0! Q {%W+  0>HHlZ = c]: v  %{qHQ6i {]g60]]+ : H6 : cc] l{]HKWQ: {H!baa]W!  c5a ! 0lZ v c: 0lZ %Hv q]]HW cS] W5>: D+ 3 c]xK HK%]qv  c ] ]%q=   =S v i:  3agq5]aDil>q6%D: b]DH33 ]S6q!Q!: W cW  : Hv D6>Z: aa 0{W=: + %66+ 3Zxc{HSWK!{DHW=5qlSD%=Hcڝ v H ZbxZ%xD : ]qcKgW : K ]ccc]q  b{W  HH: W]{S+ ixZ c0H  6cb+ =0!DlxSiDWDi!>c%&"cl0D : HDiHv S] % WW: 5qll Wlv W0>6c  i>+ 5{00lccq : 6Dqc:  {S0W: ccq QSH=W]   + lW: 5 5H: v i%:  0: xq5 q6c] + !!=l]l0 =]0]: ]lq50{DH Wql Q: : W: WW]S]W==Q 6c> : b{q: S]i!0] H0>xDWH] Qv : : {+ 300%D:  {{5: DWc5W0DH]ccc5qDW=i=0q: HKKW %0cc   : DD%ZHHW : D%{%!]Wg lDH: Z5=cc]Z5]i+ WSi] Z!cHv : b   g HH]]=  Z]xq=  W5%l{Q+ !WWDv  c!qKKWiq]]H: !: ]v 5q0W5i]g v %3gZSlS a Kbxl>WWWq=: H%H 5=!5DDWSZ=cq : KWD%5ib5HS]  bxl: ]xv W=]b  KxDHb]gQ0l0l5ZZ0{bKKW{>{=+  + %! : =Dxi] QQQ%liv Q S{i %Q 5%0lb!l{]%{0 =b0W: + bxK%%Z%: v xbD:   Wx>]Q+ K!x]l{WH+ g: Kq0%ZDqD]: ]00%!]5D5: !cq=: : D!+  S5WW: : HZl0]i gHDDl!%i: v b!0iW v K]DlbD=: x%%]0ccx: Q 3: WD: v 5]0lxv v v g: Dbx]00l] 6 H]{]>+ 3QW>q!b: Z]lZZ= Q q0cc=v v ]xZW: + W  =0lD=bSSW5c]Q=>0WWxq%]KKZxc{H : D]l!qqZ : %]K=DKZWZ]g : ]]Db]]  : ZK: WKS0D=Wv WD>!S5KcW WWc>x]: gq]i q]lb: b5%!H: : %Z SH: HbWWH: : Z0]l{0]v + : =6c]q:  + ]c6]bDDll]]]{]WHq%Sl0{ WDig3 55i]!xD  : Hbb%]:  c]ZZ%]: : ]%]%Dbq]]qxi q%!HWWSqbxxW: v Z55WW0: : + xW!i {!]]ZDc{%K+  cccc{Hv  %%55D5=D]Zl WK+ : qlKDH  lcc0]D55KW  0{0{qK%lqWDWcHQ : W]!!]Z:  S]lq=  : qQ+ : Kg+ Q D0!l]K Q WZb]llcb  WKlZ5=]=W=00l]ZD={cx+ 3glH]!] Z0QQH]Z=ZK l0]S== H{c=QQ: Dx0ccK  5{55H5c!]l5KDDDZ!=%lq v HWZ!: + HHWHW KDq]{{] =]+ : : W]%W  Sl]{]DWb!! 5c!gWl{%K: Q55Dix]>{SHH 3 D3 : 0!l]v g  Zx]>%Wv D! : KZic{qDSSDDWi00] >+  Q %xi%{6Za W]00q : %]{lx]+ : Zxc] v   qqbq v {> : 5=Wl0{%D+ v qZ: gD%q>6cQ: c v v WWWZ0>{D5W: v ]cc0i%>>0%  W ]bv 3Q: =bq]05 g %l{li% 33 b=b]{q3W6:  3Q00!>:   W!c!!]H: W=%S0QaQ: 06q5 Q bZ55H : b06c]5+ 3: =5v v =b]Q3g%c0: Q 0c!bDg : K]!HKql{]q{%H3g%>c6>H  : Hl v W: : : cl0]g+ Qv : : g=0b : Q Wcb: v  : HWKql]]lKK==qlbl]5: : c]%i]DWH+  c6cv QQg Hbc]ZKH: : W]Zl v  K5Zi=lDW: QH%{!]%l!Hv 3 >0liZi{0SxD: HW0c=K%0  q65+ 33 !]Z QQQ: D+ gHD %K: H0D: ggD]l   : W]c0iv  : c]]x%DQ D6 QgZ + i]]]!lx  Z]6q6 &"Dv : >SqW5!]: : Z: WW]xl{%v QK0ccWg30q60gQQQv : ]c]DDS+ : SD5W{cx : HS>!q a&"D3 ]0 Q=5l{b 3Q+ 0]ZDq555Z!c{ ]]c0: 3v bc!q3 Dc6!:  b5il]xWac%Dl0ccqQQH]!+ qqc+  5%0=D0cc0lW QgD]]!l0+ 3Q: l]c gq6g  v v   WS &"D30: QQH%xc]5D> ]q%> + q%{cQa: %!>0!lKW H> Qg WHW0cK v +  00! : 5 =q6  c{l]DWWZ]0]DWl]: %qiQ]b= 3  x]{!]g]S{S 3gKWH+ cc{H 3v {0>]gZ]0c]W + : i0Q !0 : ]l!>v  q]W+  : : DS0lKaD3 W: : Z{]b{]v : WZbKD%0 D{>]Z: v W06qqWHZ]! QS   H]ic+ : DZ]  g: : D]>{!0ci a&"c%&"D>Sq6]=3 c6D ]0cli]%DQ ]6{ : Wc]]i]c 3Q: HZqqKS: 3qKD=6c!=: : v x!]5v bDH06Z{cx a+ {]: gD%c%Dl0l0] v + >]Z HQD00lDZ: Qv W%i6c : %DDl0{0  Wq]5%c0%]=]i>0]v c]]!0i a x!Q   : K] =   gHcD DDxDH =%l>QKq0>c0]SQa c{%Z: 3 c]bW D0D!xv HqiKKxx: QDi+ qZDlqK]: : : : 00DW]0>0]q%%:  {]]c+  {!>=  =0%H gl>>!0> =WbD5W5Z]{{W  K]c%S=Hv : 5K]ccHQ3Q+ K{0{x]K=H:  : cb5==qcK: : q D=WWv  KSgg Q  Wll{c{W  !c{]qW: qqq]06: + ZDb%]lcc:  ]{0l{  + W63: H HK]  !Kxi  QQ ccHH HW: !KSDb]S6c: DlHH: Z]%%W: ]{%]xW : ZK5W]x%x HK]]ZZ 3 : W]]iZx W : %{c6H : HS]]]>>]]!H 5 K{{{>]x5qD 5cS]H  i55  Kiil%x5 g + q{]53Q ZWKbiD5: gZK]: Sqq00 + Z{5Z0c SWblH Q{cqK= : K=S=5: KH]!WS05 3 Wi ]c0D  D: + %q]i  ]l{Zq!0SZ]qiKS!>=%iq + : 5Si0W!05  + : v Z=qZq=SiKH+ q  =Dx=5HDSbbqKbq]Sx] Q Dl>D{]%%]l{WH=bx]0S: Kg]!>H]D% g ]] g Zl5v b=]b  Z]i0>S=i]x{>i v xc%W  KZD5{K: ]{0=Ki%=q5Z=Dl=:  S0{i D+ v {=i=5ZD5W5: WDZ]qWbcWW5l]l%=i5Hb]]Z5! =xxqD=W5D=KKK: b!WHDlllDZqH ]0! =K]0]b!: H{l=50H gW0cl]bi: DlqK: 0]W H!0DDWW : 5i5WlWQv b]WD=b]DD  : Dil0lxSSH 5g v q!!lDH=x!=D=x]HHqb!lq 0]HSK:  =iKD  =W+ H q{5H: HWlxq{bWql=Zb%llH+ l]!Z: Hi00]ZDWDqq55WD QHbqlZ !:  Z{W]iDZb%]0]]%W: S0: Wq!bWKl= KK]= q>]]lS 5=bZDDW5bWKD5=Kq!WWDSxWWl]xD]%KDS%%q5x!%iZK%q: g: >0!]W + KDDH: ]: :   b5%]: v S]iW%W%KbqDZ!]x]]cW  KxSbDHD]0!HHK=5q: H=: {gDKK=: + gZKl]D + SKZDS=bSlq0]qD]i>!b]l0Z]l{]Zb ]: {0 b0x: v =]  S5: : %v ZiHl]=]]> Z%0Zq]%l!5xK%{  =q: : %0=] Wxv Q DS%]: : Wv !0l%0>={%W%{D DqD  %>{] HKSl=b5K+ :  : W: HH =q0>%q+ HWSKZ: Z]%lH q0Z%55K]5%ZDWW%! DKD+ v v DxKK5K]KHqW DZ v !5=b%]: + SK%]+ : 0q0] + D=]cx!Z: x{q: ]0i  ZKbWK: + =%]= Qv  !ql0: v : Wlb{i : SZ5KbK{K]Z]Zq{qxqqSH =Z]! =ZW5xxi= Hv WbZ]: : : H5=DK=qSWbS]]%ll : {lDW]]Hxq{Hi%%W v ScHW]Z: WD55DiWWKDWqDDq]ZDqK!! : x]0]D]%Wl]]WKWHW]qZ%b5=DW]Z5DW5 v ] : 5lDS+ !]%S5K: Hbc%=%]Z5KDW]0l%l> KqD]c!i]q i]=HW5K 5]%: v KDW5H: DH: W%D: =!: l0W: gKDb50WDil>]q%]qx5: ]Z]q g: K%0ZDD: v 0 ]Kv : x bK: v H%Z5: {>q=55DSDv ]!Z%0x]S]W: !Zq{l5H: Dv HKiHZi5 Qg% Hb+ QZWD5DZlK%%bKDZ]]D: D{>cb: : K %i%%DD ZD{D%l!: H%! : : Z: H+ QHKDW >%]D5DZD0l0SDKZ= 5Wc=KSDDDHDq: SD3 %cqK+ H: : + =bH S5 : qZl]iK]lc W{D>0v S5 H0qD W!q K  Sl5WDKH=v cS6Z%!W !]%Wx]ll]0iqSc=c]DDb H%5Z  !%iHi: bZD SS:  bqq]D DWDW%5Wq%5{%H 6l+  ]]qKqq]]%0]D lK]%K%Sb K: K0%DiH]]H KHK: b SxiqDK]]{g 0Q: Z%ib0]%qb5b00]cx3>H]l]W{xSi: xHH WD=+ %>q: ] 5: H= lD i5q!%0!]]x]xKxqb=+ 0{b: 3lbS]bD ]: K0lK H=bq5qK Hv D: =iZ= 0{lD]%] WcWqZb{{Z]Zx]>v 0x]K: { ]qHQK5S5WKx]D ]+ c% + W v l5  clH%  W= ZK%cbW5b]b: lD]]%W: 5x=] : 0 i=Q: K : : + D{DDDKiH3 : qi{W5: : S{%Zb%W]x{]]00]D : ]]KWDq%=D{>>W: SWH Wv  ]]0DD5]: q xZ c0W=]q=]>]Q%qKKb v qx: x{3 b>Z0xi=]WZx!q5Hg: H0]WSKlS + i=  Q]5 HDW WZ>%qq5D: =b%KS0]b%W]x5ZqS0]%]i!Kq%Z{!K%l WDiZZWK==: : : W%v H %H : ]%DZW Z>55: : cb= D]D  ]c{{c]Sbx]v ]DxD: Dbc>{lHS5WKD% v : c : D  Z =W55KZ0=Zl]]D= l>5: HD>{x{!lWW]K: {KKZqZ]qD 3QD%]===: 3 H+ %0%qbD Q Z  !QbDG?'-6D"cPxZ ˝3}OG?]tIpBث́Ő*~_ }O]jI춪qpչS G~JU!q"䯶~/oU2]cU2~AB"O q!4~PS+ ""-Z/o~I&"a3}OüDJUIp- <&"cxZ/o&"4"uuu G~jc%ګ6 c%'-:u{ G7QҊ7dJU/v "uuu~~]t4"!"ѐ'I7] G~xZ'ѐu- GJUjxZ"qQ ] &"'-U2͐*_P_*uu}Ⱦ/]t~y4q'c%]uu"&"_JU}>'-~~j/uu_j]t_O6* u]Ҿ/~y/ '-"-v /o~:uuO4~~j]&"~Puu/xZ:"ѐ6P~/o G'Sѐu] 7P/d/o ѐuѐ'-~]t/o"uѐG?c%DݝJU~A"u:/o~7Suu} G~AlBHHP~~]tOÈد˙JUA"ZPc=JUJU"c65AQH0QjAZ]]أI/oJUv QAu_~jѐuuy~~_A"}ȝڝq"': p>~ -]Q/]t}ȶڸK': 'Q5!/xZ:- c%dJUJUxcuOþ/AxZA]t]txZ HuudJUxZ:&"uZ G7U2JU/+ cOQ>ݣI]tWu"I~yJU]qc%I cOùP/:SWͼ"'&"]t7/ "- "*c%DqҾ/]t< uu}pվ/I]txZѐj"H0: xZ/oI: 7uBН_j/ouxZ]t_K6궪::IqZZlZIAd7+ "0]t'-uB/AAc% GJUauuD7_~c%]u"AAc%"v aQqq&"P: c%:AA4uu ]tjO"HuKy~_BqQ5q'-4  &">bjP:B -!&"7JUIO< GI&""uq'IP4_]uJUyA3Hѐ" G~: -Hd~yu]"q< xZ G/=ڟݹ"ž/yjJU!}ȏ'-ţBAc%06Pj" GJU/c]6 G GJUj uJU~*Hu}Ȑ*/o~Aѐu]4JUcOqc%%c%/AP_u䯝0c/c%0U27"dpS/*buu DG?~A'-uŁJU GIdѐu/A4"ڱ<0WID-4uڦ__y<: u jc%BжpZc%dxZc%jpZڭBjJU3Z/o˫A4 Gc%JU-u34JU~I]tuujj GpJUA/c%ň{:P/oѐ6~xZ4HH"Ad4 GU2"l/oAG?ZOëB&"g}pG?OÔ4SA'-U2BЁH'H ~j7BBJU/APc%qBuJU]tAg* GSuqJUdG?ѐ"Bұ<_/oA{A: uWc%ld~ݣc%{Q/ GQ_~d!53䯐*/o/]H JU~A*}ѐa:d/]}G?/Pc% BWv 4'ѐ"/"A/o~ڼp"6: GjHq࣋H~I {!"qc%W5O6!H' cک'-/IHc%JU~j݈-+ A]*&"pp3c%˝Aݾ/ *6WG?P'-BuZcA_xZJU/"B] :ux'-/ojc%} <'Pѐuq/]tdJU ѐ*:D"u G4G? %: ѐ&"JU*-c%/oc%U2:Z!c%U26Ͷ]tA/7&"aBѐ"'-JUxZ:u/oIxZ/uQU2&";/uZ4~xZG?u'c%7I:G?+ updc%]<Z&"_4U2AZc%'c% cq}ȼd"A'u~]t>qݶ AAuB G_A}ȣ 6D6_~c%6舥B7OpjP0͙ ==pՐ*AJUJUA%" G~JUuOAJUxZd/-]q*&"_uujyq< Pa"q-jJUڟ4xZꈥ:Il-c%U2:: Bpc%*-䯦j7""I/oaA_S]"A_uuݸ~~/4yc%]uua:G?% a6BУ}Aq:!q˙*Ŷ]t~U2ڶa/oD]c: G'<&" W%4JU"uuc%~JUpՔ::D}60'-QDU2:%ѐZS]t/oرD Hq<㶪c%:xB&"* &"c%:6"HB &"ᣋ G~JU6'{c%DˣI~j ]Spձc%%S3 HK G/0"IAu-&"~PK'-%Ij4ż]%"pAAA&"c%JUBuH/l!:j]6:ڵ3P/oG?qU2*S&"*uIxZ!JU6D] GPP'/HW*a"˸'/* l+ u-I]tA:&"uu'-c%:/dc%cq࣋u7~yABЫc3 !%U2/ G&"/u䯦_/o Gg} G'-"uJUI]tS]B xZyI:S}ȣZ:Pگ6"DAdQ]"JUIuѐ_yIv 6B_7u]tJUc'-AdA"-=Pu_jdAdu-]jG?}Z0'-A l5˝/&"c%ZѐA/ojWHc%ABc%*xZcc% ]+ uѐ::dxZJUp"qඪ}ȝ Gj GHS<3/7QBНD/JU6uu~/o/uQj Gqq6c%Hѐc%:A:7_Wu-ݔqc%7:/Bac6 xZ~ҭ a]d g'/ GjZu:j<P//㣋G?%ű<jy]'-A 6AdP-cJU*͹q/+ P D3]pիJUAjc%K:ݐ*c%v &""'*A/o-H}ȝAj']-{ '&"'c%>ѐ}3Z!x j/_ GZuDJUJUAJUu  GOëA4c%OøiU2ŏ~ G'-&"D!'-&""S"JUJUxZDK"/]"'-+ '-d_v ګ]c%'%pZg&"I/o'-6 䯹v /_jpZ GP}+ &"/uBBaJUPAB&"A6˶pD:/QG?iuھ/:~IB}]JUIql/qA4pBН}Ȋ] GI yJUZqͣI~~G?uѐS]tABgAxZˈAI<c'-BS"dc%<' -PU2Hݔj/o7BУv ~""]JU/-}c v 4g/ixZ~7]uu&"xZ Gc&"I/G?BЈJU< Gc%KQq04_IBBv 7c%]<ڣQIa-jJUѐ G_iqBН:xZ]]ѐ0 JUjjuBad0:0cc%'JU*Oѐ]qA~iOïKIJUp-G?:O䯝gA&"c%Z/puJUj]A%qݦ"pc%H/%U2xZ]}" '-yAѐuZp]t~dBѐ'-yy4']Z~Pa+ c 7I"6Wھ/ Gyض /a q'-:c%'䯶+ *U2q"6]Qc%c%u4']tPG?]AK4~jaOãuc/ GHQS5xc%/]]{݅ HxZP: O]"/:DSڝڅ I4'-7}"'A'-U2JU D䯹U2]txZ戥Bc%:_Ŷ]'H/47SuH AJU{Sc%7I{JUpu-PPIxZ/uZqxZ6ڝOq G c%6-p]tJU]&"{'W"/p'-'-]6jj-uS/~dI7]BЫ" gc%DJUDBҐ*A"{/III:-upP~]tc%uBxj~ADZU2j'-0%P'-Oګ;/JU]c% q0}y7QZ0 GIc%" c+ q<Puuc%_]txZ G"O0*]H/o~Aq-v '-PHKc%B: 0c%U2 *%KgH"]IqA3Sc=&""W 7Ky0 qO"]7JU~H"'_JUBЈBG?3AJU'-JU0q": 'cpJUJU}qbqG?JUyQѐ]'jU2D:D:: u qA GaD6APJUBУZؾ/:JU G6A Z'}&"]t<]uuj]txZZuG?~''-U2&": 0ŝ&" G:"c*: AD!"U2'AJU I/HZ- Id~Aţq˃76&"/oI'c䯣4 G'Z:JU{ѐ7c%7I5"Ź6'G?g GAţD/o]t_u6JU/oduuG?/oU2cڝ c%AAG?aѐu: c%A GJUPH GG?qgjI鶪BABd6<I:؝qᶪd~_-uZPJUjju-Bм GAqp]j'-䯶'-xZ:-U2a]ѐ: JUAP+ c"q+ G?j '"ݩ646G?S0cp_c%/oG?S-: 'G?JU/Z&" GAZŝڶ<% GPxZKZAJUZZU2yJUj<ѐڼu:4xZBQ+ S '-">JU'- '-"BOҾ/_'-"jI6}ȈqPAA  c-uOÝAy:AQ-] GJU'㶪:JU]t G: ]]376Zŝ Gc%IJUg/H/c%HU2PB*:y 3"c%'AW"!64P4qBv >74!B aJUyPuDy]tjdHOëqI3 G~D"B cc%qP+ " Ac%؝c%":HD:xZ"v : IPBx3DG? G3S**PuZ!: :~~A]H64A&"K"]: ::Ag' BOÙOÊQ'-4AګW4: DB-0JUJU4}ȶP*APWZ6c::]B+ b7'-P'-u A:: c%Pduѐc%~~jڞH/7xZ/Ͷc%c% /BУIc%<]S340i3c5*:+ c! c% G/AxZu"IddI4px  ѐ-aJUxZAWQiS]"v j]t_BHH-v ~j!p]4'/ cBЈS_I c%_ABB>"Sc%U2:JUlu:~~xZBu-H GIJUJU7lql]ub G/4: ́ qc%}q}'-~jqAU2* ˝O؝c%JU3]"S_ Gbݝ]Z0c%7b: H/<uˣ5:y_ضZ 0:c%cq=j~*6 *'c%PIB"䯾/~_: " -"'-/:7'ac"O}c%dI!Spc%AAሥcK/aqc%4U2H%u0:Iq*]tcu䯼A]tJU'uZ>c%iOHAd]6 &"6&"c%'BpՏ:˼c%a؝&"/o*5'-Au䯼:JUJUaU2B]A%I:}c'-P:G?WpjP] G~j ѐbU2PxZŶqG?/=&"xcqc%46Q7P GBжc%W<'-}ȏ*]tA6p]B:<:JUxZ]uKxZJUG?c]%/j/o؊䯈qIJUjG?Za'!BЏ:dc%O"v U2:xZ}]d"ڃ7'-&"gcS&"'-P4別A~_c%HuZj~JUZpqA4H64:q0S: 6ia&"6] Py/o*": >Q%qxZJU/&"Z*BOxZj %]Qc%:"ZB}Ⱦ/_~JUu/_xZ74udp! &" /U2 qcPjZ}ȼJUy6ŝ&"c%aI4ѐ >A:>>:j:" y~ZѐZc%]t GG?Zž/jJU: 66SG?{AjcuZAxZjAc%"ڵ7}Ȋ/jj GB S] 7q%'&"G?5 "]!lPJU Gu{_~JUqBЈZc%JUpո&"c%<PBПHp :~JUHu G~/o}"c%H_ Gc xZ DciDc%JUBЯ6*P3: q]q c%PG?O-q~j'-:i:A}OJU7'-AK]_~ GuZDAPP'-ţi/]B}ȝڭv 0 DAB3U2JUd]Opՙ  GQ3! G/ GPp՝Bp4xZG?{]q:JU:3-v 46u]v ~~O"-'- a :Q/I GOp%W/I0Kcv 4'ݶ]&"A䯁6D q6H'-Ac /HPju'-~y70DS/dI ż7cqZc%4]Z" '-~/o<}u6'-Ij" &"JUU2]/7qqJU͏/:JU"]qq-"U2JU~G?"HBPj_I]]g&" W Z:Zc%:j4-'-Aѐa~~y{uuAj6/D7O'-'&" JUBJU"Q&"3Qc%"6agU2: lc%'-xZxZ'- D䯼/dj*ѐuxZxZJU&"aQQS䣋u]A~jc%Ŷ6/JUWҫ̓7%u/JUxZA'Z%aAI:q6&"&"cO6c%G?Ґ*'-"%jd5cOB6 *U2/o_-uI~_'-}H34ZSZJU]SH6c%ac%c%&"0-c%j_6v : // -B A: DŸ7]BB} jv *Ic%6"q&"_xZyHu]t~_ڶB%  c%lDQc/A'i*ݫͼB'xZJUAuZQ&"D /Bо/ GxZ"a"}=: G? Gv B]:JU'-ѐG?/o<"Z&"JUA~:6lG?IJUPuu]Pyduڦ_U2gڸqp/:]U2PJU' ]؃7~]tPuBбc0II0c%&"!'-&"qpչSI6PP*c%aҫ q~P%6:g/P_-uU2c%4 G}ȣd~AڈqJUJUA%ZHIv ]/IU2 : :-a*:c%b ""]B_:}}7A66=c㈥~*0-ZjJUJUc%H=/AO0䯅 _ GA/&":D}ȁ]}Zq]tJU㶪]//oc%]U2JUJU"q: GA:d:}"G?3Oã4'/:Q:0"5 Icݏ&"Ic%]-&"P4B46/oq/qp06ADu/A~_I&"0]*D}Ȉѐ'&"*dA%}ȹ3U2] G!6c%B"qjc%&"ݾ/'-]PU2"cg7_34Z-Kڝڶ G: BAI GQ˶ѐu:_/:U2"ZJUjj{Zu'4D+ 4aBЫc%c%*:U2}i'"xZP/o} <4:uJU/c%IA4U2Kظ~ G/ Ҷ{JUJUňu~PJU:"DZ!U2DJU{I~Hc'-G?c% "c: <&"0 'v j0]]DѐOï'-c%I]tJUIqڝK}4G?Wc'U2cO6cPxZ춪/A/BжWU2]tdu6*c%AuU27G?/o6uxZAu<0/4c%0qu&"Hq~:HJUBЭA]*Dc 0JU/]t/KZ 6OA4D:'-JU~aZuAJU7Au46"*Q: /"c%Bc%III*SJUxZ'-uuAxZ c%JU"%QHU2/ѐB G/W3G?xZ:䯫:<عcy͈7'-:{7JUD-Ayu*Pc%/jjBЏ"O"JUJU0G? G&"&"4uu::d7'-P3Sa}c :]"yZ-pG?A] ŶcAaAU20"4} W/'ᶪc%D c%H'-IHuu:I//%:HcZ"c%AJU] GSOÅ a: G SD'"v 6:*4u'-'-/:ApS]&"ͩ&"]t:>%*uD3'--"'-JUG?]Ÿ&"*c% GlBй6'=]5ABJUi-/c%JUv + '-Zc{q'-]tcc%'-SKBc%/B}ȣP]W*Z}:Ig-<'Z-ݭJUc%xZ/c%JUc%uu'A:BAj *AqBи> G"P7I7j: j-iDc% /Oy pAG? :xZpSݝ_Q":/'Ic%0 jqˣc%c%c%<]H+ 7Z/"cPAA*BЯx 3&"]Occ%JU"W/oS]4qZA:Hcc 4/'-HZ6axZ bAc%aBЈ-"3xZ_/P Oݾ/'-p5%c%Zp0/o0c%BŁc%:qcq"q* HS:P-] '-'c%pՈIQc SҟlG?&"Z:  B' 4/cc%JUSq7q:JU7Qˏ7:'*!ҏ//o˝ڱ<uj G:q]:/:dpuOø7 '-G?IupխB]/ox7PpՏi:: ""!A}ȣ5JU&"I ]tqѐ!&">]A]6A/ _c%ѐc%j : Q'Q'ѐAIQ]G?dPu: 7<""3U2ڼp&"0a7qżS*PAIgO 6WG?JUpՏc%Hu-'- GxZJUZ5p P'-uu&"'c/A47Aع: &"OPZAxZIB]6c%+ /<"Pc%*:/ˊ嶪pdڟd Gv '-]!'-S&"qU2y GcZc%3  PO/c"G?' p:Q6OÝڼ:: c3S: -=<_-"SA]t% JU ZS:c%&"W<36Dquj:Sc%'/c%&"SqWڼZ'<~ZA:"ҟ*'-6Ҽ HI'SU2G?c%!APD'-]iq݈]DqA6P%7/:"up]00]c%<cKPB-]U2JU죋ؗJU/]} /ZjAp:AHD !c]ثB U2_yڼ}~-&" 7cBЙ7Q]ݣI*Q> K*c!c%'"46]BН<j}ȹD:I/O'S6*JUD46+ 6]-6xZ/o/o&"lu: c% {c%xZ+ Z"H&"U2]3 :ڝ GS SbWc%&"WI-: v dI6O ѐ}}0c%JU"SJUc%P"&"DDU2c%]uxZBJU:x/xZQ':u+ &"_ GBjS"l&"IG?'-/c%u G: pՏA}:A:JUQ* OSq:/*upA'-'Ay-}SU2*ZqZD:PjH0WKQBНڼ7: K* gc%I3BOÝc3&"WJU꣋c%ݝ>c%c%/"q :66-&"A{]=q: <6]c% G'&"W: Bpՙpv = *JUP}ﶪ :/c{W=I6q'A'-ş&"<4'q!qOBЯWU24 G<3H䯫 bv Q :::c60Zc%AZ*]i4g7c%˝SQ3 *'-AZ'c%Qc: }Q OqD4/bW!a"uڅ PxZ4AU2 B" ] U2 G'-=> HWqBSl'-&"'-lBc&"c%6B'*q{g 6 c%Wpիͼ aQ" <'bcS B=]c%c%'Zد ]6Oq3/76x cW*c%'%{c%/Wpկc%'-4 cZ=Bݼc%/4&" q> 06ci*HH{]Za{l{6 3S g ccQ gKQ]D S]cq cZQDDWcH%5'D]lWq!QaW000%qDc{]0bD]]{x+ 3Db ccDa : 5]ݟ H 5cl0 K c%3K QSc{H=ZZixqHDiDݼ!D{ac%Hݝگ+    i bqb]Zlc' ]KW 00]: : c% c%]H+ ]: + ]=]>+ Wq'/ Z!% 6]5 Q>% ]65!%6H+  H: 0l6S0Sg%: agځ 3 K l0q v v {{ SS HlSD : 3c0+ a0 50W6qaQD]K S66]c% {=]]iQW]v q] 0W: Dl0]5]c%a: + K60: =lK: : Qa>>5060gQ%>> 0q =!6c: K%ZZc gHi] 3 D]0ZKc>H : l{DH%]l v 0 c>! H]v 6c  0!0 q!Z{{i]v : ]>!3]{bZW !%iq HgD D00Q:  ] 5qx{SH K+ + lDZK W Qq xq%Wl%{lv l!H Hbc0D  ZS0xv + SbxbD  : {iHD]%W  i5 %KHQ K0cv D%!x: !liv SQQq!%ZH5]%0{%  Z%0%03 Q300l  v ]]Z5QWKx =lS : 0xv  Zc: : H!0]qql qblD Wl]HWW 0] %l5]W% : xc+  + Z>qQ%DDi]v :  l>]=WD0%D%l ]]0c] v K!l=WDDx]qDH 0H  : : q5+ : HHWi0q g : Kb%bKZ+ qD%lc{Z: W: !ccc{lK: : : l!>0bD: H: qlc>%%Q : W0>D: : DWxbv 0 =5bZl= gQQ6c DW =5S6]W=5H: D>x{l+ : cH!]q bKDq : 00 Q ]%]ZQKxW5 c>5 {bHqbx%5v : cS6!Z: Hv lc0=Z!xZc5W W+ + 5cD Z%Dq!]% ]g==]: 3 5]0ZHW]5 v Z{]]+ ZD]xqll : =0>!WW>l{Z5: SDbcv 55S5: ]0q v : %%06]D :  : QgqZq5: : DDD5qiil]W]xS%l0]Z HKil{Dg  00]>0 ]{6l: QQDq5: H=v =l]SDKD: W5W   WS]0{Dv Hv : %{]c==D5c]]qZ] b:  v >]5Sq 3Q>S=: HH0 : DHDlSS : ]>q Q=5W]00{]i: 0!qlDb]%=]0lD+ Hb]!b=: + D0%D QQ : 5b]]]Z D: H +  H]0H=]]: Wi=W: Zl!]5q 0{0: : %0q]%]q5 + q>lbK5+ : H%%b  v ]]SDbH  Hl0llKD : H]bZ]%!cq %c6lH: : ZD{]]H%Z{D5KDK: D>]v : DqH  {DKKq%K: WDiS]]]l 5]l>%]Z H0{0DS=%SH : =]6 + 5W i: : W0 D0ZD%!qv x%l]D S%ll%ZlqKi]]Db]]q ]v W!%Sq+ g H5WKZ%H iHHK%b]Q ]qZ>{DK ]!]ll%5li]0lv : DbqZ : q0!S0HWWq%HW]q:  ]H: Wi =W+ : =Z0xD HWW!0lii: W%0{q]!]K5Dil5S]%]ZZDDKl0bW5  Dq%b5{%H  WqZD=Z=D =DDKiZ=bWDZDDZ=Kl0!%DDKl]bi50: D55q>0K 5KDHD]D  v x{iW=W: =D: q%bWHWW]]]0lv K]b=!c>WWbll0DDxl]gQ ]]0lqDZZ 5WqDDSH 5D= ]]=55lKWWKbDqx%Z==D!q]xK%]%qlqqlD: WDiWWZ q: ZZ: : WSD=KK]i DKiSW!!]KH]]qSH>0 v Db]l]Db=]0D : DZZ%]%W : Wbx+ QQW]]HWD: b]qWv D5DqDZ]%Z==Z]]D]ZD]%{0HWiii%0xZ=55bSWK5x]Dq]Z: DbD=DDZZ+ Z5KKK: 0l: : Zb%ZD]ql{HKl{qZbii]: b]]K: WKW5: 5K5Z% =q=H Q: K: =W{ZKbD]]D%]{{{5ZSDb]: Z]iWWDK=5Z=5: 5xSb=S!0i+ =Z%l]b=W %%xx0{0Zb{qD==D]qHSq%q WWZq0>%: =Z=DD: + HDK5=blq: ZSD : Z%]lDWDbq]q]%%i0i=]Z]bq]Z55=H%i5H HD5=DS=W5WDW5%DH5lHbDqZH=bZH%l>DZ5D%]x0Z5Z!%qqWDK=v + q]q: :  %%W H=bSDZ]]ZH55!q!Zbx]!K]ZbqKKWHDil{W : ]0]D DiZD v 5W+ ]KKKDW: %qK Sl]l]Kq{H5K>!%]%q]0DKK5bb=KKqx%S=WWKDKSbW=KHH=5%qZ=WSxbSqiKZKllZD0%]{]q+ HW]WW%l]HD: D=D5Z=WqqW: : Sb]lxq H: bDKxq=Wxbq]>{0{ZWq]]Dll!]DDK=SqD%]q]x: Wb]qiZ DS==HKZZKblq: =qKD%D%lWDiZx%]lSDZlqxl]{]qbHWDb]DD]x]WDDZK: H55: %x]%S 5: H%]q=bqii]]b!iqqqiS=SSDl  5xKD + WKbDZ===WS==%q=WHq= ZqSDDZ]lx=bDcKb]!SD==q]WD+ SWq%5H: S]]W  ]]DW=D!!KDWH]D]%5K=D=S00q{0ZDH]x]0]DD]HqZSb%]v gDK5=W: WWDDZSH: : {SW=]iZqZ=qiWS]D]0D%D]]W=x5]ZDD5DKv  %K5DDq%q=: v bK SDZ=W]iD=Z%%bb%]qqZ%!5{W]]xZWDllqHH: SiDH : : ]bZWZbq]q: qiZDK5ZbZD=5%]ZDKb]%ZD!] H%bDWblKDSWZ %q : WWWKZSW%: H]WZqqZ]iWKqq]DZ]]xi5=bK]>!: W=ZK5H 5555D=HKWSiiD K]{lW{i%q]{lD: b5KxW: Wl]]ZH : Wx]]bD+ ]qqD=W=xqH DWl{lZ]xDZZ05Kibq{ZZWD=bxi%l]5W 5b: Q + WDZlx]qW=WDlxbW: =l]qxqKZ]]=%!]bb0{lq]]DDDbK5D!SD5SbHDHHZ=SKD qb: D50lx=SWZi]D]]K0c0=K%DZl0%5W5q]i%ZZDDHK=DDZ: KD Hq%DW: : D%q]H50iSK]H55H]{qDK]%K]0{]KK%%iDKqq5 HD]qx]iD: SlS: + K% D=D: =%5xD: ]q5HK5=q%q!l{xxW: %]%5 =K]%+ i DxD5KHDKg i: S{Kq WS]q!  ]06c0K]]Z: !=Dlqi!%H+ =b!bbq5qH]q   0 v : H ! : Wql]%Kv DqqS%HWbZKi>0H{]]]x: %0i=: : Hq]qxiDK!: =0W =K]{0SZ: H] 3v ]HHWZq: q ql : %%]%%q>lxD: iq{i%: WH]b00!bDW Hi=g0{K 5D= W{!=W=xqv  x>Db=WZS=: q0>]bW: ]: : S0Z l{]Z5 0lSW=]DHv =llZ DWiKWH +  : v %S b0KDKSH S=b]%HHZ5!%bZx>5HWH lK+ Dq{D QgWWDZKKH : ]l0!%]W55=bD Z5DDZ50c00]%]g H 0!Zx] >]v v > WWq5 : bW D%]qZK{qH=H{SH>0ZSDZZHHlZ%v : 6ZZ5Z]]5>HS]]]]0qSS  S{DWv W v Q=]q: H=q%5D!0Dqx{]{Zg!%D]0bq%iK l]] : v : ]Z]DbZb: v H  =ZHHHQSD50HbWKDbxi=D%HW00qHK=i%]: : Z5Zl= qlD%  ]0]bDxDD Q K: Z5 55]>+ !]!>Z]%{{bK]>] ]l : W={DHWqW W gHv : x!v : ]+ q%l : KSq%q0: : H]i5bx{+ D5l: Wl5 =bK %WDDQlS> %!K==WlZ: K]S]!!K S] 5%0lKZ={]%: =%Zq 5=W Db]%DSSW==l3+ 0S%%H =K=W=%00lbx%i]{ KD0H  + {>g xv %WWi+ :  gK]q5Z= H0!i+ W]D5xS=+ %DS]Kq5 %0]%>ZqW=D0]l:  : DS%]q ]]!] ] ZZq: 0!Hxv %b]qi>!WD5q{> ]0D q{{K  DZW%=WD  g{+ g: Zq0KD{=Z=b50c{WDlW+ : S]lZ%5 : qZ{qD !%=: iSD 5]0: 0 Sqiq=WDb: Wg =lll x bbK5ql{ 5%! WqW 0!> %qQ: b]{ : ==: l  H]DDWK0l: DZiZi=!Di!Si>>xSZ 5]Zxb SilH! =%l!K=+ 5%5Dl Hv   WSD Dx =S!x]{]qv WxDD ]!]l{: ]]>: li !!ZD!]SDxH : %DS : b: b ] q 5]]ZD%lc%%3 =xl>Z!{Wq]S{]iZHWZ+ i>: Q ]0%5Z=Dqb: 0 0=  g qb]%%W%: ]0{ =b0=]W]]qDD%cxZl: DiZgSl>: =DW Hb]%D % K5HD =D=%=% =3 {H]{6: W5 %q+ : Dlq0]i%x !D0HKDDq0!!+  i!{5xq : 560QWx{D+ x0lq:  ciD5: =W5{S: Kb]Zi]>0]K: v 0]b=: !DHb%QcWZD] %5 =]q: Q x HqH ]!DqKc0> D: v Q 0c]W=H ]igScx: Dl!+ 6 !: %iW5 Z!q Qc% !K]%0lZ : W ]: K0]iWQ6i%= g>!lb!{b]q0: D0]W v W%Ki!qx5%Z K5Wlbg qx Kv WS  SZ]cv  q6cZD gDl]cD {i  HZ 5ؼ Kq%{]>5l  ZxbQ ZHK! + HiWWDi v  lc> iW: ]{0>xbD0%{Qq6lZS %WDqxqi gD: ]5QQx 0c> H  D q%Dbx+  ZW!qcq W=! cl>: v S3Z0Hql]W cc]%W S05 bi  0: ZWbx{3 : H> =D 00!b 3QlW3: !%x: 5  q!{q5! ]Kv H + Sc%W]!=g{=: v Q: ]0K q: i]gcql] H: W]3Dll 3!Z3H  i%DW55qq cS0DgWS0bv ]cxH  6HiQZ=b+ ]Z: 00qD5S%6>b QcgqQ+ W]: Hv 3: ZcZWH]g: >]0  H : 6cZ]K{l >WK]qQicl% : HS =% c5: Z:  Z% : v Z0: : : {]q]: gg  Qv >]iDl%i!DbqW]{]%Q Dq6 c6q0ibHQ c%c%v  %6  qg3=]!: gc%S qQW:  {{ + 5: SZc&"ciW{6   :   c6c]6gZH]]gZ=&"Q+ ]!>= H!c gD%SqScK   Q c5 {> Z{ =gScD: ac>  ځ Db] ]D]K l: ]60 5 ]W: Kcc gDx WQ ll{l6x+ Hl a+ %{D ] Sq0c  : xv g5q=g lv {q ac%Kx : 0iHQQlb]iD KHv : ]D QqQQ =l]Q]0W: %K   6c]5Sc]v H: KcZ5D>{iZ>WDK3KK Hlb] Q]l:  ]6 ZQ D%Z aZQ0i 36cW q]Di500]v H!]lb : c: iHbSH 3+ Z%Qc0: Z0]  D]Q: ]{cW: + 3 0>]cZ{!]D%: ]c]l: W: ]6] %q Bq Qa x3%xK]]W&"D+ 3+ Q3qZQ5!] {6cx0 +  Q ]0SH3 6  3q6lW {l5{{0cZ+   0H%v ] + c+ : Z 6ڟHQib H ]H5Q]K:  q!]] giv  + : ]>>{]06aHqqxc=b0 QbcS=: 3b: !SW + ]qWZ Q Q+ D: =v W6: cl= : ]+ c6{+ c> 5c0cc]Di{cqv ZS66 W:  ]Dq05W :  ]c cZ3 l: l]c0v cS c aHlq]qqqcHa0v Wq36Dc!i%ZSWS DD+ ={cS]3v 'WH]]p՞ Q: Dl6alS3qcQ6l%]03{&"{ݸ Wb Wc0ZHi D33S>  5 3H c: a qS6DQD  !]=q=v 56 ={ = q6+ Q QQQ0S=qDDWx+ 3Hl]DSڟ/*v 0cB/ GABН pѐOj~ GU2BZqWdu~Pa"S'-/oj a4ZѐA]tq"]Z:~d GAxu*A" _ G!'/o-cv GBжAjj3+ DZQ_jc%I]]l4~jpu-pG? GJUpՊڼ!'Dq&"cJUJUu:JU GG? pՈAPOuZ&" G"b Z6QU2U2"/*H3jyp JUͣAU2G?u/AA'Ł&"3 HAy~7u0'-xZ4Sѐ}c%c%JU~ ѐuBG?/oA0 G_P]"'7AJUأc'-jѐAdAcZ"c%]tu":JUdj-}0 G˶c%/oJUuѐBA]tjuH~JUW'cp"H"JU&"ŵxZ"U2JU Gq_xZJU'-/-˃7&"-jc%"JU//'-ѐcD'P]tuZdD'JUIBЈ4+ }aJUjpHѐj~* u'-j*A~JUuu͋y/o:&"6"ѐ: 3 Q*Z_j]JUJU:W"AJU Guu&"JUJU5'-: Au'-JU~uڦ_c%G?j p՝"/~ѐ y~3aOc%PJUѐBK]j]t:*c%xZuu Gg Gcѐuc%]t GOÈ ]:jJUuAxZU2}HDxZG? S䶪}cU2'"{4cͶ Gyd: GuulDj_BHJUPBg=A_:-uxZ~IG?"OOÐ*jjJU]]ѐq47 ţG?4Z"B6]tj&"u*d˶4A5cxuc%/o~/oů]c%Ac%Dѐ{p Q:]t/4v gJU"c%JU~_OO-DIydc-u Ŋ'&"JUU2gAHZ~JUᣋc%::D]3ѐZAc%Z0Sc%JU/xZ'xZxZ/c% }ѐ"G?y~jZ6: + dJUu ~~xZv أcA~j 46-7Dq*Ap䯝U2JUJUIxZ-"KK Gjc%0ABЯP"ZAjxZG? !}'-JUD-}Ȑ*]tuy G_jAuuxZIA'6u}jdBЫOA_ GJU GѐOxZ+ '//'-OZ'-/o5A] G74+ U2'-B{/oj ؁I3/4p3Iڱ'-Ac%Z] 7cpյ0lq6U2dPU2O3HAW"˭xZ~A"c"aU2 GI KAP}Z'JUAH-5 G*A*%Oq GA W؏c%IG?qඪ/ Z Z"U2_d3҈:A:HBНS 㶪PA GI/عc!]-AxZ0gccDc%v 60 6lq+ * GAc%%qp0]6c/'-c06 q%Q%6: g6BQ'*]OqD D+ cqQ   v 6ccү{/abS 0qlc%3: 50%&":'5 q{0+ '- Q ]{b00 %v qڟxbbS03'-&"b6HDK0l Hq!gc%c%{c3&"l>Z '' Z 'U2K: q 3H!HD]qx]Q6  Db qx0{: laW 6 W] + v Dv ثݸ c%c%!K= 3 a >W 5S QD%H=+ : ccQ QS6cZKWW xWDq{3&"/]bDK>+ +  Q6q6 i >cH0W=lq5Qg ZD]Q3cQ'- =0W 3Hv !5v 6l  D6{H&"cZW ]Qv c{ 0QD>{+ Dg =05Sx]: 6: &"]!Q  Q0c!aHl + + %S: 3 c{Sl{ l%0x]0 g{qg+ =H]v : D+ b0gq: l0 W!5HW aqS  &": c3: 5 HH iS c] ic6%3 =l!]q{0 5q]S: H]Zc{0xq5SHZSW  ]: gQHb>6 Di=ZQ : : a l!iW%v 3]6g]K5Q ccDWxx6]v  qWW]v q]] Q KZq0v W0!+  S: 5D>b K + H0S ]0]0xg]>>qlS] q0 HZv D]cQ]= = Wc6Dg HHWx!x  : : Hb=q ]l Z%ZKcWv W+ 0>0H>%]%l Dq{%l0DD gq{6qlH5 5x]xq D+ DH%]] 3{D ]S=v Q: {  {x%{= =D: ]c0cqqbc5%Zi%: : l0H0+ 5: %0]HQQv gv q: ] : D K: ]b= H % l]Z= 6D: KHbc{D>0{0ib]D]xqZQ qc0{]l+  Z=H]b] a 0xWS= !lW: c]Db5Hql!lK5qD]DDl]i  l>%K KK%]]K+  = 5W: q5q : qb  !]H {>>]b=W!{]x H v 000{> ZlZc%ZZ %%q]HWq{+ ]: ] Qg%lbDq]  g5Z D=W!W{: : S=K: > + q05 : c!=]l : > =HZHDH]xDD + D{%%+ b% Sql!K: 5W=c]K5%DiDSZqSb ]qqDqDSxi0]W+ K: =%]HDWl: gQ 5xxKKZblxKH: %qD: D : 5{]qZ%lSW5 H]!]qb{+ :  v x0]0 : DZ5%S]KD HZ: Ki+ Q: 5]ZDiS5 v D5Z0DKQ Hi=Hlx>lH  0c0xiSb0qbDK%= 00WH%]: 3 ]l]]v 5 K!]  =]q%SKqqxK : W0%KWH{0S%q0{]b W>!qil >l{H qD]xK gZ : : D5Q S+ KD!0 biD=ZWDZ{]%bSx%]]>bHHD]SS: + KDx : b=bHH=Z: 5: : ]c]%+ :  0]5 : ]DbKqW]{0qK=D0KcxilK]Wx]qSWW5DD5%lDWWb5W%q=  Wb5Dq=Sb5+ v Z]0x : ixiD KWK=lD=Z0DDZZ=b! 0l 5%i l%iD5: WWW%lHg  KDZ: b S% : bWcb: SKDD]g ]06]lD W]]ZZK]%S%]0q K%ZDiZ v + : DDK: : S0!D5q!Kv 50DZbi: =xxZ+ g0{lKZDZq]0{i]iH+ Z0l5]0%DH0q DW: + ==xlq  gqDb{: llbD%%HH q%qZ=q]q]l% {c]qq%=%DK0x: ==KKS=W bDW:  5q%S= qKSW=x]!]]>]l%]cc{%SS: H WbbKqqSHl=DW=D]=D%KW= =5D] i%6D: ]%K]blqWW!DWDl: D{q!D HxD%ib5WDDHKbSZqKD= KSiZZ]D: q]q]%=lHWZqKDiK]%]Zq]lH!{]b: : Z% >: iK : : D 5li =i+ W ]]Wqc%=ZDiK=%qZb]qbW]%0{gD!  !6%qbb=i]0qSD: li: : + : D: ZqKv Wqbb5HD5 =Dx]ZD%=: g: Z]lD0x KZH: {]!l]xZ{H: WWDD% DWK+ ]]!q5=D WD=5xiibbHSbi]S 50q HWKD0lZ={c>Z = 5W]qbi]x+ K%K%b qbbH: ]%b: =D: D S:  cq>0WH %q5!>D]0W]{]{!= HSc5q bW bH+ iK: : WDQq%%=Z555b !0] H]l5Sx: !qZ: {l5SS{0q + 5>l{v v K]>Z5D bW + %Z%ZW]H ]05]Sv l{bb0> =HZ0]W5: %Z=] ]DW+ : HDWDl>: : : QQ]!%]]3: b] 3 ]Slq]]Zi=Wq%Z%K0>l]0iv DHq%: qc ix]q Q  =DxW: : q  : S{H ={]%%D: lD=!0x %%]{]]c! x>D5H:    qcDv ZcK5+ S !! ]S=D0HKH+ Z: W5W W%bcScDK00{]{{lZK!l:  ] =i0!:  =K%W qqZiq+ Z W  q0 !: q5SZZx bWx%Dq x]%%l]qi0i=bK v ]]]= : =SQ  WZWZx  : 0]>+ c]iSv l: b]KW5l+ 5l6Db0] ] = D v ZDv : D: K=+ : g + HWHS {{v H%!%0liZ 00QQ 6]!c0 gi]% 0!{HD]%K v ]>%  b] q:  bW W ]]x =  { Qqc6!: c] >D0S=]Z 5l{x]Q{: ]HDD5q 5: g3c HZ: v  : + %5 xx: ]03Sb=Z: Wl 60!: D6]: c{il: {]gi5v H3>>gKl Qg5 ]0 %  c3 qW: 55D5%WlWHxc !D]qv 0]D{i0 : l DSDKl>Q]]  + bgH&"D:  iH: {q : gv %]H6 xQ >KbW>>0b: l 0bbZ: bDi] HZ]%D:  Q: ]a Q]Wx{ H {c Q0biZl + ]=bKD Zcc: ] H0lW : K]x> il!5K ] D: 0c {a Z acc0    >0 Z0 : 05]b qW>%c]]v 5q%] % H B %: q=K: : Hc>v 33 W% 5q Q=: {W%: 3{b] v  cDW0{S K!>:  l6] lDa0Z]DKWx b0]gbW%0%=WZcq= i]6W  H]{]gqD ]: !l: !]i0 5ixZ  l 6>H: : l% 0]6+ : ]]{agbgi3W]S Dc60bi+ %+ %!cq3 ]]SWZ ]50]%c{ ]q5qa*=q]c c% !H*D %>qilKDW0iaHv c ZHDic: ]3=!Qc63  WSH6%Z{DQi{]]5W gWSl6D c6S: qc+ c>lQ+ c%*6]D+ lKc%Q&"cZq  l%: v 363&": S%cq6WZZSqc gc6H5>c0: + caq c 5: 60]K>% i H0ax]'q S0 0{bQq! qc6D q K: l %5c{% >63 6%x v 0{KK{+ : Z ]H'   3  aQ5>>: 3 q >: giq]: 03]]c D6{D:  ] ]0: '3lHg 6Q: {bc%+ : a&" ]i]: W Qڼ: + c55]0 a006a 0+ ڼ 0K   0q'-3BB06+ Q] cc03%0bi0% Wx qqWD Ql! %3Z6  q{Hݟ! xl6  Sv ]: 0> cS!W S: : g5> K 5>x0500 + : av W: %0bHW! Qc%Q Dl: c]bgv KQi%QDSSc%x3 c]D0Sccҟ{>3!D> = a5> 0aZcqb>cc c%WH]  c%%c!: QD* { : =0 b56cc% 0%gW0] ]S3SqH]H{{Db v bD]%lx{l: g 3c%qqW b% 6QSl0؏a cB D%cv &"D%S% {b=5D: SSc0cQ: ]]] c>: S0 ca: iSv 366 SW0 lqBl: *5>]0c%3i0i60 : 0q!ic%Qq]lb =D  + 0]!0>v g c: ݼDW+ cڊ!v c%'xBDx ]Q&"*/cڗ/OÅ '-/!]c>D6a]cU2Hq: 6!=%=]v c%Dcq c%0Sl  6 q00/&"BSc {c6v ҝZW&": {]acҫ6 &"c%Sal3gD3{0QbS56>q* ]%: ]0gS] DqBWZ>&"lK%c: c K/b QW3qcZşc iH W0qH+ Z6Dg c%p{66SZQ %>B Q6݊c%+ qD: 3ZZ ]]W]DlcSq/DڼSW+ q6lga Q: a &" 6c%3K6Wv WQgl]c+ '-]icxg]cDi lg: {&"%+  plc%:* B{: H͝v 3Q3U2'*S '-  { D0q>+ 3x+ W3 ]DS c]cgqcS'-: c%:&"660c%'- 6BЯq 3݁DU2] ͝ڭ /W ݝv &" 6: QZ c%:0%S: 3>'-:!WK<'p *&"W4ݝ0K&"QK'= 0 qKc}4cc"ҝ7*c%cqp՟0c%{>q+ */li0v &" c%KH66pS ݩg{ ab0c37>W6{!&"/H+ : D 3v OO:  Hc:  /b%q>q]caDq ]{qpՁ60q3 qiD:KD' {6SBН}!Hg'&"]''-6{DH6 : Q]&"&":c% }KSc%'-4O%D':]"xD c Q D0}H '-c%=cQ c6c!Wcc> c%q B{*/xH&"v Q6U2Ac: ]xiS 6c  aA/"v QqBЗ:qqa GSqIP:DS 6a6&"c%'-KccU2c% p"0}Bqc%%c% S q>G?: /S'c% 0]c% c66W&"gH!6SW]ݐ*v c /  ]: l >>S  ]: *ݝڗq*: c%Sq >!0U2Kx6]6c%/+ q:ISc cSc%c{}Q: WQ]6 ' ݔpD:H"D"q!Ac%c%>cq '&"+ pռ=pՁc3qiZc{S:   D+ {Z+ B: g'-6*]ͅ :/Qؔc% ]: 0/H=c3 36%qBHa'-: !Ҽ0K 6 Qc%b]p60QG?4' 0ڼ]p: 3a&"Z]{/A">3/*c:S Q'- 5W/ Gq؝ U27!0: aBx : *i7'>xc//U2 c"&" 6q%c%7'6BНڝݾ/6b36Pc5WA>: B7: '-S+ c%]SQݼ'-pv 3ڝ JU:c%A6D7Kc%%cH/}"q'S}OÏ{K'-Q0 pc%*c: '0**c%QD !'c%Qc: : S0'-'/: *6HڏaDDU2q6A Scc%q'6qBB0! xZc%Ҽ+ "S: AA: OřS:'-QBi ' 'Bо/&"!Qiq'-&"cHG?3{/+ '"'-q6KBcPc%0ccڟSSI lcc/:c%'-D: : bK 7ҹKc%3A'*c/c06cD::<"䯯'-'->}ȈD/BЃ7JU_v Sa aBѐ6W<&"c% *'S"6S G?U2=Qgpն5"&"A''- {c%'-Dڼ}Q&"Q5>Q=q  :q6&"ݼ]'-c%'0WH ''-4aHBО D/cH"'-D6B3U2qඪ//:pՙ 0Ac%""OHG?G?&"la + c}ȩ&"*c% Zv {]gc'- l]:D:/BҟZc%*Z4Ac6cpթU2 Gacl6pS/Z{5I/6cڵ'/ͦb]64'-/Oc: *Dp c%}ȝڏP  7&"0"/3ҝڝ'x>c% >"'/4ڝOQIqi:/g/&"]"/AA Gc% &"Ba&"3q%c%6]کA:qv AAU2/ aͭ"O]q :P'-] qbq0:c% }OU2{D'-  a/c%0c6U2 07G?䯝{pDc%! v IB/c%47Scq6+ p&"4 Q䯙{lp6 qQ؝G?<KB{QG?{S'-WW+ ˼<*'-JUSBЫ!B3*&"DSB+ > G!H:v 3 ڶqB: '4: PJU&"aWci ]0q گZ]ڝ6 5ڐ*7q]&"Hc{B]JUI>bbv 3'&":6W6cU2c%qA3SҼ'-ؔ c%"qݝڝU2Wc%l3'0"JU]tBBНcDcSP G?&"Sv : 6 ]c%cc% 6"%}ҸD 0 7ݭ/Qa G?:Q46lq{ Gdc%/ض=* {: D<ZS'BZ *]t4KKݹIJUD<c%c>  l/A+ p DOB"c'-&" 4/7cc%3B6v  G/ "O:ݸ0&" 0q]"cQG?/OB: l7Qa'/xZD"=BЦ]:ydI Pc%:=-}ȯcc%/3 c U2Oŝa}Iؙ4؝]txZK]0*c%d]t G 66 6gc'c '-:G?6ѐ-OÁ"*d{ڭ7Bac%4:B6"6QQG? G/U2c%</6S cc%D:6i0Av >}xb*"6]> G?70]Sq͝D*'䯝: A}cxcꈥ>c%a'-/ 6=>ѐD G/U2{v  SW }U27JU/0"l}SgG?A:DŶ0c%c%/: G}B 0I}ȣ0JU3AqU2/q}Ȑ*S] GI: i4ѐ '< BqBжSWBжq:4I + cQ G3 cc؝c%/:3/635˝ZO/AJUB D] P: 'G?Qq"p'-q*6/c%D6]BaI 7BЁc' :U2Q: 'O: Qi cK U2aBOæ_:l&"4~~]txZZjd]tdJUA*u-aydxZP:uuG?pѐjZJU~/oJU:xZ uѐZ_y/odxZ]ѐZ'-/o_ Gc ]tdJUI/H-BcZZA/ojxZPc%uuAdxZ-"JU]tjxZP:"-d_ڏDxZG?6ddxZň}Ȧ_jdxZJU]:/i]/ojJU4]pqxZ:7<-ѐ4j_JUA*Oѐѐ-] GxZP*ZZDq]t]tj_: Z*Sj]tjxZ7--OãId+ ]""6JUd/ojxZPAѐZdJU'-xZA:U2ž/BНc]"˸~]tdJU7]-jd*j:Q"_JUxZJU<PjdPZ]]tjxZqp"OÝڣI~/odJUPA؝:uu궪ZjdxZJU:c%'-Z jP] /A G:AdddJU G5WJUAJU/AjJU&"-jxZPG?}u]"G?jxZB"/ojJU" /oj_JUABЈa4cy_JU4Ac%B&"jxZ G6""c%~yjIq࣋݃7/o_JU:H]Kyj_ IJU G:uuuѐjj_JU-: dJUG?-HuZ"~~]tdJU/ѐcZ3c%"BЦ_~yj&"c%/oJUG?ѐ-p'U2]"W]t/ojdJU G- ">򶪶" GJUdJUJUI'ѐj_JUW-/dxZAc%jdJU GJUAB4JU7v ѐZU2 :Z dPJU4_IQHJUJU]-"JUAA} ~jxZ G"-Z]~]tjxZJUAgA43uuu"]tjJUڣI G"ѐ4ZZ"x~~]tJUDxB6jc%d]"Bо/~~/od<"]A~/ojxZJU GG?4-uuu'g--A]tjxZA}bAj_v uuuu/o_Oþ/JUJUPA/uu]B]t~~yjxZPB-ѐI&"j~~~Pc%͈]I}ظ~~qd7~]t/odJU GWuu䯱~y/o&"Z]~~jPZOJU]t/odJU {uѐ-q_/oj_U2P:'uuuѐ__PuuѐjjxZU2"]*: Duu&":uѐxca~~~~/o_IBuH-"6q'd~~]tG?/oyyjxZp"]A~~~jP-uѐ"'dyd&"G?HuBxZHH-]:~~yxZ G'-0JU/uuuuq~~~d"u]'ˋyU2]'-c~y_y GHpc%" G Gj]taPK}"c%xZ/7j:P:uuuuѐS~y]tjJUA}uu-S~~~~~/ocu"]JU0: 3~~~~_{uuc Gj~JUjxZ/uuug~yjPc%quuuH䯱<~]tB4~~jc%'PDHuuu]'3ѐZ"c%j~~~jZ'c%'-j_4uuuuZj/o~~d'AIBcBѐuuZ3d~]t}ȶJU&"/4jxZuuA/]B&" G?xZ~~/od<]Z uuZBZly~~~jG?OöuujqU2U2ţڶ~~]tjJUuuuuA:~~~PI: u䯣IA"< Gc%!B:]txZOuuu/~~yydlpՃ7A]u-uҟ'j~~y0O /<jJUBu]uH- jG? j~~~d*}uuu"d~~_j/oJU Guuu*䯫 %0 GJUjy/o Guuu<~JUOö JUA G_7/JU~_Dѐuuu/o~~~~]txZQuuuOA͹Q~~~/o3Bu"HBB G~~j/<}"Z>v IᶪP~yxZZuHua~~~~~]tjPuuuujyjPy:u-HuxZ~jjjA/-uѐD0WcxZJU~jyJU]t GuuHu/p:<OZ6~/oc ]t+ JUAAu䯹j~~/oxZSuuuu"cA/o~~~yjI"uuuu-~~~~~/o_c%u07ѐadjv ~_>c%]t~/oPquuBcH"]tJUc%/o~JUuu'-j7c%Z-]P~P+ c%/G?JUu"Ź'IP~~]td/ݝuuuuŸ~~j_䯶uH䯾/]t~~A S 4OuSuZc _Ij/o3]Ő*JU~*]"j~~~juuHѐ"xZ~~~A: ڶH]4]t~JU/o7/g*"]c%*JU G'6:U2 uuu-Zv ~~~]t~j u䯝݊Bж-}H*ҝjy/~]t/odAqqඪuuuu7_~~BBU2I~/c%uuq%y~y~yABHuuupզ_~~G?:I&"ZuZ6U2IpZc%0Bŝڝ/o~~~~j'uuu"6:I]6Aj:xZ~]tdP]uuͶW4Pp/7xZ&"-ZuZc%{A//o~yj<: HuuuHZDj~~~A BЩ7"uѐ-ڏI~~IDZq """3'-3_A/U2_ZI:<jj㣋uuuuZ+ ~~~~~䯣]ZZű<~~~jQc%jDq]-6IAJUZAupզ_/o~y4&"jHu-B'46~Id""/㶪 ţj~~j:H}uѐ GP&"*-y~~xZB]]ҶҝJU GJU"}qحJU]*_Ic%JUI&"pՙ0uuuZ4jyP 3q]Ajp"j~xZ]"~~jJUBжp!S ѐAU2~Ad'-ZuZDG?/j~~dQq]: "pgU27da~ybIq6趪ڹpP~ /oHK&"/uu-˅ DP~dѐ&"'-JUj 6j:Z"䯶pD~/oc%'-ѐBDd/P:JUAJUJU/uu]JU~~jc%~_'ppն-B0 ]ː*j'p-/o~JUKc%jjZ4G?c%:-Z'-/oj_dv cuuҐ*6:xZ~jG?'>}HHu]: c%g/~~/p:JUI"ѐB"/~~/oyPxc%7B]+ 3ݝ&"uݾ/~~~~/oc]"uB]/o/o~~/oѐ&"P/oP7I P]'-'G?-uZ䯾/~dAjPD "u}]a0Z":G?JUdj/A-u䯈"c%y]t~~JU33"u/_j GiuH"ŭ~]tJUdA7QH" A]ZͫBx""" ]t~~~]t G<ѐuuucJU~~~jZ] ݐ*&"<:*dZq'-/guu"c%Bŏ~I/odB]p'- G: ͭG?O}~~]tJU3"ѐuuK춪QI3IxZi"p"IdxZ~7/Du--}ȝڱ&"A7xZxZA"uuuѐAP~~/o:ݹ"B鈥˩/<__H}]U2 G_jxZB" 00"/*c%!Qi͝%g/oj4H]Q G~'-xZA -uuѐ] ~yAc%JUU2 OÏD&"xBHu p䯶ڸ~~~~jJU-H]"ˊ:G?j G4]ZSg4d~~j:KZ7P*::JU33uuudIcAJUKqb'-'-Z" /o~~~_/OqBu"Ŷ*_PP_"q7 GJU4HuZ>qU2&"Ijd'-"Hu6-AJU~~~:6&"H6HZ˱*:~_}pؼ:]t'-U2/oBZU2JUy:AB4JUWͣQ'd~~~~d ""ѐuuQP]t~A G'q"A4 G7>uuuZ"U23xZ~~yP䯶H別x'-xc%AAڱ<*P: B]uu-ݝDA]t~~j'WqHudd:6W3'-3'-/˝pAU2JUJU&"ڊWuuZ]4_jJUd/o06"B c%cň] Gj+ ]33c%Acp0]%OOë:~JU/Oü  Q+ AHl/K"u]!i_' G? Gcݏ'c4O"' G~~7ž/6A&"gZJU~~~Iqp"c%jjxZxZ Guq: lK'-IdBж"xZ GJU/ " GJU~jgG?'--uu}S]!y~/oj/'7Ocu-/_:JUxZݟZ3PdZZ*6/pcZD"+ d:c%]ѐBBqAJUc%]t%*3}Zuѐ}ȟj~~~~ G-˶ѐIAU23//o~jBŶňHOöQdj_xZAj4Oupݣ]c%]tPq"uc%P&"U2 GŶuJU/ GU2IJU: G GDuѐu6!SJU]ty/A70]H]'c%JU/oy4D -uH G~~dG?ZѐcBУII Gj*<ŁBНp*: GAJUJUJU""6]Bc%&"APZ"AjyI/ojJUZuuuucG?j]tj_II>"uO}U2 G&"xZ4d~_: u"pl'-JUPJU~dI*-u-v >ڏ{*jZ6c%IdJU: pBuOÙaJUc%/_~~xZ0HuOSSQG?jA&"-Bq*_I]Z0'W'JUAqpչ=Sl݃7P4*]"B]g*/ GAcڝ: G?7}ҝc}7uu:ac% :JUy~c%*cBЫ]uuѐ_jj7Qc%:ڞc%>Ac%HuZZ:y~~P*D>"ua G/oPx6uc%+ HIJUddP/]Zѐ"6I~~~d7HuuBм:IJU]tj/o*c/'-ppնuuQ<*:d]t0'JU'-}uu =:_d]tѐO:I_PAѐѐ: */oJU/oj/+ BpHuc% GU2_]t4/c%:4DS"64c6uu]l_~]t~~d: puuB  GjyxZ*ZD/xZjˈP&" + x'- 6HQB-ZJU~jxZZ]Zѐlc%DU2IJU{"BЯc%4W:4u"HD'JUyA6HO6'-W:I4Q:3pD+ ݣuuJUd~~]t:c: lBBА*"v xZ'D&"v }qQc%7Ic]OZ'P7Ac%a {cv &"-Z] GA GJUPjjc%}Q!uu: GjWJUG?cA3-<~~jxZBНڼ&"Q/'-q7Ic%4d/oc%ҶuZ]aSI7]tdI<>]P0quuuѐ/~~~PJUA0u"{::Iڼ*6Zѐ-Q0G?j:6q W'JU: ZSHBJUc%y]txZ~_capBУѐB'a%HD'PU2A""q/xZ~j7c%3"}ݶ!/o~~j_g"HD BPPx}ȝAU2AiIgDb""BН:HU2䯟Oæ~yyJUv ">uu"cU2~j~yJUѐѐu"c  GPd~~JUѐѐZp"&"<:%: "xJU/o3c%G?c%b]"Z"ݔc%'H4c%qc]&"DJU//"ѐv *JUj~j Guuڏ G/oU2>Qc%&": WѐOã'xZ_JU: xZPJU6ZuH}]/ 3Ay'&"a]c&"DP6pBѐ":c%:~v c>/'-c&"B"c}c%*~PU2Ad<_d<-uu3~JUG?~xZcBBZ"l G7:<]u'Bqc%A*c%'-&"'-3aOö-7&"AdP7JU G/"] IIuA_c%: c%4 G'uID OPdJUu-Z- G:74'-!!JUU2/oyJU-Hu7 G~~dJUQi""B340S JUjjSu"6c'-xZ::xZž/ѐubA/ G4 Zc%*A/*Bv -"ڝa~~PjP'BZuѐpgy~JUc% ]"q: c% AA": ]t/oA &"ˣu0i Gc%//oJU: 0p  6 S䶪ř0/d~~~dAg--ѐ"D6BЃ7JU:*U2 GOÊU2!H- <4*l_jJUuuuu0JUj/o~~_]-]BPJUAg7IOu"pA~AA:v c: ѐqI G3c%c%"" *_U23/]}'~/oI"quuc%~~j/qQO}cQc: 4/o:ZU2IAAҫͣ&"IId~IZB]uJUA GJUAc0S]: _4 GG?ﶪŝO/JU</&"<jdAݶѐB6pW]c<6"4]tPxZU2&"ڶuZc%AAc%HG?]} qS*p՝ڝBжAJU]tJU:IS5ū+ ]4<:q]*JU>7p-uZG?~~JUq""؈c%_xZ<:4q': =p/7BxZj/JUIq˝]]] A GIG?Ou6&"*U2 Gj:&" ]": qK5 B>]JU~JUA6q]ѐJU~jB'I<P/c%Bᶪ37JUP G<cŹBНڝڹ: JU4'*'- ݔځ<'-A&"Zi-ZI~~~A{"ص7Ic%DqҼ/Q&"Ij_a3궪uZ"B˸D37A4xZDl}"-3/SKSc%APU2JUd ]uu"}{d~~/odxZaѐ66"{BqI&"B: AIPd4U2BuѐO]P7IG? _/:uu":JUc% + U2 =Sq c%JU<0}B]: !B˝O6Dd__*"OqB37c%ڟBЈ'PxZJUA݈"00b&"4PcqHOO"q4AI]t~<҈-4j/c: %/ O&"6-6"77A:+ l G?&"!ѐZcD3Aj~jDZuѐH+ /A/o'D*/A6pHW"Bc''I:"]6I']ݼ3&">PA:'-]3_4BOc4qIc%c%IP0: '-}ş] Q5c%G?6"]c%~~JU "'&"/JUU2c%6aڣ{ S%+ &"   GI&"JUAHAAA_JU ZHu"G?~/o<"c% Dc%* 0B]IxZ:A:U2BřSp&"/ GP<Hѐcl:JUIAJU: 䯹"B}/G?'-P c6"{A"G?&": ݟc%AaS% G?AHuWjy GWgS5AAc%6B]-qJUJU4 W'c%D]䯶'-P]tjc%6Q c ]BB0a3U2B66~~xZQ}u"!7G?ңq"O"c%/U2c%AI"5ZaG?'G?Pj%uug:JU_PjAqB"ŝaU2JU "O]q7 &"'-*] W : QG?/q{'"]JUIIdJUc%cBڗS3=: qu-B'-_/oyJU"}BН]]Oݫ Gd G: 6c%AS"ŶZ*A_G?IJU/]B&"JU]t~P=Ŷ"}D GxZxZ/o Gq6cuѐ"6}U2 /c%BП'dd4I"ѐq0b6qPx*</"BjxZ6q/g7/]AbJU<ҙcpBBc%A/cc%icː*c%AD::u]/G?c%OgQ<'G? GcBc{:&"cc0x}]'-JU/cؼS'-JUJU G&"7؏䯼O7/oA/4AA"q0G? D 'v '&"]H"lc%jy/oAc}B""ңcP!a*v a&": c%HBOö{7jdPgB%{'-BBZ"6:JU44/o~A%㶪HS'xZ_dA/qŹ"c: :c%WBЏ/*]D}Ґ*II&"-BЯ: : Gd~PWqBйDa G]ѐѐ0' G/U2lSp6p]':PG?I pB涪"Oö>AJU<_G?/ bc%WB]gc%7B&"'xZPc% :uSQ'-/ 6&"0iK OBж6ݼl3:BcW'-qc%%&" < W!S䶪G?cځDj:*Q-ucS 4c%Aj=H"}66/Q4PxZ/]Bq cBQ]ҏ/ G~]t7"/ GZAG?qq"H G:Dq G{{K6O6}5:QA/]ڝ"]: 'H<Z]6qQv 5AP3"B %=%: BЯ/7Kv "a/ GJUxZU2/0B䯅 '-SZl 5_c%JUAPuq GPxZ]t7ѐO47U2DU24"]6ڙګ6Q{D  60JUG?O˾/v < GP'-H]gDABBН--0U2xZjA::*Z-ҝž/JU6cˏ<7/_~xZAc%+ Ź Sː* "JU GI:ADB!HZBҝ+ &"U27*]Q:4 *"JU~dd:]q6Z"6 GAIA&":U2c%BO/0ݩc"c >q&"c%c%B'B I:4iOpG?ݹ*g'- :c%˔"'-c عI&"upո~xZ/IZ {"H"B67U2 GڈuJUj:JUJU/4q63Z &"G?/olv c؝qJUJU3}]uHxZxZ/oOG?7*c%+ ]":v PA GA3p"upBAJU GIy~xZDѐu_U2q䯅 c%AJUAPAAc%"ZҶWgD GIPv *: B"BЃ7__{WpjjxZc%-]S'_jyA*  Hv 'A_j4}"ݹ}/>Ad~~P/ѐu-"]tyxZ_O65:BlA'-"]qdPDDq 45qx+ /AU2Quupc%P~JUIU2 żuccIj:xZAW]uuZS3:: <DG?/xZ䯝ڵ c: 䯶uBЦ'-G?~~~j G%c"]'-G?jP6'-䯹/od<Pv u q0P~/oJU/o GuuuuD&"_A/o77 !:%㶪]xZSxZjG?JUx"uZp}ȼQQJUJUc%b͝3%' cpնq/~/:JU =c%{<x0p=OK*JUIc%: 4ABBŝڼ3 HPQ: } *'aq :i*D/BO]0cD3 ]cDS* ]" 7/o GڊpqOÝڦڐ*'-H  U2DK؊66{DU23lQl&"U2]:&"Q"i/6'6+ c6qU2'{Zl"< K 'ҝ BqSpg Gc%'-p՞x6'6]}ȝڭc%qB c%PI!%: =%U2v  A SIJUc%ū&"IG?pZ]c%/A&"apO' qqZAc% g]c4: ż&"JUD ڝ]]DcSBG?:*{ھ/G?6SQ&"v Bcڸ]'Ag%lSW>'- >]gg{ cc%:S]c*c% ؔ Gڹ{q'QHc%c% 0B 3: ګ ] 7: ŝiq&"ap5< G?c%6*{6 DqB}Ȑ*G?q6q+ Q'-'-!Wc%U26}Ȑ*xZIqG?c3xZc% Oöݾ/A-]*j&"I_'! G'-c%Q}"}ȸ:Pc&"~j˃77O}ȫqඪSQ'-4xZc%'&"ҝڅ gO"U2/-Z3P+ ]ڐ*c%U240U2Oücqv I{&"]t}]tJU'qݹBv c%U2yJU'xZ G؈ҶBЊD'c%0"xBWBZSc%"BЏ؝AJU'-Qc%: WOq}ȣIPg3:v  q'-v "}O4xZq}Ⱦ//S{pՏQ!pG?/c%''/ BU2 {ŭblD">A&"cZ gc% BAp~c%JU OÝڭ&"U2/O6pQc6 AOãOD4/: v HpյI: G?0cbQx bG?U2O]4˹ 6Q:'ag' B G"c%pQ &"!3 %/]җv c%/cc%: ]0': : ]A/o3"c}ھ/'-{:3D"j G"G?A AcqBB'Ac%4/U26 c% ڝ: %q&""j]&"/c%'-/Z6}%&"{U2>IB''/D]}c pՏ=Sڟ"JUg  c%U2I G'B]66Kc% W/A 3"Sc q6 '* /3: l 6 q &" B䯞:  6ѐ']l'&"'*H>+ 4]0ڗcQd/Z4'Sc%pչp: QB>%I:*D D"c% D:la{ݶ"c'- &"6ڐ*00v '/Sڼ=&"c%: }HBS/ 0&"lO"!4'c%ũq&"4:7SBDݸq]'c%qSc  l S/lq'Sc%҃7D'-6"4&"pO! 3x6p՝D: WBб<: ŭ˝: Zc%7: ]c]DSJUQ0ظBU2:cQ&">q6''cq3䯝Hc D 0Q&"*4ţ_bpQ:Aͦa6x63Sg Sc%'-&"KxD&"Hc%3BaD}4gBqU2'BЏ؝U2]OS6a'-i6舥+ U2caJUI]ؾ/g aJUJU壋:Z"/B]txZc%U2xZOq"O4A6趪 AgDU2xZc%<ҝڝ'/QbDc%7أ Gc%=qBZ4JUc]tA3B:c%u-: c%7}ȹpqJU_JUI:5"Sc%<ݔ!ѐ'-ݟqO6JUyJU4Q 3&"-}B""%6c%46/]tWU2*/b "-!ddQBо/عASc% :A GB]S'-cH !AG?c%BB6}qpi&" B'-jxZ Iq Z::S<:pն4AG?춪0v 7D*0AgbAOÙHc%:76JU }c%aҹ*dDj G JUJU: -u6: 0   G'&"_/:Z>O}S䶪i c A/%JUS"Bpqˏ /D '-/Axl 0 A'-pD!: iQ'Ac44ѐ/Dv A7Q  "A/HW GaBB j&""}]xZ SW>a q"I{Ogp5 4p%3{ SqBq Al %6A>0c%cS ؝c%plD]&"&"I] c6DxQ  PDp: 'B"W7ZJU'-+ 6j<ڶھ/3-uAA!'IPS-*JUqDQ: aHG?ѐD&"~cyd G H- OuG?/䯝_PJU: : qgU2䯈ŶAIyd=] c%jJUuA>K6Z /4Hc%/ ]OlII66 D }ȝp*/춪O 7< GxZ_U2鈥ZK}-D G_A'&"ڏc%"" ڱ<7ݟWl]4cBЯ&"6S6&" G&" G:'숥'-6Bc%% G4aS&"BS>''p՝A4OO'-G?Q"ݶ3  WjA']pն㈥c3p/c%ADc%U2qU2:'-&": 鶪]/ͫ G?/c%U2Ac%ڈ]+  6 G} U2:Sc%SI}c%}c%A+ 7bgZq GBЭc%: DQpՅ ]}4 qc%&"cbAH} &""ݯcA<0">&"ZBqOb7'-!cg+ &"Aqv c: c/́0]aOÞ/{': _c%c 0<&"a3Sq + c% U2{'qؔ*pZaː*4c%c%c%c]BЏ"c%JU3"* Gc%U2-D A: GU24<6B6D䯣]Dv GAG?{JUPc 6 /3H  0S]&"&"*/Q*JU3]4v Zڣb G'ݯI&"S6Z>cbcBv =:]c%c%JU7c˝{"cH%<cA/G?7b"S"c&"+  '/60%'-/:: <'-bq6: "řqc%b /'-/3]BccU2]I'-BНAAڼ S0ث ' <:+ ' }"BPJUc/گ]ݝ4: ] /U2/Hc%c%'-'-a BЃ7'-0%A 0 W33]c%c%!&"qc/ KcDcB{D6&"c%D+ ڏc%B] ap՝AQ{6c%݁: A H BaBм&" WڏU2BO *B&" ]c%]c%]Dc Kp4g&"W67DDũqq/c3a/c% p]p :c66] a:Bи*DOïݾ/: DDB6]qW<=BмBqp4BU2a"/c/ˣ//:W%c00Oݐ**OWc%< qc%U2q}'6 ABНc6A'-*cO]G?a:=xBq]]'IDG?u]c% >Dc%Ŷ*:i0%c" /o GDD/P'-BqD"6BiڶU2/ G/]p: ""'-/_ Gc G:/b]&"p}pp]Bj"p՞K4KlQcK3&"v : =:dx <6 _أ䯣JUc"/JU Gp}}AP"WQS0/4SگŐ* G&"&"]"D04v q&"jP}S3j4 6SG?"c pն<*JU{bc%qZ+ ͟別: Ac%/+ c%'-'-p՝""]'q/ :P}'AK!4؁34AqŃ7:6pգJU+ c7*c%c% Gc%a/oc%>Bж]l6Wqi{qQA*䯼x'-4qA!c%P!O:cSqA͸S5OÝڝBД<47D"aJU7_:c%cqc%"]]]-pH G/&"+ IJU G Gc%ŏضOöqO /'K IDQxpչ]0}c G'Q7QS/": gq A6Q ňŝ}ȫ͟:]U2A/<a+ Oq"iA4 K/HJU}}ȣI{> G6K40A:7 Gq5q*qS/qc%U2/]: ]6a: q*'Aҟ:]7B ҈AH]c%'}&"qඪ!P7c%PB>S&"{: H'-ڐ*/a6qŐ*PDp4ŝU2c% !v /"3*c%ᶪOñ˝} A:c%B G6cک '-JU670]SDv c%c/Qc%c% BЁ&" BD/:A> 4Bګ4D+ >BB0 Ac%Hد:!Dqq: 0G?!iDl: cc%/B'-G?c%qqHc"˝_QG?g0A+ U2 iZA'-Aڵg6'c%]pcZ4c%6c0*"q AG? ˣ=>H!Sv 3 ""*4v ]'-BQ pխ46c%3*p{c<؝c%ھ//l&"U204c5S0}G?<>v JU6'-:I ]ѐuD]tP&"6"*BНҁU2]t_ GqDAD"B" "<:JU&"y*ڣ䯝'-S]tJU&"]APS"&"0p6c%': G*"+ + ˈB'-:/JU<jc%-/JUG?˝OÝھ//c%'>'~4: /0: !AJU/oA'&"cZѐu6ڶ"B&"JUAAG?]7AJU6Zݣcѐ]"cU2K4"/'-ABO_04:73jxZH݊u䯝&"D/I4c%xZc%S+ c%0S-pնڣ'-&"6__:q'clc%Q"6ڶ"q36 U2A_PDˏB}S }ȝ/ cg=D> G6P6]BHy7"xZ/'&"JU؝U2'-]0' cc%c%JU:q͏ŝ-Aa : c% G3'-"]+ JU3/oSJU :">c}˝ڶa6/JUIJU :g'-/JU3BSa7P/_]BжZp:  G GP}Ⱦ/A AA"u"6 GAc%]Z*"SAIc%/PcS] KڼQݶ Av /]"c%U2 B䯹ھ/!S*>Q'&"'Q/c%*gOcS'-!-_Ad5 7_AlqccOö/""d KJUAAc%"c% GxdJU] JU"'-I"A AD'-B"}'-}ȹ G]ddWa:]6+ aZ-p3: 3G?P]t'Q_c%S 0݈ud G-/ojAJU:BНZG?d:Q c% /c%'-JU/:'-: KpBI }ȏaqc%U2]v dU20ک"BЏ/gpAp/oa"Iұ<: c/"4A䯝ڃ7BА*PcA*6/Q3ѐ:a]/SDl5'-":'-'-4Qؼ&"qc%*}ȫc%pl G '-BxxZ*g/c%ڞ3SI͊&" 7 }g"KBZI/Iqc%]4OcBЃ7A G:3g4q">+ G?QbH7W{㈥:v /ŭBНAG?BHABc嶪䯃7 pc%7/c%ũg]A}ȈB"˾/qHI'A0jSpc%06 c: gcHcر<  %U2A: : G?Av pݶx/lc%/pP!"q>6͊Kll]U2:&"&"JUc'4lHZB"3I3c'Dq lJU%]q&"/0HqA G4]+ }HpՐ*6']:A:: a0H3p7:: B}BSG?'c%&"A3c%]>x"v 5QJU+ Oc%'B]: DżS'7]p՝]ک6I* G B OU2 ŝ0D/&"ݩpqc g5O6&"]:Hc%4pնi<"ڱ Ipթ/7'/q0":c%'-I/6cU2=6:{]U2]Hڅ JU 3l}ȫSi G'47pQav 6"B '-DI&" BЁ:{D؝&"Ba]/cc%" q"<: p6S G}cq"l]QD/5c3!/==5ڏ>ݭqQ6%D*S+ pՁc%>3]&"c%3D*%&": OÞcc% '-B:: Q: g>S JUp:ABv *}g7&"c%6䯶3U27:a}: I%p3G?Ņ 64Sa''-l "6'-=Ҹ/:ũ G: HB-䯯" lc%qaAc% i]S{ ac%]B:3 /S'p]/ '-{q+ 4'-5 ccOc%*7&"a*:c%%c%DBZqq㶪pկWb4/q: 0! : /B::*SZ䯹BDG?gU2W݅ +  v '- ͝iż qU2DjIJUD}ȣc%ѐ ]AI!c&"_~Ac%*pչ]Z"'c%'H7c%Sp՟QScc%//-6AABlB"}ȸcHG?7AaU2:*""i}ȝڙ/PPJU c%3DS>q /4 ]S pZq'Z'AG?!+ H5]䯯'Qci7Dv : 0"x*c% 6:/6: ѐq:4U2//]"Sx /40SH cA 4JUU2/ U20 ضK6&" G:BB'c%G?/%S U26 60lQAAS " *DpD qA_c%v *: u"0S'Dc%IG?*Hv /Wl"c"U2_]tc%:7BНݝl}4'-67WbPyPqc%c%]' ]: A궪B0/ڝڣAxZc%A"*QpQU2JU'-]%c%c%HZ : ͶZi AG?q/}ȝ"q D'p؏U27JU45c+ "6"Sc]a%>v :+ /<ZqW]6"'- /D4'- Gc%S"B}ݞjPAc% Ź'G?Pc% q<&"c%%c= K '-/U2Q*p"Ҷp56D:A4c%͏ '0p!ccq/{궪 c%c: q/c%c% v pչ5!/+ }'-A4c%Qc%>/v c%ҏ'-} / Gڝc%/pSSc]'-c%%''-ݫA:OBp'-c%+ c!lB!6H3JU B pqpB Ha]'v 7'&"BB'- x˝4Dc% c% :cKa:":: 5'-*< &"3]+ '-Aq}"/&"] Q{: Z]"ݱ7"a"D~7]6c%b3DSqi': DqG?}ZAW/a:B:  v x/؝33'&" '-G? ˱<0ڱ<7A 0{v 6䯁U2c%'-QQA q6lc6/G? 6BНھ//}IP] 37B Q c%Oc:U2%6bl]Sc%]x + W Aj:7QؼA< :  '-: "c%&""S'-adA]qc{3c% DpD<ͱ'JU: BЏK]v : "6:AQI:3pBx /oc%<"xZ GWD: GQ4%'/v SD/7㈥:D d6B]] *WB6<c p՝ }ȁc%7ع &"]p{G?' B0 ]a]/=] Sq57"qU2c%*q>66G?6دA/BBqDŝڼ G*JUqQc%qBмG? &"0ū4/ GSQH/c%aG? ݾ/WşAAccc%A:B&"˔S%cqi%SҟG?Sc%c q]'p:4ݝڝ6:: U2qpկ  4}c%c% v AqU2>0Z7="'-A ""DJU4"I<"7_ ZѐI7䯵 GU2 }W3K"O6ڦc%j46q]] pU24qSZ0WHQA3&" : 3a:/p6c%q*c c5JU'A*7=c%ݫBм]u":c%/:G?-'-:c%g"ݏ]6 c%A="D Wp5 b&"Zaa3Q4H: q '-6*c%qgc%'3q4cc""AS> j:&"'-v 5Oa:Apկ˾/7 BD%0a*JUp0U2cc%'SW}ȝ}JUAc%]+ p ھ/ O l؏/ͫ Gj!DIp->/5c%gpcA/DxBc%g'-&"=:G?}Ȋgc%U2c!a]/ 664qc% a*q/A=6q0c%"Zqڐ*c%Q6HQ&"b6 Gqv ڭip䯃7xZc%H"BЗ&" Gav 6c 5cc%DJU] {: "q: 'JU/6&"'/qݝc%"]4v 7xZ/"WIc%}ȝpq U2PD]l G&"&"}ȩG?lOÏA!u]t죋PA/xZBЏ 'xѐOpѐ+  GW&"jJU  JUD4%؈BЭ: i6Z]g4dq G3"*&"' G:I&"A%궪]U2/'-%%Oï:{A06->0ZD<< 6ظJUJU: 궪 G*ݝѐ% G_jJUDqppp%Z4cSG?jJU0ac"B GG?c%'Hc"/xZ{7'-]c'-a!ŗc%]ګ͗ Gc%c%7AxZJU""Z{qc% GA OÐ*<ҙ6"D G *c%{q"Z:SJUdq biW*_xZ!Ź"SA5ڦ_U2&" <'-/}ȝ}%v AW: aPPAxq/B 0A6 30JUj ]SOS Gq7B06BA ]"Ic%c%Sҫ:/ş{'P]AP/<"]lq%c4"AJUac%pQ '-y"U2'-pD *lc%/oIIG?Sc% OëQ'-JUc%q 5/qv p: U2]"SB WD5=5c4 :c%*B*}DxZP0{G?AQic%7/}BЏ]/"JUD &"xZp՝S]pؾ//qD{0 c%OAc%D3AD]7cWZOc%jD G G?c%]4:"-: "䯈QS'JU'QOp]IAjBУ>*ݶPJU c%Ŷ/U2JUADSgű0BD*' D:B>c%:&"a Gc%݅  qq% 7*W>%lxq3D'*cqgc: ]S3c%qSq G/S3&"*/c6䯔qZqpc: : *:D6%3< OBЦqc=WcQD}>'- *3Bc%c%ݯ: ccq 0'QD4 AAD!"]iK: {/:*'4Z&"" : a %> B>cqa G*Hc]b{>Zc%c%QqBK c%pգ'/Q0aH60q c% %c6{B clAZc> ppHa ݯc%7c%qţ:Qpնqc%JU"'-q3 0+ q%6c%%]A/6] p6KWaD]SQccv 0]:aq*0=}ȼ0!> A4*DWc%<3 ү6Dc]{ :K: &"U2:l6Dڼ + p'6ҝB'-BqQD%U2] q<c%4aSpxp4q"؝3*IA:  *c%Źpq{G?P/]c{: B'-Ac%a/Kc'-c%3"!&"&"c%: *7˝ځ]q{3H G:'-%]U2/&"]HqأSD/6c%6366Z6Z*&"]3 3H6pՈc qq{'- b%Q3S6v av  W&"*H!ca+ ab&"c%Sڟ'- : 0!clZD c%' S56%Wx 0cqB>DaBc%]S c{c+ x0Q>W{{]QcڝpHlc%c%5bq&"a=BaD: Q'+ %qZ 'Wq]00D: کc K]la3=}l' Dݏq{Wcq /qڼK!{x ]/%bZclx]Wc 6 ]Z56:  6: '-&" + : 3 l: Q: H c% qc  3! Sڝ0{+ i{5 0caq:  56  c%D D]B6c%S]xG?g: q6BП' g0: l!c0  3QW>366}l؈{ qqlH]  DQ%c%c%: ݸ%Z] c%: + a ]l6!   6>x066ݟ%b%Q aD: {6/0 >]xD&"0c0g*Q=q&"%*DBpcQA7lq 3+ p՟6q Q'&" Q6Ogx ]a : /&"00 cDqDac%v D%: Dc+ >073 cZWcppD&"W '-{+ % c>>: : + : cD+ q]3Dccq c*DcQ7c%v cqDg= >c0H:   6l]Q{] cDDK3S 0SW0:  4' cl*gS 6Bx Za> D0Q>SxSQQc%>] b] SQ]0qg]: Ql6v 3aS0q=&"ݼ! S 'c% =]]6]c% 0]W660 Dag]cc0A]cv /ca{0]   a/Oï!p՝Bqc%:c%'&"G?g"́cqp&"a3 B+ qxl3c%&"c%c%c%0 B>q]ž/c*U2c%c%c qZcp5 %'i6qDHc%q3!3  &"3 b>Sˁ{=qc 3 pթ0 W{{{c%p=0c%Ic%Dq 0gc%H0qc%>BУ*c%0ؼB c%pկ7 c] }: {D/0&"+ : ]6'-iZQQ lcq&"a+ %{!&": W + %aq ]Q&"Q    ]6 c v D0cK%Z Kc]  q*xbcD5'b6 + 3 q %c6Q]Qq0]: ] cK c%l6Q']6W lݟ ci/g!iS6Z5xQ6DS+ Hc%60+ Q6ccg D 3!c%: v  ؈+ 6c% p՝3%] QSg g665&" c0a=3 Bм%q : QcS Q= D q6cq]Q : ]D6H=lKlc  qlc%S:6 : D: S5q >: Q: Qv l&" >v 6 l : 0+ 'a D: ݝgHZWcqc%%g >qWQ%3 q SD/0صv Z'33S6DD c%l:'0cQKbQ: 66ZQ3]0WaDv ] : + {v v iScbl q :  : ]: : BW qc3 x=: !%ic]WK: v 0c KH c%DS+ 30 !{x 7 D6xBЊc%]ڏ: 6qݣ3HҼcD>a/ D   6H + 6pp՝: >*:q'ql!: 6 3 ݝڸIgc0c%BНpb ]+ ii0g Dc  'SccpQv Q K+ 6: &": Dc3 {{H */60c%WlZ6ڣ  6c QZBx': S5cq!a* lpՔ : c qc =+ iS6Zc: ac!&"4HqSq6S%*a4ҫͣ3BА*&"  BcBaDZA{AU2c%W>0v Bй" / 6 a '-_: aˈ˞l c%']c'G?_dc%]6q':*OöBl"U2 ]P4c=Q a'6}qqx>c%&"&"c 3U2 g! 6c65D >S%: 3U2]>: cc6p =cS'v &"c%'-q+ 6Hl=6W0: 5]qڝ'-  { q]دqK3:  Qg6c%6 S/3  li%>Qq30'D i]ҏ D' : i: !B '6c%i0Zlc:'-qv >q}ȯZ6 3Kc%v DccSQDc%6Qq=]=v Q D{6]cc%6W'-clWZ7]qpl a Wp!/ 0%Waq0>qg'K ]v &"qBП*Q3c%{Qq D>+ c%Qp՗v %U2c%]66c% W c' &"6"H&"cW { ]6Bq+ D ccҼ4Q6Haai Zc{qZSڼH 3qq :U2c%/&"Hx: cD{ W63c&"Sv c% cq : c%c %cv qi{ !D3*5&"6BЙ*&"iq=c%v cڼc%DHg43c: {'4QQ SW %&"*Wxaq]6B+ 0q7Qcx ]Dqq6lgS&"QaS &"%D]=  0Sg0B*W'-'-g 63 Sqv c%*l: c= %SH0'-Q!q7 : Sq: + WS3!6%cHgDc%q&" >%5>qcA: D6 v %lZ !  %q=&"00x q'&" : c 66x3 qlac%cB}]  *&">: cQDSQ: acDD0D>]'">gb=Q Hc!!HH 6l =c%{' cp =؅ q{0 c%cqB0]/+ v B>'-S6H=ggD'Dc%5D0Q6v W'-U2{Dcq'-: 6W: q] + p6أ/a0:  {Q!cBПBЊ%0q0Dl+ xcU2q 3!ac%DqDKS% '-S!v c%5{/QlK&"6B3c%SqaqSc%4*O5/QSi06=gS W3c: cx c%*'-%&"lqBgc%c&"{Q0=q/Dcc&" c%!D / Kc/: qS'-:73*qڹcccQc QDQSS&" ؁4S%= B6cBУ &"bv BD4 0q3G? p"BУc%:&"5qp"ک'6 Bм60DSK c%B{q '  c}+ q%4c%' Wq]D=q+ 6U2c%: <c3*q/v 6g'-D D4* ]% + Q6DOxc%//'3cݝڟg c%أ:6b :5+ cc"qi:/OöB7U2bG?'-ŁDaA!ڝ5alq0q'-3S3<B&"/6:x//"{*K'U2Aqgŝ:KcHlQ*JUJU: ]pa"&"&"' *4 4l"Z}Ȋc%AW/:O}p &" 4&"ZWc06]&"  a!ݝ'-U2QH+ lZ Q="qq'-3:5" 6!3""a'{aڝ]'-*O c%Q3ݝ3: >Z6x&"KG? 66'-:cc%B<'BQ3aQ *c{ v ڏS/qa: 6ځa+ v DQ]]/aqҐ* Z{]6>6 */:qOҏb DcW=306]0baZ&"BЁlKcS*3q/+ p %=cc%3a* ]q66c%aq6*: b!c  7BDݏc0Dv '-Dگ*0q]cQڙWݩ Gcc%  : p!&" 6D'Sڸ34]Q/W]'4'K0gv c%v aDG?ڼpq agQqI&"B]%a؝g:/xpHSD&"͟* c+ c Z'WI* &"+ c4/Iv c%'-ݼ3]-c%D>c%lZ/Q q]a&"QqH&"0%/*c%q]c qүqqcv bZ'-cq6: %W0>v !> &"6+ SSqq ]%qg  c%Qp c&": c JUDQp= c%0ڟ3>/B 3SqZSc*4 ZSi 37BaK6: '6 36O>cQ37'S60p/c%4]4'0: Q6 :c%/{ݼ4Ka/ ݵ: Bc{: /G?*B%v c˝c%OÔ c%Z+ %%BBc%/QBH{ {&"6! xQgHS' Dacl&"c%/x!]ҫ{l4 G GU2BBЁ&"Qd4춪4~ G3B˹qڟ6A%p6: 4v Zl0Bpi3SW x}c%AJU7c%<]O䯝کU2icqW5c%c% + U2p6c 'S7 ŝ Gc'U2'-˩؝c%']=yI{7p>* '/G?qH:: : "b/': c ]]a *cKc%5c%/] ]ZxZc%0!Ov 'Qpռ G?g<6q>Bc%>qU2QB'-c'6Sű WQqc%<c qpaڟU2ag70JUd }Ȑ*IQ6}pկ4B%laJUc%pH6%c%&"ظ3O"ؔ4JU<{ "B:Q B˝گ&"qq'c0q!'c%Spqc%iq6c5q*AcZ*Ŋ0/i'-a  lqg'-үc%c}D B5}_c%&"ؙ&"v ڝc% B3/͏ }ȔI Ic%6xqg*>6pc%6iA'-%>c%qcOë: 6:/  0q''}+ Sc% ˝ڭpU2U2c%c%U2H >74>0DpՅ !/SS0c%c Dv ݫ3a'%qcc%v Q"4' >/6}җ/Ab%D*ͶBcv A&"K7'&"SBЅ }cq: %Daqb'c:!Kc%%66{v >ڊHc%4D0'-˼l cDW{] SK/: qcc%D x/p6]lSS/7Q>K%%6c=W0ҝ:'{bSc%͝/*xaH v K6 S؈xZ *b&"c%  qBccQK D%c6H a' &" bD3a/Bм*:U2:Sc + Q3ڵ<ig0! 6&"K ]lb{q*c%lSc6}{:l*0i: *pK p]: cڟZWqc/6&"ѐp/<c%0c3D3DҁcG?gc' 06 7qpxIU26:'-BS ]%v lD:73a!6c%0O7c"c%4:؊]>c% D/ڸc%{6c5qڵ + qQ/*73pc%Qcq/3c%Zҏq]cD: U2c%: {!v q>g]QBDAc5qD]Z'-&"ݹ6 4KWBqc%'- c%Z 'c]S: q"*DU2 Ab: BOþ/H'-OPaqSv  "+ 4Z&"0c%c%U2Oc60q"b Gc%: 5Dlc'la ' H60>͏'-]c%P: '-*䯟gq]/7/%D*QbcDc &"BЈBУI'KZq: 7aW%Aq=cSJU4 a !3 :b= '-!%Q5*q0cDc%}H &"0Z&"+ 6c%/{c: gҝ= 4/Q: ڟBa عJU]c%:'q: Bqpկv '-ag0*c%: /l]0{S*c%}ݹl:lv Q 6U2&"c'-OÝ궪'- pD*q**'-؁Ő*cڸSI]l6pcż''-/B6c%7JUqu6_'pJU>c%";/ c%'A%qBG?P// 6ݝBж ݝa *c0q _:U2A{qکq 6a'ظ!3'-:O *pզ]Z:lI4qq/ D'&"c%]ODBо/Q< ҝ3'qpq&"A&"JUc%D "䯩G?%]aK G DP:4K<:lU24""c%''-c%<  '-JU6SŊc%&"ڙ '- B"q +  + :U2 D "cDD'-3p˦%S0q4c% ŝ3U24/0p0aa"/BcQcg&"qS/< + c%Iqݞg"ݾ/IQ0˝c7dO!'-I]c%:c%"/D"BJU_:cDS]>"]c˾/a:"أc%JU/: >*:gBЁ* 6c/"]K+ Aq>pl67PU2]q + /qc6U2:Wa0a+ ApՈ]//ҫQcb-6ڝW7]q<ZplH'-G? U2I6">c%":  aaJUa4qSڐ*pU2c%3&"04+ : }BB]_/S!U2c%"=&"=: c%c% *6> + 0<'c=݈H'D˝B6 DqS]/c%W 4 G6c%'SbOBpՐ*<PJUqc}: "a%p&"c%B": Q/Hc Q'-7]6U26cq'-Zc%%/6xݗPDcxZA}ȶ"7 G'-"A:䯝c] 67'c!qc%&"G?c%U2&"BНڸI7q"q Gjڔ3Q<3&"v pD c%c%q>'P iP/olH G'S/H'lqq:AB"q/BpZU24c%cD ŁJU Q0 cl"4]U2G?6-qc%ڟA!]: :DŔl'-a 6 c%c%K0q&"> / G 4 6G?>q::6"* ]g*="pc%U2҃7"Da6Bо/:+ cQ 7/WOW06/&"ص  /cID0 c0'-bc> ApB:c%:U27Oö6<cˏ'/!c% BPBK" GQ/: U2!JU}]ھ/4 ͯZ G6-c 7JUH]c%BЯB&"&"0SxU2c%Sc%'-K6q"B37l G3*+ c%cI%lq"Q:yڶBc%_p&"}]U2v >a//q ͭ/IJUB*7c%AKBb"B}: c%JU{*ҝڝQ&"U2c/"ݙI c%ppնc  }U2!qҫ4:K]؊]QG?:{ * qa*qJUݱS*qxB6lPZث% 4v 3Ac% : A}q ]6c%&"O34 c%_OحcScl}ȝ'-c% GjB-Bб<AG?0BЅ :3DB䯁l/aDgc%c% IAA ѐD䯸P/bZS}0&" Ic%}ȼ'-JUABНګ3}ȭjqp: :cP76BЫpj G* 䯶c%g'-cpՈq]_~xZB]Z'- GS؏6"/q7Ajc%''S+  6qڝ DjA_&"H+ B{p6*'͐*"c%xZjH6gﶪ0: 'd Gx"HBU2c%:6U2d<'-:6q"pq%A_j3*p]!Qc G4&":JU'Apq-Zڏ>3c%4c%JU:qŔ}ȯ{0c%Dp>4j4D]˩SIdj  G 'D0p"OÏc{ddAPq0 <P/o:6趪uuѐ"Sg7*P/: bxH7'3!q6 c%c%B]OO6//oj G cWPG?]t:: "}ȣ]ŝd~P-x GJUP G06c%/]}3G? Gc%S-0: *]"xxZy~d3݈DBZ䯶]p c G?d~~]tJU]SﶪuѐڝD c%: '-xZ]t_+ "]}g7 y~xZ/5OScݣIP:]BbA:II" &":7ݵ:'->ccB]/PJUIPP=&" }Zqc"qU2:~~j74Oæ䯈Scc%IG?&"c%:_/*c%q͙"BU2/'-dj:6-uu"P:c%U240]" G?D'xZAQuuuK&"3  DP GPj Gc%Oöu-]qc%Pc%/a<~~jJUuuH6D'->U2c%JU<&"6BaWK'/&"ڶ/<*6˶&"PxZ GG?7/嶪HbJUc%Bd~I4Q G?: cQ3ax㈥c툥 d~/o:=D'-Bм"}p>D؏*&"7/oJU/oJU "ѐ- S>D'-PU2U20 q""=c%c%:{" Gj'U2]-uuqPA7:*g: :< Gp]Hu-JUJUD 4P~_P4-uu"6A0QAU2c%&"/IH҈ */AOø!ŔA6c% /~P/&"ZKH: 6݈&" GA GU2U2b]c%&"G?  U2D ͩ ]c%::c%: p]"0}SZ*xZ~P&"D: 6"c36ڟP<'-U2c%:QAU2 S: *I4 "uH]i'  a GIc%::Qc%cuu]SHG?JU G + AJU/0c"""Oqq{ '-< cSq c%'-0 '/_JUA-ū]<c%AI/o/o]t/o G]]uuuu<:/6p{/AxZJU::&"]}cKqc&"HAd G3]HH؏ GxZ7c%%S/A'-: %]ŝ-˾/_~]tdxZPcDB-"B"""H*JUJU GJUxZA3&" pն':}"]BgJU_U2I"䯶S{AjJUc{6c /"ѐ]: G G/A͹/JUdJU/!]"]Z"BеZIjI+ OBЫPIPA]]iU2 IJUJU}ݝq5&"P:p]a/G?U2AU2 BP* 6q݁JU GP䯈qcU2 GPaU2<73"]uuZ˩:7cG?' GyyJU HuH: c% IAH*A/o_/uu-"SHc%: v W{/I/oAq->'-D5'q/' A_:IKclxZG?A/g:/&"]G?xZ:Oïŏ!pşcG?P:7JUG?36]qWBq}G?D>0JUj~yI/ѐZؼ6OOïxZjAQ Gjc%"c%I"%A:4:43ZuѐZ}JUJUA/AAJUAD0&"ݟ別uv 7xZaKPjJUAJUc%ځ"6"u]7P'-'-D5Q*6>c}0q *A'3}Zuuc%dG?/c% G&" GdU2/cZѐP4'- APj~JUc%ݫ]Bq/ K"Ag/cc%/ G_U2>]BBBZ}ȹAP GxZdyd:-H-6c%3gA~]t*p]Z]Q404c% !B䯶!'/:A< GDq*<6ѐuOI]tI*xZd/o7Où  uuU2PG?c%PAa 3U2BB6ҫ́A G4q--}q G_c%U2 c%"c%3qWQ'JU~~JU7 SK"% dxZ_ddxZ/Ҷ] : c}q]: gp%*A/oI]B PA}uZ]S  Q]dPJUI&"D0cc"c5//S]u0c% GG?:*3S/Iݝ]ڝU20p5c%/q>Zq GjU2:S%'7O]c]/A::7]tJUacD/]Z-Oq}i*6S /~U2/*]Bѐ G~xZA/: ZŸ44  '-JU:D Z%"c%Pv :A/AAc%>pBД: qŸZO"p՗ G &"c 3v :AI:/ 3p]pն؝ڶIxZ~II: + cp66BOÔJUJUjJUqxZ/q]' G؅ U2c%0uZ"c%P_:/S: a' GxZp]Huug/4A:'-]tPc%B6 c"BxBЗ/c%q a3':'l0: '-:7ѐBН/A*AH ]B&"P Giž/dq]3q xZ~~JU'-66]ZA'7: qcc%G?c% ]Buu"v q%*]t~~_<-]6Bж04:xZJU7AJU GOÝcZQuؾ/jIU2jŶqW݁*::4PDu-: >qc}B dI4Ajdc%q3ضň-uu:jJU 6cQgpռq/'/Kc U2]"A~xZ+ Z}ȝQg]6cq%5AI/odc%]uZB>g Z 6q]--A~~IKpՁ-]47żDI~jJUcBxڝqqBЙ!c%Sg ab6ع}!d/o:H]BcI~yIc%qඪ/A:ZZpSx: G'DAP G4:BOö-}}"IxZJUDżc%JUj:D"BݵSO]&"*/'-c%: i '4pչ6]WHi: 6lq>c%'-JU'-KB3xZ~~:cuuѐڃ7jj</7b3c%]4'gň: G4}Ł'xZJUJU76ؼ%6uc%Icpŝ:~~xZ*auuu/AA<:c%SAI㈥䯶ѐѐP~~7{xZxZD O]}4~~I{"B GJUKO&"l %U2/77:PA'-""u<~~IO"cU2I GBBЁI&"""A6"U2JUc%AAګ]c%U2]t/o7}]<7*"BЅ *'-76pյ U2'-G?:/::BжBlѐBНAP/oxZ~P: '-<*ѐuuuBAy<: '-7JU cҝp /q*&"ADuZ<jjdU2ѐ0bP_">]/A'-0:xZ!ѐu"/q{=SJUjSaJUjJU/uZ"av *DZW*Dc]6&" &"c%/&" c }ȶ-H GA G:G?AxZdxZŹ-HuSU2~dIJUA:/ZD3䯈uZc%HҝPAIJU<䯶BB*/ BНD/BuHBЯc%G?G?]t~j&"qqඪH//4}~~JUSQ]D ͝ڝګpW'c%g6aac%:'G?PU2҈3c%7:G?궪"K]:75 :'ݝ]]}ȝ7:c% GJUc%"QDG?JU 䯙c%AJUř: BHB 4_JU3U2IG?>+ uuqp7A7'-A* JUjPc%Huu"*Ic%jyy G*ūڈ&"< G*DP GH-S: p P:/IyxZp-"W">Z!!A<_<JUc]u '-=BЈI~JU/S]DI"%qaU2qBНڹAU2P/'-'-xZIuuuq7B-]B] G~~~G?]q}Z] /G?I4D"}ȝڟ/'-D] '&"/7ū͟c%؁]ѐ-QI]t67D/K: :xZHuZla:/AG?6'-:j]tAp䯶"uc%QpqB6B:j~G?_*]]Zc6ţ-6G?__Aڝ<__AqBBЈG?:Pjj"IxZQ: l0]/U24U2I G:]Oc%&""D6]OÝO]A Gc% :c]ݶ!U2jyA/Hu4:!pq: 7c% &"pՏ3c%WgI DڶHJUIc6> : G-]!3"S: <PD G:&"c%/Q ѐuu&"/oy]tSq:c%*U2]&"A~7ҫua]tdpS7G?~]tJU/ضp՝cq&"//v OqI:'O""݃7/o~j-}ȯ&"D6䯶3&"  pؾ/yJUg'qc%AZҝBНxx% G4a/c%Id"]-DQ G?:Z6: JUj4>&"c%0"گ춪"djj G7҈: SBН4P:: GI: ]7BqU2"Wyj+ : DG?Pc%0Bqq؝BйcqajPQ Zy~_B"]uD'_A/! /G?d H ض䯹ѐI/oP+ BНB{JU~]t}qOB: djG?:"6 "ѐdG?c%: qq+ {Q'-7c%Qp-'-D"qc~~Icqqp&"jxZcZu"}S{:U2 3/ሥž/A:: /d&"uH/ G}}AA_xZj*ѐZS: cD/D+ cګ q U2]txZqO'-> B6c%dADG?] OÈ:/au7/oyD"S*U2 GJU]t'pZZZŝAI]tj:><7B"-Z&"c%p՝K4JUA*3"A U2B]}'AIP: ݝ{ q GjJUA:/S"-&"v 30ůG?'-:jAڝ:JUBq6Ŷ: OBp>I~y'-cq]ڦ_~xZQ{>Huv /c%7D/73 6glڟSB: JU_Ic%}'-:D""iIJUU2}c%<'-3+ O}HlD/PI''-P4͹p՟"}ݏ':/oIa]OùJU~]t6ZH"6 + PPc%ҟ3'-::'Zc%-şHp<_IU2DHuSA/c"ڝ///7B:A*= q>p&"/Ij_]uuc/JUAp+ OJUxZ/a pj]t~U2]uHOb S>p3P/o Gc!cpBG?y_3c""BB6+ /__Q0 W: c66Qc%xZI˝pՈѐy~yPBУHѐijj'B} B]/PAAjJU*q]]"cD" JU~_: 7AxZ'--uq/"jxZ-B _JUPq6Bй"qG?j~U2Bйq 40؝O'4U2'-64IjxZ*]uuaSJU~I: : %! S]}ȈBc%jd<a44' ]p c%qqc3JUxZAc67D6B_~/oHuU2A*OÝ A'- KSBc%: G*BЈq{"} 7&"S*&"/A c5uA~y:66JUdAx]"3"*3a/***4x:~~A궪͝4AA3SU2*گW&"A7''-c%{͈}p՟ G?P7!ac%&"%Bж"cˈ]cxZ~~P l  a! -ZQAI:ڭJUIBc GyjJUWuuG?JUPݟqlc%U2݈Z"c%__JUc%؝]c]BQQS3/Ac% D/c%qS-id~jc%qB */cͯq/&" "ѐP~/oڝ] PjIaZHU2JU4 ڹc{%U2_4q=c"0y~j-u}'c%]6ڞWaDOl3AJU<!Q:}Ȉ"6ū}ȝ0'-AIj76OëcQ:/%p6ţ}D_~~ Gqඪ] :JU:-D':+ 6Sq D/p'-4G?4 ""B5PjjU2ګ] c%'-c%&""]>U2G?c%"ŭjdPU2K0v Oů{%6'G?*v {: c%D : ҫ]uu"d~JU&" ] G'-c%{ͶBЅ &"H]xZxZA'j_:-3JU*&"c%: ݐ*P7&"BН"<~]t GA:B䯝3Bж&"D6WD]t~P'B% cqѐB '-y]tc%BЏ4 xWBZ-I~j}KU2I G<4cB"JUA䯶6: 7AG?:0pDdG?O"x7JUxZ/-+ av QD 6"BЏJU~Pؐ*A/B]Z"pզ  U2JUPPc%B"B"]Idqڶ-4_yJU: a'S䶪Zѐ U2!c%dyxZc%6ŝځ//}-}O} 4:c%U2:* AP'6S3BuuP]tJU*H<4 ]Zѐ͝ڼ: / GPc%c: 306}6A_ GG? c%]: "OÝکBжG?dyJUc%Wp*:>pZac%DDJUPj'AS0}ȝqxSA]t]tP=ň6H"bgq/JUPl "" qJU/oj<D: q>ض́c"]Ad~j: W>p"bZ3c%&"0qb: 3*]&"74*żH3*7>]v IJUG?&"cp˸g}ȫc */c% + D/Ha6춪BBЯII!c%<* lS}ȁ6 c63U2D'-JU']bc}B6Q]S''-]l+ c%D*!6I &"c%]B!cG? Ga&" cکW6 qc: *c% GP*{ ڝD4=:q4gBУB: pիpx'-0q<4]%/:'c%WWK6q]* BУAicBDp0 *}OÞ:!c%q c"]< Gc% Q< ]Hl'= OøAc%>pcAQBD!AQc" GA:qiKcQ0'-: 06v /}!'-Oac%c%]0: : c% Gpūc%/qQ ˁac% ccˊg/: }"q5c%<"+ U26cWgc/!*c%ҝ Q64&" v WZ'- BKWS: ZlcQa&"c%0b3/&": >B"c%A*qSc645W6c!cc>=H6!gl6ؙ 3 lcZa 6qW:c% cBНl : Ga}cqDc%g: 0c : 3S0Q}؞3gQ :Q6 %Bq3<ڝڔg*p՝+ c+ Z{'-/ c6qgHpի͹ 3U2Wqqc%cq7pB]Wc%&"G?OÝc&"l'c% c%4/! : Dc6'-3c= c/c% BB*c%>{c c{D!Z*"!HS&" c%6]bc% p v D*v B &"+ S6D365 + SB G?: p՝!Q]c%cq&"Z!6> 05 0]Hv x B003c%]>SZ]Sg D6%څ : Q q]v =v W]+ &"c%c&"&"qDD%cp '-* li03]]>v il= : DS+ ccBЯ :&"Sc]c 6v v K: Dp6+ K' : v 6ڸҭAc%5aSc '=cqQc%albD Bp6%D//cS]{H ]l gv S >6 *KBcS]bi]+ + i>cHqA/Q]B"6/c g6'3c%B}l'-*+  Q{}ȝڸ3>a+ 5 D: q>D!: c :  0>WxgHDS/!Qc'-Q: {Kc%c% q l5: !6 3 0 D]c D5]63iQc%cBН c%'ڝD: qv g ]v S&"U2%BB{3a˝p'G?lcDq>! &"pթW&""'-7{] 0%6Ҕc%'-*5a Q ڝ D 6cW3b6: SWQҩc%{Bc{Z0ū͙ '&"c% ]3:c%S˯>: c !i=5a0QBЭ3؝+ cҙ/v  c% H'-q6 6!: ac%c+ q! c+ =Q6: HQ cOW'q5=0+ 0c 0qbWv :5cQiHZQZ]=bv ]DqW c%qD:  ZD q{a a  6qlv ]  3: c60]{0ګ͊HK H]!gc%:  c+ q  =K5ݯ Z{Q'-qgv ]q0 '-v a cQ6c0b'/gB0!QSݫ͟q دD'Zl0WQv Kڝc% ݸ D xla!q6Dc=q'- 3 H&"6qg/%6U2v v : %]HZlH% Kc 5a: D0cc%'-QS ]q{WH+ !>]] : ]q0>!]D] v v  ݁&"c%QB> Z c!QDca : S==Di{ D>lK &" c6 qv &": lv  a6S+ ]3 ]ZSq0 &" 66]Q]&"c%b6lq Q]KB=&"D=ZQclQ&": {6%] D=W S3BН : v !Sc%: 06ilqK]{l3cq Saa/&"OqZK+ v v cD&" c gc0 QH] W5: ccD ڭ &" ]l:  S!Bq/66 ''q: D ac%cc3K6 qc{K+ v  %l6QZ6DKq v qpխ  pq: &"4D{6g 3 6'-&"0c%W0 c%: 50 aݼDD 6%: Z6WS D lH{63D*H OëW 'c% i %: DHڝ&"U2 ]q c Dڝl: &"c%cQH %6c%Kc a63b+ 55ql] Sq: c%Dc: D]+ Z: q'-+ c%c]iv =06+  Sڈ gQS%Kv {SD  &"' ڝڝڸD/*a>B!x%q0H* 0' Kac%*0: D0ŝc&"c* /a6BK] b%: cccSi]+ : 0lv ccD&" l36KD6c] 3Dq: > gb /Q0> aq+ c%0cv v &"W  D  q W!D0g/]Z6]6>{ SDcl0&"]bc%v SS+ + 3W ci HQSݝc%&"c}&"&"7*pDZO >/' 0  lݟ qv ll Q: : qp> v =D'&"أ!SlH 30]0Div Qp =HH': WxSD Sgc%   {} 5Wa: 6{: 0qS0S  i ݟW Q S0bqZ a 6/pՁ3cS+ q3Dv S3 0]q Q: HgHx > a cc: i0] 4 =pռx! + a*&"xc + = a]cv c%3lZ 6Zb WSx: D5 Q]c >l 5WH  5!]cc : 6i]]c&"&"c=l&"HBQ!cc>/c%3 {&"*S S0 7U2c%%c{Hq]qblxi* cv =%cDcڼ{ W QZ5Dcq]S33% >c%>S: !0bD3bD : ڝڏiHڸ5c3xgQ5c%0g30: D=!D: x W= : q66qW>W60  x+ 3v %6S!]v %K: : Wi]ZSA'-3!!0xa: 6g+ !3 *: c/ ݯ + xccl: + c%>c   q &"ScqK0+ D]{ DSڦ 0: !ݗ 0D : c%HZqW gڼ &"6 a+ c%D6pHcүb!c%/ : Q/ v g>cKac%a%]c%: pH6p՟50 q aW  Q cqqv : DQ0c0 '+ QHKv p66!{D3:c%SݙcWD cWc%'lc: a&" c% ] {c>x6c%Z{!+ ] l6W  cQ]DҹB: ]/c%4pD*!}ȔSq: lc%Dqa ˼v : : A={ xxQc%&"'-q: c{x3cBЭ: Sv Dc%!pռ{c%c% "5&"]HpՏ:/S/v pՙ0  =0c%͔ &"S%p՝ &"6qQ'-  K HWlc '0!"6c%46ݭ*ڝ]ڟa ]c%Q4WD3D6K3a  Q *B3Dgv ݙc6&"] pգ:3pP/ 0 lc%/p 00D&"xHBKZ]'-D30p6qDQ: : v 'BПOQbK3Klqؼ: 3] 6ScB: c%Hc'-v ZxQ  Sl!'-q ZB: + : QSDcZ&"q>33c%S!/3K6lS =]]&"U2ZiSp: &"&"=cSSclQa: q3  HKScxv : 0%QS0q&"*!c3'D'- p՝S SD ccc% q: c%/Bc% abpca0+ lq v >: q>%67'-Z: lݝ: 3]Z + D  {q >6&"q=/aZ6"0lW D3c% B%%3]Bg{{&"KlS6{/q6&"  ڸac cZ: KpB g>!c%K6c]U2']Q0Qv cڏa/c%b ]6>%' 0b00Dc%D]ݟW &"ZcBpD Kv *S:%ig{]H{+ g: ] >5al>q!'Qc%3QKDK: bl DD c%{q%0]cc%&"K]Hq>ݦWagSS ݫ͈QU2'"'qcH}*a!ڝ qW6qKc%0"'-p6Sc+  6{{3&"Wc% ݝ>}ݵQ* >DWpHqc: 00l'cl'-7U2x: HS{6*{Q'-'gˊpDc%53c l i00aD: clDD/]0{'Hc c%'-!v c%B]* av ]xB˝0Wc%&"lc% HD>؟>&"W BBc%=D qүG?]S]{qq:  W6!0Dv WpՁc%lqc/A']l: xcq]v Z= 3c% c% c%WBQ+  534 K6{Qqcͫ0+ c%5baHc%}Q= i+ BНA3 c%c}p'6l䯝'-6bDx: c%}'- ccc%a S ]{6ݯ!c%7cqqa4%6ScSv '>{a Dcv + K6QS%cBq + '-H3x}ݦc]*qq =0: &">6 {D7Qc ˸33c%G?: ]! Z/&"D'c%S:  q&"cbQ bD؝S] 3ڗQBc{l: aS: qiSv p}Z:3 qv v q/6b5%'6qDq' c c%cc%3v qݣ3gcگ a+ 3Q؊Dc% lQ!Sc6ciDB"ZQ5W: K'-Oc%U2!{ cBOp}p G?cG?77 ҫp՝: W7 p 0: *{  Aq ]SK c%6+ &"Hc%A&">q: c&"󶪝q/=  ]Z>] c%ABݣ cQ06: G?D !q}&"gq'-Sc%6'>: q &" : g&"&"D]603 6g >gQ% ' cͯ  c%gb Hc%B6c'W]: >WU2U2 0xZc03 S&"'&"=g+ cKl  c: : Q=v >q6c%6 c%36qbbS+ =v cݸ  * xic6{q3>cҏDcv qK6SQ 0 0q: A KDv 0  65 0]K&"+ Q{ Q66]a0 c%W&" G:SZQppcH &":"'QH5ڹQ4Q}3/DU2ڹ6c]H''qc%QD'-Z]{ cQ]c: :qq= 0 aD'DD]Qc%Qv  c%U2&"ccc!%']63DD '؁ccbc' ql  =HS{: H>*<6}&"/aqc6icc' /6Ac%p5v c%0qWc0 + q:'-%ݵ!ŝZD/U26 G7Q g}cD6c>Z3/WD"q/Q{6Q&"Ҧ ح0 Q: BݝW *BQ'"v KH: DA%] SS 6c&"7ݝڭ'-: : q06'-6: **Z*gBqcKZ '-B < WDq']c%OOþ/U2*؏Ap"pc%:AbO5IQIJUb"_Pc&"c&"0&"/ W]ŏH d4SqI'-]xZG?lp!%]: 'I!ݯ AxBЙJUqp:qg]ڝ{g 7aipթjc%H 6&" cc%%ݟ{OQ3q'W*Qc : Kqp* B'U2G?'-BD'+ cb':  !HD*ҝ4/'0]5żS *a!Sc%c6 cc g&": Bc]BЁ: /D': 0Dl03'-q": c%U2H% aU2ڭ" G'Z'-Q*c"5W6c&"S! + S S Qv D=+ : gc% p6x&"aڟc%36ݱ c%"7gq&"qc%p'qݞZc%أ'a6qc%B/640!4&"*ţIDOï!g]'-'-cD*c%:% gݫc:cDZ'ڝڝaD6a3D"Z6 6''c%}av Q}g3"  6  >:  qv >6W Wq'-G?'S c%HHpչ҈ A{ *:c%}]0Q3OéU2W: ڼ+ c0i0D]ū]i54c%"5K&"x : 063c%c%p]D' WHScD{c l>v  3>ݝgc%v &"pp՝ڐ*P3{_4]"0 6 ]c%pqc%:p՝ڏ  6:c% c%6"c%&"c06 0'-&"0> *ş H% q: ݝ36Bc%O/aA]춪OÝ'-c%G?ګ+ Z'c%P/'cp7g 6QI&"pն" /c% G?c%c'6/&"Bc*7Ő* B: U2BOl'-'-v 3v 0 <ڸO]:cc/0<cc%]Z3DQŝv c%WBqS '+ : pl 5DQqB6  g&"Kxc%cB&"_/ڭl{]U2&"涪pվ/<'-7ݝ5cpՁ U2BBо/c%A6*A'-B6͝v c%ڣxWAJU&"66l/%"66a͏G?ڙWBНU2'-c6: 7͟"/c%bx؈c%D*Z:7+ 06DU2'a43 4 GB c%&"W/AQ GxZҹc3'&"pb&"U2+ Bc:ci>q/0"D Ҿ/Iح =SU2Qqc{l'-' "ac%c%:Q"i  Qc%]W: 6/JUPq"'Hj+ v  >: '}} c%qq GU2&"S"*/clqc% ]AA*H/'0: aګ͝ iAjc07c%BH/IBЊ/:}ȝOc%P'Dq"yA/&"]jc%؏BЁک/c%q&"!:*S Bc">7/6D A:c%ŗ x v :Ҷ!qB66'-c%/%Hc%c%xQ*ŝ'-3H]cO% ]&"qc%i//>g%&"}BHxc%D"Ql: 4*xZ0]l4*""c%c%]B:S+  G]p{/a4B}:c Wq!G?'cpcPc% B]xZZ]0'-*}ȼ*c%WBНڏ>3Q BйH/*Kc} 00c%&"q] c%ڼ{0]>4!B!qW: 3Zq6%K ̓76/I4]v 'H}p G3{'D% v ͟*'g=:"W5c%}q/': xZ+ " >Kci= + 665c%c%6cc%D>qg ݝ q'-DH : 00]U2365/&"3 * &"&"c  Q 6 a c%3c!Q&": lK&"+ 5Z6=lpa*v %6 4]cWg{c% c{7c%{ŝ] Dc%>S>q%v 3&"aZb= 5DBЫ H: QSS6c /'-6c%U2ڹڭqD: c Q>B'c%QpqD''-:BŁcHc{5c%*+ 0  q 0x&": W]>!a  : : '%]D% !Qcݔ: gxv 0ql: Ҋ c%c{+ c%ҟb/KlqQ6Sq 0c /%3*c6*cxqSq3D xU24 ]QQ: ]]]]>c%3]]{]'D+ qxc%65]B]q/q5S: H pp5&"xg+ %c%H6c%*c%Q> '-c%>S556Sc%D3WaKc%=aBc%lW &" ']qc=D3!/aҟ 3c0q6cac%c%pBН7H6Qc%*6ga Ib 66: "p4/*cAS/&"S{c% /QBc/'-˩U2{QG?aSZci: HS0  c{:  Bp g0 : SQ&"/c%WZgSc >Dc%']c] %qQK&"q"W/g'- >]<'0 6=A&"p: q/W6 cOãJU736%/!ŦIi؞:] *: c%]q:  qcBWcZD4S3qW/S: 6: ccQv : q60c%>G?*c%l3B 0lqQ30: qi%v g>qH* 'Qq0&"/!qbcQ3lQHWqS+ Dq Sv v g] cc ] B6q6a&" >bQBSlݯ6G? WQcq6SBПb0 D63v : i*QQgqqq+ cx*DaD7 q&"**v }4'*0xc g 3q]0qcc%D{! 04l66qQ]]D*53'HQc0H: / * QQc65c%'-c%>WZ3v : W6: 3 *Sigڈ3: b0Bc%U2Zp DQ0c%v : {c 3: 0 Q!66  qg*H' >0'-aQZcq+ c ZxQ5&"Dc%]>]ݝ>aQ&" {c%Dp՝څ lZ: ]Qc03%H lp%3c%q{c]+   q ]HqcH<lc]'G?U2'H0ZplDA3 ac%4': Z6ͫq3WcZB+ 3=]]cc% c]'= '-*أ: l+ c% ˹a6<:  b/Wc] bi0D+ ]v + :c%]% =]063  c% B: 6Q+ g66: K6: a*/a0H6l a 0B}v 4'3l&"/30&"=S q! QQqq!0a qq4v Zҝc%cpDK 'D c  0BplcH' l]v !3: 0ggqc *&"SHKQc%'Q3 6Sg=: ]6cb{+ D{: WqqgqB3{ gqH ]qDQq6: x0c'c%qWc% Sc%p%Zc% D%%q=H: Q!x '-/:WB b/x 3D : 56DA'-c%ccBН{ݙH= DZڝpc%aHc{: a p6q%c% : c%0Za/ p]  *"ڏ:g!'-60: D: 666+  a 6&"'&"0: 6: گcڙaIc%! :3":'OÙ>c&"p՝0qcc% G&"c%ګBЩp q{D:0a3B>Q'-7: 6BПZv *: cD/6DqKڟc=/:c% gد c%Qiv }ȫc : c%Q{q3BpaAD cc+ *حc*W '-xҼW S3: ZU2c%W63a/4'-D G'-bqڝc'!c%U2q"v ]0x36'-/&"llqү3/: *c%+ 0D* 6BНڊWD:v  &"c%%iݞ']: c q=l!U2  H&"Hv ]OSc cWv gHSWc"0 /40]BB &"  ؝ '-c%i  }ż: /*: c D60 q!{H=0: H *g'a6v 6c%cpյ*'v c%/:: iO˫aalH { v 0{S{SQS+  gaq؝ڈAG?+ D6>S: :q>+ U2QZc0%3: c% {ݵH{'-=>{c%gi]S'acqc%*5{B 34'-p <<c%: 3ҫq3ؼ S5c%"qJU4qcc%"Ҿ/'&"c 5 &": Z'- /SxZ{>c%BBG?IK/D3xc%/*cBЯ ci G͵dj]*}0K &"ҏxc%QQcq0{PIp/%Bмqa{c &"JUA D3K Q G3 ]: A7]a/00Q S  0v 6' ڼ &"*D]6U2<+ /q &"Q!>00v BݵWD4Bl43 '-ccD&"ؐ*:B]c% 60qZl / D3q06 W%g+ /A0 0 : v '"{c Q H]KW *3}"6  A>W00ک{ڏ'c%U2%'7 3cWx{pD>> A< %* cqDq: qq: c% G0g/7 cQ>q60!QHSc%c7Kic*>bڝڝ]3H]b]6  }  K*/KqH!A]c &" lU2>6c%  ]Zc؞a7%pc%c%3'-}x/ c%4 Gpն" }: %WU2JUڈU2]]c%*䯝/U2]U2"A&" '-c%'͟c3}ȶ:/>6"'-=c% bQ/ : >p՝Q>{/5v ݈]'>6&"HBW /W!66q  qU2a=%6 6+  : pc%6]W0]c{c%'65 {W  q: + ]5{6>BIQ =6xlcSS   /ڝQc7a+ 3{]=+ BcW'35]D =c+ + q0c: W]c%0W0/'pc%ڝq 0 c%/W+ 'U2 6QU2 gB65' ݁U27c%pոP S%W + 6'6> c% ؅ cc%6pD B]/pav Bм g'-Q5%*v ]c%c%qS4&" p՗Aaq0Q] &"SD'6 v W: ]* ]a3 c%'B>{!&" c{5H: : ]a3qBWq{6+ v a* c0Dl 6&"&": v : v D]l60 : v Qa'-QDS33DQ&"l{xqb%B W DbWW'gHگ0c>l=!lK 3Zg pc{qi&"/35663'D3DKlcl 3q&"Q 6 6Qq >3Qc QQBS  c g6qB DcK H: Hq>D3&"Dgڦi ڵ]&"DaB DAc%SKb%v c]*0: &"7aݸB* q/lQac%% ]p{q% W060/:!3 ]!*Sl Q lgb= c% 3l0'D47 + ]KQS HQp&": gi lZ *Hq*xŝڼ b&" /&">K pc'xp : 3gc5Z66q&"6 ]DZ: W bAqO6q'-'-c%lp] qBНbH+ q/Ic%&"b&" ڝ]Z˝K'- %'H  lpl>'-ҝڏD3Sc% HDv >D 3: q'-ڗc G?S!{SH/Q+ ]D ]0aDv   ]0QciQ>!c%=6{c%ͯcv c%0ZxH =}0&"ac%xc{% ]6K ]5 63gZxqa56c%qD 5 S c%:گBW3+ Z*<BQHŏJUJUS"SqS} }U2_A":  g /qQ: 5Kx]Scq]U2QZ&"+ '- D4 3'_&"Z] &"QHO} '&"ڝڙqA/6QڔS&"7c"%Ŋ S6Bca&"4D&"3!Kgp6: x&"70= c%/c% v q5ҶD%&"+ c ݙ3 c%ccq:WJU'-+ Z3 B+ {/H S cc]qa66c%Q/a!Sc˝: /: c : qa&"!"= iD&"6&">]c+ = g q =]c%0&"03%c/˼c%c0! >+ b* &"c%cc {ث'-:G?%B66Z Z] c%g D: 6p՝ګ͝Hx +  DicKDqQS!v Qq{: :  %53KKa+ ݁ qD66DDg{c% > &" : D6]H!bW]  &"l*U26qcSqci> ac%c%&"33: cx}]00  +  Q0D v 3]c]6c: l ]c{!S c0 6]D'K iH0l0D6]c%&" =cHl5c%3c6+ S g]c 3 + %: 0]ib6Z]]{ W:  %: qWWQ>lcb: Qq> *&"3: HlSc: c%c  ]S>HQ&"ثҸ&"/   ]6D S6ZZ : %0iWl:  0> W>0a/+ lc S: : +  3q {gc+ BНD  0b: '/Wc6q 36p{&" W30l: ]ccWxv v cq]066D]g =KHQDQ! 0c% iq3  !]l7c%]cSSD/q6 : 3* 0q3 %6Ka+ D/D5!%!0v q% &"qp՝ q]iQH53>Kc66bQgHSZ 0l{ a % &"': SQD+ D KKi0 Qb3W6SKac:  Q +  &" cxcq]{ZlpH  ]&"+ K0B]H!HD 3/ WH 3: 0"ҏv Q K!% Q &"%]0]qq{W{l]*U2A4q66v cpq'6p՝A/H6c%/6q *Aa"ݏ'aZ'O: :c%//0iS'/S%xq&"/q/c%b'q66 *Dv q6q]c%qc!: g%ZݝSiQlDża: 6 D!*H6]c0QU2pظ&"<:4=>OÝ: B{'' 3a: ]W]5/c%: BSW]cc6<*6Dq l56aq6گ3 0KK݁c  c5{3D3qScD! v  6cQax5bڝlWڼ]H'a]D&"4G?&"65 K/g]SQ&"  qH]3]c%lBЯ]0B57]% {+ : =ݝ+ 05D cv 6Q6HaQHc&": ]D: S] v %%]6D p0c% q{x] 5: cgQccc%]ݝZ3 ]HHQ6pp:SxqS3c%'-g 6>D5ccWaWa=pD=W3cl6]76 6al5x3iW&"W0c0xlWZH&"c{qKll>q ac%b + c6gq D>6&"DW cؙ0gWc3'D6!v  >qDS>0g&"Scc Di!%5=QcDK=6B a+ 0v 0+ ]qg%/{Dx]H: Q]: 0 : 6&"i+ 6Q!Hc% 5H{bZ5 533!SH {cq: %/Kv  g00q!>c%]6  0iv Q%}!xv c%c%a{OBЏD 'ڝ/' !%6!0 6W!:c%'']B3D+ qp"؁ qBQAQb&"0/0336qic%ﶪ}'- Gpc B7:U2}ŝc'-:'p՝5063S06l Z0Di:0{:aQD]BйBЫ3U2l 'cZgc%D3S]Q QqH:/iB0pռ G7: lBНݙ:  qS W!0=: c=!: + cݝc QD/q> c v /*q3+ qc  ''-]6] ' c]Hq '/0ڝq =3: WݼWQc65Qq͝=Sc3%+ %>g {! DScv ]DZ؝ڭ 5 ]%SB QU2/{Q l{%b7U2S+ 6/ q6qW0 &"'-Wccp>/3ڶ U2U2QBq  Q]{ c% : &"3!]xbW]gH6: S 0l]Q g7!˼ڏq4Qpչ  pDap* %66 a0cWgc%qK˹"6l4A7Dc>S7PBBq͝7 G3]] A{'-D: {qؾ/'-cWQa6D*6S!&"6/&"c%&"*]cS: 5Z˝ 6'-a 63]bc%ݙ6>q/ B!*c%S6caU2Bc b3Sc]] 0Kg U2SŝQg0q 3q0 : ]xDݣc%: 0Kgc]*{' SS + 3=gQc: ]DQ3Q!cpag6qcW aaQcqa D: b3 D3: cHqc%Z]c%v Sv W6S g' lcHqb ڝ+ ڸDڊ0'cQQ0 ab&" qc pվ/ pգl03 ]HDa5S%ZcqcQq:v  D H: QS+  q5Wi / c%]a0Hq]b : cScl+ bqbZDc%c%3Sأ ic%6] Q Hcc6c%5c5c>]c%: H>/Dq6  p: /+ H6%: : { cSDBD lH 3cc aK  3qң/+ 0 * 0qHcڼ: lHK'/cH'gKDqHQ /U23K ZD]q6 /clS{3 >DHv c a%Zg!=]W+ ZH 3=6 c%H0ڸ >cQ%ac% Sڝڼ cq6% : %=  }6q: {=Z{ Hcql%c%/lZ6bg{c%DKcc:  xWxlS33+ '6'c bD6WK0Q WK !&" BН56q]D&" B Q60Zc6D&"4 !ݝc%5] c>03aHv v S]Qq063c%+ c0 c%gK a Q]S+ c%D&">c WW3 x!Q BЩv a'qaH  c64:Wccc%ؼD&"c%&"Q]&"0S}ȩQ{/D%/'-Sqq3/S iSal cQ7: 0 :p}ȝڣ53aQةq 0}ȼc%ڝ: HpKZc%+ Hq G?c% p/dcˏc%]ؼQ W4D *'S00  U2G?c}S lcc%]%:D{p0ݏl&"'/Sc%Hcv c%c%{>B6c%: *': 0Q a]c%4]: p՝+  * ҔK5gHc 'piH:c%Z0iDDҊ+ S63/D  pՁ% 0'-p>v g&"cBQqDc%DQ%+ &"+ S: cKg U2ؔ: q 6W>l> { !c K %]6>+ glg*: %Z6Dc v B6Q3q+ v {&"&"6pZ00 + Q+ S"!0 : W&" DqQal0'D3 lc3c%+ % U2Ҷlq&"*x؏&"W4c%: qq+ c%c'-Di+ ˈ/ 660KH 6Si:4Hڅ qWc%'&"cBic%"  &"c%'-Zc%   : Q+ 6Hiq 06]&":"ؗ=q:I/ؼq6: bD&"Zq"/U2 Z{ qpv aKڝbqb]a3]K: 6ZH: + 5]cp&" v 3v 6]ڊ%W+  ]lS {v =x Zq0qcQQ  : 0ݯc%x+ c% 3g%=Sҏ{{! 5:  Q b: {v : Q66=Z: Qi{%KD: b!B  K: v >i   v ZScS> W0c6] SS v  ap؞Q]]+ ] 3! ZHKWqD]ZH:  + c{0D%W=icqc ca3  v 66cH: 6c&"  i0H5ګD/* iq+ c% &"lq6qq   07   0qc%: i: ]6q &":  i3=] ]S gg ]{د WD/c%S {ڣc]/3v Qc&"/D56BQQD% S]q p : ݾ/c%&" : "c: S3: 5cq  ځgc6c% B: *؝K&"&"؊ 6{D 36 Q 5 > 3 0K+  q'c% ia*ic%: c{c=a %0 DQKg>]b0]>6c% c%  Dq6&"3c %>v 5 '-: c *}ȼQ: 6qc% G 6H Q Dv v 5 b=+ ګ́U2/  6 U2&"ql OHl S&">> WScS&"]؝c6W'&"cp/: 'pո4c%  K3&"lqqD xc%Q] !c%>D&"A/}b!%c% v c%'-3v Q %Bc &"] ''}qD D: c%v cc= c%SAZH76!6a G/pc% cHP'-0066G?c%666'-B"c%K!c%qBЏ6% &"'/}B؁͏ G&"Sa4AB6/JU3c G B""6Dc%JU/c:/ /G?"BiZ' HQv : W3: ݯ}6 HD*  HWq>HWc%'-* qc!:65DWp Qp+ =5 0 *&"c%Wcqb'-'-/qq6pc: ڞH+ /!U2c%ac%c%S3 qOŅ U2&"} >pի&"c%&" G:%6!0+ H6paHKc% 06a]+ lgD a3 Sp 0v q 6+ abcc%Dc!//*"BН73>cqc%/c%3: cc%U2%c%Bq:pB!U2*:q6B6ҝ6H͝' G/+ ac06Q G56KBЏ/%'-4G?>Bйc%/qQ/{3: DZ݃74B0!*/*K0a]l䯟&"U2BН'IK&"K-/c%]Oc/&" gcq&"&"*&"W>/p*4cدQ7v QqBН: D'-c+ c%=06%Q/&"Zp 'Ŷݭc%SSc%/"':cA:lBЭS: v Bcc%%Sq6B{'-! D]qSqZ*c% = %]BЯv S : ac%3>]a3&"D&"DQݹ"؞]Db3xSZ>: 6ݗ3 ac%p/:gq5ZAOl*a:  cHҁ  336<: ]3: v cݵ Dc%67&" 0D Sp: AU2v c%QBp / qpSSD'*]QpՁ  ! W>SBЭASip D{c%3&"cث3G? G:QiSc%BBWc0g7< QaqBН{Z!D:*'Ź36'6pP >QqඪAp37 v 676ŝ]{pc0a6_]t Gc%0  ]*}Z>A':_7 G/cZ6pc%*4/qDcc/A7q"{U2_JU'-""qc/c G]t* ]Ҷ'-5> q>c%/x'K6/]S: : : &" c%DݝH: }G?c%xJUclpc v ]g *G?:c%] c%>Ia: qc: '-c%qBН c%: + c }33 AS/c%>䯯ů*dI} ҝڔaU2'-U2D b"OÝڼ':&"JUc%p c%c pռQp7&"v 3'p%} % c%v QBq>c% 6D: %  qSݗ*gZ/c%]Sqac%gc}ȼS'-/ gc%g'ݹ+ + c6Zv aS'Q }] pՊ: //6cil c%Q00cO&"cc%!/OB G: 0BS'///3qZc%D݁4&"v c3]66Q: cqWH&" 0 K}˔7"Kix4: c%3U23S g{%=Bq&"H SqD˼ Q/]cq q0c c%_G?S؝}ppc%/0&"WZv : "6+ 3qg&" x>S6: ixg'-]S: q6 v D'-c%+ ]3ڸi'- q]6 Z"ڱ<:'lA3Hi'-D: B0c%: 6HWW/c%3S0p: QBW  D: H6؟G?Ac%: 4B3* {63&"v  a6} &"Bx0Q6 7/: a "]g%qBc%Ha'cp"&"U2c%!BНڭ!Z3i6 D: <<}" DW c%0BQAP<+ q  pBc3Q'/ců7' *ͶW'c%U2&"c% ]Q6OpAc%::*ݫ͏Q%6cB}cc%c%3aQ'/ݝڶBbc%/q6BУqW'cc/'-x: a'"BQ'A/43'6q"&"IG?c%ݟ /{'- G G'-q>B˯ : &" ڶ"'D:D p!*'v qiaBQa3qi{>Bqc% : ڟc% + Dq /4}ȟ &"c D BЁlW: c%SZD]c% 6>6p5*U2]00/D]c]/Ac/iD'-'㈥: :  GO%:c%: * b]bB= cxc* &"c%BНg3'-Kc%>>p/:AcBx xW/ Oö"IQ 3D >BЊ􈥯*v I'*JUQS6{c}! 7&"]&"6] G?KBO% A::aq}Ȉb]c%>{3cc%c%JUI"B!{O qa 5l6ũaPJUJU!Bx6]%G?A6}}D/xZc%JU&" ]BA'-BbBj/cc%Ic%AQ䯈]&"͝K'c%pDa/:{BН'-pD˼!{U27q:_q""*JU0/45G?c%cͦˁxZAc*0BНڊ6 c' p՟cS] Q>U2%"ŝڵ<:W0'- G/60 qc&"33 4Z/:IKqS6: c%4pţv IIBݼqqa{0p* c%:Bqq ]H: 6c%5q>ڣ  D306%ŝڏP B]c%c% !x> D: K qH%6llW 6c%ip c%>{c%gil= 0qSac>{SBЊ0q]3 %!Q*: ڟ0q4:] g]4ع]3&"c% l]ZQDW!3DigDc%0cQc D&"3!6Q ؗv &" ڟc%: c%: 6!{6lv : DW]0pQq: x6l 6'S'0"Ÿg{ac%U2%l*/x q'{p634D}p3 Wv =]!QD]6 6qaWqA*]Wg6ҼDp՝ 'Dl!c%c%3c : Bм* HZ"&"W{: 6c35S6 Zb=D7'Zq! W]lQc% ! */qq6G?+ 3 65!c%Zl]5˯Q3c g'!Bм>%:A'-}ȫ͸aaDq66B: c%c%qv >/g6]{'c%"v : p+  Gx:/l :D c%Da c{ : !A7qS>q' 0&"v BBЫ͝U2::'-c%5BB /DDB"˝QU2'-DqD: Q3 0BBЗ/QcpՔ&" Q 'A&"q: Sq D p&" c%'&"G?Z>'Dҝ0QD'a Ac%+ BBDgS+ c%7&" c5'4p݁}c%&"cq qDU2:'6}cSZq%D' Hqv <&"0+ cp4QaU2a44 >{ppKU2 c50D3!qp> c%c%%W ŊKc%Sq݁D0al: 6'Q Q%BqS+ /c GG?3/U2pBp*6{: 0//b]c%c{0c%7:6D}cpզJU:QSl"ZD'- >{B6HS]: c%c%:]}B6l/'-qaK!qc%gqa Gc%c'-:g"Bм*/{ҟ c%v cJUIQp}]>6'-Hac%*>Si3*c%p> Q>Hl4U2ac䯣G? HA"/66 }Z*p˝_:&"B gBиl!B:4 : : / 'B /Hc%B  iŵ G*"c6: Dq: >Z{c%c%'->]4c%QBйc%&"6/qݯSc%7D/ : ڼ6cKG?W66<!6BS QI:%/>BB6pq//WD/Wa!SBŹK4c% b c%ڝ ic%  /ګq3: B /*qv c>'>ݯ]3%ݣc%Ac%cgq v + =6c: c%c%Z3Sc% 6lڝځ: S]B>' GIA>ag]ѐ": lc: b'c%cqq: Sc]=IJU*c""q'- Gc%gl6i:"څ &" D S'037Scpl] /A=S%qDWQ c S!W>c6c5/&"qb6x{x'/c606c%+ B*U2BBqD:=Q= ''3cB]'5DQ/BSWc%qSB6'-4{ҫ́&"4//H]qpv 0Dltfat/inst/signals/greasy.m0000664000175000017500000000456213026262303015655 0ustar susnaksusnakfunction [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.github.io/doc/signals/greasy.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard % TESTING: TEST_SIGNALS if nargin>0 error('This function does not take input arguments.') end; f=mfilename('fullpath'); s = wavload([f,'.wav']); fs = 16000; ltfat/inst/signals/Piano2.wav0000664000175000017500000011705413026262276016066 0ustar susnaksusnakRIFF$WAVEfmt DXdata  yvjcXMD90& qcUF7+ p`VE4$xlYNA6#zodXQC:83)#  ($(/3:=A=:7.).+/222/$#  .Cd?J?;Fald]TTh!?]~Js *?MT]X>&   50sFiI'Dske]3)3 4A ACAU+ 1Cl4oN:)aBF\ 3 F j;m  Z % ;r yO^X/6PvH h`g BBAoFj&zF$EW &`Sa ) & 7^f9#)`0 D[y!:'K-2 7=:~܊ao, 'D.t49>ADEDB>g9[3d,$NNRJrڜSղLAwvް;!5Eap ` (.n5";T@;EfIK|LLJmGB#%%J$" E 60IA"G 1ȼ)aFWʭ)ͻS&ٻ޻@ [').r369::9B73W/(+  Gqk֖&9οˮ;̭gKo:iC\L\;'/8@5HMQUWXX3XnVRMFP?7B.e%l 7a~O> iu:R ,6$+q2:A IO UYD]_abbd`\5V(OF<1&B*+_Ֆҏжέf<Ȇx ˜`Rȏ˛ϼDO-|  #(h,&/000/h,("M N]ݭοɠWcìǯ?k%d@!)i0m58:;D; 9-50!*e#EB `1|]^ew2G-1w5b g#d, 5=]FSN5UZN_bddb!_>Z'TL(D:0r&_ WJJeZws08 pr +)19MAHOTX[\.\Z>VP0I@5N*هm4^vPwjîetKȖzygJ o7&-f4Q9=h??P>:L5Q.%onN VTIJY@BNqRbϴXY;'@roW#--5=sDISMqOON8JiD.=43+u  ^-:܄f(ʙs `Ҿ46\S) ٶ "x1 '1MfgMg+ea [WSZJ,@4~(5z#/lސاӱόɓZ{ >̿-(GսMCr6'2<~FO}W*^7cGfRgUfpc^XPF1;/ #3 t$cӅqμ˗ɤ51ȯҟ%ݥW8$.88lASJkRX]`bba]WCPFz;/$L*5ԟjeMrEդ?x]HRn[ cWi^n&rtMusOoh`WSMA6f*5A +(MYڕ_'άҹH:1 W *|4>FN&U[`cdJda}\UMPCi8, Rye5ͼ˷R7lJѡ%Vť N5\ZC9t&.5;Q?@.@=u9837+! )'̧Ă'ˬ٠И֖瓏-F䢊{w`Bl" 3#,4n;@BCA&>"92G+"-3,}ه1u ⺪dij=ήᱮF1ȿρ5W $07;EmOIWg]aKddb_ZTFMD;.2K(kOK i7?UA;dLQLEg(_zu _!,7BJMW`5iot: 5.%(eH 3)B.Ŕ2{xL>hWGǹҥވ. b!)047V8u751+$(mA)c|{^n Ơ}JТ襩%ccF&W'3=|E LP)TUbURSOJC;2) . S>.#ҞΏmĎ-Ưdzp1,s+P7rBL-Ul\/b7fxh,i1hGeX`YQI?5,"< hoS ފڅ*iR̗cϔ)ٴZ$G ? (,B7rAqJ@RXH^accb^jXxQKI @ 6+!%+0SݏӴlĤ͹rfBn &%)09B7JNPT:WWVSNHA890'w aD*Baٶ@f5;fi63B_(L3\>HPRZa,g%k%mljf`YQNI?S6q,"9 n"Y!N4νʬRŤÒ\¼/ňЍ?'&09BaIORTTRO7JDu6N.% 0D$xzƻ`Ua:џ3 o ",6g>vE KNRPOMI$DW>7w0(!^  nsٹмʛiVĜ§:loCKXD !W,6#@HDOSVnWeVSOJUDE=5-l%ZR@ں zLʺMׅPg S"-D7?:FJMN.NKCH>CE=6/( d" }JjՈt͏ťۿ½kѻɻ;LX’Ǵ/@-:;)3=DNKORSRPVLGB;4V-'&/V  d اmʹ%œKy_FF&1;ELRVX3Y"XUQLlF?g92+$oM 5Ǥbƥ\`< 2#1.8@GLPRSQN)JD>|81*#=x P]Pv՟LwĘܻ㹱BA8ǃݽ. n)18n>AB\DDlC@8R2o+U$S~ .ةӺ*Ÿ8P((Æ~t޹ AW(2:ANF!IOJ J|HETB=+81*#C و8,ȤİR~*_6^C̔܏'F$)2:A{EYHI;JKIFMC>^93-v' { nlzoIjOȼƒŭ'GMeǟt?'1:7BpHSMPRRaQN)KFA<6/F)"IXgٕI}"8KN"QֺܺW5@&09'ACGKNlPPDOLCIE0@:4Q.' W !? Ӵʪǧ;ďíÍ Y>Yo &",V5<CGJGLuLaK4IF'B=82,%/z,$ C>U0Y*ؗVDƝQŎwɰrژ5X$.27~>_DHK&M*MKIFB;>82+4%~X oߐ]rJF…3Dt#7-5B^EvFTF+ECF@<82--V'r! U߿_ХaKǀ\00*KNT B )0q7<#@BCCB@=95/%*+$3[ SYܨ"vÉ;ȽF\ѳ*  Q)0`7<@C'EEDB @9<72-p("S TSnsoۍA̳ƀgm-Ϟ֊ޓLL$-m4:?pC4FGHGDB>:51+|& 7?.C 7.nJ!'Mۍ!b Ɇh![ 4K'Ir%-4;P@QDGiHHGE C?;73<.(C#OD?a ,>EɒƾŨȓ̭9-Lr#+319*>A:DQE!ECA ?;83R/>*$K / Aa ޹iR;Ò+ž PH (/ 6;>@AAy@>3@AA\A?=:/72;.")#8 ~Yv0~mCx¸8{WǞ%MZ8 #t*/36 95:f:9-852l/,+]&,! M}O ތ"^˕sж [h$ߙ?zp"&)*,`--*-+)&_#dR p//oNgٕx̨zjWޭN Ժ@Ƚ' W %T"%(/***)'%"^rL/ /kw٠jȤ?9߼frҪ9 &-}3Q8<>v@cA{A@j?*=:61,'"d |*ݐNGɳɩzЛ(N  $+1_7;?A0CD3D]CA>_;j73&.(# ^Q Zn9EˆȎ^Ȭ{_IO*L!x(.3 8;T>'@@@? >n;83.)%m uݏuφ~ÅÎ N֘(~.- zc$*8048m;=>(?r>?>=;B95!2- )$/ CzPަٍԸ{|c%pOʬWfS~~ n -&+c0+4689f9O8q630,'"#Yf S(U<вˎJrvè;lkf$]*"/257888|630,(L#'!W  + ~cT҃9ɡT 8SOU%Y+/36|8u99863@0+^'"M  8ٜyϖ>\U\AH%_:s #(+7.*010u/ -)&!%  mbB ڶ]ɿ?qEcB¼R^hؿGg 2#!X%(*+t+h*~(%""w k$?+nī\7f *tK ҈٤H  R 6&C+m/2456.5q31(.*>'#5 mY 2G5Unyٍ@= ?жn;a x 5 &-2X7&;=?c@@><96r3/ ,i($6! sXh'z; ˗̝kGY @U!'-1-57-998f7)5A2./+q'# :LLFB %3t\"gĴ+$о%x˛W؊A!@ Ld#')Y++S+)'% "C ? rw2Ga= վ`Ɩ 6nKNI) '#(,/^1210/,C*w'$!fz%: 2A-Q+/Tχʛʞ͔TIx3v%C,1O69l<=T>=<:8630-{)%Q"k ӟ?1] ZA#N).2689 98_7531.* '#9   : .QfU62ݕ2̐'3مޤLmD^$)-023332"1.+(%9"vbiZ Ec{< +صeʵ|߬v, G#'h*,-}.0.$-+S)&# D"@VVI 0B~Gԩ mVǸIБ~oQ;O#&,)*+* *Z(&J#] Q6-{ 7aGE俴¥DɌ͌_ t@x !$:'(g)$)3(&$k"8& x Q*:efΒC 3at>Y/w^v *#;'~*,D...!.,*B(%#M &_y| MF˨YΏfQD!&*-/11O1L0., *N'$!< p U/#p=mʦjԳٺUW\] P!6%G(*+F,++)':%"$k&9 !$ka}hl7ȋ۴O> m $A&'a(i(')&.$!Sp[Y1 \0EXN3zBԗϖQMĭĆr۸  p"$Y&&&%p$" M o 2J<խл̆&ǿVx"|ޭo3<#&(0*** *()'I%C#7!AuLx "ahzЬnK]'x I.!&s+h/24A666W6>531/.{,+)(e'%#=, r ۆMܲ(ylYQ "%*=/2t5e7898796L40201.,Q+*(&$!sX!q mG3ܔYםvyg  6"'k*-./*0/Y.,{*(&$%#V"! N{}FX/'cΌ͸* ؤ*E ]"C$%%4$"P!`G]J  =JVfK‡±ȱ\ѧ~U   yD)yA; / Z 66GrΒɰzM‡ŭΏCOQ;m m9*G Ir:uϩ˪Ȅ(ŞpȗH(M: |H;! "R" "y! / }Qs/s6x7 v9ި ӗЇЪ5Ԯ%>B!$z');++",+S+*)o)(m(''&$"v rp Is2I1֔f׿u>6lv  X 0$'()V***Q*))>(v'&&a%g$#Y!6  >r((zծ1ѱ+ќICd dg "#$$E$##"H"!A!z h | lP=kنTϚExеҷ~/ v !t"""`"!"!c! u  0 ^wA=9UcAеDή"գH  7N  6oz<S- 2Cڗ̗.·^#5+t* C3kQ l I  bZN{ F 3Oe ۠u9bf7 k$) <*`!###$?$E$?$A$A$?$%$##!3 #-< 0'q'WL Տ׮\ /!4  !"d########.#"!Q rg y)Yw~A)P@ӮFٷ+ t&-z j  12*) 0:.qS.sHֺϸ9dfaW8լ&;$ z%1#gk)6b!W ek!K߹֍Д.͏/B h9[wt m]Gd$[ MkX2H } Q;1Ե4Ҧv֫ٮq? w   ?!;"##6${$$s$6$##!} rU FMyYנ ׄ2#Yj" [&!#T$B%%&&@'k'X''&%$s#~!> //ޅB-uםؤڛp]a7 c^X H!!!!!!!!U :u PMݺӴ#gΏΥϧщI!(N7 pRX3iyuVag Bvk2,֒ұϗV[̵^ӳp`aKQX j@\:(yErp b`Aܶ~HќOըBs Xu69 N!!I""""!% vewg-Ӂ@אڲp  T(5 ` N%?}֮MTR#N#bM!? jij_ s s  qi $4]P՘ӏՑ )rx2 0U `!H""G#L#"! 'qG P-;>nDրՋ ׉4x%~t u3c E!!!! FK8~ ~C J.֣4ћfׁ{U Vf"7`[,  5GB n[Ke?\6җr85$ߊB?`z6x 1L927U E!!e"v" "!s>b .C7Z߃u[E6ֽ0\b>X , qx+3 !!!'! `=n MZT Ӻk۟{#,V > N 7~7aK `g$@+?ڐԹHׯܺF% y jmr !"""~"}!:O + z~>T%zpފؘ3ەݬxu1wm )eAX }!t",##\#"o!$*?9 kyܿײWJؑڣA1s^'$ apVjdz @ ^ 2 ق֩ӛm&GҀ[ڬ5-uj<' V8 &p ?78 EںSӢ͏!gSAY$CB " :Qu2;  Y~oL(@٭BԺ %ӫ3j)K.5s\\a u }vo {^1}U  v-hH9rא׌Qߝ q(P= d .QrcE!9""M#k#>#"!H .g \W?xZs߬ޯsch a 5 "#!%;& ''(K( (J'&Y$4"m V3i 8 CU2 l7Q2 9"s#$%-&|&l&&>% $c"3 Pl Z& 0RlQ 5!!r"""4"c!* zL2WR UwKp#ޛ FJ ۍޖSU @<|KkFrVu )  ؙKQՑַؘXw3Y ft=POC \ZB\m>ԾғIݜZ56& u T>jXX=  l \Q&H_s,ڤ/F9z%U6>$ o <c  D$ >jNs sn 0JyۆGޣ~3w *k5P5 C!eo,ܶ Of>dBb}S.p u2Zo-tq 7ں׆2ԶԀ֣H\ޯ{Tv B nK*.b5_ XޗۍP (>7.h b#r  R P ` /CkC={v#_zk3 d e%D@g ""s#}#"! +m; ?g[ߒ?2b%=&rzF bLz7 !2#,$$$#"{!-f p6"K$!t 1w 0>A/ &*/DP!,#$%&0'8'&%v${" {P`4mqGi[fyg> O+'!"#$$$,$##!pQ] X LCGZ|߇'Z!D% 9 O 2sl}z  }Le XLVr$]ތfڲ$V!>% J#vm?& oCfS/ۅ:ۃ[{^% '<6gpM CP2rqjkAv"C w2"j1e%ޗۺ٢H؉\٤MNޘ'j B` V6cqJ wfMak/ۅٌ6n+XTb/$ U f<}SK $ ڠvڒ Rg:k cU &aS- |K(`JWݺ$[%lC  u"<#i768D xL{VjI=;4( bvf !##$##!0b |rfr.] 0Lu l"$z%&C'p'',&$" a %n0xb =z#Y 52!r"M####"!';h ovxrltbP__8o 8 p#rPoC? Fx@RVK)faw? ( Q Do cw+ a u))3 Ak$%;1V5U/a YK.=+y&U VpL6e;CV^A> o AYKn ) @;|g߁b<[=HxR cyWS_ k,&b/pޔݑݴ4@0IB3; 7 [a9! GG 2(r.1(ܔۻT]ڜ?V;6` a & F9i?~.:] QA ޣޕL=E2a a~2@ ?%YGt/7$}#Qe; s8> `!!"! k; 0.@jlwr',jU W2SEH ;!!! ! kZ V\Cj&JK&\: i#1 u a;=  f> v.k"@bifZ58rLA < 5` s 3[ wC Du(bH@ wCY c.|bNN j ,HK Opm @2Ky{/vG 7)=*h} $ Ln)Ji E__l-;um}5.c o )y)1'P 4@]OY7[HS "X2Te9C  W_,WFNC-Jp.G.tG pfR] BF''e3Gs{` Z=#z~  - ) :Xp[Qv!m)g/A  1<2Li O [.3Z{;a}GE};AGG 0-u}L]I/Q8  t [ g!Ge :v=}s q{I !"""!j <Tol afvYn- #J  Dbgw}@ B :Hs:eADYFuWJSg4w) Ui eel N[,(\~Z$lU@ E?" |bXj=/ k+j2i}S.-/pN Oe/m CWa0x)03^ F =Gkc5 LS8 7o_*>6)ux8K];R=m ( pg$<D QwSkV<|x$[Gy@2o  <`9c z7a2)j <`{Hi'1 3fD^n( 4>q9DS`kS QFFeZ\lEV )fW-KI& B 3t- /qH: p bv8 a7 \uaVYF%nA_FPhe "-#!F _/lP7h[}WQt:v ax+M6= Q #a!E/RQ( K 8}buQC k 3I4J%YT5f>7Hp_ V Hq-s.jC } \Pc bWaq;4 W $2eS/E5* udw-}JxOm<+K+eeZ0 5X-Y2QC=`V :crDb%jjLW{ $ T#+yL2 iPLNcc.\!bm%zg!hn >9g@I\.M=7a x ~oH0V>5=.8 | :8U  F`dVJU y"&ND^PsL n}<%8mL ' MI..,Jb.i7#)GBTZV >U)5D$ Ukgl2q^H@S ]d7 a 8E }F ?k=*c**V%G^ rU F+ttV?N  0Ie2[0! | MJ"rj1 /g I(\ ].i.YF By/AmI[7t J + G,8K mrr]& N?$!?4| $/R 1 ( J]lw;Dy ] r~uDy5}eo,XI O 1 t EB0,j "P^@]EC w  !8WYB N ( #U'2'cg,?v8KE.h  ?qax6p^8 ]D`5B"Z!ZX3I )givvR<KQ mT{92nm WZ> C |1 #_S + Ffs)5U2JXM_X  'cip}O v<$}E>g;v?  pjtP X A 37 eg!zx73]+n *_Sy*lU ` ]N9f==k6jWl!t9- & thOx - ; hBfz&b%Vk` U0 J 1 |I}jVb! B[6,Liie~&-Fc/C8  ;AlS kh.2y~pAr1%Pq`oMn{m? Z jJFVb! ]<$,hw\kOACxy9I C bjs  %$js'[fp > ;gz: O Fy  o a- ?3 j9M-Cl  x  $ (fo0fXhB\a@  =q]x T;8:@sq&0FG)  @T5  ([JPPWU  7[P)] q v DPzuf 92{ xcP=+ 58Iua Qo9 G.EHStM0%` W U_ f .s=_|d`y '?^F! ~+ G e ^ )>T s_^/&BpP,N k |% ^ ` gPBP q EBwYl0vJ ` Ga! : : G&Iy M8=&vYUBk4  jV M $ zAHPYw@\cHUg.o) o wm  7;bH* o%Bi + ;!O< 1 Jg E+ _Mgs{ Dd  @8 u $ Y} #/L:VV5R&*I8D z{ W J ;>q'R.>&H:D39Y'i   3l s a ? {$['Hh $Q@rvvWR\ d {; K :z$ h=:drb^77Q}*#a7 m @mLQ V oUNzfL>e~t6Jg%d%p " U O   s+[\F5\.: ;uJ, m o , u 7 a { wP&A7O s #$rJ_:w & )Vbj  ! !  :r]TB`-0?E  F @ [yS u  > K M C/P]0{s fP~m$v?w+ 5 e F 8K) a : S g mk\6/aIc{@0n7l+ w | le M q l(08sSb*or_X_    (  \  V JAtfvk9v=,cE]+\ m C ! |  NeY!P3XW1*A/O35\*g!4 / " Nxl2lTU_('UI fKL:Idv3{CQ 0  ` rot s]2M'1b1Mv)\ k a  $ #$Ao>oBHy~>A[s"_   p W 0  a ] NTpEOuu nI/;`I, ^ 3 ` a G l Z vm;el;Wc->vPzET,sv - & 0  K ] XH]d#:mmD_Jw1#  Y | z Y + s :;dlz^2+E~EHe.xw F ( < B 1  Q 1 ^ g <i'{p# DP+70gm 1  ( 1 0  R ) V U (}#.65k]w+7 )  " 0 ,  3 4: #$<_LD`.9!RhpkOdPJ{krL" >yTS`X\!Fdsk0+zxR\S7zjr7qQb#? :J80B )  g [H?M-S5+=n1t(kVz: Q o g 7 ^RNzpc~5r}c 9kIFM,+R^CB84kv\A T+Np+~+ l ` ~DNo&U;/ i  &  & J D   o%{RF_r./[08g_3 ^ ] :  (  8 z \ ,(\(,d.HnMT}Aog:$;C " { d  B>N+j.o_y^0f3irCNz:7 e C`N'K P$I12tgX:Z  > p7p! M BS_+.W:+)< 4mrFHV'5kgF^f7T`S*r7v/dC x x 4 hx: !LkIn~EBgxnX.g,X ? I \Bgni};9hEQD''6P`]M,\NC $ J 6 k TL.W@vPXcHFUVPC, ~=g? l G :T,,?Y}+}-x?j'}G 4;a tE/'!&6Lq3)cd6naPB(? z %)kUKECNhooETpTMTepgR.}V?4-2+  \  G U M ?- $<_{XjzsiT:t= x O t o?(]\+j+PkC( ^  B R!wy hfwl4_{9pZRG4  D < z r]SC7(`j5:yraIv0osKksoeUMNNNPIA7,/>g.$:n2{4F|!>]d`PA+ *WIrU\(P QpK?QURHBEB:.2rngQW8]>+.>Wjsl8:aO  A_rdD,+O3PEjd+]>59QrQIgNEkQ# TQ /WrQR 7el ] g   Q '?PE(BH 'cnVp!z6,e 1 o l  ItjA);y[j6.k/~?8c D 5 H  D i nFl<$!J/`B\nlvjE;Ml / w  YwL `+D= 2~ktjNAp62Jeg v  z(BMH9g$+}YdR+{QEQd CT<8_PPF_}3I%z#%$NkzdGM,&E B"M w,a-BY!gX[Oy7I vJ.6a!CP;:I7 U; |/wy o z&}7[*$Av?kv`#hd+mVk0S2y(!dT`]z/`{a ] ~ x ` / FRI'M?[0I3oEFitN  6 0  ) Mwl2Q$?h\sLy7!$ h-k|I .L?{2dus+Uz#67c>x`]0`lW*eTf[BPu(Y{eVd?`gMU < K F ) T>J/ `:%:tp3/R~L`BK_{w3;aR_'[$>N[dk{t/J[X3^ sdf+}d&7>>:=M_ /Tk_80 e ~ { Z  `t;vNLnHBp:$)DlN+ \ x t R  <YZ4c-P3X3 LtZZr}E~+]vl?':LWk_UL7F3DH7#/$A;hE7J~U*3!~>,coXzrI~IkD;AUCoxY K _`rU(6Q  o%ah 0}A(zM oBJl2 `z  i J + NJ$vlxP+ n%}_hG5*v0:C  t )MdT~NHa:=]JN[ /ield/#~M$]s3 5 {V: g(P!%#(TsR0 Uzo!\$h= CGQ v`9(zU!a&X XC_F z;s$e<gR+A=% QLT%{0U0&?{YoAM E| #|vQ=FlCY ~l/ H(v8_AQlz43+~XURhA=XzQItI!tZcv l+0v'Gn w9Z'z2 7xI_6L.'Fw}(,o>FhC5sv#v7aFY#hMaz/Xghhv473!Tv dEFl4}'Fr# T}J4r!4B]UkE8`<\.d4 K ( ?#d9Yeh!+ 'L# p p]<h~jX:)23j+P;8TlWN:hV 7cCKZ ?TjlIAU/o\glS?3+`r,X`BF} Bs7{'rkndP%49l0.z09ajRGE<< AgH;r xPe3VY/6p, 4QV8 Y(p9X?v 4;/d[EHavm+  Ug7En v\w**nR  Yk<QL;&;Zd>#t70] Nw ,Z(E(k>2{wI &Ho$V2+:[>}(EDr vnI !BgrR:$F'El(EF4NtQ=606FVnlQ:=[gRzp-4tp>gwiE N+tG^<{`C(6XhQ__,{ww;E$vv?szhI?t*y`RMB>>Nv!hB:MvJ!.lJ\K:>s,l\L:*/`eFEaJ Loc Q}z#w4eL739TCE_Z,JV XJg>;6,>X!a= %dn6&5UvM2\X'z4.z+$ yva!~LV8+A}s2*BNC>a,L%WjdBeJd*$E!>[g[4Q`a [W+0't.`.{L#L77QU,UBY w/>cZQng,}B \5 $R; 6TN+j{:Ekql|`}IENr_=k=N??gU%z,6Tl,n(E}}{ IV#?9/+NjkL  MkoY;`(B_WEXQI.\eN`?!XlkV:c$ 0 #6sdw($?7#22vCg _ig(U+!}g=u,:}c; Fuci:i.AT::s[[J*5RN`NE:n:(J}xlJ76FJJFEA:+7p=oK0s2'7#V)y=j}vseL%_9v2{I,$oskC[v=Qext\9g'Dv/cU!0tQ. s w2RetxdFtHgJ($. v}7!0w{7 ~+((;ELL?!Rz\I>'23cA hY$LezxMFWlhAo\UW /(xQ%0d6NengM%#>{1lGgFF hPhj:l&Ft\'[eQC-.w6!A`"kW;w* wJ/}X' {)t'F 9 Y#:a=Y h 7{5w2`+p l]`Tg0[u9R/nj/=Z_dfjrzF ]oHP9X`G+s(vkW3&'\6[+*QJaj rAn}P fW0bRIjNYQ "[h6TYAJ[HEITXL6"F=oNUc:-F6wA$(_\7(',6;2 ]7 P]H] n]_Yc0RtechleMPUF:,ltfat/inst/signals/ltfattext.png0000664000175000017500000000326013026262276016735 0ustar susnaksusnakPNG  IHDRXwIDATxmeU;3:Y4"" !`BBFI6T "D1?ɀDERh&J 0m^p0g{3/k=~Y{g?^>/ss@! W<2iczL\Ӧ*k-.`T`ҊҦ*+ߝK+>46U!XVZZq}iSs%Hl/ہX/V;=p0T`ںƭhSZo5smB2}5 l߳klsZXf*Ef`~*Ezu`z M280r h6Cw.hkF6Ю]8 X5r*p6 /zVcB}R5#rlm8cT ."F5(MpA:k]xiJe"uYlW=ݫD؋&JΪtW Ӎ"UXcd!H@ jV i у(n!LE "T`V0 : PaB laI9d` KttۓkLL9іĹl'6>#LcFqAb7,W& _v#Wi+:hoP<܎F*T]djR,"E5*M5"B2j3ai+H [T\^͙:ٵ=fɚΤDf];Gu[N!Sޤp' vod8>vd6{6窘Wԋ,LHeR,ӜBݕ:#)`d9g( H 9 +ی­ a0vL A& ֎nb4Qv!1U#h  pPi"x#ڌJm7FS 4љ"P2ʁ6+Aښ~{., )ʐ"QI F@w1KvEX0LǤd C1Kvm3̐.eeCB5M O8RHF8(.X1,Z][1DC u2ۛvՌ. Å ^qbOWIH(b5JjHkTTջL\Q/ϚP{i `%FaO)kMЭ$)]QfZ| MTj:JTW!rETDq]! !h#]kW EFP 6Z,]Iƴ-4Cmp{E3 ɵ Tؠ"  !C] $(BFI1-X108`Ӄ8"x&Xy}*C)Df39S'4i(R5JY@TJ$*85zo UH|CMdY()^a/^n`j 4!: 6 6Wnkv*v&-D&, GQ}r"8K@a`KPYDž%y"KPz$о0ԅ80ͱs.NA z<5][$\pLRJC:b $"cYh`бر7JD912ȅl(2hYQ1fAX0)LMzj7ᦒRD7ȍJ-)f!TAp#|P@Q@@pd)+ր@DŚx'Ay k 2f6U|Bu|,If{s%90R*7{r#v'r1DR.h bx,f+"2Dys ,jR4DQr]6pf֥K0 Ύ X6B=c̄%z>B*׈C bK~s\y`ꁎT#Πʚ:0E_nh0̮Q0U mM]F}CTEpRP*X,*.4cj*!Sggi`?P A$1pHq( slnB0u(fcldhx07$g=E"Q$m&xhtoeBO[Hn@BRW{|p q1ds_Q. `b0t#B, 2r؈`+@Qf!0PWB! 6 *eI& 4d 2 fLakJ ]  c!hjoc8i{f$pra{26RIIՂ7U@X2E $I ة1ʖ2Dp@ajCfS3$GAm\Q/] gP:1uȐXYA5!3JE@ `wtW{],&`r!L yW= 3Xj!B.BJb{uWJ9XTni[ X%,h+UR)

h=.C-)i,^$0=)Zߕ$g,<#LՔ l% .Ԧ#-$L {)hP34<.1{bs;9Y-@En֋hZ05A1>uݬ& "Z(/(@g*~f  gKؘ!knٮթ%.4'Klj,8r->݄ (Z:5I+Ed'(} XUό :k2'ڕ D   MX8@Gl),]f5[1>r)zAM+ )=C/ܙ;1"6C/W.| V#\QSo).OUBӞCm,(G%2VEՅ9;W,,:rL_p &3=6!A%0 1# Xܭm$2(hd b15 S߬׶@#&!|neܖֵAl(/R) U* (296B,.b5G8,(J'rn]Wm z: Yѳնu!ͼϕj #/y!nSs5*9Xِ?6p2`C[ܙy '+Oٖ8 Q  \5׊ =6O1 )z.c$5 tL$8x+::3& +~Bg#^6u52*O k@^/Q5}/sV!"O v#2T1.^H $q& pV#_1\5M!- w i6E/;) H]%'6;'"6*^? **"7 Qkݟյ \  OJdYt!9ZњW(~'y LfB=/4 P z/P9B'2/$~ޢP( #=JDq]}q׵kZ4#ބ .r)T#i>QܫN10O)P:ںs162kޞ] g#+,cp5ti!yY=*h: p߼G^p)l/%3 >Tԅ׫L/O;)1X z3޿'+;02\okt 43\BY !$1$] _;NA~U̩"W !i'- Lm,6%t}E]X]'9,%S1إhE2C) ہ->g& 4hJ fI\ sK,2 iQ A([)W#Եv -5E1DAwEhإ~,$/b1P5#&Gߩڛf:/ bYw,'ݽLY1 siYJс$-.+b I2 { &%614n[ڀ 48M?sS,'\.RSr0^N%XJb*Oh? !/U%y7wv$-;}1r,%v8y2' _Jpjv2[0 I\=_#!" ׻O#$?!۠uM8)3C0' 5%? 51c2f), xtH;eH*^-R$ #CO !d%! (4gڌ,l P\R4`s:v &$ +ِd9)&/i ay2 K.7& i-b&2J#@D +,۲ _ # 2`#!^"MF F\401R$x.L߰045%V` Ӷ1208S)c d9p6 (^/!PM Y7%\( eث6J#\jhҵ"-b,&+ 2kαU03y05]n.3/% ڱah(.,0 " ?` u!7_;%G-I($nΡ'4g-y )oѱ#!4-@1ݓ܎L .#*'~4[? &# +F3 Wnف(݆V$T%=h֖9/!+: ; ?xL&5)k J\X,$}F!lc'(R - ": a ^RݗA|xWՆQ F"_%&C!^јٙ$,,zS՞H!:.d1"R "&^5 !!FkX9ݴ+  B׀. h%G)[6@.Z00 s}~l;,1P- 23Q L}<x'b/_}"Ef2R +D Vx6_G[Yq ,Y-' !Daf},);Zov(& 3! ;+MOj : .g>h#|P MY"=%#iF8fc),'5٣݌$#(!$ {o %/9 bj0ALG .![`?9ORb!,I%Z[r5Εw$.N$[ԋQ%(D#7e4R&=+G& S0 G'+D$s bbVR #( `$f&7> # 8" U hgIc V"k<KЕ}ے|$*+@ :AЃ5c 3'(^/߉ %$=UII   1EI]\c8;܂)"#ֶ~ )I&F!r΀o $W0_-פ׋~w(:&*G8V q(A$1I*!;^#}؃($c#w9M=N+P&Gگ+(Y &81m#4gWtq#y \#Z `$ /3"$'#4<IY%?)! ׳qz')Ey.!6p"(&4Sq# .rgS#" ?գVtH%}$qrRK'+ ݥ] &T*sX0ުg$([\ }{!O}CpUTkWZlg N#B8Ӻv##w"*('"(،Fl##$UHOKMZ" d3  ]IW $4F }C+`%='~R _"'J%*U@!&'$|*kx `p[\I   9ݲBE?fQqst)!$]iMՇjV G{*f#֕D N {*1!uI< @# jG COi[>"0\|$. 5 aB "s'$_T0oХ)[#R{5UݏV"!D\5g G,T_ v٪"$ S$B%zT?;  $+E W<)P 6$^'}7 6ޓ2i(X, ]u [Y8m.z !evoN!$$H=p>%#h+Og$  *AY4 29\n|G!\Jz(rW{##"IT?y""x$dL! $1 3.!^,5{d`##{t܁ݱ0`b KJ#/W2l n(0vZ ? o ]ߔ]R 9 "L lL!w"zm"j!!$ *߱o^$ @<F:4us(d Gc! ^ (B@ژc@#:"< Eڝx L! ݐp= 3gTJ/ pv4J}L  BfU-n (@OL#=!QذVHF7^UB:I 6?_`Np Qul ro ^sQ, ?!F| U"W? 8-5$Il3#2D( |&w ~2-)pD CYviH~t(;AM ;L*ޟ d"w/?BVjE!ff7נ&IdL;4`SDq> @ R*3_;ef!"PI # a:]lVڛ^XQ):&7 vki*j  ;_AJQz%H#:o!ޞ  X"N-nVPers^}I# [/":LG[[h sL+,Vj #,! nHܞ_ &V {_ WdHl .2{c:4 I)T#p6L~ !t?5ؗ݁] 7V Q %NsAE E ~oSF/#u7N zH)M:#p *ީߚs"m) N :Px |"A  =+Y ,s=:<  nOQ!H"}rMsJ"} p:e_8z1Jvq9:$ Yc?. }JbV2y[". V"ܡ l)#!5%C% XL#^ rUI  gF IE~cL F$# gk#mp#vY8r FD> bxPP9o& U!b_ 1z g%f WZIcd .+= CMg!WIY8[z0 L`Tn"M$"]{= ~GDWjF?Q7jR/T6W|@W +2|R V[~ov 3! 5#~z_ U u  {k >D^ tz8 tBWW{=8ot  R8L]# h!YTG =&)DT m]! qg4z7*}2 .#G = ~%[ @ 7cCc w_>%Lb^}y|d  * \D1 SMU3l 2 >r $$r,6U12mt 2LAwS9iC* 6\ Axqs .` f<('UM:(ޟ9Ym vv iik A 6! bT< nyo*f ^Fr} i  qT+ }Xh" 0% v -36 p= #"dF4  m\ 3bXW >|mv @f|ElL <#f 7 2! ONEg&g8o 5 Xe|w  h\Q !$ qqm 5e tx K@| pT |j.\ 7{ W:N}  t/  vME`h_@._? 'C? cT*8R.Cm@Ub  A/TS9= )Q,dA: 2gu2 ? rO_1iRVozX)8.e0} cc E2%3 * IgI [Wm }G2l!W v- a$KnyV~pN }  + 4W{EX =;NV 'Xtk0 K9 8s>  .y9OUC !R y4%i] Rg[F3u7J]lH lIPcB ^  ps [< < B~2K  bQ_?NY6 |B { @QO3W qM p],*9'  XFf  BT Ko $Na&P=- SN-j~*  B%{(f "r  T\T>X / 5mhzpp|U&; 8n Pe^t5)~%ue alW  9Q}`. k e VB Wa1Ry\-TE1{997}#{nJ+ p Yvp + uj 6 \e lnk!:%0^@KKN be \7PJW[*BxP _ ^ [A.uo!iBJP C(K5  ( )%w9I2N I 3 5i+E,v_o/a%  W{5{ 1 |%2 B^ ej -xnU&%R{ cTV$   KX L M~:DMiWu7L C [@/>s dv=vy `iM7jV~AF2H _u0& |3 ]Y = '=' i 76 kzM \{ /{ qlsR )Q3O>Q.*d `qri MG \ 9 9!_<*8irbw&R_1?u/ <^D L9| fW!  G\w+;q Ye5~i K 8 F ? x {T v8_nlX _ZmX[ &ykZ?3Ly H  ud  z qQZuMO+sn= P:%%   1NY5 {}V2+! r`Lq ^zM u 6NqLr' :&E J/zD # + a S FO7 p7 DDX C_Nnj>H ns  E%D $q #c+ - |FQt 9 yHHZT d` F V% ):om*$tTF aB +P'/iN  !@y -  ?h /' lKq{X}V# y65Q=%kv}' 3 #_~@ l YM# mJ'JP @@}J1 nm'5 c~cea %  @w/K{Vor d;*z V`X}VR$Mpy\n#` cq 9PN@ ju w1lK&li [gC/Z$TucgQ% O= * ?@D <wWy4"'z;]6ny%[%4`K/eO Kc 0@c} chV$]7N k|,! W(5  =(kPSi nKVoE 8f>RH 7F "s+ . bi D_b?D#X3b > g" z n rnK PG NxRZ Uk _G& JQ ie}/4 :'6 4  689 dzI8f R ]r  6 |?:] %bLc2 AQ zB k B/^  _I ]yD &ZvL`@c;v H)} ^TypM j22<:uT?k~E]D \=/Q6Xmh$l sU7 YJ>U& ;+> \v Ez1C*Eq1R`DAQP0Xc,wS= .  `L*G W $4O  . 74CF\ MgC: 7P>koV ? ]MWr U zc ( 'bpEGVv 47>, QU{wNc&l: $! MC c#>  J9^t &j +k/= ;Q;t c_ #G v lJ5# $ vZ g 9 A5]6" * =7&  v n  } dH8dc 7N L #I jL OA {A6yC\ j f?v3<9 %DV Wp=*Dqy@ `K3-32 Y] v8e t S@Jz& >2  $V S(O#5r l q gC  S%yn  #*zQLuo(PP^Cw''~ W9  h, m( F se??yB i;~h.oEH  FB/@+* Xs v&q P +SF] p 3UqgzpQ u{#_ULlZq 3 a ZjUT K *r_ u^= i  f Y d P{ I  e$V $ ; X jNq u r  VXgooYqXMzFi"IPfHH >f x( g A7L O uw k&p w Lm-.`#a/4H{bh\! o n%p  t |,, 1 `7JT  W*Dsfg$) sA:L 5Eb+ = 0[2rpn =lw LdCv o  Yl =! ~ jt/%" o 7#8,! 7 2 7), ubT ,  \ fXo n <z! Z ^ obd}' $5- s  u~j ?. D"l y_9 8AQzZ   U\ >&TB zd\  ] $\I( ,:>P4T1lh(jno%%,  .   = :Q B V :97R/` H $ !HX 8C^Y eR  Gq' &t %S,?jE ?: @te% n GXq  3`$d G : "f<9 yJSy@ &0([>a]MB o 5~aymcO0  tHk Y : cp 4 uiC  a x }J- l*T1d s ;_-=Yg{  xTQ:N] l \MxpF eg"H ~ep&X az|HC gv F/ }a :( H   T] e lWP   [y2H"  t U |"r_ffKY)^z5zP  r}' A5 | 01}}7f9#  { Q41_W. L y 6 \ j5- ?Q>C[2 -X R 0 ggdY  E y-&X t_PG H {FF A d# -Q4\t  ,0 .N{   h`L   |6 F8 [A# 3]OS:)|}nRqg Q | )Sa $d 43?y\ A #h c TeR o KF~c 0  Ej/ik}>  XK6% jV`OJO@ {H z Bn;TF%  |hf+ V:VS:PbF : *i\@w: 'pggpVbO)' C++` gH _q/]cL@/dn (k H1 olj? K i~f6FWO >R ^{[[ BD_q PR@8 } te0hq{ Ui Q"ATd>kD}E | EJH Q i ],HVkv sq< E?%i? *c[]B4 c~+P0 4 O 1jP { s h8 | M pmN boI+>Oe [@ AU(R% F.2W,b N ( c#Mi a <3e~  `;.Va  Dq;WF z+-# ' S,#V q $80~ [ bl1<$ bV &8 R & b > 6$ n2| M07.%F  '8I&f\ Z7M'2 U#)S)N >+ F  ( c7 j Q !31zw F ~aK =]?> =Z+ G  (1 /  0|=O*~QO  r # ?6 Y)Pv;Qy[1  .u<s  dik .gXt Kd] w8 ZlK  |u Tf#oV|5M` # )if E OVI]Y\# U SLSvY 3x]\ ;#N@  D8\ /  U2~' \ }agkQ T / Nj ]~t{  FT4_ " @ Y\`9q@DZJ m[ ,];P / \SN  ,LE  CV^g p`0$l d.zd \ L\/ :7=JAA29IS]  A=' c 2ER7$L 32o`5 *0S1"XG=.GAv g3L`v;; geT' hH 0KJ~` S  |#2!fBt ^ ` ?E[U .V4$1~  X = ` Q0tY > P T  $lR 8 w5d <cGoeU J F ]Zg >R y!+=  `*ex 3" = IMwWs @ _o-st ze  6 [ Q]#s&! p k.yJ l  F]/uR ~ | v2 O d 7a c]xKd=G ' kFO  fC$` +[G] ; Tk]|mXI =fE `:Id  [O3c ~ r ?m - Ys,|?M'.K8 Fjx`P 1n7 /EY~0IA :8 u5zjh 35N  Y ^X cD d"z>nL >pF] ] shKC: Sp#$yvx T%`s- ^ (~mB>S W ] "* qqT c 3v%.tu1 ?(_m7  Qj.  o SJO  7pvT| @+ J 50{S# u ~h  boQ; h%. xL [ TNn`)/I%S A6 Sgb  ~3j(Q 6f- ;%t.U]  U  #)r&NSkmR oRQo  rN yCSSy`N- 8 =<;4  x: ,(w ~VD{xY z  7>  8N Cu)|  MNZC ' <Y~s/ - xy[+$KG% uB1H!U/FZ 'qo 6CxwM)Ve5q 0 D 6'ej >h/'  B4 JaA |F ~ _ |K ? 2}g_ &dWNwPNa ' cp { qIPP,YAXa 77 n {U HmU0eag<U V *dd` R Rar R 7BGW { yW: J ;^_nw \Q~_ 4: `~5  7%6  Hv?k H p 3C gO(*  b>K& YHA g 6+Z_'3& M^ u%N7  C 3wrK o)ly<{czU v +" w  O` U7e ~ v -+9tg  0 xa7Qyc +]T1 \l$ dF4 G =LhV  5vW.  M'1 Emg ^ (y/x >, U[*Gp '. rm _ ` F'v]I/ai+,Ng sxKT u;B  `ziT]V  43l 2[RXp[R~s#I : J)3 3 _ SCxCl H pPZa)+ J pp 0>~CyHE` La{ ! zjJ.  # w%Ud  W =>^B2w q@~ (: | \oTK # VO?mEF \ rO R B]vW  pcV* n #?I,`    L)Q q R 2zG48[ w erR%/o,`4 U_1_ ^ ?8uCq W y"'s t M_u_] .x^thT$u F WU(g0 k E+ 2   (SyM6f qT>} q3~ yN-3k y* f { xn b j{#'|3-_ A,B ` ? 4 "  \ V\.< ZQG sl)/#T{ \X"FR G8 H&m WFqQ vD;jGy.lnc{-q$Ur D+)Dra - 5 {G O$=5p&gpr l ua!B| }.h`    Z schC  *;'Ct, I ~;a#} _, %w% <1zD6"bW5~usU- Y i $57 rR  X t2 { uk O l1GDg w[Q . qL(1= O   U  *+`~xN\wN5CsggIc#  S@N k j< 2 Hn% B tAX2@ X pTc P!"bbi & y8n T GvP  h" q  Y  \Iy,W;y%3-k /DJ6>c o +3/ ,|K+AÉ\W0Q?@AUUqRv2tD#ӸBj x'('Ԁ m)c1&_55g .  aws$0 . Vt:5 j4tb\:$4 n EOO ' aMP# #6~Ff `N$belVg z  `o )$+%oQ+j= + lKmF$4" l Q׊әI"(l(h i z 'D #1 -I~* ~{OLpP l H0X<$#%4N3 Rdnt9܍%( #cU(\:.|qli}F&phI \c& O cߘFv&n$ioL'4 GHUzS ,Uy uyb 1{Y:W'(~s, &t!LX B\)P < 3 ?Ui '/G2l" A % ."O 3?!)!yH T}qXD~- 0r(1IgX6M z hr E T '/n# |R[ $X &NK4  '`eAEk   A_/S : r}h  '{ prOV Zr # &AIgK!  Pg*f #?@ g DF n 4Sh>Us d߰a(T% r>:|2{  Ix*R"2}s 7)Bp _"^;'b O;Pz$vOA v y +u@ OR F .3 %t(:%--@]\) =G!Z5   $pj$ nZb52H CH1 h+~k u?ޞv+)!n9 C e%^l3 Xh5 nlI1X <T-] $$l7\Vڴ%7} sKk@ c zBJ7 nw24 tr oh3d z03 X s: OWdN !8 1iI } M wT[<  x ?? $mܢN W$vAdl 4 |sjo/G*fqH-P@H L=94? uB 7<P '0{\~ "|:3Ay  ] Nx% \ >'j:.j ( |%#? t ? hgg F. 59% | JpgXXV7tPB %8l]ZF #E\) pCXs{z6%vRm?&&JnK r5 XZC߄ n]Gt?^o[B[:R } Dh?`C)F R O ;Hx@   7V<V'v"G2}5[REMYm P ?GwnhG 09O'bwMs9V /is { c WLK D *D2e zE#yD+ ^ ? j h f _pu .`g K ryܢoh q 5Y  7-[ "D Y >:c J[#}ct i^X~s2@#j us߹axERv,q c E  ow6 SGc6 !O%h, S3>u0&G!\T:C2q,Fvk8MI I b:; 5%Ji1"z\! `W// J yx`c0+wbk :]R]]  [UN }  ~zpb GH v R<# ;!~ ~. _\1 H9?i.q;| &_:{=m ?YulW e,m7b sm iX j>K? 6Tr3 ?X)-] q.%_/]=&0< $cs. 4(o 13 g[8{xt  jxg )L6!SW6 > YKjPL,KxY 4cdi2| #l e!T> 0h.v?3:"Jg f\.d N!tf Q d@E } ` _ (a:qej f  rkv 9| )>U8lDsSn V A gGh _tߜ \Zm7  < Xsa^ !H" oDus#a=PV|O ' <UhE' <u^^+D, vJ < <.B v #zAR # V{ 8*9,H\Z} #hf  o)}Ya\AMaKe+-n ; O3`%mU"x0pg X *i><) a" -% " d gE5Qbaj~ ea7o |JMNvhH) / a;.l>/:FjGa fs N ~&sH2E f* ;LmorR:1v  $GG | _U3 X 4J 3rld D| 'h5h=V* \5 SbV0Iun<1 ZF*v )t< =wP n  i . A -m-iN }W5 Jc 3 z V /%y M lx_: i d(3g'xm< JV =Pg  _JM "rh# B`q4~yGp[  ys_5 %LAo6VAoC*HaG|c*Z &(h^Ba!LC ; $ k  >a/ '  e LG,Y93o c%AbzB U{+04 ^tjVeP '9 oh"rp = s'{5- ZbR8JV r=7\<dVX 8|4 0 {tl<:8 I  tRr T 1lc'd6,CpF )Fy(oQbC.Lz hn'ui    ;q"t ;7U \!g UFPY EK>| H nQ7bU e x h ?Ei*+Bb  ?wR- +0; ' q}M *]h  Uku db3wZ. + " )y H   Hs.! PIF};?d B.kD: A9 1q#)Jzkw=[   U7i . :=1{l  ';DF'g:Wpv 8 $5NV_*ph T6K - D/99# dpyh`+5Bt|-c@ ,N 8!kF\/     G gz RkMB w hUu .K3j pP Cv\g5F< ' [ TG ^Je!ko G&}G*>  Q kF& G 3 SA : VzS70Fc LR&I\~eZ,"6 \ j`(q>:Qi<>b*_UX e{j}f p o"?;c _ w Y kV,S\O { a :  *(??X:ch&#=_ Vzbf  uW SO M (Co DeP8(U g{l|  lzmm >k2=]V n H  a d% t1 *f}}%D^p j.qdy:. oIr ; " ~O dk;$ 5I 9& UB5( 6Zf,g=y P  |}U~% _h;jzz??} cX$u &1+HLEt9N@G `FjV! rr& C%"/Q .<_ # p l? + X [6H M >utS_TX vIN D&ya ]kID4WB] u`,G v x+|WXyl< ? $F& d):_wr8 z3 Oo-y/; EQE w  e !0101m C\ZF1.  SK&<&BKIf N$h,0v?#jdR / G >1T   [ym d pU B dG~5m f&p j(Q&-Z s` ,N wpSkv Hu/(FF[>u L =dx g ^ .B II32+ 4_ +{Y%9P@ M6 dh=[aPI ^84  s~S?2  xYDUS t^Q4V (m{-\ :X zMr m  Zl[  W  QB `  QMPS r# m CYsJ <T h,dMN % }!A3#s/ & ##sE# %4&ONbZ# g KO 9f%Va j o 5 &8 V`V I[  B2ehi 2kw8,Wb {v-7D !d} P| q`?S~ r3~y;islrt j ox7 i  M MSyS  Wybdk_ iU6q}PbNv !?[T 7^ `B v6$ s @  4  VHgn+#Z a77:F nL em] oQ %s[& S4s5L98 f y qE' e:  KnR7LQPq Cd8`t c jF8^[Fe  ae }b o/0Px'< +R~j b|  e)` $ E"@Y | ~x 6 e{9Y #=M/IN _iLV f u%K L a 8sDnU}q i.p I.. ? ,lsYl / 8W|#Z )c hG}|j !G)s= lT^ \p 0Z f blXn$@  @ 8j Q 8Z%q%x~"__zf |%:O U < . ygBS ?<*"n vzTWhqF ) eqtR ?Ao~ Y hq0+~"R Vk 1p"eD -]e=q s v$<;O  Y3&SGFi{cY^sx :T :k8 y ' zwr  Q r`qP|:P ^Qwj p6 JuZ,x$xL #s9[<7b"  #6 BYK  xm- 3 >h=Ng  |fB<1| ;U 3GH %M ${69Q  s\VKKwk 6z8?C s%UZ Jro p ~%  Ypup l58   /1" 6<  c,i{f e  >p0 U O ;vW g C?e@ <]N9 Kjx }5+0[ F'Ryc]$2 ^AnnI- q l~s ZL* xh)( 8 )@K=ol2TKy] P 8mj) a O ^[_ Q7vguA &=f?E q  Z)f {(d * 05"+m  G oC+UvZ`u" _'8#X^ ( [i = s N@/!_ n@ 2 1C#xVXP ?+a|},K a t! e [['c b < 49Z% h D?{LzCwV1V yIzqkbEN y K\aJ]cKC ny  VNk!5T  D_h iMGWT *< . 8 zq{\q ( F` ,3  nS >'=3]29 t $QVxC Lq n -y*  ai t bE'] z tI/w %_@ {R "qI~a?&$T OIf Q\nw@\F D  _ ^ W}2  x WuK [ +6'4z wcGR; 7CQQa* c R  2 y 2 <o Evez5} a 6x0PB WHGcY B `VC # F -r?U_4 O1"   {PR @ 6j-3 v `m`tG c J=!  j\gh*yFD 8 o,c3x{ 3P & ~q'u1  Vcq& kzl'\{x5V R|c95 2 \_ n y i/Kk J - : s x  hCc* q9 1 ]  ~#C w ` (U _ AD `9 .$=( ] /mR>Ra s $ {Af\ RZK aj 8CN jE <  . Ux  8"]o@{  { !/K K!BZ43f{zzS I9L` P $P['A" Fu;E ) F,2J7n?W ) URUp b t !M2w  ,rlD!R -= Ow ! :p !dgsk~x  %|>g^1 {  ot0  ~pOnuB m !]4 11^yJW: I !piqc= $ HahAP NQ #xEG/ s, *2g O( +V6r ^& 6Sx/Hr w T 03' e  x A\9]+Z \ ^O p <`.  4V!: h t*Y l<$,M,s #6 v". $G%fu  ;' WVx ` Y2 xf 6  ]\ ?  mVU; N mo~ Wk   j e#Z +uP2  A% b{@  g^SXM[ @ 3Qw% ~ zI pL+ a  `Er+  &?R!np -< _DlSE? lUNC  R'a 3T_pA A *,{;|M P 5_/cj) I rz-V a INO=F )k DT wcZ  n_!Ycc p f VeTv1bS ||\B! Tp)D{Z j)8  "r;6x X y:%5 J]Rf 4Y Mf o Q h>= e #G^Yy 4\^_pV;Q # pF|s le3NM c'K  V}F  i P6H:I B }LkA   ;dIC f<h .s z  l  yU [ nG&$ o}?0 *H j#M|iPJ : X 4aby , } ,t6-H&%s |Bx =y ewNb@ ?# ~-D.K d  ,#}Orrm = `0476PRy ! 3Bl  S7mB " 4 I#4\  } =Cn$RQ$zk != |B #0bs5L ] 4g%x; ` ?Rbk | le {Ki  wNC jZt 8 ^VR:4 Q; iIB * w 8Ha< jI\x d}0 g # +n~@O B tU+M, B o je DX 2i {\xx.KBa[ ~e 3*O@' 7 F 6t+ n, o0#M c QGUX*r rMsU * EiM : $[% z sdr* = e/a [r 7Y?= pUKx  Q$~ c 36,B G b : tjn  G*/ :o:Y| px >I38^ 4.  ] \>(&X [  U)3 w< xm7 M ex = CK=Yg s o h @Lu P 8GV w5  oQCx  Q;h  xfn7> n)u ) +bI;2Y   dH ( h$){v E $ I|pP 9 d,L V( dK   _+L *iA{'I &^ S%HM  0qI/ R Y q U0k~n A Y k=Sa d  u )k EHo7lF w DP+ ,  K \:y}\ d  ,0wn~ `d 1j;)M G? 4)l#bZu =!+F H,Frz {`kF|paht Lo>Z :Z}@sz+ xJ mW/  xIN R9 !x X 9IMOE %6 W ZS7<t z y = R: u x " ewgmk o 0 w  A"(it (H+d~ r6 xK;(b 2 u !WO+ *[0  5 e DMrKL _ -|)TaT qRi o{0 R\}9O F7}n53 ?, J + 7OD)  dYy o %(U/( d 'E36 h m [SKx; <=  }+kf Q if7e@c/< *L]`,7 V y%:; ` 4 0t&O[ K :tcWJ B @ITO9 nTB $ I +V ^}q@5 Z;| : \ 7< {fS / Y C9w x d-Qh   5x< S +@\  [2 5fA X  eo~[I  IBr :M W  zwDnp>} k1 8~@L8# o SM   lZC{sc  x-yb U  9 ]@b6i I  ._Y~ 4~ yj]A2 *  P? S/ 1jr=] Qw/1s wn d% FV (1S:+ `A1^7 ? Ueq k* L#y{ =\De>s3  4 Zrw> 3 6D3} } *   @tGsd 1 uK ~l>|w k %K{ $ 9$p*< OP 3Qal]T  [:s5 /[ _96A. xN%w! J <"=]e V $hsA ? n6# t  &S: h s ?EtF N  `D$r)p }Vrh{ uM@"bp C^9?T P  Dg$1[ Je [j _ BcNrd/fy 4 LW{D V 3P5fF M 8T4/;|4 (>EK%!G ^O?>d1' &  52KS<G ]w =_sX% UI4 asy>.H/ b &wbl/YNg - swJaK;  R?yW h  w:3 | 0pu $ f R?;^* 69c$,j1- 6 _$@WbrIZ}  %oNA  ^ :ut3? M  >5U@@  %  f8lP D  _o: = |dl   b(9Nv x M\TCp7 k  A B A(  ofO 74 @rhAIB  !Tmfv  vmx*@Yc v .^ l}sKO baM " M@\ D !]Bv3 P|7k ` '>l[ ! :e Q{ :h /`V 'rmv 1KRp[XM h QF =" qPS< }  !RM N R(K aKC1Z/{C U | : '6oH I' DO=  wvQ[]r"` ']FJ = RTB{ &N MCrS 3U P}2 L o T$= XG8xF V)X! _ 3 lpdnqh| 0_,   Mmz " T|%w |#$  T@f-]  t< L; s7! q[bTZ  U  L9c\ ` Pxf j  ?G!w= M S6X64u n 'tXfvi"{#oP `  R8Lhd L BxDO uc ;xz.QR J "I](b; w M1?Dl<{TI:Td ]e|Hf Z Vo462u J K $V]-   !3EY)l -8 e ;&_ w<`sh8 , 8JC ! Q 4whe6|  ^ Ui*U' ` W gG6}~d k 6hY } hl=q R#!Qg%uJ W Z:GN .o kjPu/ p;*46 / KQiA1 fU"c:" i   Cz   RE~n P wa _Ms  Qe 9<xfAR 4 + osM| [ 4=o(,' +OH:  h9kw2!%HopU \>Dtm`K?% 4}Zj M 1yM}xB T ^ 5. ZF~du0R~`n{x[E4 ' 5 e G + rqV / ? } aks+  ^/z,I &^!   )52]eR  m52uS { p  >J+% % ,  }i^$:Nj2U$`%  u$ O p) e H x:Q" { y+D< -&E1*Z/yV H R R7Df + 8:d3 n "fzb Y < B8>,^E)&l  Kqf i@ _  HBh  qkOop' ugDrFc]V~ /v 6 $^zAd T i (F/CE`EzqAh890g0~ 3 =l< M l LU Z )t  y'Y@N1fs ; ,[I# <9 9'L+'-  ( 5o5M$ n n hVuw=wJv*y 6 jx05* r |CU : I: ch, ~  b  &OU J G|2r h z M51 rUe?'W@ $$|S?8>=#} c u4  = @AY) t YrB  I fhmpub d7ho*11h Y O$B } m B{_! ~ -;f d3M7\BV[ =Gg/  T I7 # $ jX 5n D 2uSv"w w "i5nH ^KD } }Au*m_ p y VP}k4Pwvp$/~sU `L{i1 - k T_fn1N 4A[w K:Ypc`, y:+&y% ~P6_3!p 9 wuq1j  |qv[N $oGc)7@"; z DI0 S ~ q] / >9TZ3s W Mt' MuM -.fZ  C C#p9 g UvouZ Fo';QV,Rvg=Xq}E6p{ T l C ^ 0 _ w#9 x"U+VkVkrRiV/1 ? B vwGR  6 HbkM *Oq5Ey@y8Q6;h_Y Q l O \e-zi q OZPb J n P+vCOHc(eD}CC@rx5 y C1U % UiF11   ;(m  ,m|1-}b8| w7a- .\ } Wol{7b   C?Z 6k2g  UHhY.3:( N /0"L<_B@  Q  Te = 1 ;/@=tliw7)[~\&@T } w wW,{_[V Mj0v O 3"z_&V3 `*DoZ [ 3+  P [@tV SM9< t9K> ?v77^`UL_# X 8,9 V H K&I T} A]_ }`\Exus eRGA 7 3 \ )q EAt 5 O=2BSz, v ?w,JML0GS Q cOdPeX - <P  MoVuS  wY.,xO!_R1QC B ^-H's Z c]y%,u " M'KP|xjwkG,]S|(2[ K , 0U& c Q $C0 KRKDJ>[Cz} m , i=iC  S V kNl vzV9G#@9(RX`[ TA~g1L 4j  s%45$9l!?I+8N-bq+k9Lf ((Wt y fc1s{ 08JkD~*lnkaMR5Am2 :BT_ bw9+ n  |Hb`&'XPS4W -Nu_#3 jB&z  Oj.hoW pJl>:\ G~/I G ^ fzU  4joQuKN1@u8xA]q  YC2 o /~i/): c @+H([8"Rs-TsTB m Lz1eb K s /*H f|K' uhh+%[C]- l  C0{BxOs e *l`dH%MxhMy M<=15:(\'  `4->  -"/0zL3' "a?GYTvDYwqyx*! 7$~A+>/Np `X12 ! _t  B bX.)1DJ$41 rP9JW2=& I lP4/IM P vpe B{0B  ~=P8#'Jpz7n; l  kDVh -xDH  *;M7/~ezaL?[%1G9IUi! x R{  wPH2  R:J&%)zX`?VGI>eh_ I|:3J //y2W V 4Xnzq0!y9QD@n&/r6t iVvRb r!`\PC<c b R9dy{D xYe]/*)O:3hlZ' v /W   C3Y'Z*-6+&Q[95~:p$f![ j $2 <^ } u8V2"%NO&ZW{_~9o ' oai / y _)!)q I1Z4>IsH;-& !^{g?F! w  c~UTwA  e dtae S -m4V<OO",4BeB [_~I3dc w 5K; k 2AEN-vX[|RX^7 HV"z4: [ +KX)P$I  & S|}bd?w^1`;_qsy_ E& C 7&,?N 7 G)Z .) k ?GNc\Bb\u1GlkAP25  f  ^ iIw # bI]z9Kehg^Mt(pO%  f  K! =A|.@|1zt0=] @k\ dPi~T\l 7 f 6D(T_Z8CcMmNlIM:~7 Vb j cYU)  g: i3H$?r1k*q((q(}"z 4J T[?H!L Fh$:\# # f {hmp2oaI" { i "C(_ Cw VAM$NfUp,~ Nb!= R@U@ ] Wz@4a<0rjh ]~Ar;kn tc,w  G qu% NU'H?uJ4Rn|Nr! Eufd  8qIp<:r% ^  7J_)3MPrQ7 a@9#nysmi] d \ <_1) Gy[4oWylRd.I_?xrM} < ;;CIS h@.Y{X \ Dkth4al(zddp86tV03 C t +FY \dsL  vqV[ ETSTs*8/*m93Kp`l!-{ & nki' aTDu{.gj1~Nc~i Uqi APU.2sn4?^A ycXA #iv! ek^NJHx(/YS  u2v'4 JN7'>,BVM@h1xp]: 5gV~+ (33 c ge`(jG<1gx"k2Hal)y!tn / ^  Z W hW]l{ng07{hL 5-+ Mh# J "51F*8x 7UTC <na{S"n NcC ei j &c #g kT<[c$Y^5:$@=v p daan0[  ojer^zuMPJ99A+Rt8(c~9} (@1HZ-ik"etHE:KdfgnC V $z.yUe >  ADzo !T;oFO:uD8lpad[}}Q l%v*$k -48NB3G,Y;m~~0 l,+`x P/(f 40ic8d) {G<5 qpDZY"~"U `xt  A1`6= p7B(SA3h(,(hj5S}[ i{fdGo 'w ezmsF3g 3kD5L:@5`fYJ.+wKInB5W'  jSM{)R(d4;mW~ $hg4Ck`M ;A7NT/s`}j,Z~?)h.hQ9.BUx:%mgr`#n>; X_ys,?R$/_9OUN$ZFvl0Lz/IQf  j P =pRkzzcUV.zS_JdQ|D {bSd/_lf3D X {S-l@ %#{702z^D|z\`! o=l$6.4MBB X r)5c<zQd{nGc,MEN~: bs" R2< & I R?qhJ"5WlkZ%TRv5u jqibxu$MT FsrIx;w r?,TK! v7c 8 u"P}6X+MR2\}#cG|Vst<9[W2+R9Mp *?Q []?0d+JNQq3WT3U{GOg'jf#Y$ny>9j6nO N}E_i/|aj^@=o>z .zWe{U>?::b &yUXA)E*I\*5kH)JsCE<IA]F!}^% 8!m 9_gni82|I]w S]IV%{9fbG} J Sa|wiT#w:{l,AVcHtY/N! D>i X ]BH}lM5QSn1-Q48#ALRYtz^! vL;5t0r"v%'@o[z:r_@Q.bst!wC j, kDx;Gw-hwF7E2#D3i@>q=E C  U%f>0wA U]:`q%s*[d]]. O11E, l=!4!xD18rd"=7s]v1ur`pQ' P/! ;}^q"/w'hDH*(-,^>06{\eI= 5j   AP9a*l B}81"3DF|; LQ :1 U J,2:e #?C0GMF53HX!Uy\f!|YWB^P$F,[3iOYyH5]ire  Q 6YZl< t4 7.87)!Dr]A 1  DRO>{A(PCUVSR?Z2P:yU+}lO~ehw;2a=SOP"t|f3ldWpRz0l4{<$-[@a$rV+xB?`m T:7(6#H<MAb7D?:/}rH >`Nt4Jt L}m#lV /e>7|T;ag&\K 2Q]>,!(hcIWGfy{(o9Gm n3rXxuKD{PalSWBlP; qMxz?4Iix)#c >/ wj`8#Th%6aY/T_+1 "^)I3U+X K!OqW+`7 ;sX XKS2% |Eu3bKmXr`nxA$`kPL 8X-7gS-m[%6,,]-~=ncRIpraSW6C-{apu)jPnzyli;{=Vo42QvA! O6ayWe{FlgZ`MKRn3:u8ws_i ki&Wm]cB(f& ^<XnRJjX,4$il>=,XVVdh l,Q?,Z*5sC`jpzCw {aap2GyH[k{j^tr#zR!u0;S? }k7TZG*{R*Bx/ C_.lnk~jbG]U`FYlixfFF; _In~`rOfT Bw!DZw1u-+D5%lJ<QSh(2QTol eom H^$6a"$NjpTc8G$?=}jj;{,t? Yxw|cZAJ}e]lX}I6SH}hq4#40wl?E#=:h{V&i#,!4U'2tnU8v|2kj;&(R8&L5Fe[10 ` v+v* |&; G9@s $L #|d?0/?~b0s*@a/Oey'B8vv4Sv!wG{}WZy5BFag,B2g4BMyBitV2${.o8&*"ETB|KUO0nr7qIfAgF n0KfcU(.x1<9x; nfcBlx$YJP*vQgn_q)[m%7hbl@siHLy\u~$DGa Tq! o^5N%2_fg{Yu'K</U:N8,w0#{7Bl Z{MRa:X\ e;C{;=$T|BY_I ?sv +Z 2s&bbSwZQ*`joR:2VU0vjr naYH=1;/Qz9} xGM?5NF\CTQve  ~m;9-fYc`eQ8XV&i2J[!gwEhC d^8V>i9$YS4i4mvPqwbgKxSDpk!o-p2(1 P~O8;Dx5$ 5H-JCy@~6#:]_d(pz%T6I7`+M7;(fZD)"}S$nzql5t%? &`tk}I'|wu15QK~V`$[ZzBl|O@->; &y* C};?C2u[ #iS ?P6}Ai~uwE25PjNiq\()1y 3,GTQd??SP8/u_gM&C (a,79,}Eb& !Li]qm$d!'i:xZK& WxK^q+c,$kt"36m; $@I+)h+;p(4FK5/Gl%x:0-$4 ,->cb?t'"&O  xa4fE3$W DA/uMReq\ OJX%<"Lg[PP8:p.Cya];( zxpQ4IH 3(,mwxT|A!Q{ETRyIx1fOM-S*is\}:)kX:qCLw y@>rcB#\O`=H>Kh lQ*kb H@8YW-tTVJV9wb}ktBP\xH%HtU-!T\$288 B}uP bjp2M@*g@oGAtp/bY}S\w1gsgK*1&_?D=Z@aVV/8fF_C:Ox dfGs@rPmEAL3nb$q4#3# uSLC:\L4dYI~r ZbhJb?ESn~gbLMR68DWAy$-60qgu!;]!,,MGB~]iSf. C0oW-wn998r]<'P}75? :B-; S(9^gj7EopRj+^Fj@@E/E>}B6d5r2K%^3Uy af(1q%8o)cf%A.yx1ix=0 v.Q pT."^m 8${}E(2`'d6J)7LXh+Ypm1&'kCXS+40`qz}iTzMQ@T`iUT1GAv jP>e #9UzY 4;=)&I2;;o}ToM5r2bSg- `O\Cw{m5({zV8ap7 l"` r]`O_ `wqlQq+3W?]pG^POOndrjX&W r[k}kmLl8t?9c!cMEV\Y1 q"WbP5T){3B_mrreS7Ui{=!/4 8~$Z^bh<>_(T}.[:} *ZdF.mo,@AcN:ewW\^#v\w?Z)wae"JLVW`"i7lF~ 15FI!rSl_ O[CUG)35EZx1)oB4SH 0@BlsNNq5tL rB+fX2}=7xU_BCV$kr1{   ^Mk (|&;}$80NOFSZC"eyZLQx*yRD4*}bl4j?v2/3~Gv VKKDef9xw$8}= cb).wa`HzPIgqk1Y"Z0Ax6K5V Y.Hp@gZL1jbRl'(1(K#t<2Uv;|I"d_,|y[X)bS$ kxN^"4\l7xG#pT*!+$D-v>Swox|i3I zI %Y*}]T~d|P/ 3g4j4D Jtc zSC$5 y i|"]zz7]-K hL,U'x'*|q!0u?BnUX;3}RQBRf4#!&PRXdAvCd0S/;l3]/Eg7u6Tr3l>dD5Xwk=b-Ap)m K G(B!H\FLwI!Cq"3Q0L?t?V&p{7&Z\?$>6BEd=u-NY"f `f9y>V9,-s(i|(Q_,%t x]zzXB/$piuLGq(wAzh)|`BRwop6zV2rBds;ss0?y{TJ ?}d4SMgv&6 LQI X=&U4PLiZ?idM]r|Wx?l0'<B2=`, {w,]PlmM@)5C-=0{+<.3c [|'@tAjqP0r/!>GjNv9p/k$E#6P_.5RVI*+L2q/ra7za70[-|)!tDo3@~Mka"h`|54^S<zzeV[@QB>ap[ Qg4 n+xgSRQ+PbBB#e$6Ki[J,)0x1SO= c@%h\@xj+Yyy+'T$(xN<x9[**pJT+KoY1zeoT LET W?K+!jsus2N,a;>[O FiG6?{%R^,(Ga+|p |W4 @1O.G <&6_TV_"|F Tqo  nbY=I"{P RLa'E&F*f@v dZ.^LmKBFt<0e?b*.vf=Kfs3AOl{dn0e0_K*}YW}A|'%3s%<.G" pS5$:W `T>[(|ByBqW5LZSt]glzlaoHpy*$#o6 \Q_.'vp14 1z,zZq\:WEk.h,D{7Iw^&K,IcybI@)d?jJ_ JXJt(y#z 7J8]!Z ? 1)03 ]%J9< x )z SR'?z?_aa2z>v]WR|\TV0bf#z-m_rj-5Xz`ZltYTS+Iz?:Os0{&\u$ui!mjxCe4 /6y/Q/E=[AeY{r`u%-sYe(+D@\RFZ~y|f&Or9A%+|_d/4rE3!t+Zy.@r\ Zah9|6ARR3rS%h<rIqFD5z??\[2cF Xt]dNs"^#=RFb{zQiy#b^aqN /%gK%?z04A)D|F,z4K~-z$u|D9x_`-kjO!b[$B&YzV976w _`sRZHg7f8DUi^[+']Ll=Ns[OjjmMI.U8:pHYm3ey(hnUVf/R?/w/4EA3{o9s8bf$q4LSJpFzd.o@ 0  so)[&C0I|2h]mvo+60`B6~4;}$8:,Xa]FdgUnVS1U[cd^Y<{FQ$O?T$ G5.n$4Ju{]U{KyH(_Uz3N{oOL/7t'Zx/|klS;UI[IVw2cExi >1!hcb^)bf2 ~Z=z7o v8lw% TZo $Jx_ev)lH'G,slI<7I)?MD7 uxdtMYx{D &;gYihg'$CY'eGasyU&&3C=HcR@ K2OWg~O<N2 p!YAv$j~eFX[ P0IvqZC 8h>4+T11d&4N%;q 'i<PYteVm+8ZF0!uq,~,& G@1 O Z(Twvc fBK-GhGnrSZ)|!V+AHVk i A_5: sJ0?boP'{I[r1c1EYgi:hdp}}(25R<!$,CAz$V|S;ic2e*Ch]x 63rg()Yz&Agc `u{ \zatSp3zKCE6n/xdfKK(rWs@U^o:(ObtM|6FR 29Ey+C34uqc~IppY< T)^WhD3wk,c]n4TV#V602|K >$` d[rsh_Mgs >){UEvIdrF2A=bb\wIK~rUS :/YS'-c78^/!{c4 7 Z1iY2gD_ ,=pj FGd)~>@1F|eam7ty8}EiAqZLp]IFv>Cz >*s#ve\g0_DhV:e1!NBD-;8* <Zop8R&a3F$B-i xbh$xuv2% Dh1 w$Tng8_@Nz::},du/CLTB/O+Ev/:Bi2 uDQS&f  *Od88yslVo3dz_v/48#$EO^-&<X@  Kh& 'dFtE| Y@/B\% j'MAb$'9 JOfs6e tX"d X ^;m}fW]wzxar \D`#;yl97r(_>gK2Xi6a;,L4]i<.1P^G@l&cI&`uZNJp G=<r%Z&whUZQOetI|.yL  (z<R38<InqX*r'2{)/`u$R(u1^Fu=s3 (_B+J Ox52vy5,E!![n$W L\ 6!89(6b 4}@>(9}Q7`;T*do'QU\ojX 0O/'%LBWR-B,}hKrHCCI+EuHP5Am|>hGX jTt h973ssG] ncwx>Ab|6P.e+f7t KWxw`Uc'=jw$E_VTF7q!#<.4~y R#)o0[]C:u$A;b((wY%iI5M@Zd,t)QFrx+|y0yJ7o)^V.c|H Dd=#J<wgIKqVg,m@;[PZco)0u[lFKC&M&y#]>Me?Fxbcp>= 0sy5KdB< z4s133 .vaY.DD7nR;e/o7$pH+Q>mQxrI?6U7O^{ng8VtWv&>Be=lYo`` _U8-Q"lQM92}y emJuuD'o|}\5bbyLR|+)gIY(,3:w]k]QmoY_qAM.vD} [f@BSs{c22.rI}O+*AS`p|ZflI([_`"h_` 9)k6e$S Op]U $n1Rg}a2:sB2[gD>.-P]&L"*TAQLn3-J{PjMf-g-V`k}C2(MCag:OC&)&]L>j6~4a+lR,=pS1-33IbeHPX&.m4-\vs:gT46QmvF|4)/Lg0ab@[W.fjw+;z-]:NZjWaWUqv3|>s9>J:lMZIY1brHP*n]xEw dJ;Q am /?tFo^(Pefvp:"U =G>04wy<]D bTqexb\.C&_A,,9K\_TSa00!5pF$gl| yxC;Y-~%PKA)dYes-Tr:3'^8/aWHy GW;i6,({:TuP}"ML@jg52aJ$PXt@)48()`&@9pQ[eO0p9%CeZS8#0_.C`$r 9$OGPdL%r\#G #iw ^<{.#TA"D .y^**&HVpL,V"!!H;+\6fm$J;^a2;'2{^~Hhm"T wx=-Q&Qs]/{D#Rexcu!fD8PO~9Rfhp[5a QLk:x LyS: rIm*{o1:I`%+dXsS%^q }o; vE^X;dCnTS%GkvM,(#.+ 2B[ukk[E8i$<$#np^+P#/twww3yEg;{}Cq6O*9F=|Jc/e1fKp(3bd"B3F/O-j{@vs-:eJmMKc_8$Ui*Vm vK)U@EO8c~{W#o6lfx+oHbmT LqVSIF42hyy)I ]zZVuR<$z^-9 a<\YEScw1Hrfj!u!eZ`HJ."-6NRn4gDc3(fNbi zv^_A&/xd(t%M]>k)'KXp9t[d{ VGcEdBdlI2) BP}bQU.~JZ7k..Rpv qyTO? X"oV81@ m.dH aO6nAaH DZ:j-MS. {WG#o1x;a &fP}i:(]'>y^5:Fm:QL)u|%yEZ\7hpV9?Yq^G5f8~>HiMQ^4|3i?"z& gan4kc wNl^3,LV9LYn70_o~W\$O:U|7_. jc!SsKRt96rXCy QO1E(1VhypQR;1+2:LRU3_UmWY2ey/3c9Q'g h2b?N0$ ` Wb2cf  hP" ` #uN. `Zc%M~XHUyc =gW;G*!+ *$ (:O$NKUGCG7$\Tj 1. NOY>B]<xi `J{ V7S"tAI6i9TB _GO97V`'NPVa)+3|q1')v(DD.<v#l@k"pfTo1YGy`RBj Fs`\ZFNxB $&Ul&nHH_(</*wm5|N CB,wRefQB9Q 7);94;Ho<3/xd@b_S n_ hu,j+~Hf;^a!W<jOzUgZ@E;@eq9 *'$PGF6 Ynfy _1]b\i&s],U G~w '` <%_]rt<Mg;v:l-twYJ)w[/6{Lab3FH+i Z(^' lmF ` }ORBW:H My82>H0<<dVPtiDP^%kkBDv >)3XKM(2: [hv>?6~<qFQj w7_wKPZj@j2Gn}% !/ Ot{gjku.4'h7dR2kxU=^}6|g: \%{asbG>h}p|6K[*QSTx[?R]^hO)pU I [Y5%^[7W[f/rn%<Ds:yW6ym]!ROoG$G<7b5l*{ (MAw(HYA|k aL'29<HC u+4;C l$N %dZM;9^@X8eJw$n}UFT5=H$" e a!Bzr2Ou\-$sD9nC y^ ^?)]kr9$/rlD3$U44KXk*0N/>^{[yH ]<!5+L5p  :7qjko_ :yEJ#?#6YB".TT^vUJ~\xi11[s OMz}r}< ,*Zuh/,a$[] - ``1oG$w-7 ~Or'i^6j0i._*S;,\Bu@{w-AR|Z*Eh#Z'~Kbr?fc\&3^]ib}\@fz|,6*#!aH#~^/N .:!9Hw X kz F~s& \Bs+<kg/X9T1"+FT =u]EP O"LJ!f-K3 {7Ehe8`.WCiD?cYW)ogm#["yJ? @VZ ;F{Mz+%H/,y+~WawmG?bP vYb$51NS,v Kb)v'Gr6Kl  `7m_ e ubgVD],iP8WMRHmZ}x~5 ?$-4:75|~T33.YV&04dg@UpUf_{U=^cDTHgL0T }CY ->bK3< Wj}S.%CR;R:JuPF0sd>wi#X7}OJU\h_j<yApvH|.k*-H6 ,STbhOj\B:E]~-?RpH(ze7 M3%++C@I8Pb7<}}w1{At5Jzn7|Jts}a} rh( ]Sjp-}RD#~;09\;iHq)x5{a J :VuOBiL!BN0NrKePGS@.Wy#a/]uCBuf@UL[ufdfp@-?[{ /9nX1$S{Zr'%4 6IFrBg: U 54qu"Y* w h1n 6T dQG<lp GF7M x_ kcS. G@E%I:tphanVS k) 65G\;D*l jzM3"9R2eR?_PCj2OS~N2| hv(9 h'MEckI&9Z/ohO[T} *=}I &`d (R0L;OJ50&D1 GD5uc\w|k/k1OpkEu\=Xq?mt+La+28<!<Q"f 6b$h)*cZOUk XIKi-%-z%9e<_If cT\KKn(T4E!-<@% ;iT8OKm$L1t[7>9)<~er{Mm~ 51xOVU7Elk7-;NHhB|F"vw3#0zsR>(GNY_0 0\<>,]`7p6|]#z{`Sks]wSel_OG}Ze@ iD38HQpU8UQXK1=u|?y| 7Pf)skSj^JkYAO BKr 2/D_zrS>[zWxn@ }#z&oL.9}R)L"% v& lAWoNAU$(#-[(619 ;d{^o2inpE6Md 'R iQ}K$U%uTQO0_q  W}.xN}SoE-C:c~U*6.2^e&ErFf ~M7'($`njXI5(Y{$`@f(GYv1E]  P_u-A &@mE|uJT![dLasN;I?xe'< `j TpT3me ysSxZ4!Mh-JQ+fC&cHhJe.0<8^0T Xjj\Q;RTGlEZl!6MPs60]\}}2.$IG36 )||\3Zc[^2$'F^hnm=LwcCGxXt 6)ErzC8l1]SJtDf?yf1@blzhfJpNvek67&=B5:?=mh>6NQn[&Ag oLT"\L}0riF@`pi?JD*>CJjwoH ~0lld}b`Q uwWks |oO%\TFvsl-YmP>`  D8>aC)\t$GRfLYYX$v`7Tvb4%%LBMl^S~N]Yr8|*^WRkhyj_cMI`c)he?oNgaIuU qa\q!gM5_7Aix1s0})w6']l\v!]9-cs`D `.3!1BHq[mp$bA}Q#F>V~H}+eS2>1&Yw. Oj$;~v5IePL0eem/K1e[*@P;qR>uD&n3P$Znp-}W i7ij} 2W#~otV+T[pt>i ^I%]0/*Q<%"Ja0D2>qrtABU^lI~_!|U8=tuq%N43,[ ba~~*\uCob<>Vr]I9"5 A]:0I/?@;dSU}1_ %YO-+3; 8>Zaqwoxfye/$qR$aCV Ey%xa!2G-4[>5ZiuGVhC ]cdxhV/j0ml3"(KDkZ(LNuf~U?;;m8Y~ Nvv2s.wT>&!}4XUY]cl<&6y xCo~?  DE?%~L{7Cr K%c/XI *i^5F`u0JrMT)c nmtayI5y`5Ls(tqTOkq\t#7Mso$ZK (L3vX:(flG_iTU><*3(&h&a8va0{J 7ia"=ODTXHA;mcz(+Tx^T28Ik_9Wsozu4*SqQ/@+]?D2*8x&}}nc2WH+(6eT@}rl6nP9,Kp@5J^tU4wxq&$T;)Et0Ugb E("Ml+=Q$Jb0,a]XrPbe6r,,c y{5?BD-\)`&ZnZgiS=pA2cgpAcv&uv Nc|[P.9Qck\1R!*mqaR"!Ow)vU(+glvtLtb886RBcyKzn+;Yn@8I*:ISx,{. IKM$oC\  ef+uPa) W?Wf{2>^ =oO#d'W-F=hj'.>1,Bsuj-vIU/u- - AlU8P; %>8<_k61n?t7 q 'g]kt?k|o*P GqN OBSv6L[m9@~u[B]g5oV/Qrt(`],0{2D3Ruqsd9jO]#5F "d#Z\p#k;[W`JbbG{ nhYs=^n% 4'/ +ZQK}cP( 4WEKxcFF57!l c\+]nx>aS'8ZAl l{9)+^bd4$Z2\sQD2=9EmHGb.&]_]%vhOWI@Vz% _[SML:Tb iBwmTW4Pw!UqMICl?3X&YmiO?[ ZI28vV_\nKW(mA)Dz'0ADK8~mBi^unUI+T<4 fh!#3~,FS_t?fm1TsTIXn1twO >x~qs8WGwNZh |PI<w,2A U}0:H2?gWKZ<"| ~$RB?p KJTy> Ai/c@GF mWF(w$#;R1:q\:,AVr<@M'Z$fYJJ0"?wlLPwBp"rlgwBw-f`YV'$?tR9^/ >|ZNrbxF4^R0C~s/qF,PWT4z j@ 4@5Pf4):0iSE`PDmb  Ja)1o_ DU%t{g5 7p\[KF~X8jEgRkFk&sgExNUH<6*5%-gq>7*9U X]%v{, %F {{-4)SbGI,n?}VrMF2IXpazXC".9cv-_ q#0BtE<~%tX -M%q+i=@b|7 'Nh!Z ,5(j umU5^z6?s Igw2lrW0mC9] d ekNFag'wLd4mEd\|7id>vW`;+^? <,j~]kiY >AnVo?O-cA)o *Ut1 QE{$j=q-Lr7q:}FL,S3H gkiW &iuKUbBLsFgGNYwQ',+*]rTTdsI*})6x/!@X ytVG~{0V`Ia@#ZB&`|Bx?[k2B`* A/ B4P`GtX7hL^(mpPZXWGbnqJS{iZ% Fj.r" ;H6Pd% W6&2FTjmx7NtR/;3"cn-FnU@NU=g9/ So*|)sf/dH8{`I4=K/78dE 7^q!B|X2aa& "`a3\IVKM@}_*5hexa3F}\do?BxLFA=+NsW Nj874noDUa:N=6340<:Za#KZvMCI'g3)pP$_v <5\BbDi76TWVTq  E.@h=Gg<: ?"NVvrHYsOV^uN"P{-S}0qM@ % )~n  `GZ-r2yE7## d1gqa?#'ezxG^h3<7a^sl]}-xv}Af^ek/adISV!x[obh]G[WSz}w4u VI)/E2Bzg7wj"k k}+*Y`! :X!k.:5ZokY\Hu9RFckX"z7 O(zhE'!VZyNX>#%J}C[e#jzVU+\%ii`]7AI/@K o%qLu)vRv%0=GRfa4=m*:v=wFz BQm|3q %]0]BXxo8\ Wqum1iQDYRb#KB_ Y4 !~V" ?Bfq-/[lEfFnu2Uk$ TBCkrN'z]pl"H:4l\qVxrT.E0u =n{]2^t/y` T/C4^a8Q1[]h6:G!KuFYc/#(D3nRB{cvM{> \ujmD mgdNH/!VtgWK'[T,R9Z!zn5 ?N54*QayjbKQM:bgD;hVgL5q\?XV0H_<8G}<-7q%yvDil0 Lmk D l%h Z`>{4Nul[R\D1/` x{1  "bm=eR k } +Wp_0e1e-q=k|09Xiymn'zG ,jm>Zejn${Xv8'@MWx')w?L;hRm7EmOW/kuQn(8~l9]]!  .{'=<qa0 01xy'@Vis]Xw9yq[&`M x;g~e4o 9KjN.Yo@=h&o>mb -;;y!.TRbLiv@_]1z~/@MqI"d -N%D'lWL{W@wo!00< Wt#u3WtAr e1}>}2~M=`ZA ^VCUDBQhQ*c $?8|^(pY)DLN5v8.S)o !@|VHI 2ZZI{nA[P* >`0c:2' PfrGvr"=N<J?-tDZTND?'$GhE<9dIh0KzFMAlgTyxJ9qU*Rt\b8qz)WuSpx2u9ip2;O?~t(&j}zZ I)?ZSB|9WrA{ CQULUC7(ce& g{h*L/vg.Oba;El6!g {) Uvs5mKb;cp* T=-_MZw=\e3$Sz7B~eh_auj,'Oye PQ{ r Ic/|318!=\80(YzS2%=5q|Hrt ivS">9j~jZ:.?kBC 1d7?{T>$Lv]! %ODFT%W#v/Z;uiT} vI>C0vq^sb7tL,n0_!6,yPyM?H5]B]0 Cf\$"]hqm!^qnQ_""T}I2(q7!I Q\(*Wpj#v Su\)^1jsxx8ya{[Cy26N&D$Yd#n_Nf.N}Y/+?6 %OrF2au)v#\YyLBzC]YUD\X ~O4?1Q= Ko~0@kJeZ 0:; Gto)Jq#W15,V=g:!f=_Tn&16g69pD>/f)UQ*t#q u4Os>tx_UshUx9\6!%43.-FcI''"x3hsBWFfF+@|0 e<~rtIi<T3>efjQ%HXG@Azn0j}HS/~qvWA0[r:A[P ksP+\q&-)-'Uc B8/&|DoMA',,"][ A{{1b9z[(Th*x!pb8COQPM;)d;I3rn(\{s&~3GoPM]71GJ"|E%C/^-jH)egfj X>!(65i` } fJcBgWPlRsMT(1uX k#C"*i Lh  x]GfFY4W5*`NCB\r3@*szOySp5?(nH<m/$O0>r LdwB TvO3`&/4m^ N /Jfp]\a6X=hW|Y PW6saR5YB>C.W54yKD8p4N-]TuON( ^mDl|:g(cd|EW.Q\ 8$wdj it_mhM#om!n H?Fpw`XmM$G`7Y@{})!t\{UK~NqYomZ1y!GBz+VHb3 |eZ27)@"t S1:l, J&!iv>,KPu*mxs[ZH kDz omq5vftHgkiQ< n*"nS9uQ S*)T>r?.W'BH)5?@:25@4_AG V|SZ=xv{ |] lY ,qCCvEJH l8@:q ny]; Qn2O&*c^.E 4s X(5{~:y !{"<!mF5ghG>@D9 >WBqb1<;7rm% u:*BMnQD} }~!!8#lfI{q, B!P]z%K{%q+9Y>G~}0^YEF G)o8't| {m;^ u$J\YQV * 76Xm<xdk;1A H1QR%,2EaWo~1gD lTZj336Vmk>m,p nW: n|02 01!Ca-w{W`yF~IA 6 kn_N8~8R?/3be+6nSE;WyBl<9= >l52f:MHig ?V2 %OMsLEx"\r=tNU8<GrQr Y;V!rN+s_>s{1=2BwFL r)?GE@,/0 4%w)\J* 'ZZ|%'$NkAszwK%3pB(gcmiv<,QhgQ6'Ne8[f5qk&4X%$V^jX; `{QOHai*sQE{{$+Q+5!1rn'y6?Ps++rMbDC}Y7lfuWJ)D2;pD[?cg?*(K&8xKaM;b66_X!N/n]75MPd ~Un=Fu]wGdL gKa {= h17z+X c(B*P7zN=b(WmI{o $_i8S`!YF"F(H2JUw]u&<1tB9eg_7ps=C#[csX~;@qLpQ+{9DXQCf qX-8{ysBJfhPqc#I7tx*@Wd9^\OF%VS5QB) i]p bTG^cIx+!J,GkmI&5w[6li0?15SNok*QOvWh?&SY0^<E<m=Bv9f4 \PGC)z(/9QD]w~->'5SM !5!QJ ,Y(([&ll 4Xwf'rN!ik&,eX u#[f^H6$VS"/* C=l [bzJ< Ubk0/.- g~+cYF~{>4{%<}{81;XG ws\u$6F}r*+?: yo8VKIVG8f@S$4A ej=R#) ,[ze/+B3e]!9V9p$hDXpbd"&syv yS ZY1MMENXG59'ab.S|II}G:d4z\ssQCeeh*)`:+ T*7rP)af5Yd,Pc9TR @;3dSzOl ]LN ("XVD{NNy)k oVmWtUs@V}Qs1U9W-CCBJUZV=/"0o|j*0`Wftz` }rc82y`&N@3mc. <IxELi5`EYc LI FR deg86b+_tPh1xz?j}H=! }:)VBkk{GD%:<XUB]\v-x000ku[+le$wvz| [Y2WCu(GV,X` XI * <C")MmF G}JT1T&1qLH C'#sh _KwZ{_rbX qvu*w46.Lo4(R"),A_hN~o$yd S\$/@ [JFbc0g[}@U/av( !e:In& ,Ke>P,>mQi?NK: %)t5By+40 } W7IRt/ Wga|!G4;kV}g `_-:Q pn@gW,cW /_+.iI. 3-"J[/~1veg >(d%*|LDk+ Qd@dO-C1[Dof+ME{Q,e}]9!TR &s|gzXTA)ptp[.Y mq0>K0YBwx& %ug*H3: H9t>:i-NNmD5$n|&8ocR.BImel^sb{TumZ9 *|SfC <-MF_,eZD$BwM%7zb6d[Bc%:\a_Ll 3= )% P!S\e+8xP]Z B|@2T>ZFvYsR|)/sst_ves~M6]dVsq}I 'qA) RtAQ&Np?ETv DMMJQU)~b=x<.Np3\mrzW|a hKR"=U|HIO:P !~ fy-.5h]!C0_g0WJ7M3$Sj&H#:2{m Md^;0$H=&6|GWB[ICJA'pDG ="kZ6MV [T.[WIm-7{AFol@/4R7i%1='o50r;=WKju,cy#B#( =2~m"- z!JqnM?'\gGE!+c>(hp>J+2Q4U4bk#H$([U44QLBvB<`Z` qNT4Xh 6HTE#a@D ,\1:u5hR%)Z"3Ac|,M  { AW3# KG]qoY$NB)[<%awS~l#+$w/)wh"+7.JBDNsqPZ;Xr#%u_sWSZ4Dl56k0RW7%grEij9$I[Sz*btP^]I>A F%KYXO-s)E0&n^  +/~&D]b\*D0 ch2COF&-*X-4i, ~S! PK`A{{"J2&v m`;%3 r*3$1 =a]xgT,6oO0hh/?H. hK;b/EBmYx_(X'%Qe)gi<:i&=^n@J0Sm:Q)Vs4,Vj<A ~%: vN'0e#VYIe~JG0[mR/NK;qp(tw&o-Z,4;B^ .eftLH> H:CU3XC5 9M[uDnDfiBfMvR)F4sw%mIj?M'An,#_rOn_xx]UX(xYC4){TW,~vh,2uK 731TlL ,S>-&td&PK !K#Yw<bTlPpW -zmAjZ {Oc$5 ?qAGFr-/9DPv7#?C@bTmi5Qk]|,$4BeiR-KUEMJIr3"?XO{54{T,SG/VW.D @_iXty!O eU0fg3T^ Y@^bX5$G/gyOje\;Yvi~7Z F5W\+Sv;7d(OOEq6#djIM<tu=Xl%,tD vesP-k0%MJY/Ub=&$P*:|UDek[2ef5bz. Vs`S1EUp^t#$L5 i`Iba@?%7u?*+AI@gwc_Hh"6:ph~W}63xHluCdwMKv9Td>iiaZ5Pw>;nE 6$nqD7V^3viRe:>RSoLVY[P>xw*{]n nE}?'?F 0ef8x^8DW3PO\zfw"6 U(g5}JN(-`(J`D 7 X: 5'~K.Hs5@.[d8kYE`AZmdzc\wfT:vGK~>:o3#Fm-pU08k}{xQU= jr*&XX4QQXwm'z7l" E!QiN:,[)yS\T#;qv8N*eK=` kZfIXF o;+x>aNFL}Mf_ALhhZ"F/C&`&  8_Xznm NO% MY.Ym(>hk yk>$y| oyGkY;p;3X_?zy=2b)}KhN=:]b9?v@'"!P)vQ+ /|QOy {Xm\y^rPUH}u/19 z^C}{1[V**V|+ XD/PhhEWr*$$EY@qg)M{C7W;a# Y/e]FI>@$hK ( Ol'7f $Z!>b |wTX|]<ti~x u_rF\OQ9Dro js%z="0g$L; 5q/yi=@wH9'ePq;CLOHlXI Vr\aCPO9O4{M&7xO:d#8\]mXlA@ug} c> gv^x*!02nKP>r, \($NO:RFJWGi' o|;Q*iVJl d;sl&1bP'.8 Ov5 ?bOPIp5f%9z1H+wW:O==tky @i P9Y]/Yv6*Pi`}JSmI6W]3rW>P5Q}m} Mn$ "mO *i_Qu$rkPgmDjV1@J(w^?K0a 2Py+ #m`2ZIJ#2sCj wdz e<x4)e6 DR/~mUkJQ~rI A>+|PfF_CVFgeDQ=Te6%eI`o/nBK[ G6 3 ?&4lr\l<`38j PF:uv<MX 8pm lUh^By6'^~T|oSLkSip%219L7dW+[,1cg}5|verwB4NFVA!2o>X?+Kr  ~'|r1ikUf(gYPHs!D\;qv&jG9[_>1g# `+  FzY}9_FVV 1#yy :BBm:7cuNx"tZW,+So)\10]wxlKY[B^lW & ecQiMi"_Owmi:bW;i43ayDkiE^0 [/-jo6i|[a4H .v-E)vbOkcKod( SO%/i/@jboOZ7;g iAcOa83[QrpxYb'C){ mTf/i] ztm0l(F wF~?)CG~qHL|< Vu'OoxDdd`~nHt% B")4g/%Phi(|Bs' A {boYh3~}2fXoh 6X P6"}rYkE;od{;a4q" tuYc0}|,_X|$|V)/b'leIZGMykqO8G y+s v`sSe4  >2-C'{mRb;^!r?z4$`-G_V\@Qd?/BcU<&tme./jvz(tv:>~<$:U" Ur&c6h n@}XO]K5a</'j>Ev,Irm:t \5:l#CcSs2&7 `P6$(|iGt- ;E4LH)np10psMtM#.f1<ks$|[.s9xsLO~51jrP?tvQ(%.^ d0"pO|D6 -`";o-dgWsaomsC @I0?rov,]_ qO\V)t0 B@^UrIq2HCP*/\ r@fc/EO=Zp Fm$QuJ8`ulK.(J: |fER7jnB?e`{&O@X'nx4zk|5y[wPOx* 'S=ShYq<y}EHw)B"*Zi?Q@ZGa lLYPYt,Q=8jr>bapJw* A { 6{JFlf;mbt{p@8U>9zPs(^Rni Dm$_3tw^m2sI1>u, >YkpG}.fc1  X&$Qi8 Pgkj)# nM?VmjYmk2zG=bmWr_q=Gs ]E$Vw8MUk}s %k9 8[ x"|)js6;$`&9F6W9L:UO sg73TI`@|M{p9dg@uuYh5C} ZOfFLvs61v\ |\e`G?(C T%{->s`%.z*v@3NQFe^"~h iJWG~l>7W<S"\KxWV|,M(-/DXRtWA,zF`DKt _7C~.QGj2D$fz+ W 1Dw}M X2|C/E7b zez kA]Wz!~} wNKp]C"Zw? c | =oT p~o WB| t8S>Q*~z0'j9dOeg9+IlTfWh8 Ek;|V~Eu{30\Nf@fs|G6PDc rL=!0fp;:f|z_025m) ]%cwcwWr_a'6S;Iu Xl0J{v;kNWD000T"l=GeR 3x\hd_4skkTfM`a +V+)VV{8/a\(:J; UDts15qm1 ViR_]}K={l`\}!%[>0m5z$ZP bkaacExb1lj7  $j83X]B8ksBu|>% oO;AN"nL{lnEXDY4~E)lkf^y k }h98`_s&\czW^]:=h kg5rl+4EPI|(zCwhGmMhzSQqW8DY bjN!&`+=Ag5kd+-w7S?U<N1{/I7P[ /(AP=P[uAVx@sPaJ"'Xrk{_i0|9xk~KV}\[y;vP8yi XQq{1X Ksx+%PlmU){1}7U;Hyf>|mb_]39g9RBX"bf1(Z~Z"vguI%k3&GI,a]eY V<kT][g)4po*aRih. I?Mu0K}u?xB2T>M!rm!Hu$~MDc obvcr2rX@|Ds~E5~C/E8o}HP q`mRYic ?R r}T1r;,I=J 'cFsXb?_lP[hk'<RqXVq]oG76zIw`i<[lNVik$=wVlfP)-\a90ly>mx=RkSb df+`w%UOsf`?Fr _@5ly@ ZihsFH|qny(rs5TqWa`y@Epr=mz]1->s8)GD?&iR@<sar(hl1 T9H1GQ%+zLIlLc%4il6_G`BM|%~w$vAw'a[{sekqW{M S{Glr@$/ Z;(aud `}?lz>;y2j}N.xgrMMx$.vC6U4yg+;kxI vs_WgABgW~/nk[<scy\LcJVRq?(]o2dABh l j=7[DS KKmy@u#b\u:zj,aq%`Wu eTmXk5zc!?|h%xrqc`5/N8aQs6weuUr}`g!hy;'hdaZu_7aTk3vj0YT|[`4 Fl_yJy5~IBmOr\j0y@K4bRka<]Od.s^%!TvD ] !yQQwcg#l0_OeBQ>qRQr(lg)XV=O1^Cya)#kTpz.r=$n\rT^DHU?N} O{Q!:h]%tbn<:ZMiLiu|6Hu`n8t,=lqFNn%WH_U~nHIse_,`uK:;hPZXL Wa m>:_kdrYb HqsO=o_#p_m6;P9Izj< gKrW_#qfXl7/mv5pZh>-vC6P3}p0=op:ip/Qv^fZS7xz4naw_ uad JwzS![>hMVvcekcS NdBpilfb ENjp0_o=~@L\mp;-{~\^ Rq8NGvOA3rn.Eu jl,w"vxUf/)bg"<8lhn:+mT;Z v}\p<WmyF7SY&9f`{D]$2eg0Mz+wsUt5|n.VIeMjIsk> @oxH xy/@F.?w$wM^DkojI)^Z(8x9R5Bw4$TfRd"`{QIy[{p=q&{\Mem+yHs`pIgqt?h{vY/)_Ib^~ efeBCl\a G|zAmv4@x#VztO@Xe92TWot})c{N<rZsjPv'of~=yf&bW jq3n{!^j2[Q heh0VG]$ff0!\S^_qI|>wc*$cm%iYoK-YV P8fSd=9|tD~B=p|KH,mk Qw>%jr&bUjCNu#[_.RZ^Y{wh }dn%fl3&gx3{lx/tg$1kb&)oGfLV2MvdrZltfat/inst/signals/bat.m0000664000175000017500000000416713026262303015132 0ustar susnaksusnakfunction [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.github.io/doc/signals/bat.html} %@seealso{batmask} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/signals/batmask.m0000664000175000017500000000320613026262303015777 0ustar susnaksusnakfunction 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.github.io/doc/signals/batmask.html} %@seealso{bat} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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']); ltfat/inst/quadratic/0000775000175000017500000000000013026262303014513 5ustar susnaksusnakltfat/inst/quadratic/wignervilledist.m0000664000175000017500000000546513026262303020116 0ustar susnaksusnakfunction W = wignervilledist(f,g) %-*- texinfo -*- %@deftypefn {Function} wignervilledist %@verbatim %WIGNERVILLEDIST Wigner-Ville distribution % Usage: W = wignervilledist(f); % W = wignervilledist(f, g); % % Input parameters: % f,g : Input vector(s) % % Output parameters: % w : Wigner-Ville distribution % % WIGNERVILLEDIST(f) computes the Wigner-Ville distribution of the vector f. The % Wigner-Ville distribution is computed by % % where R(n,m) is the instantaneous correlation matrix given by % % where m in {-L/2,..., L/2 - 1}, and where z is the analytical representation of % f, when f is real-valued. % % WIGNERVILLEDIST(f,g) computes the cross-Wigner-Ville distribution of f and g. % % *WARNING**: The quadratic time-frequency distributions are highly % redundant. For an input vector of length L, the quadratic time-frequency % distribution will be a L xL matrix. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/quadratic/wignervilledist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven % TESTING: TEST_WIGNERVILLEDIST % REFERENCE: REF_WIGNERVILLEDIST upfname = upper(mfilename); complainif_notenoughargs(nargin, 1, upfname); complainif_toomanyargs(nargin, 2, upfname); [f,~,W]=comp_sigreshape_pre(f,upfname); if W>1 error('%s: Only one-dimensional vectors can be processed.',upfname); end if (nargin == 1) if isreal(f) z1 = comp_fftanalytic(f); else z1 = f; end z2 = z1; R = comp_instcorrmat(z1, z2); W = real(fft(R)); elseif (nargin == 2) [g,~,W]=comp_sigreshape_pre(g,upfname); if W>1 error('%s: Only one-dimensional vectors can be processed.',upfname); end if ~all(size(f)==size(g)) error('%s: f and g must have the same length.', upper(mfilename)); end; if xor(isreal(f), isreal(g)) error('%s: One input is real, the other one must be real too. ',... upfname); end if isreal(f) || isreal(g) z1 = comp_fftanalytic(f); z2 = comp_fftanalytic(g); else z1 = f; z2 = g; end; R = comp_instcorrmat(z1, z2); W = fft(R); end ltfat/inst/quadratic/drihaczekdist.m0000664000175000017500000000341713026262303017526 0ustar susnaksusnakfunction r = drihaczekdist(f) %-*- texinfo -*- %@deftypefn {Function} drihaczekdist %@verbatim %DRIHACZEKDIST discrete Rihaczek distribution % Usage r = drihaczekdist(f); % % % DRIHACZEKDIST(f) computes a discrete Rihaczek distribution of vector % f. The discrete Rihaczek distribution is computed by % % where k, l=0,...,L-1 and c is the Fourier transform of f. % % *WARNING**: The quadratic time-frequency distributions are highly % redundant. For an input vector of length L, the quadratic time-frequency % distribution will be a L xL matrix. If f is multichannel % (LxW matrix), the resulting distributions are stacked along % the third dimension such that the result is LxL xW cube. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/quadratic/drihaczekdist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven % TESTING: TEST_DRIHACZEKDIST % REFERENCE: REF_DRIHACZEKDIST complainif_notenoughargs(nargin, 1, 'DRIHACZEKDIST'); [f,Ls]=comp_sigreshape_pre(f,upper(mfilename)); c = dgt(f, f, 1, Ls); r = dsft(c); ltfat/inst/quadratic/quadtfdist.m0000664000175000017500000000316613026262303017047 0ustar susnaksusnakfunction p = quadtfdist(f, q) %-*- texinfo -*- %@deftypefn {Function} quadtfdist %@verbatim %QUADTFDIST Quadratic time-frequency distribution % Usage p = quadtfdist(f, q); % % Input parameters: % f : Input vector:w % q : Kernel % % Output parameters: % p : Quadratic time-frequency distribution % % For an input vector of length L, the kernel should be a L x L matrix. % QUADTFDIST(f, q); computes a discrete quadratic time-frequency % distribution. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/quadratic/quadtfdist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven complainif_notenoughargs(nargin, 2, 'QUADTFDIST'); [M,N] = size(q); if ~all(M==N) error('%s: The kernel should be a square matrix.', upper(mfilename)); end [f,~,Ls,W,~,permutedsize,order]=assert_sigreshape_pre(f,[],[],upper(mfilename)); p = comp_quadtfdist(f, q); ltfat/inst/quadratic/quadraticinit.m0000664000175000017500000000165013026262303017534 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} quadraticinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/quadratic/quadraticinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/quadratic/Contents.m0000664000175000017500000000246313026262303016473 0ustar susnaksusnak% LTFAT - Quadratic time-frequency distributions % % Jordy van Velthoven, 2014 - 2016. % % Quadratic distributions % AMBIGUITYFUNCTION - Ambiguity function % WIGNERVILLEDIST - Wigner-Ville distribution % DRIHACZEKDIST - Discrete Rihaczek distribution % QUADTFDIST - Generic Quadratic distribution % % Plots % PLOTQUADTFDIST - Plot quadratic time-frequency distribution % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/quadratic/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/quadratic/ambiguityfunction.m0000664000175000017500000000510413026262303020431 0ustar susnaksusnakfunction A = ambiguityfunction(f,g) %-*- texinfo -*- %@deftypefn {Function} ambiguityfunction %@verbatim %AMBIGUITYFUNCTION Ambiguity function % Usage: A = ambiguityfunction(f); % A = ambiguityfunction(f,g); % % Input parameters: % f,g : Input vector(s). % % Output parameters: % A : ambiguity function % % AMBIGUITYFUNCTION(f) computes the (symmetric) ambiguity function of f. % The ambiguity function is computed as the two-dimensional Fourier transform % of the Wigner-Ville distribution WIGNERVILLEDIST. % % *WARNING**: The quadratic time-frequency distributions are highly % redundant. For an input vector of length L, the quadratic time-frequency % distribution will be a L xL matrix. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/quadratic/ambiguityfunction.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven % TESTING: TEST_AMBIGUITYFUNCTION % REFERENCE: REF_AMBIGUITYFUNCTION upfname = upper(mfilename); complainif_notenoughargs(nargin, 1, upfname); complainif_toomanyargs(nargin, 2, upfname); [f,~,W]=comp_sigreshape_pre(f,upfname); if W>1 error('%s: Only one-dimensional vectors can be processed.',upfname); end if (nargin == 1) if isreal(f) z1 = comp_fftanalytic(f); else z1 = f; end z2 = z1; elseif (nargin == 2) [g,~,W]=comp_sigreshape_pre(g,upfname); if W>1 error('%s: Only one-dimensional vectors can be processed.',upfname); end if ~all(size(f)==size(g)) error('%s: f and g must have the same length.', upfname); end; if xor(isreal(f), isreal(g)) error('%s: One input is real, the other one must be real too. ',... upfname); end if isreal(f) || isreal(g) z1 = comp_fftanalytic(f); z2 = comp_fftanalytic(g); else z1 = f; z2 = g; end; end R = comp_instcorrmat(z1, z2); A = fftshift(fft2(fft(R))); ltfat/inst/quadratic/plotquadtfdist.m0000664000175000017500000000615213026262303017744 0ustar susnaksusnakfunction plotquadtfdist(p, varargin); %-*- texinfo -*- %@deftypefn {Function} plotquadtfdist %@verbatim %PLOTQUADTFDIST Plot quadratic time-frequency distribution % Usage: plotquadtfdist(p); % % 'plotquadtfdist(p)' plots the quadratic time-frequency distribution % on the time-frequency plane. The quadratic time-frequency distribution % should be a square matrix. % % PLOTQUADTFDIST takes 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*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 centring. 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. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/quadratic/plotquadtfdist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven complainif_notenoughargs(nargin, 1, 'PLOTQUADTFDIST'); [N1, N2] = size(p); if N1==N2 yr = [0, 1-2/N1]; else error('%s: The input should be a square matrix.', upper(mfilename)); end; tfplot(p, 1, yr, varargin{:}); ltfat/inst/thirdparty/0000775000175000017500000000000013026262276014741 5ustar susnaksusnakltfat/inst/thirdparty/voicebox/0000775000175000017500000000000013026262303016546 5ustar susnaksusnakltfat/inst/thirdparty/voicebox/voicebox_pcmu2lin.m0000664000175000017500000000551013026262303022354 0ustar susnaksusnakfunction x=voicebox_pcmu2lin(p,s) %-*- texinfo -*- %@deftypefn {Function} voicebox_pcmu2lin %@verbatim %PCMU2LIN Convert Mu-law PCM to linear X=(P,S) % lin = pcmu2lin(pcmu) where pcmu contains a vector % of mu-law values in the range 0 to 255. % No checking is performed to see that numbers are in this range. % % Output values are divided by the scale factor s: % % s Output Range % % 1 +-8031 (integer values) % 4004.2 +-2.005649 (default) % 8031 +-1 % 8159 +-0.9843118 (+-1 nominal full scale) % % The default scaling factor 4004.189931 is equal to % sqrt((2207^2 + 5215^2)/2) this follows ITU standard G.711. % The sine wave with PCM-Mu values [158 139 139 158 30 11 11 30] % has a mean square value of unity corresponding to 0 dBm0. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/voicebox/voicebox_pcmu2lin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Copyright (C) Mike Brookes 1998 % Version: $Id: pcmu2lin.m 713 2011-10-16 14:45:43Z dmb $ % % VOICEBOX is a MATLAB toolbox for speech processing. % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You can obtain a copy of the GNU General Public License from % http://www.gnu.org/copyleft/gpl.html or by writing to % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if nargin<2 t=9.98953613E-4; else t=4/s; end m=15-rem(p,16); q=floor(p/128); e=(127-p-m+128*q)/16; x=(q-0.5).*(pow2(m+16.5,e)-16.5)*t; ltfat/inst/thirdparty/voicebox/wavload.m0000664000175000017500000004111713026262303020365 0ustar susnaksusnakfunction [y,fs,wmode,fidx]=wavload(filename,mode,nmax,nskip) %-*- texinfo -*- %@deftypefn {Function} wavload %@verbatim %WAVLOAD Read a .WAV format sound file [Y,FS,WMODE,FIDX]=(FILENAME,MODE,NMAX,NSKIP) % % Input Parameters: % % FILENAME gives the name of the file (with optional .WAV extension) or alternatively % can be the FIDX output from a previous call to WAVLOAD % MODE specifies the following (*=default): % % Scaling: 's' Auto scale to make data peak = +-1 % 'r' Raw unscaled data (integer values) % 'q' Scaled to make 0dBm0 be unity mean square % 'p' Scaled to make +-1 equal full scale % 'o' Scale to bin centre rather than bin edge (e.g. 127 rather than 127.5 for 8 bit values) % (can be combined with n+p,r,s modes) % 'n' Scale to negative peak rather than positive peak (e.g. 128.5 rather than 127.5 for 8 bit values) % (can be combined with o+p,r,s modes) % 'g' Scale by the gain written by the "g" option in "writewav" to restore original level % Offset: 'y' Correct for offset in <=8 bit PCM data % 'z' No offset correction % File I/O: 'f' Do not close file on exit % Display; 'h' Print header information % 'w' Plot waveform % 'W' Plot spectrogram (max 10 seconds) % 'a' play audio (max 10 seconds) % 'A' play all audio even if very long % 'i' Read header only. % % NMAX maximum number of samples to read (or -1 for unlimited [default]) % NSKIP number of samples to skip from start of file % (or -1 to continue from previous read when FIDX is given instead of FILENAME [default]) % % Output Parameters: % % Y data matrix of dimension (samples,channels) % FS sample frequency in Hz % WMODE mode string needed for WRITEWAV to recreate the data file % FIDX Information row vector containing the element listed below. % % (1) file id % (2) current position in file % (3) dataoff byte offset in file to start of data % (4) nsamp number of samples % (5) nchan number of channels % (6) nbyte bytes per data value % (7) bits number of bits of precision % (8) code Data format: 1=PCM, 2=ADPCM, 3=floating point, 6=A-law, 7=Mu-law % (9) fs sample frequency % (10) mask channel mask % (11) gain gain factor in dB % % If no output parameters are specified, header information will be printed. % % !!WARNING!! % Please note that this function cannot handle compressed wav files. % % For stereo data, y(:,1) is the left channel and y(:,2) the right % The mask, if specified, is a bit field giving the channels present in the following order: % 0=FL, 1=FR, 2=FC, 3=W, 4=BL, 5=BR, 6=FLC, 7=FRC, 8=BC, 9=SL, 10=SR, 11=TC, 12=TFL, 13=TFC, 14=TFR, 15=TBL, 16=TBC, 17=TBR % where F=front, L=left, C=centre, W=woofer (low frequency), B=back, LC=left of centre, RC=right of centre, S=side, T=top % % * Note on scaling ** % If we want to scale signal values in the range +-1 to an integer in the % range [-128,127] then we have four plausible choices corresponding to % scale factors of (a) 127, (b) 127.5, (c) 128 or (d) 128.5 but each choice % has disadvantages. % For forward scaling: (c) and (d) cause clipping on inputs of +1. % For reverse scaling: (a) and (b) can generate output values < -1. % Any of these scalings can be selected via the mode input: (a) 'o', (b) default, (c) 'on', (d) 'n' % % Copyright (C) Mike Brookes 1998-2011 % Version: Id: readwav.m 713 2011-10-16 14:45:43Z dmb % % VOICEBOX is a MATLAB toolbox for speech processing. % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html % % * NOTE ON CHANGES ** % The original name of this function in VOICEBOX was readwav. It was % renamed to avoid possible namespace clash. % Modified by: Zdenek Prusa 2015 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You can obtain a copy of the GNU General Public License from % http://www.gnu.org/copyleft/gpl.html or by writing to % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/voicebox/wavload.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Bugs/suggestions: if nargin<1 error('Usage: [y,fs,wmode,fidx]=WAVLOAD(filename,mode,nmax,nskip)'); end if nargin<2 mode='p'; else mode = [mode(:).' 'p']; end k=find((mode>='p') & (mode<='s')); mno=all(mode~='o'); % scale to input limits not output limits sc=mode(k(1)); z=128*all(mode~='z'); info=zeros(1,11); if ischar(filename) % if any(mode=='d') % filename=fullfile(voicebox('dir_data'),filename); % end fid=fopen(filename,'rb','l'); if fid == -1 fn=[filename,'.wav']; fid=fopen(fn,'rb','l'); if fid ~= -1 filename=fn; end end if fid == -1 error('Can''t open %s for input',filename); end info(1)=fid; elseif isvector(filename) && numel(filename) == 11 info=filename; fid=info(1); else error('%s: The first argument must be either a filename or FIDX vector.',... upper(mfilename)); end getdat= nargout>0 && ~any(mode=='i'); getdat= getdat || any(lower(mode)=='w') || any(lower(mode)=='a'); mh=any(mode=='h'); if ~info(3) fseek(fid,8,-1); % read riff chunk header=fread(fid,4,'*char')'; if ~strcmp(header,'WAVE') fclose(fid); error('File does not begin with a WAVE chunck'); end if mh fprintf('\nWAVE file: %s\n',filename); end fmtlen=-1; datalen=-1; instlen=-1; factlen=-1; riffmt='e'; % default is original wave file format while datalen<0 % loop until FMT and DATA chuncks both found header=fread(fid,4,'uint8=>char')'; len=fread(fid,1,'uint32'); if mh fprintf(' %s chunk: %d bytes\n',header,len); end if strcmp(header,'fmt ') % ******* found FMT chunk ********* fmtlen=len; % remember the length if len>16 riffmt='x'; % might be WAVEFORMATEX format end wavfmt=fread(fid,1,'int16'); % format: 1=PCM, 6=A-law, 7-Mu-law info(8)=wavfmt; info(5)=fread(fid,1,'uint16'); % number of channels fs=fread(fid,1,'uint32'); % sample rate in Hz info(9)=fs; % sample rate in Hz rate=fread(fid,1,'uint32'); % average bytes per second (ignore) align=fread(fid,1,'uint16'); % block alignment in bytes (container size * #channels) bps=fread(fid,1,'uint16'); % bits per sample info(7)=bps; % info(6)=ceil(info(7)/8); % round up to a byte count info(6)=floor(align/info(5)); % assume block size/channels = container size if info(8)==-2 % wave format extensible cb=fread(fid,1,'uint16'); % extra bytes must be >=22 riffmt='X'; % WAVEFORMATEXTENSIBLE format wfxsamp=fread(fid,1,'uint16'); % samples union if wfxsamp>0 info(7)=wfxsamp; % valid bits per sample end info(10)=fread(fid,1,'uint32'); % channel mask wfxguida=fread(fid,1,'uint32'); % GUID wfxguidb=fread(fid,2,'uint16'); % GUID wfxguidc=fread(fid,8,'uchar'); % GUID if wfxguida<65536 info(8)=wfxguida; % turn it into normal wav format end fseek(fid,len-40,0); % skip to end of header else if align>0 && align<(info(6)+4)*info(5) info(6)=ceil(align/info(5)); end fseek(fid,len-16,0); % skip to end of header end if mh fmttypes={'?' 'PCM' 'ADPCM' 'IEEE-float' '?' '?' 'A-law' '�-law' '?'}; fprintf(' Format: %d = %s',info(8),fmttypes{1+max(min(info(8),8),0)}); if wavfmt==-2 fprintf(' (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)\n',wfxguida,wfxguidb,wfxguidc); else fprintf('\n'); end fprintf(' %d channels at %g kHz sample rate (%d kbytes/s)\n',info(5),fs/1000,rate/1000); fprintf(' Mask=%x:',info(10)); spkpos={'FL' 'FR' 'FC' 'W' 'BL' 'BR' 'FLC' 'FRC' 'BC' 'SL' 'SR' 'TC' 'TFL' 'TFC' 'TFR' 'TBL' 'TBC' 'TBR'}; for i=1:18 if mod(floor(info(10)*pow2(1-i)),2) fprintf([' ' spkpos{i}]); end end fprintf('\n %d valid bits of %d per sample (%d byte block size)\n',info(7),bps,align); end elseif strcmp(header,'data') % ******* found DATA chunk ********* if fmtlen<0 fclose(fid); error('File %s does not contain a FMT chunck',filename); end if factlen>3 && nsamp >0 info(4)=nsamp; % take data length from FACT chunk else info(4) = fix(len/(info(6)*info(5))); % number of samples end info(3)=ftell(fid); % start of data datalen=len; if mh fprintf(' %d samples x %d channels x %d bytes/samp',info(4:6)); if prod(info(4:6))~=len fprintf(' + %d padding bytes',len-prod(info(4:6))); end fprintf(' = %g sec\n',info(4)/fs); end elseif strcmp(header,'fact') % ******* found FACT chunk ********* factlen=len; if len<4 error('FACT chunk too short'); end nsamp=fread(fid,1,'uint32'); % number of samples fseek(fid,len-4,0); % skip to end of header if mh fprintf(' %d samples = %.3g seconds\n',nsamp,nsamp/fs); end elseif strcmp(header,'inst') % ******* found INST chunk ********* instlen=len; if len<7 error('INST chunk too short'); end inst=fread(fid,3,'schar'); info(11)=double(inst(3)); % gain in dB if mh fprintf(' Gain = %d dB\n',info(11)); end fseek(fid,len-3,0); % skip to end of header else % ******* found unwanted chunk ********* fseek(fid,len,0); end end else fs=info(9); end if nargin<4 || nskip<0 nskip=info(2); % resume at current file position end ksamples=info(4)-nskip; % number of samples remaining if nargin>2 if nmax>=0 ksamples=min(nmax,ksamples); end elseif mh ksamples=min(5,ksamples); % just read 5 samples so we can print the first few data values elseif ~getdat ksamples = 0; end if ksamples>0 info(2)=nskip+ksamples; fseek(fid,info(3)+info(6)*info(5)*nskip,-1); nsamples=info(5)*ksamples; if any(info(8)==3) % floating point format pk=1; % peak is 1 switch info(6) case 4 y=fread(fid,nsamples,'float32'); case 8 y=fread(fid,nsamples,'float64'); otherwise error('cannot read %d-byte floating point numbers',info(6)); end else if ~any(info(8)==[1 6 7]) sc='r'; % read strange formats in raw integer mode end pk=pow2(0.5,8*info(6))*(1+(mno/2-all(mode~='n'))/pow2(0.5,info(7))); % use modes o and n to determine effective peak switch info(6) case 1 y=fread(fid,nsamples,'uchar'); if info(8)==1 y=y-z; elseif info(8)==6 y=voicebox_pcma2lin(y,213,1); pk=4032+mno*64; elseif info(8)==7 y=voicebox_pcmu2lin(y,1); pk=8031+mno*128; end case 2 y=fread(fid,nsamples,'int16'); case 3 y=fread(fid,3*nsamples,'uchar'); y=reshape(y,3,nsamples); y=([1 256 65536]*y-pow2(fix(pow2(y(3,:),-7)),24)).'; case 4 y=fread(fid,nsamples,'int32'); otherwise error('cannot read %d-byte integers',info(6)); end end if sc ~= 'r' if sc=='s' sf=1/max(abs(y(:))); elseif sc=='p' sf=1/pk; else if info(8)==7 sf=2.03761563/pk; else sf=2.03033976/pk; end end y=sf*y; else % mode = 'r' - output raw values if info(8)==1 y=y*pow2(1,info(7)-8*info(6)); % shift to get the bits correct end end if any(mode=='g') && info(11)~=0 y=y*10^(info(11)/20); % scale by the gain end if info(5)>1 y = reshape(y,info(5),ksamples).'; end else y=[]; end if all(mode~='f') fclose(fid); end if nargout>2 % sort out the mode input for writing this format wmode=char([riffmt sc 'z'-z/128]); if factlen>0 wmode=[wmode 'E']; end if info(6)>1 && info(6)<5 cszc=' cCL'; wmode=[wmode cszc(info(6))]; end switch info(8) case 1 % PCM modes if ~mno wmode=[wmode 'o']; end if any(mode=='n') wmode=[wmode 'n']; end wmode=[wmode num2str(info(7))]; case 3 if info(7)<=32 wmode = [wmode 'v']; else wmode = [wmode 'V']; end case 6 wmode = [wmode 'a']; case 7 wmode = [wmode 'u']; end fidx=info; end [ns,nchan]=size(y); if mh && ns>0 nsh=min(ns,5); % print first few samples for i=1:nsh fprintf(' %d:',i); fprintf(' %.3g',y(i,:)); fprintf('\n'); end end if ns>0.01*fs if any(lower(mode)=='a') nsh=min(ns,10*fs+ns*any(mode=='A')); soundsc(y(1:nsh,1:min(nchan,2)),fs); end if any(mode=='W') && any(mode=='w') error('Cannot plot waveform and spectrogram at the same time.'); end if any(mode=='W') clf; if nchan>1 for i=nchan:-1:1 subplot(nchan,1,i) maxsamp = fs sgram(y(:,i),fs,90); end else sgram(y,fs,90); end elseif any(mode=='w') clf; if nchan>1 for i=nchan:-1:1 subplot(nchan,1,i) plot((1:ns)/fs,y(:,i)); ylabel(['Chan ' num2str(i)]); if i==nchan xlabel('Time (s)'); end end else plot((1:ns)/fs,y); xlabel('Time (s)'); end end end if nargout==0 clear y; end ltfat/inst/thirdparty/voicebox/voicebox_pcma2lin.m0000664000175000017500000000601213026262303022326 0ustar susnaksusnakfunction x=voicebox_pcma2lin(p,m,s) %-*- texinfo -*- %@deftypefn {Function} voicebox_pcma2lin %@verbatim %PCMU2LIN Convert A-law PCM to linear X=(P,M,S) % lin = pcma2lin(pcma,m,s) where pcma contains a vector or matrix % of A-law values in the range 0 to 255. % No checking is performed to see that numbers are in this range. % % Input values are exclusive ored with m (default=85) % % Output values are divided by the scale factor s: % % s Output Range % % 1 +-4032 (integer values) % 2017.396342 +-1.998616 (default) % 4032 +-1 % 4096 +-0.984375 (+-1 nominal full scale) % % The default value of s is 2017.396342 which equals % sqrt((1120^2 + 2624^2)/2). This factor follows ITU standard G.711 and % the sine wave with PCM-A values [225 244 244 225 97 116 116 97] % has a mean square value of unity corresponding to 0 dBm0. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/voicebox/voicebox_pcma2lin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Copyright (C) Mike Brookes 1998 % Version: $Id: pcma2lin.m 713 2011-10-16 14:45:43Z dmb $ % % VOICEBOX is a MATLAB toolbox for speech processing. % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You can obtain a copy of the GNU General Public License from % http://www.gnu.org/copyleft/gpl.html or by writing to % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if nargin<3 t=4.95688418E-4; if nargin<2 m=85; end else t=1/s; end if m q=bitxor(p,m); else q=p; end; k=rem(q,16); g=floor(q/128); e=(q-k-128*g)/16; f=(abs(e-1)-e+1)/2; x=(2*g-1).*(pow2(k+16.5,e)+f.*(k-15.5))*t; ltfat/inst/thirdparty/voicebox/wavsave.m0000664000175000017500000003554413026262303020413 0ustar susnaksusnakfunction fidx=wavsave(d,fs,filename,mode,nskip,mask) %-*- texinfo -*- %@deftypefn {Function} wavsave %@verbatim %WAVSAVE Creates .WAV format sound files FIDX=(D,FS,FILENAME,MODE,NSKIP,MASK) % % The input arguments for WAVSAVE are as follows: % % D The sampled data to save % FS The rate at which the data was sampled % FILENAME A string containing the name of the .WAV file to create or % alternatively the FIDX output from a previous wavsave call % MODE String containing any reasonable mixture of flags below (*=default): % NSKIP Number of samples to skip before writing or -1[default] to continue from previous write % Only valid if FIDX is specified for FILENAME % MASK specifies the speaker positions included as a bit mask (see readwav) % % MODE flags (*=default): % Precision: 'a' for 8-bit A-law PCM % 'u' for 8-bit mu-law PCM % '16' for 16 bit PCM data % '8' for 8 bit PCM data % ... any number in the range 2 to 32 for PCM % 'v' 32-bit floating point % 'V' 64-bit floating point % 'c' embed in 16 bits % 'C' embed in 24 bits % 'L' embed in 32 bits % Dither: 'w' White triangular dither of amplitude +-1 LSB (PCM modes only) % 'h' High pass dither (filtered by 1-1/z) (PCM modes only) % 'l' Low pass dither (filtered by 1+1/z) (PCM modes only) % Scaling: 's' Auto scale to make data peak = +-1 % 'r' Raw unscaled data (integer values) % 'q' Scaled to make unity mean square correspond to 0dBm according to G.711 % 'p' Scaled to make +-1 equal full scale % 'o' Scale to bin centre rather than bin edge (e.g. 127 rather than 127.5 for 8 bit values) % (can be combined with n+p,r,s modes) % 'n' Scale to negative peak rather than positive peak (e.g. 128.5 rather than 127.5 for 8 bit values) % (can be combined with o+p,r,s modes) % 'g' Include a gain factor so that "readwav" will restore the correct level % Offset: 'y' Correct for offset in <=8 bit PCM data % 'z' Do not apply offset correction % Format: 'x' use WAVEFORMATEX format (default for non PCM) % 'X' use WAVEFORMATEXTENSIBLE (default if MASK input is given) % 'e' use original WAVEFORMAT (default for PCM) % 'E' include a 'fact' chunk (default for non-PCM) % File I/O: 'f' Do not close file on exit % % % Output Parameter: % % FIDX Information row vector containing the element listed below. % % (1) file id % (2) current position in file (in samples, 0=start of file) % (3) dataoff length of file header in bytes % (4) nsamp number of samples % (5) nchan number of channels % (6) nbyte bytes per data value % (7) bits number of bits of precision % (8) code Data format: 1=PCM, 2=ADPCM, 6=A-law, 7=Mu-law % (9) fs sample frequency % (10) dither state variable % (11) gain in dB (in INST chunk) % % Note: WAVSAVE will create an 16-bit PCM, auto-scaled wave file by default. % For stereo data, d(:,1) is the left channel and d(:,2) the right % % * Note on scaling ** % If we want to scale signal values in the range +-1 to an integer in the % range [-128,127] then we have four plausible choices corresponding to % scale factors of (a) 127, (b) 127.5, (c) 128 or (d) 128.5 but each choice % has disadvantages. % For forward scaling: (c) and (d) cause clipping on inputs of +1. % For reverse scaling: (a) and (b) can generate output values < -1. % Any of these scalings can be selected via the mode input: (a) 'o', (b) default, (c) 'on', (d) 'n' %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/voicebox/wavsave.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Copyright (C) Mike Brookes 1998-2011 % Version: $Id: writewav.m 713 2011-10-16 14:45:43Z dmb $ % % VOICEBOX is a MATLAB toolbox for speech processing. % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html % % *** NOTE ON CHANGES *** % The original name of this function in VOICEBOX was writewav. It was % renamed to avoid possible namespace clash. % Modified by: Zdenek Prusa 2015 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You can obtain a copy of the GNU General Public License from % http://www.gnu.org/copyleft/gpl.html or by writing to % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Acknowledgements % Thanks to Hugh Barnes for sorting out seek problems with MATLAB 6.5 % Bugs/suggestions % Save the following factors in FIDX: (a) scale factor, (b) offset (c) low/high clip limits % (d) dither position (e) rounding position if nargin<3 error('Usage: WAVSAVE(data,fs,filename,mode,nskip)'); end if nargin<6 mask=0; end info=zeros(1,11); info(9)=fs; if nargin<4 mode='p'; else mode = [mode(:).' 'p']; % no scaling by default end info(8)=1; % default mode is PCM mno=all(mode~='o'); % scale to input limits not output limits k=find((mode>='0') & (mode<='9'),1); if k, info(7)=sscanf(mode(k:end),'%d'); % valid bits per data value else info(7)=16; end if any(mode=='c') info(6)=2; % bytes per data value = 2 elseif any(mode=='C') info(6)=3; % bytes per data value = 3 elseif any(mode=='L') info(6)=4; % bytes per data value = 4 else info(6)=ceil(info(7)/8); % bytes per data value end lo=-pow2(0.5,info(7)); hi=-1-lo; pk=pow2(0.5,8*info(6))*(1-(mno/2-all(mode~='n'))/lo); % use modes o and n to determine effective peak % should perhaps have another variable besides info(7) to control dither position (or set info(7) later) % for A and mu law the dither position is not the same as the number of bits. if any(mode=='a') info(8)=6; pk=4032+mno*64; info(7)=8; % Some sources say this should be listed as 16 valid bits info(6)=1; elseif any(mode=='u') info(8)=7; pk=8031+mno*128; info(7)=8; % Some sources say this should be listed as 16 valid bits info(6)=1; elseif any(mode=='v') pk=1; mode(end)='r'; % default scaling is 'r' info(6)=4; % bytes info(7)=32; % bits info(8)=3; % WAVE type elseif any(mode=='V') pk=1; mode(end)='r'; % default scaling is 'r' info(6)=8; % bytes info(7)=64; % bits info(8)=3; % WAVE type end % is this pk value correct ? sc=mode(find((mode>='p') & (mode<='s'),1)); % find the first scaling option (always exists) z=128*all(mode~='z'); if any(mode=='w') di='w'; % select dither mode elseif any(mode=='h') di='h'; elseif any(mode=='l') di='l'; else di='n'; end % Now sort out which wave format to use if any(mode=='e') wavtype=1; elseif any(mode=='x') wavtype=2; elseif any(mode=='X') || nargin>=6 wavtype=3; else wavtype=2-(info(8)==1); end wavfmt=info(8)*(wavtype<3)+(pow2(16)-2)*(wavtype==3); fmtlen=[16 18 40]; % length of format chunk factlen=12*(any(mode=='E') || info(8)~=1); instlen=16*any(mode=='g'); % length of INST chunk (force to be even since some readers do not like odd lengths) wavlen=[36 38 60]+factlen+instlen; % length of entire WAVE chunk except for the data (not including 8 byte RIFF header) [n,nc]=size(d); if n==1 n=nc; nc=1; else d = d.'; end; if nc>32 error('WAVSAVE: attempt to write a sound file with >32 channels'); end nc=max(nc,1); ncy=nc*info(6); % bytes per sample time nyd=n*ncy; % bytes to write if ischar(filename) if any(mode=='d') filename=fullfile(voicebox('dir_data'),filename); end ny=nyd; if isempty(findstr(filename,'.')) filename=[filename,'.wav']; end fid=fopen(filename,'wb+','l'); if fid == -1 error('Can''t open %s for output',filename); end info(1)=fid; fwrite(fid,'RIFF','uchar'); % main RIFF header fwrite(fid,wavlen(wavtype)+2*ceil(ny/2),'uint32'); % fwrite(fid,'WAVEfmt ','uchar'); % write "WAVE" ID and "fmt" chunk fwrite(fid,[fmtlen(wavtype) 0 wavfmt nc],'uint16'); % chunk size, format code, number of channels fwrite(fid,[fs fs*ncy],'uint32'); % sample rate, bytes per sec switch wavtype case 1 fwrite(fid,[ncy info(7)],'uint16'); % block size, bits-per-sample case 2 fwrite(fid,[ncy info(7)],'uint16'); % block size, bits-per-sample fwrite(fid,0,'uint16'); % size of the extension=0 case 3 fwrite(fid,[ncy 8*info(6)],'uint16'); % block size, bits-per-sample (aways a multiple of 8) fwrite(fid,[22 info(7)],'uint16'); % size of the extension=22, valid bits fwrite(fid,[mask info(8)],'uint32'); % speaker position mask, encoding format fwrite(fid,[0 16 128 43520 14336 29083],'uint16'); % GUID end if factlen fwrite(fid,'fact','uchar'); % fact chunk header fwrite(fid,[4 n],'uint32'); % length in bytes + number of samples end if instlen fwrite(fid,'inst','uchar'); % fact chunk header fwrite(fid,instlen-8,'uint32'); % length in bytes fwrite(fid,zeros(1,instlen-8),'uchar'); % inst data (zero for now) end fwrite(fid,'data','uchar'); % data header fwrite(fid,ny,'uint32'); % data length in bytes nskip=0; % over-ride any nskip argument info(3)=8+wavlen(wavtype); % length of all header information info(4)=n; % number of samples (per channel) info(2)=n; % current file position (in samples) info(10)=rand(1); % seed for dither generation else info=filename; fid=info(1); fseek(fid,0,1); % go to end of file if nargin<5 || nskip<0 nskip=info(2); % use previous high water mark end info(2)=n+nskip; % file position following this write operation (in samples) ny=nyd+nskip*ncy; % file position following this write operation (in bytes following header) if n && (info(2)>info(4)) % update high water mark if ~info(4) % if no data written previously fseek(fid,22,-1); fwrite(fid,nc,'uint16'); % update number of channels fseek(fid,28,-1); fwrite(fid,fs*ncy,'uint32'); % update bytes/second fwrite(fid,ncy,'uint16'); % update bytes/sample end fseek(fid,4,-1); fwrite(fid,wavlen(wavtype)+2*ceil(ny/2),'uint32'); % update RIFF length if factlen fseek(fid,wavlen(wavtype)-4-instlen,-1); fwrite(fid,n,'uint32'); % update FACT number of samples end fseek(fid,4+wavlen(wavtype),-1); fwrite(fid,ny,'uint32'); % update DATA length info(4)=info(2); end end info(5)=nc; if n if sc~='r' % 'r' = no scaling if sc=='s' % 's' = scale to peak signal pd=max(abs(d(:))); pd=pd+(pd==0); % scale to 1 if data is all zero elseif sc=='p' % 'p' = scale to +-1 = full scale pd=1; else % 'q' = scale to 0dBm if info(8)==7 % mu-law pd=2.03761563; else % A-law or anything else pd=2.03033976; end end if instlen info(11)=min(max(ceil(20*log10(pd)),-128),127); d=pk*10^(-0.05*info(11))*d; if fseek(fid,0,-1) % MATLAB V6.5 fails if this is omitted error('Cannot rewind file'); end if fseek(fid,info(3)-instlen+2,-1); error('Cannot seek to INST chunk gain byte'); end fwrite(fid,info(11),'schar'); % write the INST gain in dB else d=pk/pd*d; end end if fseek(fid,0,-1) % MATLAB V6.5 fails if this is omitted error('Cannot rewind file'); end if fseek(fid,info(3)+nskip*nc*info(6),-1) error('Cannot seek to byte %d in output file',info(3)+nskip*nc*info(6)); end if info(8)==3 % floating point if info(6)==4 fwrite(fid,d,'float32'); else fwrite(fid,d,'float64'); end else % integer data if info(8)<6 % PCM if di=='n' d=round(d); else [d,info(10)]=voicebox_ditherq(d,di,info(10)); end d=min(max(d,lo),hi)*pow2(1,8*info(6)-info(7)); % clip data and shift to most significant bits else % mu or A law z=0; if info(8) < 7 d=lin2pcma(d,213,1); else d=lin2pcmu(d,1); end end if info(6)<3 if info(6)<2 fwrite(fid,d+z,'uchar'); else fwrite(fid,d,'int16'); end else if info(6)<4 d=d(:)'; d2=floor(d/65536); d=d-65536*d2; fwrite(fid,[rem(d,256); floor(d/256); d2+256*(d2<0)],'uchar'); else fwrite(fid,d,'int32'); end end if rem(ny,2) % pad to an even number of bytes fwrite(fid,0,'uchar'); end end end if all(mode~='f') fclose(fid); end if nargout fidx=info; end ltfat/inst/thirdparty/voicebox/voiceboxinit.m0000664000175000017500000000166013026262303021431 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} voiceboxinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/voicebox/voiceboxinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/thirdparty/voicebox/voicebox_ditherq.m0000664000175000017500000000547313026262303022273 0ustar susnaksusnakfunction [y,zf]=voicebox_ditherq(x,m,zi) %-*- texinfo -*- %@deftypefn {Function} voicebox_ditherq %@verbatim %DITHERQ add dither and quantize [Y,ZF]=(X,M,ZI) % Inputs: % x is the input signal % m specifies the mode: % 'w' white dither (default) % 'h' high-pass dither (filtered by 1 - z^-1) % 'l' low pass filter (filtered by 1 + z^-1) % 'n' no dither %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/voicebox/voicebox_ditherq.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Copyright (C) Mike Brookes 1997 % Version: $Id: ditherq.m 713 2011-10-16 14:45:43Z dmb $ % % VOICEBOX is a MATLAB toolbox for speech processing. % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You can obtain a copy of the GNU General Public License from % http://www.gnu.org/copyleft/gpl.html or by writing to % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% s=size(x); n=length(x); if nargin<3 | ~length(zi) zi=rand(1); end if nargin<2 m='w'; end if any(m=='n') y=round(x); elseif any(m=='h') | any(m=='l') v=rand(n+1,1); v(1)=zi; zf=v(end); if any(m=='h') y=round(x(:)+v(2:end)-v(1:end-1)); else y=round(x(:)+v(2:end)+v(1:end-1)-1); end else y=round(x(:)+rand(n,2)*[1;-1]); zf=rand(1); % output a random number anyway end if s(1)==1 y=y.'; end ltfat/inst/thirdparty/misc/0000775000175000017500000000000013026262303015663 5ustar susnaksusnakltfat/inst/thirdparty/misc/ltfat_viridis.m0000664000175000017500000002236013026262303020707 0ustar susnaksusnakfunction ret = ltfat_viridis() %-*- texinfo -*- %@deftypefn {Function} ltfat_viridis %@verbatim %LTFAT_VIRIDIS Viridis colormap % % The function returns 255 x 3 matrix representing % RGB values of a colormap. % % The colormap was generated using Matplotlib 2.0 % http://matplotlib.org/users/colormaps.html % % Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/misc/ltfat_viridis.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ret=[[ 0.267004 0.004874 0.329415] [ 0.26851 0.009605 0.335427] [ 0.269944 0.014625 0.341379] [ 0.271305 0.019942 0.347269] [ 0.272594 0.025563 0.353093] [ 0.273809 0.031497 0.358853] [ 0.274952 0.037752 0.364543] [ 0.276022 0.044167 0.370164] [ 0.277018 0.050344 0.375715] [ 0.277941 0.056324 0.381191] [ 0.278791 0.062145 0.386592] [ 0.279566 0.067836 0.391917] [ 0.280267 0.073417 0.397163] [ 0.280894 0.078907 0.402329] [ 0.281446 0.08432 0.407414] [ 0.281924 0.089666 0.412415] [ 0.282327 0.094955 0.417331] [ 0.282656 0.100196 0.42216 ] [ 0.28291 0.105393 0.426902] [ 0.283091 0.110553 0.431554] [ 0.283197 0.11568 0.436115] [ 0.283229 0.120777 0.440584] [ 0.283187 0.125848 0.44496 ] [ 0.283072 0.130895 0.449241] [ 0.282884 0.13592 0.453427] [ 0.282623 0.140926 0.457517] [ 0.28229 0.145912 0.46151 ] [ 0.281887 0.150881 0.465405] [ 0.281412 0.155834 0.469201] [ 0.280868 0.160771 0.472899] [ 0.280255 0.165693 0.476498] [ 0.279574 0.170599 0.479997] [ 0.278826 0.17549 0.483397] [ 0.278012 0.180367 0.486697] [ 0.277134 0.185228 0.489898] [ 0.276194 0.190074 0.493001] [ 0.275191 0.194905 0.496005] [ 0.274128 0.199721 0.498911] [ 0.273006 0.20452 0.501721] [ 0.271828 0.209303 0.504434] [ 0.270595 0.214069 0.507052] [ 0.269308 0.218818 0.509577] [ 0.267968 0.223549 0.512008] [ 0.26658 0.228262 0.514349] [ 0.265145 0.232956 0.516599] [ 0.263663 0.237631 0.518762] [ 0.262138 0.242286 0.520837] [ 0.260571 0.246922 0.522828] [ 0.258965 0.251537 0.524736] [ 0.257322 0.25613 0.526563] [ 0.255645 0.260703 0.528312] [ 0.253935 0.265254 0.529983] [ 0.252194 0.269783 0.531579] [ 0.250425 0.27429 0.533103] [ 0.248629 0.278775 0.534556] [ 0.246811 0.283237 0.535941] [ 0.244972 0.287675 0.53726 ] [ 0.243113 0.292092 0.538516] [ 0.241237 0.296485 0.539709] [ 0.239346 0.300855 0.540844] [ 0.237441 0.305202 0.541921] [ 0.235526 0.309527 0.542944] [ 0.233603 0.313828 0.543914] [ 0.231674 0.318106 0.544834] [ 0.229739 0.322361 0.545706] [ 0.227802 0.326594 0.546532] [ 0.225863 0.330805 0.547314] [ 0.223925 0.334994 0.548053] [ 0.221989 0.339161 0.548752] [ 0.220057 0.343307 0.549413] [ 0.21813 0.347432 0.550038] [ 0.21621 0.351535 0.550627] [ 0.214298 0.355619 0.551184] [ 0.212395 0.359683 0.55171 ] [ 0.210503 0.363727 0.552206] [ 0.208623 0.367752 0.552675] [ 0.206756 0.371758 0.553117] [ 0.204903 0.375746 0.553533] [ 0.203063 0.379716 0.553925] [ 0.201239 0.38367 0.554294] [ 0.19943 0.387607 0.554642] [ 0.197636 0.391528 0.554969] [ 0.19586 0.395433 0.555276] [ 0.1941 0.399323 0.555565] [ 0.192357 0.403199 0.555836] [ 0.190631 0.407061 0.556089] [ 0.188923 0.41091 0.556326] [ 0.187231 0.414746 0.556547] [ 0.185556 0.41857 0.556753] [ 0.183898 0.422383 0.556944] [ 0.182256 0.426184 0.55712 ] [ 0.180629 0.429975 0.557282] [ 0.179019 0.433756 0.55743 ] [ 0.177423 0.437527 0.557565] [ 0.175841 0.44129 0.557685] [ 0.174274 0.445044 0.557792] [ 0.172719 0.448791 0.557885] [ 0.171176 0.45253 0.557965] [ 0.169646 0.456262 0.55803 ] [ 0.168126 0.459988 0.558082] [ 0.166617 0.463708 0.558119] [ 0.165117 0.467423 0.558141] [ 0.163625 0.471133 0.558148] [ 0.162142 0.474838 0.55814 ] [ 0.160665 0.47854 0.558115] [ 0.159194 0.482237 0.558073] [ 0.157729 0.485932 0.558013] [ 0.15627 0.489624 0.557936] [ 0.154815 0.493313 0.55784 ] [ 0.153364 0.497 0.557724] [ 0.151918 0.500685 0.557587] [ 0.150476 0.504369 0.55743 ] [ 0.149039 0.508051 0.55725 ] [ 0.147607 0.511733 0.557049] [ 0.14618 0.515413 0.556823] [ 0.144759 0.519093 0.556572] [ 0.143343 0.522773 0.556295] [ 0.141935 0.526453 0.555991] [ 0.140536 0.530132 0.555659] [ 0.139147 0.533812 0.555298] [ 0.13777 0.537492 0.554906] [ 0.136408 0.541173 0.554483] [ 0.135066 0.544853 0.554029] [ 0.133743 0.548535 0.553541] [ 0.132444 0.552216 0.553018] [ 0.131172 0.555899 0.552459] [ 0.129933 0.559582 0.551864] [ 0.128729 0.563265 0.551229] [ 0.127568 0.566949 0.550556] [ 0.126453 0.570633 0.549841] [ 0.125394 0.574318 0.549086] [ 0.124395 0.578002 0.548287] [ 0.123463 0.581687 0.547445] [ 0.122606 0.585371 0.546557] [ 0.121831 0.589055 0.545623] [ 0.121148 0.592739 0.544641] [ 0.120565 0.596422 0.543611] [ 0.120092 0.600104 0.54253 ] [ 0.119738 0.603785 0.5414 ] [ 0.119512 0.607464 0.540218] [ 0.119423 0.611141 0.538982] [ 0.119483 0.614817 0.537692] [ 0.119699 0.61849 0.536347] [ 0.120081 0.622161 0.534946] [ 0.120638 0.625828 0.533488] [ 0.12138 0.629492 0.531973] [ 0.122312 0.633153 0.530398] [ 0.123444 0.636809 0.528763] [ 0.12478 0.640461 0.527068] [ 0.126326 0.644107 0.525311] [ 0.128087 0.647749 0.523491] [ 0.130067 0.651384 0.521608] [ 0.132268 0.655014 0.519661] [ 0.134692 0.658636 0.517649] [ 0.137339 0.662252 0.515571] [ 0.14021 0.665859 0.513427] [ 0.143303 0.669459 0.511215] [ 0.146616 0.67305 0.508936] [ 0.150148 0.676631 0.506589] [ 0.153894 0.680203 0.504172] [ 0.157851 0.683765 0.501686] [ 0.162016 0.687316 0.499129] [ 0.166383 0.690856 0.496502] [ 0.170948 0.694384 0.493803] [ 0.175707 0.6979 0.491033] [ 0.180653 0.701402 0.488189] [ 0.185783 0.704891 0.485273] [ 0.19109 0.708366 0.482284] [ 0.196571 0.711827 0.479221] [ 0.202219 0.715272 0.476084] [ 0.20803 0.718701 0.472873] [ 0.214 0.722114 0.469588] [ 0.220124 0.725509 0.466226] [ 0.226397 0.728888 0.462789] [ 0.232815 0.732247 0.459277] [ 0.239374 0.735588 0.455688] [ 0.24607 0.73891 0.452024] [ 0.252899 0.742211 0.448284] [ 0.259857 0.745492 0.444467] [ 0.266941 0.748751 0.440573] [ 0.274149 0.751988 0.436601] [ 0.281477 0.755203 0.432552] [ 0.288921 0.758394 0.428426] [ 0.296479 0.761561 0.424223] [ 0.304148 0.764704 0.419943] [ 0.311925 0.767822 0.415586] [ 0.319809 0.770914 0.411152] [ 0.327796 0.77398 0.40664 ] [ 0.335885 0.777018 0.402049] [ 0.344074 0.780029 0.397381] [ 0.35236 0.783011 0.392636] [ 0.360741 0.785964 0.387814] [ 0.369214 0.788888 0.382914] [ 0.377779 0.791781 0.377939] [ 0.386433 0.794644 0.372886] [ 0.395174 0.797475 0.367757] [ 0.404001 0.800275 0.362552] [ 0.412913 0.803041 0.357269] [ 0.421908 0.805774 0.35191 ] [ 0.430983 0.808473 0.346476] [ 0.440137 0.811138 0.340967] [ 0.449368 0.813768 0.335384] [ 0.458674 0.816363 0.329727] [ 0.468053 0.818921 0.323998] [ 0.477504 0.821444 0.318195] [ 0.487026 0.823929 0.312321] [ 0.496615 0.826376 0.306377] [ 0.506271 0.828786 0.300362] [ 0.515992 0.831158 0.294279] [ 0.525776 0.833491 0.288127] [ 0.535621 0.835785 0.281908] [ 0.545524 0.838039 0.275626] [ 0.555484 0.840254 0.269281] [ 0.565498 0.84243 0.262877] [ 0.575563 0.844566 0.256415] [ 0.585678 0.846661 0.249897] [ 0.595839 0.848717 0.243329] [ 0.606045 0.850733 0.236712] [ 0.616293 0.852709 0.230052] [ 0.626579 0.854645 0.223353] [ 0.636902 0.856542 0.21662 ] [ 0.647257 0.8584 0.209861] [ 0.657642 0.860219 0.203082] [ 0.668054 0.861999 0.196293] [ 0.678489 0.863742 0.189503] [ 0.688944 0.865448 0.182725] [ 0.699415 0.867117 0.175971] [ 0.709898 0.868751 0.169257] [ 0.720391 0.87035 0.162603] [ 0.730889 0.871916 0.156029] [ 0.741388 0.873449 0.149561] [ 0.751884 0.874951 0.143228] [ 0.762373 0.876424 0.137064] [ 0.772852 0.877868 0.131109] [ 0.783315 0.879285 0.125405] [ 0.79376 0.880678 0.120005] [ 0.804182 0.882046 0.114965] [ 0.814576 0.883393 0.110347] [ 0.82494 0.88472 0.106217] [ 0.83527 0.886029 0.102646] [ 0.845561 0.887322 0.099702] [ 0.85581 0.888601 0.097452] [ 0.866013 0.889868 0.095953] [ 0.876168 0.891125 0.09525 ] [ 0.886271 0.892374 0.095374] [ 0.89632 0.893616 0.096335] [ 0.906311 0.894855 0.098125] [ 0.916242 0.896091 0.100717] [ 0.926106 0.89733 0.104071] [ 0.935904 0.89857 0.108131] [ 0.945636 0.899815 0.112838] [ 0.9553 0.901065 0.118128] [ 0.964894 0.902323 0.123941] [ 0.974417 0.90359 0.130215] [ 0.983868 0.904867 0.136897] [ 0.993248 0.906157 0.143936] ]; ltfat/inst/thirdparty/misc/ltfat_plasma.m0000664000175000017500000002245013026262303020513 0ustar susnaksusnakfunction ret = ltfat_plasma() %-*- texinfo -*- %@deftypefn {Function} ltfat_plasma %@verbatim % LTFAT_PLASMA Plasma colormap % % The function returns 255 x 3 matrix representing % RGB values of a colormap. % % The colormap was generated using Matplotlib 2.0 % http://matplotlib.org/users/colormaps.html % % Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/misc/ltfat_plasma.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ret=[[ 0.050383 0.029803 0.527975] [ 0.063536 0.028426 0.533124] [ 0.075353 0.027206 0.538007] [ 0.086222 0.026125 0.542658] [ 0.096379 0.025165 0.547103] [ 0.10598 0.024309 0.551368] [ 0.115124 0.023556 0.555468] [ 0.123903 0.022878 0.559423] [ 0.132381 0.022258 0.56325 ] [ 0.140603 0.021687 0.566959] [ 0.148607 0.021154 0.570562] [ 0.156421 0.020651 0.574065] [ 0.16407 0.020171 0.577478] [ 0.171574 0.019706 0.580806] [ 0.17895 0.019252 0.584054] [ 0.186213 0.018803 0.587228] [ 0.193374 0.018354 0.59033 ] [ 0.200445 0.017902 0.593364] [ 0.207435 0.017442 0.596333] [ 0.21435 0.016973 0.599239] [ 0.221197 0.016497 0.602083] [ 0.227983 0.016007 0.604867] [ 0.234715 0.015502 0.607592] [ 0.241396 0.014979 0.610259] [ 0.248032 0.014439 0.612868] [ 0.254627 0.013882 0.615419] [ 0.261183 0.013308 0.617911] [ 0.267703 0.012716 0.620346] [ 0.274191 0.012109 0.622722] [ 0.280648 0.011488 0.625038] [ 0.287076 0.010855 0.627295] [ 0.293478 0.010213 0.62949 ] [ 0.299855 0.009561 0.631624] [ 0.30621 0.008902 0.633694] [ 0.312543 0.008239 0.6357 ] [ 0.318856 0.007576 0.63764 ] [ 0.32515 0.006915 0.639512] [ 0.331426 0.006261 0.641316] [ 0.337683 0.005618 0.643049] [ 0.343925 0.004991 0.64471 ] [ 0.35015 0.004382 0.646298] [ 0.356359 0.003798 0.64781 ] [ 0.362553 0.003243 0.649245] [ 0.368733 0.002724 0.650601] [ 0.374897 0.002245 0.651876] [ 0.381047 0.001814 0.653068] [ 0.387183 0.001434 0.654177] [ 0.393304 0.001114 0.655199] [ 0.399411 0.000859 0.656133] [ 0.405503 0.000678 0.656977] [ 4.11580000e-01 5.77000000e-04 6.57730000e-01] [ 4.17642000e-01 5.64000000e-04 6.58390000e-01] [ 4.23689000e-01 6.46000000e-04 6.58956000e-01] [ 0.429719 0.000831 0.659425] [ 0.435734 0.001127 0.659797] [ 0.441732 0.00154 0.660069] [ 0.447714 0.00208 0.66024 ] [ 0.453677 0.002755 0.66031 ] [ 0.459623 0.003574 0.660277] [ 0.46555 0.004545 0.660139] [ 0.471457 0.005678 0.659897] [ 0.477344 0.00698 0.659549] [ 0.48321 0.00846 0.659095] [ 0.489055 0.010127 0.658534] [ 0.494877 0.01199 0.657865] [ 0.500678 0.014055 0.657088] [ 0.506454 0.016333 0.656202] [ 0.512206 0.018833 0.655209] [ 0.517933 0.021563 0.654109] [ 0.523633 0.024532 0.652901] [ 0.529306 0.027747 0.651586] [ 0.534952 0.031217 0.650165] [ 0.54057 0.03495 0.64864] [ 0.546157 0.038954 0.64701 ] [ 0.551715 0.043136 0.645277] [ 0.557243 0.047331 0.643443] [ 0.562738 0.051545 0.641509] [ 0.568201 0.055778 0.639477] [ 0.573632 0.060028 0.637349] [ 0.579029 0.064296 0.635126] [ 0.584391 0.068579 0.632812] [ 0.589719 0.072878 0.630408] [ 0.595011 0.07719 0.627917] [ 0.600266 0.081516 0.625342] [ 0.605485 0.085854 0.622686] [ 0.610667 0.090204 0.619951] [ 0.615812 0.094564 0.61714 ] [ 0.620919 0.098934 0.614257] [ 0.625987 0.103312 0.611305] [ 0.631017 0.107699 0.608287] [ 0.636008 0.112092 0.605205] [ 0.640959 0.116492 0.602065] [ 0.645872 0.120898 0.598867] [ 0.650746 0.125309 0.595617] [ 0.65558 0.129725 0.592317] [ 0.660374 0.134144 0.588971] [ 0.665129 0.138566 0.585582] [ 0.669845 0.142992 0.582154] [ 0.674522 0.147419 0.578688] [ 0.67916 0.151848 0.575189] [ 0.683758 0.156278 0.57166 ] [ 0.688318 0.160709 0.568103] [ 0.69284 0.165141 0.564522] [ 0.697324 0.169573 0.560919] [ 0.701769 0.174005 0.557296] [ 0.706178 0.178437 0.553657] [ 0.710549 0.182868 0.550004] [ 0.714883 0.187299 0.546338] [ 0.719181 0.191729 0.542663] [ 0.723444 0.196158 0.538981] [ 0.72767 0.200586 0.535293] [ 0.731862 0.205013 0.531601] [ 0.736019 0.209439 0.527908] [ 0.740143 0.213864 0.524216] [ 0.744232 0.218288 0.520524] [ 0.748289 0.222711 0.516834] [ 0.752312 0.227133 0.513149] [ 0.756304 0.231555 0.509468] [ 0.760264 0.235976 0.505794] [ 0.764193 0.240396 0.502126] [ 0.76809 0.244817 0.498465] [ 0.771958 0.249237 0.494813] [ 0.775796 0.253658 0.491171] [ 0.779604 0.258078 0.487539] [ 0.783383 0.2625 0.483918] [ 0.787133 0.266922 0.480307] [ 0.790855 0.271345 0.476706] [ 0.794549 0.27577 0.473117] [ 0.798216 0.280197 0.469538] [ 0.801855 0.284626 0.465971] [ 0.805467 0.289057 0.462415] [ 0.809052 0.293491 0.45887 ] [ 0.812612 0.297928 0.455338] [ 0.816144 0.302368 0.451816] [ 0.819651 0.306812 0.448306] [ 0.823132 0.311261 0.444806] [ 0.826588 0.315714 0.441316] [ 0.830018 0.320172 0.437836] [ 0.833422 0.324635 0.434366] [ 0.836801 0.329105 0.430905] [ 0.840155 0.33358 0.427455] [ 0.843484 0.338062 0.424013] [ 0.846788 0.342551 0.420579] [ 0.850066 0.347048 0.417153] [ 0.853319 0.351553 0.413734] [ 0.856547 0.356066 0.410322] [ 0.85975 0.360588 0.406917] [ 0.862927 0.365119 0.403519] [ 0.866078 0.36966 0.400126] [ 0.869203 0.374212 0.396738] [ 0.872303 0.378774 0.393355] [ 0.875376 0.383347 0.389976] [ 0.878423 0.387932 0.3866 ] [ 0.881443 0.392529 0.383229] [ 0.884436 0.397139 0.37986 ] [ 0.887402 0.401762 0.376494] [ 0.89034 0.406398 0.37313 ] [ 0.89325 0.411048 0.369768] [ 0.896131 0.415712 0.366407] [ 0.898984 0.420392 0.363047] [ 0.901807 0.425087 0.359688] [ 0.904601 0.429797 0.356329] [ 0.907365 0.434524 0.35297 ] [ 0.910098 0.439268 0.34961 ] [ 0.9128 0.444029 0.346251] [ 0.915471 0.448807 0.34289 ] [ 0.918109 0.453603 0.339529] [ 0.920714 0.458417 0.336166] [ 0.923287 0.463251 0.332801] [ 0.925825 0.468103 0.329435] [ 0.928329 0.472975 0.326067] [ 0.930798 0.477867 0.322697] [ 0.933232 0.48278 0.319325] [ 0.93563 0.487712 0.315952] [ 0.93799 0.492667 0.312575] [ 0.940313 0.497642 0.309197] [ 0.942598 0.502639 0.305816] [ 0.944844 0.507658 0.302433] [ 0.947051 0.512699 0.299049] [ 0.949217 0.517763 0.295662] [ 0.951344 0.52285 0.292275] [ 0.953428 0.52796 0.288883] [ 0.95547 0.533093 0.28549 ] [ 0.957469 0.53825 0.282096] [ 0.959424 0.543431 0.278701] [ 0.961336 0.548636 0.275305] [ 0.963203 0.553865 0.271909] [ 0.965024 0.559118 0.268513] [ 0.966798 0.564396 0.265118] [ 0.968526 0.5697 0.261721] [ 0.970205 0.575028 0.258325] [ 0.971835 0.580382 0.254931] [ 0.973416 0.585761 0.25154 ] [ 0.974947 0.591165 0.248151] [ 0.976428 0.596595 0.244767] [ 0.977856 0.602051 0.241387] [ 0.979233 0.607532 0.238013] [ 0.980556 0.613039 0.234646] [ 0.981826 0.618572 0.231287] [ 0.983041 0.624131 0.227937] [ 0.984199 0.629718 0.224595] [ 0.985301 0.63533 0.221265] [ 0.986345 0.640969 0.217948] [ 0.987332 0.646633 0.214648] [ 0.98826 0.652325 0.211364] [ 0.989128 0.658043 0.2081 ] [ 0.989935 0.663787 0.204859] [ 0.990681 0.669558 0.201642] [ 0.991365 0.675355 0.198453] [ 0.991985 0.681179 0.195295] [ 0.992541 0.68703 0.19217 ] [ 0.993032 0.692907 0.189084] [ 0.993456 0.69881 0.186041] [ 0.993814 0.704741 0.183043] [ 0.994103 0.710698 0.180097] [ 0.994324 0.716681 0.177208] [ 0.994474 0.722691 0.174381] [ 0.994553 0.728728 0.171622] [ 0.994561 0.734791 0.168938] [ 0.994495 0.74088 0.166335] [ 0.994355 0.746995 0.163821] [ 0.994141 0.753137 0.161404] [ 0.993851 0.759304 0.159092] [ 0.993482 0.765499 0.156891] [ 0.993033 0.77172 0.154808] [ 0.992505 0.777967 0.152855] [ 0.991897 0.784239 0.151042] [ 0.991209 0.790537 0.149377] [ 0.990439 0.796859 0.14787 ] [ 0.989587 0.803205 0.146529] [ 0.988648 0.809579 0.145357] [ 0.987621 0.815978 0.144363] [ 0.986509 0.822401 0.143557] [ 0.985314 0.828846 0.142945] [ 0.984031 0.835315 0.142528] [ 0.982653 0.841812 0.142303] [ 0.98119 0.848329 0.142279] [ 0.979644 0.854866 0.142453] [ 0.977995 0.861432 0.142808] [ 0.976265 0.868016 0.143351] [ 0.974443 0.874622 0.144061] [ 0.97253 0.88125 0.144923] [ 0.970533 0.887896 0.145919] [ 0.968443 0.894564 0.147014] [ 0.966271 0.901249 0.14818 ] [ 0.964021 0.90795 0.14937 ] [ 0.961681 0.914672 0.15052 ] [ 0.959276 0.921407 0.151566] [ 0.956808 0.928152 0.152409] [ 0.954287 0.934908 0.152921] [ 0.951726 0.941671 0.152925] [ 0.949151 0.948435 0.152178] [ 0.946602 0.95519 0.150328] [ 0.944152 0.961916 0.146861] [ 0.941896 0.96859 0.140956] [ 0.940015 0.975158 0.131326] ]; ltfat/inst/thirdparty/misc/ltfat_inferno.m0000664000175000017500000002236113026262303020677 0ustar susnaksusnakfunction ret = ltfat_inferno() %-*- texinfo -*- %@deftypefn {Function} ltfat_inferno %@verbatim % LTFAT_INFERNO Inferno colormap % % The function returns 255 x 3 matrix representing % RGB values of a colormap. % % The colormap was generated using Matplotlib 2.0 % http://matplotlib.org/users/colormaps.html % % Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/misc/ltfat_inferno.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ret=[[ 0.001462 0.000466 0.013866] [ 0.002267 0.00127 0.01857 ] [ 0.003299 0.002249 0.024239] [ 0.004547 0.003392 0.030909] [ 0.006006 0.004692 0.038558] [ 0.007676 0.006136 0.046836] [ 0.009561 0.007713 0.055143] [ 0.011663 0.009417 0.06346 ] [ 0.013995 0.011225 0.071862] [ 0.016561 0.013136 0.080282] [ 0.019373 0.015133 0.088767] [ 0.022447 0.017199 0.097327] [ 0.025793 0.019331 0.10593 ] [ 0.029432 0.021503 0.114621] [ 0.033385 0.023702 0.123397] [ 0.037668 0.025921 0.132232] [ 0.042253 0.028139 0.141141] [ 0.046915 0.030324 0.150164] [ 0.051644 0.032474 0.159254] [ 0.056449 0.034569 0.168414] [ 0.06134 0.03659 0.177642] [ 0.066331 0.038504 0.186962] [ 0.071429 0.040294 0.196354] [ 0.076637 0.041905 0.205799] [ 0.081962 0.043328 0.215289] [ 0.087411 0.044556 0.224813] [ 0.09299 0.045583 0.234358] [ 0.098702 0.046402 0.243904] [ 0.104551 0.047008 0.25343 ] [ 0.110536 0.047399 0.262912] [ 0.116656 0.047574 0.272321] [ 0.122908 0.047536 0.281624] [ 0.129285 0.047293 0.290788] [ 0.135778 0.046856 0.299776] [ 0.142378 0.046242 0.308553] [ 0.149073 0.045468 0.317085] [ 0.15585 0.044559 0.325338] [ 0.162689 0.043554 0.333277] [ 0.169575 0.042489 0.340874] [ 0.176493 0.041402 0.348111] [ 0.183429 0.040329 0.354971] [ 0.190367 0.039309 0.361447] [ 0.197297 0.0384 0.367535] [ 0.204209 0.037632 0.373238] [ 0.211095 0.03703 0.378563] [ 0.217949 0.036615 0.383522] [ 0.224763 0.036405 0.388129] [ 0.231538 0.036405 0.3924 ] [ 0.238273 0.036621 0.396353] [ 0.244967 0.037055 0.400007] [ 0.25162 0.037705 0.403378] [ 0.258234 0.038571 0.406485] [ 0.26481 0.039647 0.409345] [ 0.271347 0.040922 0.411976] [ 0.27785 0.042353 0.414392] [ 0.284321 0.043933 0.416608] [ 0.290763 0.045644 0.418637] [ 0.297178 0.04747 0.420491] [ 0.303568 0.049396 0.422182] [ 0.309935 0.051407 0.423721] [ 0.316282 0.05349 0.425116] [ 0.32261 0.055634 0.426377] [ 0.328921 0.057827 0.427511] [ 0.335217 0.06006 0.428524] [ 0.3415 0.062325 0.429425] [ 0.347771 0.064616 0.430217] [ 0.354032 0.066925 0.430906] [ 0.360284 0.069247 0.431497] [ 0.366529 0.071579 0.431994] [ 0.372768 0.073915 0.4324 ] [ 0.379001 0.076253 0.432719] [ 0.385228 0.078591 0.432955] [ 0.391453 0.080927 0.433109] [ 0.397674 0.083257 0.433183] [ 0.403894 0.08558 0.433179] [ 0.410113 0.087896 0.433098] [ 0.416331 0.090203 0.432943] [ 0.422549 0.092501 0.432714] [ 0.428768 0.09479 0.432412] [ 0.434987 0.097069 0.432039] [ 0.441207 0.099338 0.431594] [ 0.447428 0.101597 0.43108 ] [ 0.453651 0.103848 0.430498] [ 0.459875 0.106089 0.429846] [ 0.4661 0.108322 0.429125] [ 0.472328 0.110547 0.428334] [ 0.478558 0.112764 0.427475] [ 0.484789 0.114974 0.426548] [ 0.491022 0.117179 0.425552] [ 0.497257 0.119379 0.424488] [ 0.503493 0.121575 0.423356] [ 0.50973 0.123769 0.422156] [ 0.515967 0.12596 0.420887] [ 0.522206 0.12815 0.419549] [ 0.528444 0.130341 0.418142] [ 0.534683 0.132534 0.416667] [ 0.54092 0.134729 0.415123] [ 0.547157 0.136929 0.413511] [ 0.553392 0.139134 0.411829] [ 0.559624 0.141346 0.410078] [ 0.565854 0.143567 0.408258] [ 0.572081 0.145797 0.406369] [ 0.578304 0.148039 0.404411] [ 0.584521 0.150294 0.402385] [ 0.590734 0.152563 0.40029 ] [ 0.59694 0.154848 0.398125] [ 0.603139 0.157151 0.395891] [ 0.60933 0.159474 0.393589] [ 0.615513 0.161817 0.391219] [ 0.621685 0.164184 0.388781] [ 0.627847 0.166575 0.386276] [ 0.633998 0.168992 0.383704] [ 0.640135 0.171438 0.381065] [ 0.64626 0.173914 0.378359] [ 0.652369 0.176421 0.375586] [ 0.658463 0.178962 0.372748] [ 0.66454 0.181539 0.369846] [ 0.670599 0.184153 0.366879] [ 0.676638 0.186807 0.363849] [ 0.682656 0.189501 0.360757] [ 0.688653 0.192239 0.357603] [ 0.694627 0.195021 0.354388] [ 0.700576 0.197851 0.351113] [ 0.7065 0.200728 0.347777] [ 0.712396 0.203656 0.344383] [ 0.718264 0.206636 0.340931] [ 0.724103 0.20967 0.337424] [ 0.729909 0.212759 0.333861] [ 0.735683 0.215906 0.330245] [ 0.741423 0.219112 0.326576] [ 0.747127 0.222378 0.322856] [ 0.752794 0.225706 0.319085] [ 0.758422 0.229097 0.315266] [ 0.76401 0.232554 0.311399] [ 0.769556 0.236077 0.307485] [ 0.775059 0.239667 0.303526] [ 0.780517 0.243327 0.299523] [ 0.785929 0.247056 0.295477] [ 0.791293 0.250856 0.29139 ] [ 0.796607 0.254728 0.287264] [ 0.801871 0.258674 0.283099] [ 0.807082 0.262692 0.278898] [ 0.812239 0.266786 0.274661] [ 0.817341 0.270954 0.27039 ] [ 0.822386 0.275197 0.266085] [ 0.827372 0.279517 0.26175 ] [ 0.832299 0.283913 0.257383] [ 0.837165 0.288385 0.252988] [ 0.841969 0.292933 0.248564] [ 0.846709 0.297559 0.244113] [ 0.851384 0.30226 0.239636] [ 0.855992 0.307038 0.235133] [ 0.860533 0.311892 0.230606] [ 0.865006 0.316822 0.226055] [ 0.869409 0.321827 0.221482] [ 0.873741 0.326906 0.216886] [ 0.878001 0.33206 0.212268] [ 0.882188 0.337287 0.207628] [ 0.886302 0.342586 0.202968] [ 0.890341 0.347957 0.198286] [ 0.894305 0.353399 0.193584] [ 0.898192 0.358911 0.18886 ] [ 0.902003 0.364492 0.184116] [ 0.905735 0.37014 0.17935 ] [ 0.90939 0.375856 0.174563] [ 0.912966 0.381636 0.169755] [ 0.916462 0.387481 0.164924] [ 0.919879 0.393389 0.16007 ] [ 0.923215 0.399359 0.155193] [ 0.92647 0.405389 0.150292] [ 0.929644 0.411479 0.145367] [ 0.932737 0.417627 0.140417] [ 0.935747 0.423831 0.13544 ] [ 0.938675 0.430091 0.130438] [ 0.941521 0.436405 0.125409] [ 0.944285 0.442772 0.120354] [ 0.946965 0.449191 0.115272] [ 0.949562 0.45566 0.110164] [ 0.952075 0.462178 0.105031] [ 0.954506 0.468744 0.099874] [ 0.956852 0.475356 0.094695] [ 0.959114 0.482014 0.089499] [ 0.961293 0.488716 0.084289] [ 0.963387 0.495462 0.079073] [ 0.965397 0.502249 0.073859] [ 0.967322 0.509078 0.068659] [ 0.969163 0.515946 0.063488] [ 0.970919 0.522853 0.058367] [ 0.97259 0.529798 0.053324] [ 0.974176 0.53678 0.048392] [ 0.975677 0.543798 0.043618] [ 0.977092 0.55085 0.03905 ] [ 0.978422 0.557937 0.034931] [ 0.979666 0.565057 0.031409] [ 0.980824 0.572209 0.028508] [ 0.981895 0.579392 0.02625 ] [ 0.982881 0.586606 0.024661] [ 0.983779 0.593849 0.02377 ] [ 0.984591 0.601122 0.023606] [ 0.985315 0.608422 0.024202] [ 0.985952 0.61575 0.025592] [ 0.986502 0.623105 0.027814] [ 0.986964 0.630485 0.030908] [ 0.987337 0.63789 0.034916] [ 0.987622 0.64532 0.039886] [ 0.987819 0.652773 0.045581] [ 0.987926 0.66025 0.05175 ] [ 0.987945 0.667748 0.058329] [ 0.987874 0.675267 0.065257] [ 0.987714 0.682807 0.072489] [ 0.987464 0.690366 0.07999 ] [ 0.987124 0.697944 0.087731] [ 0.986694 0.70554 0.095694] [ 0.986175 0.713153 0.103863] [ 0.985566 0.720782 0.112229] [ 0.984865 0.728427 0.120785] [ 0.984075 0.736087 0.129527] [ 0.983196 0.743758 0.138453] [ 0.982228 0.751442 0.147565] [ 0.981173 0.759135 0.156863] [ 0.980032 0.766837 0.166353] [ 0.978806 0.774545 0.176037] [ 0.977497 0.782258 0.185923] [ 0.976108 0.789974 0.196018] [ 0.974638 0.797692 0.206332] [ 0.973088 0.805409 0.216877] [ 0.971468 0.813122 0.227658] [ 0.969783 0.820825 0.238686] [ 0.968041 0.828515 0.249972] [ 0.966243 0.836191 0.261534] [ 0.964394 0.843848 0.273391] [ 0.962517 0.851476 0.285546] [ 0.960626 0.859069 0.29801 ] [ 0.95872 0.866624 0.31082 ] [ 0.956834 0.874129 0.323974] [ 0.954997 0.881569 0.337475] [ 0.953215 0.888942 0.351369] [ 0.951546 0.896226 0.365627] [ 0.950018 0.903409 0.380271] [ 0.948683 0.910473 0.395289] [ 0.947594 0.917399 0.410665] [ 0.946809 0.924168 0.426373] [ 0.946392 0.930761 0.442367] [ 0.946403 0.937159 0.458592] [ 0.946903 0.943348 0.47497 ] [ 0.947937 0.949318 0.491426] [ 0.949545 0.955063 0.50786 ] [ 0.95174 0.960587 0.524203] [ 0.954529 0.965896 0.540361] [ 0.957896 0.971003 0.556275] [ 0.961812 0.975924 0.571925] [ 0.966249 0.980678 0.587206] [ 0.971162 0.985282 0.602154] [ 0.976511 0.989753 0.61676 ] [ 0.982257 0.994109 0.631017] [ 0.988362 0.998364 0.644924] ]; ltfat/inst/thirdparty/misc/ltfat_magma.m0000664000175000017500000002234713026262303020325 0ustar susnaksusnakfunction ret = ltfat_magma() %-*- texinfo -*- %@deftypefn {Function} ltfat_magma %@verbatim % LTFAT_MAGMA Magma colormap % % The function returns 255 x 3 matrix representing % RGB values of a colormap. % % The colormap was generated using Matplotlib 2.0 % http://matplotlib.org/users/colormaps.html % % Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/misc/ltfat_magma.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ret=[[ 0.001462 0.000466 0.013866] [ 0.002258 0.001295 0.018331] [ 0.003279 0.002305 0.023708] [ 0.004512 0.00349 0.029965] [ 0.00595 0.004843 0.03713 ] [ 0.007588 0.006356 0.044973] [ 0.009426 0.008022 0.052844] [ 0.011465 0.009828 0.06075 ] [ 0.013708 0.011771 0.068667] [ 0.016156 0.01384 0.076603] [ 0.018815 0.016026 0.084584] [ 0.021692 0.01832 0.09261 ] [ 0.024792 0.020715 0.100676] [ 0.028123 0.023201 0.108787] [ 0.031696 0.025765 0.116965] [ 0.03552 0.028397 0.125209] [ 0.039608 0.03109 0.133515] [ 0.04383 0.03383 0.141886] [ 0.048062 0.036607 0.150327] [ 0.05232 0.039407 0.158841] [ 0.056615 0.04216 0.167446] [ 0.060949 0.044794 0.176129] [ 0.06533 0.047318 0.184892] [ 0.069764 0.049726 0.193735] [ 0.074257 0.052017 0.20266 ] [ 0.078815 0.054184 0.211667] [ 0.083446 0.056225 0.220755] [ 0.088155 0.058133 0.229922] [ 0.092949 0.059904 0.239164] [ 0.097833 0.061531 0.248477] [ 0.102815 0.06301 0.257854] [ 0.107899 0.064335 0.267289] [ 0.113094 0.065492 0.276784] [ 0.118405 0.066479 0.286321] [ 0.123833 0.067295 0.295879] [ 0.12938 0.067935 0.305443] [ 0.135053 0.068391 0.315 ] [ 0.140858 0.068654 0.324538] [ 0.146785 0.068738 0.334011] [ 0.152839 0.068637 0.343404] [ 0.159018 0.068354 0.352688] [ 0.165308 0.067911 0.361816] [ 0.171713 0.067305 0.370771] [ 0.178212 0.066576 0.379497] [ 0.184801 0.065732 0.387973] [ 0.19146 0.064818 0.396152] [ 0.198177 0.063862 0.404009] [ 0.204935 0.062907 0.411514] [ 0.211718 0.061992 0.418647] [ 0.218512 0.061158 0.425392] [ 0.225302 0.060445 0.431742] [ 0.232077 0.059889 0.437695] [ 0.238826 0.059517 0.443256] [ 0.245543 0.059352 0.448436] [ 0.25222 0.059415 0.453248] [ 0.258857 0.059706 0.45771 ] [ 0.265447 0.060237 0.46184 ] [ 0.271994 0.060994 0.46566 ] [ 0.278493 0.061978 0.46919 ] [ 0.284951 0.063168 0.472451] [ 0.291366 0.064553 0.475462] [ 0.29774 0.066117 0.478243] [ 0.304081 0.067835 0.480812] [ 0.310382 0.069702 0.483186] [ 0.316654 0.07169 0.48538 ] [ 0.322899 0.073782 0.487408] [ 0.329114 0.075972 0.489287] [ 0.335308 0.078236 0.491024] [ 0.341482 0.080564 0.492631] [ 0.347636 0.082946 0.494121] [ 0.353773 0.085373 0.495501] [ 0.359898 0.087831 0.496778] [ 0.366012 0.090314 0.49796 ] [ 0.372116 0.092816 0.499053] [ 0.378211 0.095332 0.500067] [ 0.384299 0.097855 0.501002] [ 0.390384 0.100379 0.501864] [ 0.396467 0.102902 0.502658] [ 0.402548 0.10542 0.503386] [ 0.408629 0.10793 0.504052] [ 0.414709 0.110431 0.504662] [ 0.420791 0.11292 0.505215] [ 0.426877 0.115395 0.505714] [ 0.432967 0.117855 0.50616 ] [ 0.439062 0.120298 0.506555] [ 0.445163 0.122724 0.506901] [ 0.451271 0.125132 0.507198] [ 0.457386 0.127522 0.507448] [ 0.463508 0.129893 0.507652] [ 0.46964 0.132245 0.507809] [ 0.47578 0.134577 0.507921] [ 0.481929 0.136891 0.507989] [ 0.488088 0.139186 0.508011] [ 0.494258 0.141462 0.507988] [ 0.500438 0.143719 0.50792 ] [ 0.506629 0.145958 0.507806] [ 0.512831 0.148179 0.507648] [ 0.519045 0.150383 0.507443] [ 0.52527 0.152569 0.507192] [ 0.531507 0.154739 0.506895] [ 0.537755 0.156894 0.506551] [ 0.544015 0.159033 0.506159] [ 0.550287 0.161158 0.505719] [ 0.556571 0.163269 0.50523 ] [ 0.562866 0.165368 0.504692] [ 0.569172 0.167454 0.504105] [ 0.57549 0.16953 0.503466] [ 0.581819 0.171596 0.502777] [ 0.588158 0.173652 0.502035] [ 0.594508 0.175701 0.501241] [ 0.600868 0.177743 0.500394] [ 0.607238 0.179779 0.499492] [ 0.613617 0.181811 0.498536] [ 0.620005 0.18384 0.497524] [ 0.626401 0.185867 0.496456] [ 0.632805 0.187893 0.495332] [ 0.639216 0.189921 0.49415 ] [ 0.645633 0.191952 0.49291 ] [ 0.652056 0.193986 0.491611] [ 0.658483 0.196027 0.490253] [ 0.664915 0.198075 0.488836] [ 0.671349 0.200133 0.487358] [ 0.677786 0.202203 0.485819] [ 0.684224 0.204286 0.484219] [ 0.690661 0.206384 0.482558] [ 0.697098 0.208501 0.480835] [ 0.703532 0.210638 0.479049] [ 0.709962 0.212797 0.477201] [ 0.716387 0.214982 0.47529 ] [ 0.722805 0.217194 0.473316] [ 0.729216 0.219437 0.471279] [ 0.735616 0.221713 0.46918 ] [ 0.742004 0.224025 0.467018] [ 0.748378 0.226377 0.464794] [ 0.754737 0.228772 0.462509] [ 0.761077 0.231214 0.460162] [ 0.767398 0.233705 0.457755] [ 0.773695 0.236249 0.455289] [ 0.779968 0.238851 0.452765] [ 0.786212 0.241514 0.450184] [ 0.792427 0.244242 0.447543] [ 0.798608 0.24704 0.444848] [ 0.804752 0.249911 0.442102] [ 0.810855 0.252861 0.439305] [ 0.816914 0.255895 0.436461] [ 0.822926 0.259016 0.433573] [ 0.828886 0.262229 0.430644] [ 0.834791 0.26554 0.427671] [ 0.840636 0.268953 0.424666] [ 0.846416 0.272473 0.421631] [ 0.852126 0.276106 0.418573] [ 0.857763 0.279857 0.415496] [ 0.86332 0.283729 0.412403] [ 0.868793 0.287728 0.409303] [ 0.874176 0.291859 0.406205] [ 0.879464 0.296125 0.403118] [ 0.884651 0.30053 0.400047] [ 0.889731 0.305079 0.397002] [ 0.8947 0.309773 0.393995] [ 0.899552 0.314616 0.391037] [ 0.904281 0.31961 0.388137] [ 0.908884 0.324755 0.385308] [ 0.913354 0.330052 0.382563] [ 0.917689 0.3355 0.379915] [ 0.921884 0.341098 0.377376] [ 0.925937 0.346844 0.374959] [ 0.929845 0.352734 0.372677] [ 0.933606 0.358764 0.370541] [ 0.937221 0.364929 0.368567] [ 0.940687 0.371224 0.366762] [ 0.944006 0.377643 0.365136] [ 0.94718 0.384178 0.363701] [ 0.95021 0.39082 0.362468] [ 0.953099 0.397563 0.361438] [ 0.955849 0.4044 0.360619] [ 0.958464 0.411324 0.360014] [ 0.960949 0.418323 0.35963 ] [ 0.96331 0.42539 0.359469] [ 0.965549 0.432519 0.359529] [ 0.967671 0.439703 0.35981 ] [ 0.96968 0.446936 0.360311] [ 0.971582 0.45421 0.36103 ] [ 0.973381 0.46152 0.361965] [ 0.975082 0.468861 0.363111] [ 0.97669 0.476226 0.364466] [ 0.97821 0.483612 0.366025] [ 0.979645 0.491014 0.367783] [ 0.981 0.498428 0.369734] [ 0.982279 0.505851 0.371874] [ 0.983485 0.51328 0.374198] [ 0.984622 0.520713 0.376698] [ 0.985693 0.528148 0.379371] [ 0.9867 0.535582 0.38221 ] [ 0.987646 0.543015 0.38521 ] [ 0.988533 0.550446 0.388365] [ 0.989363 0.557873 0.391671] [ 0.990138 0.565296 0.395122] [ 0.990871 0.572706 0.398714] [ 0.991558 0.580107 0.402441] [ 0.992196 0.587502 0.406299] [ 0.992785 0.594891 0.410283] [ 0.993326 0.602275 0.41439 ] [ 0.993834 0.609644 0.418613] [ 0.994309 0.616999 0.42295 ] [ 0.994738 0.62435 0.427397] [ 0.995122 0.631696 0.431951] [ 0.99548 0.639027 0.436607] [ 0.99581 0.646344 0.441361] [ 0.996096 0.653659 0.446213] [ 0.996341 0.660969 0.45116 ] [ 0.99658 0.668256 0.456192] [ 0.996775 0.675541 0.461314] [ 0.996925 0.682828 0.466526] [ 0.997077 0.690088 0.471811] [ 0.997186 0.697349 0.477182] [ 0.997254 0.704611 0.482635] [ 0.997325 0.711848 0.488154] [ 0.997351 0.719089 0.493755] [ 0.997351 0.726324 0.499428] [ 0.997341 0.733545 0.505167] [ 0.997285 0.740772 0.510983] [ 0.997228 0.747981 0.516859] [ 0.997138 0.75519 0.522806] [ 0.997019 0.762398 0.528821] [ 0.996898 0.769591 0.534892] [ 0.996727 0.776795 0.541039] [ 0.996571 0.783977 0.547233] [ 0.996369 0.791167 0.553499] [ 0.996162 0.798348 0.55982 ] [ 0.995932 0.805527 0.566202] [ 0.99568 0.812706 0.572645] [ 0.995424 0.819875 0.57914 ] [ 0.995131 0.827052 0.585701] [ 0.994851 0.834213 0.592307] [ 0.994524 0.841387 0.598983] [ 0.994222 0.84854 0.605696] [ 0.993866 0.855711 0.612482] [ 0.993545 0.862859 0.619299] [ 0.99317 0.870024 0.626189] [ 0.992831 0.877168 0.633109] [ 0.99244 0.88433 0.640099] [ 0.992089 0.89147 0.647116] [ 0.991688 0.898627 0.654202] [ 0.991332 0.905763 0.661309] [ 0.99093 0.912915 0.668481] [ 0.99057 0.920049 0.675675] [ 0.990175 0.927196 0.682926] [ 0.989815 0.934329 0.690198] [ 0.989434 0.94147 0.697519] [ 0.989077 0.948604 0.704863] [ 0.988717 0.955742 0.712242] [ 0.988367 0.962878 0.719649] [ 0.988033 0.970012 0.727077] [ 0.987691 0.977154 0.734536] [ 0.987387 0.984288 0.742002] [ 0.987053 0.991438 0.749504] ]; ltfat/inst/thirdparty/misc/miscinit.m0000664000175000017500000000164413026262303017665 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} miscinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/misc/miscinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/thirdparty/misc/ltfat_nicecolormap.m0000664000175000017500000000547113026262303021715 0ustar susnaksusnakfunction ret = ltfat_nicecolormap() %-*- texinfo -*- %@deftypefn {Function} ltfat_nicecolormap %@verbatim % LTFAT_NICECOLORMAP Creates a nice colormap % % The function returns 64 x 3 matrix representing % RGB values of a colormap. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/thirdparty/misc/ltfat_nicecolormap.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %AUTHOR: Peret Balazs ret = ... [ 0 0 0.2000 0 0 0.2076 0 0 0.2152 0 0 0.2229 0 0 0.2305 0 0 0.2381 0 0 0.2457 0 0 0.2533 0 0 0.3778 0 0 0.5022 0 0 0.6267 0 0 0.7511 0 0 0.8756 0 0 1.0000 0 0.0857 0.9143 0 0.1714 0.8286 0 0.2571 0.7429 0 0.3429 0.6571 0 0.4286 0.5714 0 0.5143 0.4857 0 0.6000 0.4000 0.0909 0.6364 0.3636 0.1818 0.6727 0.3273 0.2727 0.7091 0.2909 0.3636 0.7455 0.2545 0.4545 0.7818 0.2182 0.5455 0.8182 0.1818 0.6364 0.8545 0.1455 0.7273 0.8909 0.1091 0.8182 0.9273 0.0727 0.9091 0.9636 0.0364 1.0000 1.0000 0 1.0000 0.8750 0 1.0000 0.7500 0 1.0000 0.6250 0 1.0000 0.5000 0 1.0000 0.3750 0 1.0000 0.2500 0 1.0000 0.1250 0 1.0000 0 0 1.0000 0.0196 0.0196 1.0000 0.0392 0.0392 1.0000 0.0588 0.0588 1.0000 0.0784 0.0784 1.0000 0.1936 0.1936 1.0000 0.3088 0.3088 1.0000 0.4240 0.4240 1.0000 0.5392 0.5392 1.0000 0.6544 0.6544 1.0000 0.7696 0.7696 1.0000 0.8848 0.8848 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000]; ltfat/inst/scalardistribute.m0000664000175000017500000000652213026262303016265 0ustar susnaksusnakfunction 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.github.io/doc/scalardistribute.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/ltfatstart.m0000664000175000017500000002134113026262303015105 0ustar susnaksusnakfunction ltfatstart(varargin) %-*- 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. % % The function walks the directory tree and adds a subdirectory % to path if the directory contain a [subdirectory,init.m] % script setting a status variable to some value greater than 0. % status==1 identifies a toolbox module any other value just a % directory to be added to path. % % LTFATSTART(0) supresses any status messages. % % !!WARNING for MATLAB users!! % ---------------------------- % % The function indirectly calls clear all, which clears all your global % and persistent variables. It comes with calling javaaddpath in % blockproc/blockprocinit.m. You can avoid calling it by passing % additional 'nojava' flag. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/ltfatstart.html} %@seealso{ltfatsetdefaults, ltfatmex, ltfathelp, ltfatstop} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard, Zdenek Prusa % TESTING: NA %% PKG_ADD: ltfatstart(0); do_java = 1; ltfatstartprint=1; if nargin>0 scalarIds = cellfun(@isscalar,varargin); nojavaIds = strcmpi('nojava',varargin); if ~all(scalarIds | nojavaIds) error(['LTFATSTART: Only a single scalar and flag, '... '''nojava'' are recognized']); end if any(nojavaIds) do_java = 0; end scalars = varargin(scalarIds); if numel(scalars)>1 error('LTFATSTART: Only a single scalar can be passed.'); elseif numel(scalars) == 1 ltfatstartprint=scalars{1}; end end; % Sometimes the run command used further does not return back to the % current directory, here we explicitly store the current directory and % cd to it at the end or is something goes wrong. currdir = pwd; % 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); pathCell = regexp(path, pathsep, 'split'); if ispc % Windows is not case-sensitive bponPath = any(strcmpi(basepath, pathCell)); else bponPath = any(strcmp(basepath, pathCell)); end if ~bponPath % To avoid recursion during pkg load addpath(basepath); end bp=basepath; % Load the version number [FID, MSG] = fopen ([bp,filesep,'ltfat_version'],'r'); if FID == -1 error(MSG); else ltfat_version = fgetl (FID); fclose(FID); end ignored_dirs_common = {[filesep(),'mat2doc'],... [filesep(),'src']}; ignored_inits = {}; if ~do_java ignored_inits{end+1} = {'blockprocinit.m',1}; end %% --- Check for old versions of Octave and Matlab if isoctave major_rq=3; minor_rq=6; intp='Octave'; req_versionname='3.6.0'; ignore_dirs = [{[filesep(),'mex']},... ignored_dirs_common]; else major_rq=7; minor_rq=9; intp='Matlab'; req_versionname='2009b'; ignore_dirs = [{[filesep(),'oct']},... ignored_dirs_common]; 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); % Pick only valid directories and wrap it in a cell array d={d(arrayfun(@(dEl) dEl.isdir && ~strcmp(dEl.name(1),'.'),d))}; basedir = {filesep}; while ~isempty(d) for ii=1:length(d{1}) name=d{1}(ii).name; % Skip ignored directories if any(cellfun(@(iEl) strcmp([basedir{1},name],iEl),ignore_dirs)) continue; end % Store only valid subdirectories, we will go trough them later dtmp = dir([bp,basedir{1},name]); dtmp = dtmp(arrayfun(@(dEl) dEl.isdir && ~strcmp(dEl.name(1),'.'),dtmp)); if ~isempty(dtmp) d{end+1} = dtmp; % Store base directory too basedir{end+1} = [basedir{1},name,filesep]; end % The file is a directory and it does not start with '.' This could % be a module initfilename = [lower(name),'init.m']; initfilefullpath = [bp,basedir{1},name,filesep,initfilename]; if ~exist(initfilefullpath,'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,basedir{1},name]); iffound = cellfun(@(iEl) strcmpi(initfilename,iEl{1}),ignored_inits); if any(iffound) status = ignored_inits{iffound}{2}; else % Execute the init file to see if the status is set. % We are super paranoid co we wrap the call to a try block try run(initfilefullpath); catch % If the run command breaks, it might not cd back to the % original directory. We do it manually here: cd(currdir); end end if status>0 % Only store top-level modules if status==1 && strcmp(basedir{1},filesep) nplug=nplug+1; modules{nplug}.name=name; modules{nplug}.version=module_version; end; else % Something failed, restore the path rmpath([bp,basedir{1},name]); end; end; % Remove the just processed dir from the list basedir(1) = []; d(1) = []; 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" immediately.'; end; banner = sprintf(['LTFAT version %s. Copyright 2005-2016 Peter L. Soendergaard. ' ... 'For help, please type "ltfathelp". %s'], ... ltfat_version,backend); disp(banner); if ~isoctave() && do_java disp('(Your global and persistent variables have just been cleared. Sorry.)'); end if exist('ltfat_binary_notes.m','file') ltfat_binary_notes; end; end; if isoctave() % On Windows the run command might not change back to the original path cd(currdir); end %% ---------- load information into ltfathelp ------------ clear ltfatarghelper; % 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]); ltfat/inst/operators/0000775000175000017500000000000013026262303014554 5ustar susnaksusnakltfat/inst/operators/spreadfun.m0000664000175000017500000000305513026262303016724 0ustar susnaksusnakfunction 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.github.io/doc/operators/spreadfun.html} %@seealso{spreadop, tconv, spreadinv, spreadadj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/operator.m0000664000175000017500000000324513026262303016571 0ustar susnaksusnakfunction 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.github.io/doc/operators/operator.html} %@seealso{operatornew, ioperator, operatoradj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/operatoreigs.m0000664000175000017500000000477113026262303017446 0ustar susnaksusnakfunction 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.github.io/doc/operators/operatoreigs.html} %@seealso{operatornew, operator, ioperator} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/operatorappr.m0000664000175000017500000000344713026262303017460 0ustar susnaksusnakfunction Opout=operatorappr(Op,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.github.io/doc/operators/operatorappr.html} %@seealso{operatornew, operator, operatoreigs} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/framemuleigs.m0000664000175000017500000001100713026262303017411 0ustar susnaksusnakfunction 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.github.io/doc/operators/framemuleigs.html} %@seealso{framemul, framemulappr} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/operators/framemul.m0000664000175000017500000000564213026262303016551 0ustar susnaksusnakfunction 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.github.io/doc/operators/framemul.html} %@seealso{iframemul, framemuladj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,bsxfun(@times,frana(Fa,f),s)); ltfat/inst/operators/spreadeigs.m0000664000175000017500000000321613026262303017062 0ustar susnaksusnakfunction [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.github.io/doc/operators/spreadeigs.html} %@seealso{tconv, spreadfun, spreadinv, spreadadj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/operatornew.m0000664000175000017500000000414113026262303017277 0ustar susnaksusnakfunction 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. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/operators/operatornew.html} %@seealso{operator, ioperator} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/framemulappr.m0000664000175000017500000000646513026262303017440 0ustar susnaksusnakfunction [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.github.io/doc/operators/framemulappr.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/operators/operatorsinit.m0000664000175000017500000000165013026262303017636 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} operatorsinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/operators/operatorsinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/operators/operatoradj.m0000664000175000017500000000335113026262303017246 0ustar susnaksusnakfunction 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.github.io/doc/operators/operatoradj.html} %@seealso{operatornew, operator, ioperator} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/ioperator.m0000664000175000017500000000331313026262303016736 0ustar susnaksusnakfunction 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.github.io/doc/operators/ioperator.html} %@seealso{operatornew, operator, operatoradj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/framemuladj.m0000664000175000017500000000333313026262303017223 0ustar susnaksusnakfunction 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. This is equivalent to calling % framemul(f,Fs,Fa,conj(s)). % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/operators/framemuladj.html} %@seealso{framemul, iframemul} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)); ltfat/inst/operators/spreadop.m0000664000175000017500000000656213026262303016560 0ustar susnaksusnakfunction 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.github.io/doc/operators/spreadop.html} %@seealso{tconv, spreadfun, spreadinv, spreadadj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/operators/spreadadj.m0000664000175000017500000000712713026262303016676 0ustar susnaksusnakfunction 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.github.io/doc/operators/spreadadj.html} %@seealso{spreadop, tconv, spreadfun, spreadinv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/operators/gabmulappr.m0000664000175000017500000001023413026262303017064 0ustar susnaksusnakfunction [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.github.io/doc/operators/gabmulappr.html} %@seealso{framemulappr, demo_gabmulappr} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/operators/iframemul.m0000664000175000017500000000632013026262303016714 0ustar susnaksusnakfunction [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.github.io/doc/operators/iframemul.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/operators/spreadinv.m0000664000175000017500000000353613026262303016734 0ustar susnaksusnakfunction 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.github.io/doc/operators/spreadinv.html} %@seealso{spreadfun, tconv, spreadfun, spreadadj} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/operators/operatormatrix.m0000664000175000017500000000267113026262303020020 0ustar susnaksusnakfunction T=operatormatrix(Op) %-*- 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.github.io/doc/operators/operatormatrix.html} %@seealso{operatornew, operator, operatoreigs} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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)); ltfat/inst/private/0000775000175000017500000000000013026262303014210 5ustar susnaksusnakltfat/inst/private/ref_edgt_1.m0000664000175000017500000000305713026262303016372 0ustar susnaksusnakfunction c=ref_edgt_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_edgt_1 %@verbatim %REF_EDGT_1 Reference Even Discrete Gabor transform by DGT % Usage c=ref_edgt(f,g,a,M); % % The input window must be odd-centered of length 2L. % % M must be even %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_edgt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); N=L/a; M=L/b; clong=ref_dgtii([f;flipud(f)],g,a,2*b); c=zeros(M*N,W); % The coefficient array is stacked from: % - The first M/2 coefficients of the first time shift. % - The body of the coefficients % - The first M/2 coefficients of the last time shift. c(:,:)=[clong(1:M/2,:); ... clong(M+1:M*N+M/2,:)]; % Scale the first coefficients correctly c(1,:)=c(1,:)/sqrt(2); c(M*(N-1)+M/2+1,:)=c(M*(N-1)+M/2+1,:)/sqrt(2); ltfat/inst/private/ref_bincoeff.m0000664000175000017500000000221513026262303016775 0ustar susnaksusnakfunction out=ref_bincoeff(u,v) %-*- texinfo -*- %@deftypefn {Function} ref_bincoeff %@verbatim %REF_BINCOEFF Binomial coefficients, possibly rational % % Compted by lambda functions. % % See formula 1.2 in Unsers paper: "Fractional splines and wavelets" %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_bincoeff.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . out=gamma(u+1)./(gamma(v+1).*gamma(u-v+1)); ltfat/inst/private/ref_rdgt.m0000664000175000017500000000310313026262303016157 0ustar susnaksusnakfunction c=ref_rdgt(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_rdgt %@verbatim %REF_RDGT Reference Real DGT % Usage: c=ref_rdgt(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); b=L/M; N=L/a; Mhalf=ceil(M/2); F=zeros(L,M*N); l=(0:L-1).'; for n=0:N-1 % Do the unmodulated coefficient. F(:,M*n+1)=circshift(g,n*a); for m=1:Mhalf-1 F(:,M*n+2*m)=sqrt(2)*cos(2*pi*m*l/M).*circshift(g,n*a); F(:,M*n+2*m+1)=sqrt(2)*sin(2*pi*m*l/M).*circshift(g,n*a); end; if mod(M,2)==0 F(:,M*(n+1))=cos(pi*l).*circshift(g,n*a); end; end; % dot-transpose will work because F is real. c=F.'*f; ltfat/inst/private/ref_rdft_1.m0000664000175000017500000000330013026262303016375 0ustar susnaksusnakfunction c=ref_rdft_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_rdft_1 %@verbatim %REF_RDFT_1 Reference RDFT by FFT % Usage: c=ref_rdft_1(f); % % Compute RDFT by doing a DFT and returning half the coefficients. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdft_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=ceil(L/2); Lend=Lhalf*2-1; if ~isreal(f) c=ref_rdft_1(real(f))+i*ref_rdft_1(imag(f)); else cc=fft(f); c=zeros(size(f)); % Copy the first coefficient, it is real c(1,:)=1/sqrt(2)*real(cc(1,:)); % Copy the cosine-part of the coefficients. c(2:2:Lend,:)=real(cc(2:Lhalf,:)); % Copy the sine-part of the coefficients. c(3:2:Lend,:)=-imag(cc(2:Lhalf,:)); % If f has an even length, we must also copy the Niquest-wave % (it is real) if mod(L,2)==0 c(end,:)=1/sqrt(2)*real(cc(L/2+1,:)); end; % Make it an ortonomal transform c=c/sqrt(L/2); end; ltfat/inst/private/ref_dgt_5.m0000664000175000017500000000440513026262303016227 0ustar susnaksusnakfunction coef=ref_dgt_5(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_5 %@verbatim %REF_DGT_5 DGT algorithm 5 % % This algorithm uses explicit convolution inside the loops. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_5.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; b=L/M; [c,h_a,h_m]=gcd(-a,M); p=a/c; q=M/c; d=N/q; w=zeros(M,N); if 0 % As ref_dgt_2, but substitution mt=k+st*p % and n =u+s*q % and apply reductions as described in the paper. for r=0:c-1 for l=0:q-1 for u=0:q-1 for k=0:p-1 for s=0:d-1 for st=0:d-1 w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)=w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)+f(mod(r+k*M+st*p*M-l*h_a*a,L)+1)*... conj(g(mod(r+k*M-u*a+(st-s)*p*M,L)+1)); end; end; end; end; end; end; end; if 1 % As above, but the inner convolution is now explicitly expressed for r=0:c-1 for l=0:q-1 for u=0:q-1 for k=0:p-1 psi=zeros(d,1); phi=zeros(d,1); for s=0:d-1 psi(s+1)=f(mod(r+k*M+s*p*M-l*h_a*a,L)+1); phi(s+1)=g(mod(r+k*M-u*a+s*p*M,L)+1); end; innerconv = pconv(psi,phi,'r'); for s=0:d-1 w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)=w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)+innerconv(s+1); end; end; end; end; end; coef=fft(w); end; ltfat/inst/private/ref_idft.m0000664000175000017500000000240413026262303016150 0ustar susnaksusnakfunction f=ref_idft(c) %-*- texinfo -*- %@deftypefn {Function} ref_idft %@verbatim %REF_IDFT Reference Inverse Discrete Fourier Transform % Usage: f=ref_dft(c); % % REF_IDFT(f) computes the unitary discrete Fourier transform of the % coefficient c. % % AUTHOR: Jordy van Velthoven %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L = length(c); f = zeros(L,1); for l=0:L-1 for k=0:L-1 f(l+1) = f(l+1) + c(k+1) * exp(2*pi*i*k*l/L); end; end; f = f/sqrt(L); ltfat/inst/private/test_wfbt.m0000664000175000017500000001055313026262303016373 0ustar susnaksusnakfunction test_failed = test_wfbt(verbose) %-*- texinfo -*- %@deftypefn {Function} test_wfbt %@verbatim %TEST_WFBTPR % % Checks perfect reconstruction of the general wavelet transform of different % filters % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('========= TEST WFBT ============'); global LTFAT_TEST_TYPE; tolerance = 2e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 1e-5; end test_failed = 0; if(nargin>0) verbose = 1; else verbose = 0; end type = {'dec'}; ext = {'per','zero','odd','even'}; J = 4; %! Mild tree wt1 = wfbtinit({'db10',6,'full'}); wt1 = wfbtremove(2,1,wt1,'force'); wt1 = wfbtremove(2,3,wt1,'force'); % %! Hardcore tree wt2 = wfbtinit({'db3',1}); wt2 = wfbtput(1,1,'mband1',wt2); wt2 = wfbtput(2,2,'mband1',wt2); wt2 = wfbtput(3,3,'mband1',wt2); wt2 = wfbtput(3,1,'db10',wt2); wt2 = wfbtput(4,1,'dgrid2',wt2); wt2 = wfbtput(5,1,'db3',wt2); %! Another tree wt3 = wfbtinit(); wt3 = wfbtput(0,0,'cmband4',wt3); wt3 = wfbtput(1,0,'cmband6',wt3); wt3 = wfbtput(1,1,'cmband6',wt3); wt3 = wfbtput(2,0,'cmband4',wt3); wt3 = wfbtput(2,1,'cmband4',wt3); wt3 = wfbtput(3,1,'cmband4',wt3); wt3 = wfbtput(3,2,'cmband4',wt3); wt3 = wfbtput(3,3,'cmband4',wt3); wt3 = wfbtput(3,4,'cmband4',wt3); % wt2 = wfbtinit(); % wt2 = wfbtput(0,0,{'db',4},wt2); % wt2 = wfbtput(1,0,{'algmband',1},wt2); % wt2 = wfbtput(1,1,{'hden',3},wt2); % wt2 = wfbtput(2,0,{'dgrid',2},wt2); % wt2 = wfbtput(2,1,{'dgrid',2},wt2); test_filters = { {'algmband2',J} % 4 filters, uniform, crit. sub. % {'db4',J} % {'algmband1',J} % 3 filters, uniform, crit. sub. %{{'hden',3},J} % 3 filters, non-uniform, no crit. sub. no correct {'dgrid1',J} % 4 filters. sub. fac. 2 wt1 wt2 wt3 }; %testLen = 4*2^7-1;%(2^J-1); testLen = 53; f = tester_rand(testLen,10); for extIdx=1:length(ext) extCur = ext{extIdx}; for typeIdx=1:length(type) for tt=1:length(test_filters) actFilt = test_filters{tt}; if verbose, if(~isstruct(actFilt))fprintf('J=%d, filt=%s, ext=%s, inLen=%d \n',actFilt{2},actFilt{1},extCur,size(f,1)); else disp('Custom'); end; end; [c,info] = wfbt(f,actFilt,extCur); fhat = iwfbt(c,actFilt,size(f,1),extCur); %MSE err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~verbose) if(~isstruct(actFilt))fprintf('J=%d, %5.5s, ext=%s, L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,size(f,1),err,fail); else fprintf('Custom, err=%.4e %s\n',err,fail); end; end if strcmpi(fail,'FAILED') if verbose if(~isstruct(actFilt)) fprintf('err=%d, filt=%s, ext=%s, inLen=%d \n',err,actFilt{1},extCur,testLen); else disp('Custom'); end; figure(1);clf;stem([f,fhat]); figure(2);clf;stem([f-fhat]); break; end end fhat2 = iwfbt(c,info); err = norm(f-fhat2,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~isstruct(actFilt)) fprintf('INFO J=%d, %5.5s, ext=%s, L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,size(f,1),err,fail); else fprintf('INFO Custom, err=%.4e %s\n',err,fail); end; if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end ltfat/inst/private/ref_dctii.m0000664000175000017500000000237413026262303016324 0ustar susnaksusnakfunction c=ref_dctii(f) %-*- texinfo -*- %@deftypefn {Function} ref_dctii %@verbatim %REF_DCTII Reference Discrete Consine Transform type II % Usage: c=ref_dctii(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dctii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=ones(L,1); w(1)=1/sqrt(2); w=w*sqrt(2/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w(n+1)*cos(pi*n*(m+.5)/L); end; end; % Compute coefficients. c=F'*f; ltfat/inst/private/testC/0000775000175000017500000000000013026262276015303 5ustar susnaksusnakltfat/inst/private/testC/runtests.sh0000775000175000017500000000056413026262276017536 0ustar susnaksusnak#!/bin/bash echo "Running unit tests:" for i in $(find . -name "test_*" -not -name "*.c") do if test -f $i then if $VALGRIND ./$i 2>> tests.log then echo $i PASS else echo "ERROR in test $i: here's tests.log" echo "------" tail tests.log exit 1 fi fi done echo "" ltfat/inst/private/testC/test_ltfatresample.c0000664000175000017500000001226713026262276021361 0ustar susnaksusnak/* The 2nd row of this file will be used as additional parameters to gcc ../../thirdparty/Playrec/ltfatresample.c -lm -pedantic -std=c99 */ #include "../../thirdparty/Playrec/ltfatresample.h" #include "dbg.h" #include "minunit.h" void fillrand(SAMPLE* a, size_t L) { size_t m; srand (time(NULL)); for (m = 0; m < L; m++) { a[m] = ((SAMPLE) (rand())) / RAND_MAX; } } char* test_filter() { size_t L, ii; SAMPLE *in, *out, *out2, err; EMQFfilters ef; size_t bufNo = 10; size_t bufLen = 65; L = bufNo * bufLen; in = malloc(L * sizeof * in); fillrand(in, L); out = malloc(L * sizeof * out); out2 = malloc(L * sizeof * out); ef = emqffilters_init(0.1); /* Filter by blocks */ for (ii = 0; ii < bufNo; ii++) { emqffilters_dofilter(ef, in + ii * bufLen, bufLen, out + ii * bufLen); } emqffilters_done(&ef); ef = emqffilters_init(0.1); /* Filter */ emqffilters_dofilter(ef, in, L, out2); emqffilters_done(&ef); err = 0; for (ii = 0; ii < L; ii++) { err += abs(out[ii] - out2[ii]); } free(in); free(out); free(out2); mu_assert(err < 1e-10, "FILT BY BLOCKS") return NULL; } char* test_resample_fixedLin() { size_t ii, bufNo = 1000, Lout, ratioId = 0, lInId = 0; double ratio[] = { 44100.0 / 8001.0, 8001.0 / 44100.0, 1, 0 }; size_t Lin[] = {896, 63, 10, 478, 966, 7563, 0}; SAMPLE* out, *in; resample_error re; resample_plan rp; while (Lin[lInId]) { while (ratio[ratioId]) { in = malloc(Lin[lInId] * sizeof * in); rp = resample_init(BSPLINE, ratio[ratioId]); for (ii = 0; ii < bufNo; ii++) { Lout = resample_nextoutlen(rp, Lin[lInId]); fillrand(in, Lin[lInId]); out = malloc(Lout * sizeof * out); re = resample_execute(rp, in, Lin[lInId], out, Lout); mu_assert(re == RESAMPLE_OK, "Overflow or undeflow in fixed Lin") free(out); } free(in); resample_done(&rp); ratioId++; } lInId++; } return NULL; } char* test_resample_altLin() { size_t ii, bufNo = 1000, Lout, ratioId = 0, lInId = 0; double ratio[] = { 44100.0 / 8001.0, 8001.0 / 44100.0, 1, 0 }; size_t Lin[] = {896, 63, 10, 478, 966, 7563, 0}; SAMPLE* out, *in; resample_error re; resample_plan rp; while (ratio[ratioId]) { in = malloc(Lin[lInId] * sizeof * in); rp = resample_init(BSPLINE, ratio[ratioId]); for (ii = 0; ii < bufNo; ii++) { Lout = resample_nextoutlen(rp, Lin[lInId]); fillrand(in, Lin[lInId]); out = malloc(Lout * sizeof * out); re = resample_execute(rp, in, Lin[lInId], out, Lout); mu_assert(re == RESAMPLE_OK, "Overflow or undeflow in alternating Lin") free(out); } free(in); resample_done(&rp); ratioId++; if(Lin[++lInId]==0) { lInId = 0; } } return NULL; } char* test_resample_fixedLout() { size_t ii, bufNo = 1000, Lin, ratioId = 0, lInId = 0; double ratio[] = { 44100.0 / 8001.0, 8001.0 / 44100.0, 1, 0.99, 0.23, 3.333, 0 }; size_t Lout[] = {896, 63, 40, 478, 966, 7563, 0}; SAMPLE* out, *in; resample_error re; resample_plan rp; while (Lout[lInId]) { while (ratio[ratioId]) { rp = resample_init(BSPLINE, ratio[ratioId]); out = malloc(Lout[lInId] * sizeof * out); for (ii = 0; ii < bufNo; ii++) { Lin = resample_nextinlen(rp, Lout[lInId]); in = malloc(Lin * sizeof(SAMPLE)); fillrand(in, Lin); re = resample_execute(rp, in, Lin, out, Lout[lInId]); mu_assert(re == RESAMPLE_OK, "Overflow or undeflow in fixed Lout") free(in); } free(out); resample_done(&rp); ratioId++; } lInId++; } return NULL; } char* test_resample_altLout() { size_t ii, bufNo = 1000, Lin, ratioId = 0, lInId = 0; double ratio[] = { 44100.0 / 8001.0, 8001.0 / 44100.0, 1, 0.99, 0.23, 3.333, 0 }; size_t Lout[] = {896, 63, 40, 478, 966, 7563, 0}; SAMPLE* out, *in; resample_error re; resample_plan rp; while (ratio[ratioId]) { rp = resample_init(BSPLINE, ratio[ratioId]); out = malloc(Lout[lInId] * sizeof * out); for (ii = 0; ii < bufNo; ii++) { Lin = resample_nextinlen(rp, Lout[lInId]); in = malloc(Lin * sizeof(SAMPLE)); fillrand(in, Lin); re = resample_execute(rp, in, Lin, out, Lout[lInId]); mu_assert(re == RESAMPLE_OK, "Overflow or undeflow in alternating Lout") free(in); } free(out); resample_done(&rp); ratioId++; if(Lout[++lInId]==0) { lInId = 0; } } return NULL; } char *all_tests() { mu_suite_start(); mu_run_test(test_filter); mu_run_test(test_resample_fixedLin); mu_run_test(test_resample_fixedLout); mu_run_test(test_resample_altLout); mu_run_test(test_resample_altLin); return NULL; } RUN_TESTS(all_tests) ltfat/inst/private/testC/minunit.h0000664000175000017500000000221113026262276017133 0ustar susnaksusnak/* * minunit.h -- A minimal unit test framework for C * * Originally from Jara design http://www.jera.com/techinfo/jtns/jtn002.html * Modified by Zed Shaw in http://c.learncodethehardway.org * * * NOTE: The UNUSED(x) macro is used to mute the unused parameter warning. * */ #undef NDEBUG #ifndef _minunit_h #define _minunit_h #include #include "dbg.h" #include #include #define UNUSED(x) (void)(x) #define mu_suite_start() char *message = NULL #define mu_assert(test, message) if (!(test)) { log_err(message); return message; } #define mu_run_test(test) debug("\n-----%s", " " #test); \ message = test(); tests_run++; if (message) return message; #define RUN_TESTS(name) int main(int argc, char *argv[]) {\ UNUSED(argc);\ debug("----- RUNNING: %s", argv[0]);\ printf("----\nRUNNING: %s\n", argv[0]);\ char *result = name();\ if (result != 0) {\ printf("FAILED: %s\n", result);\ }\ else {\ printf("ALL TESTS PASSED\n");\ }\ printf("Tests run: %d\n", tests_run);\ exit(result != 0);\ } int tests_run; #endif ltfat/inst/private/testC/dbg.h0000664000175000017500000000211213026262276016204 0ustar susnaksusnak/* * dbg.h -- Zed's awesome debug macros * * From http://c.learncodethehardway.org !/!4 * * * * */ #ifndef __dbg_h__ #define __dbg_h__ #include #include #include #ifdef NDEBUG #define debug(M, ...) #else #define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #endif #define clean_errno() (errno == 0 ? "None" : strerror(errno)) #define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) #define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) #define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } #define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } #define check_mem(A) check((A), "Out of memory.") #define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; } #endif ltfat/inst/private/testC/Makefile0000664000175000017500000000123313026262276016742 0ustar susnaksusnak# # Makefile # # A common makefile for managing compilation of all tests. # By default, the makefile supplies only the basic flags, # test-specific flags, files and libraries are read directly # from a comment in test. # # Usage: # # CFLAGS=-g -Wall -Wextra -DNDEBUG LIBS= TEST_SRC=$(wildcard test_*.c) TESTS=$(patsubst %.c,%,$(TEST_SRC)) all: $(TESTS) $(TESTS): % : %.c $(CC) $(CFLAGS) $^ $(shell sed '2q;d' $^) -o $@ $(LIBS) debug: CFLAGS=-g -Wall -Wextra debug: LIBS=-lprofiler debug: all clean: rm -rf $(TESTS) .PHONY: tests tests: $(TESTS) sh ./runtests.sh valgrind: VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE) ltfat/inst/private/ref_irdgt3_1.m0000664000175000017500000000266013026262303016642 0ustar susnaksusnakfunction f=ref_irdgt3_1(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_irdgt3_1 %@verbatim %REF_IRDGT3_1 Reference Inverse Real DGT type 3 by IDGT3 % Usage: f=ref_irdgt3_1(c,g,a,M); % % Compute a complex coefficient layout for IDGT3 %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdgt3_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); W=size(c,2); R=size(g,2); b=L/M; N=L/a; Mhalf=floor(M/2); c=reshape(c,M,N,W); cc=zeros(M,N,W); for m=0:Mhalf-1 cc(m+1,:,:)=1/sqrt(2)*(c(2*m+1,:,:)-i*c(2*m+2,:,:)); cc(M-m,:,:)=1/sqrt(2)*(c(2*m+1,:,:)+i*c(2*m+2,:,:)); end; if mod(M,2)==1 cc((M+1)/2,:,:)=c(M,:,:); end; cc=reshape(cc,M*N,W); f=ref_igdgt(cc,g,a,M,0,.5,0); ltfat/inst/private/ref_idgt.m0000664000175000017500000000262013026262303016151 0ustar susnaksusnakfunction f=ref_idgt(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idgt %@verbatim %REF_DGT Reference Inverse Discrete Gabor transform. % Usage: c=ref_idgt(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Calculate the parameters that was not specified. L=size(g,1); b=L/M; N=L/a; W=size(c,2); % Create 2x2 grid matrix.. V=[a,0; 0,b]; % Create lattice and Gabor matrix. lat=ref_lattice(V,L); G=ref_gaboratoms(g,lat); % Apply matrix to c. f=G*c; ltfat/inst/private/ref_irdft.m0000664000175000017500000000255213026262303016336 0ustar susnaksusnakfunction c=ref_irdft(f) %-*- texinfo -*- %@deftypefn {Function} ref_irdft %@verbatim %REF_IRDFT Reference Inverse Real DFT % Usage: c=ref_irdft(f); % % Compute IRDFT by explicit formulas. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=ceil(L/2); Lend=Lhalf*2-1; F=zeros(L); F(:,1)=ones(L,1); l=(0:L-1).'/L; for m=1:Lhalf-1 F(:,2*m)=sqrt(2)*cos(2*pi*m*l); F(:,2*m+1)=sqrt(2)*sin(2*pi*m*l); end; if mod(L,2)==0 F(:,L)=cos(pi*L*l); end; F=F/sqrt(L); % dot-transpose will work because F is real. c=F*f; ltfat/inst/private/test_nonsepdgt_mesh.m0000664000175000017500000001026113026262303020442 0ustar susnaksusnakar=1:1:20; Mr=1:1:20; Lmodr=1:20; %[1 3 10 100 143]; lt1r=0:10; lt2r=1:15; test_failed=0; for lt2=lt2r lt2 for lt1=lt1r if lt1>=lt2 continue; end; if gcd(lt1,lt2)>1 continue end; for M=Mr for a=ar if a>=M continue; end; for Lmod=Lmodr L=dgtlength(1,a,M,[lt1,lt2])*Lmod; lt=[lt1,lt2]; [s0,s1,br] = shearfind(L,a,M,lt); f=tester_crand(L,1); g=tester_crand(L,1); if 0 gd = gabdual(g,a,M,'lt',lt); gd_shear = gabdual(g,a,M,'lt',lt,'nsalg',2); res=norm(gd-gd_shear)/norm(g); [test_failed,fail]=ltfatdiditfail(res,test_failed); stext=sprintf(['DUAL SHEAR L:%3i a:%3i M:%3i lt1:%2i lt2:%2i %0.5g ' ... '%s'], L,a,M,lt(1),lt(2),res,fail); disp(stext) if numel(fail)>0 error('Failed test'); end; end; if 1 cc = comp_nonsepdgt_multi(f,g,a,M,lt); cc_shear = comp_nonsepdgt_shear(f,g,a,M,s0,s1,br); res = norm(cc(:)-cc_shear(:))/norm(cc(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); stext=sprintf(['DGT SHEAR L:%3i a:%3i M:%3i lt1:%2i lt2:%2i %0.5g ' ... '%s'], L,a,M,lt(1),lt(2),res,fail); disp(stext) if numel(fail)>0 error('Failed test'); end; end; if 0 r=comp_idgt(cc_shear,gd,a,lt,0,1); res=norm(f-r,'fro')/norm(f,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); stext=sprintf(['REC SHEAR L:%3i a:%3i M:%3i lt1:%2i lt2:%2i %0.5g ' ... '%s'], L,a,M,lt(1),lt(2),res,fail); disp(stext) if numel(fail)>0 error('Failed test'); end; end; if 0 s0test=(L==noshearlength(L,a,M,lt)); s0inv=(s0==0); if s0inv~=s0test [L,a,M,s0==0, s0test] end; end; end; end; end; end; end; %-*- texinfo -*- %@deftypefn {Function} test_nonsepdgt_mesh %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_nonsepdgt_mesh.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/referenceinit.m0000664000175000017500000000165213026262303017214 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} referenceinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/referenceinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_gabimagepars.m0000664000175000017500000000247713026262303020061 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_gabimagepars %@verbatim %TEST_GABIMAGEPARS % % This will run a simple test of the gabimagepars routine over a range % of sizes, and make a plot of the efficiancy in the end. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabimagepars.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . x=800; y=1200; Ntests=10000; res=zeros(Ntests,5); offset=99; for ii=1:Ntests; Ls=ii+offset; [res(ii,1),res(ii,2),res(ii,3),res(ii,4),res(ii,5)]=gabimagepars(Ls,x,y); end; figure(1); % res(:,3) is L plot(res(:,3)./((1+offset:Ntests+offset)')) ltfat/inst/private/test_dgt_alg.m0000664000175000017500000000306313026262303017030 0ustar susnaksusnakLr=[24, 24, 24, 144,108,144,24,135,35,77,20]; ar=[ 4, 3, 6, 9, 9, 12, 6, 9, 5, 7, 1]; Mr=[ 6, 4, 4, 16, 12, 24, 8, 9, 7,11,20]; for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); b=L/M; N=L/a; c=gcd(a,M); d=gcd(b,N); p=a/c; q=M/c; f=tester_crand(L,1); g=tester_crand(L,1); %gd=gabdual(g,a,M); cc = ref_dgt(f,g,a,M); for jj=1:6 cc_comp = feval(['ref_dgt_',num2str(jj)],f,g,a,M); cdiff=cc-cc_comp; res=norm(cdiff(:)); s=sprintf('REF%s L:%3i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i %0.5g',num2str(jj),L, ... a,b,c,d,p,q,res); disp(s) end; end; %-*- texinfo -*- %@deftypefn {Function} test_dgt_alg %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt_alg.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_dstii.m0000664000175000017500000000250113026262303016334 0ustar susnaksusnakfunction c=ref_dstii(f) %-*- texinfo -*- %@deftypefn {Function} ref_dstii %@verbatim %REF_DSTII Reference Discrete Sine Transform type II % Usage: c=ref_dstii(f); % % The transform is computed by an FFT of 4 times the length of f. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dstii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=ones(L,1); w(L)=1/sqrt(2); w=w*sqrt(2/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w(n+1)*sin(pi*(n+1)*(m+.5)/L); end; end; % Compute coefficients. c=F'*f; ltfat/inst/private/test_blocprocoffline.m0000664000175000017500000000310413026262303020571 0ustar susnaksusnakfunction test_failed = test_blocprocoffline() %-*- texinfo -*- %@deftypefn {Function} test_blocprocoffline %@verbatim % Scanario 1) Block reading from a wav and block writing to a wav % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_blocprocoffline.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . inName = 'test_in.wav'; outName = 'test_out.wav'; f = 2*rand(44100,1)*0.9-1; wavwsave(f,44100,inName); fs=block(inName,'offline','outfile',outName); flag = 1; while flag [fb,flag] = blockread(); blockwrite(fb/2); end % Scanario 2) blockwrite from vector to wav % % f = gspi; f2 = 2*rand(numel(f),1)*0.9-1; fs = block([f,f2],'fs',44100,'offline','outfile',outName); flag = 1; while flag [fb,flag] = blockread(44100); blockwrite(fb/2); end delete(inName); delete(outName); ltfat/inst/private/ref_irdgtii.m0000664000175000017500000000322313026262303016655 0ustar susnaksusnakfunction f=ref_irdgtii(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_irdgtii %@verbatim %REF_IRDGTII Reference Inverse Real DGT type II % Usage: c=ref_rdgt(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdgtii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); b=L/M; N=L/a; Mhalf=ceil(M/2); F=zeros(L,M*N); l=(0:L-1).'; for n=0:N-1 % Do the unmodulated coefficient. F(:,M*n+1)=circshift(g,n*a+floor(a/2)); for m=1:Mhalf-1 F(:,M*n+2*m)=sqrt(2)*cos(2*pi*m*(l+.5)/M).*circshift(g,n*a+floor(a/2));; F(:,M*n+2*m+1)=sqrt(2)*sin(2*pi*m*(l+.5)/M).*circshift(g,n*a+floor(a/2));; end; if mod(M,2)==0 F(:,M*(n+1))=cos(pi*l).*circshift(g,n*a+floor(a/2));; end; end; % dot-transpose will work because F is real. f=F*c; ltfat/inst/private/ref_dgt2.m0000664000175000017500000000230613026262303016063 0ustar susnaksusnakfunction c=ref_dgt2(f,g1,g2,a1,a2,M1,M2); %-*- texinfo -*- %@deftypefn {Function} ref_dgt2 %@verbatim %REF_DGT2 Reference DGT2 % % Compute a DGT2 using a DGT along each dimension. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L1=size(f,1); L2=size(f,2); N1=L1/a1; N2=L2/a2; c=dgt(f,g1,a1,M1); c=reshape(c,M1*N1,L2); c=c.'; c=dgt(c,g2,a2,M2); c=reshape(c,M2*N2,M1*N1); c=c.'; c=reshape(c,M1,N1,M2,N2); ltfat/inst/private/test_dgt_fac.m0000664000175000017500000000527113026262303017021 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_dgt_fac %@verbatim %TEST_DGT Test DGT full window backend % % This script runs a throrough test of the COMP_DGT_FAC % and COMP_IDGT_FAC testing them on a range of input parameters. % % Use TEST_WFAC first, to verify that COMP_WFAC and COMP_IWFAC % are working, since this tester depends on them. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt_fac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[24,16,144,108,144,24,135,35,77,20]; ar=[ 4, 4, 9, 9, 12, 6, 9, 5, 7, 1]; Mr=[ 6, 8, 16, 12, 24, 8, 9, 7,11,20]; test_failed=0; disp('--- Used subroutines ---'); which comp_wfac which comp_iwfac which comp_dgt_fac which comp_idgt_fac for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); b=L/M; N=L/a; c=gcd(a,M); d=gcd(b,N); p=a/c; q=M/c; for W=1:3 for R=1:3 for rtype=1:2 if rtype==1 rname='REAL '; f=tester_rand(L,W); g=tester_rand(L,R); else rname='CMPLX'; f=tester_crand(L,W); g=tester_crand(L,R); end; gf=comp_wfac(g,a,M); cc=comp_dgt_fac(f,gf,a,M); cc2=ref_dgt(f,g,a,M); res=norm(cc(:)-cc2(:)); failed=''; if res>10e-10 failed='FAILED'; test_failed=test_failed+1; end; s=sprintf('DGT %s L:%3i W:%2i R:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i %0.5g %s',rname,L,W,R,a,b,c,d,p,q,res,failed); disp(s) end; for rtype=1:2 if rtype==1 rname='REAL '; g=tester_rand(L,R); else rname='CMPLX'; g=tester_crand(L,R); end; cc=tester_crand(M,N*R*W); gf=comp_wfac(g,a,M); f=comp_idgt_fac(ifft(cc)*sqrt(M),gf,L,a,M); f2=ref_idgt(reshape(cc,M*N*R,W),g,a,M); res=norm(f(:)-f2(:)); failed=''; if res>10e-10 failed='FAILED'; test_failed=test_failed+1; end; s=sprintf('IDGT %s L:%3i W:%2i R:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i %0.5g %s',rname,L,W,R,a,b,c,d,p,q,res,failed); disp(s) end; end; end; end; test_failed ltfat/inst/private/rand_hpe.m0000664000175000017500000000270213026262303016147 0ustar susnaksusnakfunction f=rand_hpe(varargin) %-*- texinfo -*- %@deftypefn {Function} rand_hpe %@verbatim %RAND_HPE Random HPE even function. % Usage: f=rand_hpe(s); % % RAND_HPE(s) generates an array of size s, which is HPE along the % first dimension. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/rand_hpe.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isnumeric(varargin); s=varargin; else s=cell2mat(varargin); end; if length(s)==1 error('To avoid confusion, the size must be at least two-dimensional.'); end; shalf=s; shalf(1)=floor(shalf(1)/2); f=(randn(shalf)-.5)+(randn(shalf)-.5)*i; if rem(s(1),2)==0 f=[f;flipud(conj(f))]; else f=[f; ... randn([1 s(2:end)])-.5; ... flipud(conj(f))]; end; ltfat/inst/private/ref_col2diag.m0000664000175000017500000000223713026262303016712 0ustar susnaksusnakfunction cout=ref_col2diag(cin); %-*- texinfo -*- %@deftypefn {Function} ref_col2diag %@verbatim %REF_COL2DIAG Compute matrix represenation from spreading symbol % % This function is its own inverse. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_col2diag.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(cin,1); cout=zeros(L); for ii=0:L-1 for jj=0:L-1 cout(ii+1,jj+1)=cin(ii+1,mod(ii-jj,L)+1); end; end; ltfat/inst/private/ref_dsft.m0000664000175000017500000000227413026262303016167 0ustar susnaksusnakfunction C=ref_dsft(F) %-*- texinfo -*- %@deftypefn {Function} ref_dsft %@verbatim %REF_DSFT Reference DSFT %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dsft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard K=size(F,1); L=size(F,2); C=zeros(L,K); for m=0:L-1 for n=0:K-1 for l=0:L-1 for k=0:K-1 C(m+1,n+1)=C(m+1,n+1)+F(k+1,l+1)*exp(2*pi*i*(k*n/K-l*m/L)); end; end; end; end; C=C/sqrt(K*L); ltfat/inst/private/ref_dgt_3.m0000664000175000017500000000502413026262303016223 0ustar susnaksusnakfunction c=ref_dgt_3(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_3 %@verbatim %REF_DGT_3 DGT algorithm 3 %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_3.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; b=L/M; [c,h_a,h_m]=gcd(-a,M); p=a/c; q=M/c; d=N/q; w=zeros(M,N); if 0 % This version uses the definition. F=zeros(c,d,p,q); G=zeros(c,d,p,q); for r=0:c-1 for s=0:d-1 for k=0:p-1 for l=0:q-1 for st=0:d-1 F(r+1,s+1,k+1,l+1)=F(r+1,s+1,k+1,l+1)+f(mod(r+k*M+st*p*M-l*h_a*a,L)+1)*exp(-2*pi*i*s*st/d); G(r+1,s+1,k+1,l+1)=G(r+1,s+1,k+1,l+1)+g(mod(r+k*M-l*a+st*p*M,L)+1)*exp(-2*pi*i*s*st/d); end; end; end; end; end; for r=0:c-1 for l=0:q-1 for u=0:q-1 for s=0:d-1 for v=0:d-1 for k=0:p-1 w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)=w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)+... 1/d*F(r+1,v+1,k+1,l+1)*conj(G(r+1,v+1,k+1,u+1))*exp(2*pi*i*v*s/d); end; end; end; end; end; end; else % This version uses matrix-vector products and ffts F=zeros(c,d,p,q); G=zeros(c,d,p,q); C=zeros(c,d,q,q); % Set up the matrices for r=0:c-1 for s=0:d-1 for k=0:p-1 for l=0:q-1 F(r+1,s+1,k+1,l+1)=f(mod(r+k*M+s*p*M-l*h_a*a,L)+1); G(r+1,s+1,k+1,l+1)=sqrt(M*d)*g(mod(r+k*M-l*a+s*p*M,L)+1); end; end; end; end; % fft them F=dft(F,[],2); G=dft(G,[],2); % Multiply them for r=0:c-1 for s=0:d-1 GM=reshape(G(r+1,s+1,:,:),p,q); FM=reshape(F(r+1,s+1,:,:),p,q); C(r+1,s+1,:,:)=GM'*FM; end; end; % Inverse fft C=idft(C,[],2); % Place the result for r=0:c-1 for l=0:q-1 for u=0:q-1 for s=0:d-1 w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)=C(r+1,s+1,u+1,l+1); end; end; end; end; end; c=dft(w); ltfat/inst/private/ref_edgtii_1.m0000664000175000017500000000246613026262303016717 0ustar susnaksusnakfunction c=ref_edgtii_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_edgtii_1 %@verbatim %REF_EDGTII_1 Reference Even Discrete Gabor transform type II by DGT % Usage c=ref_edgt(f,g,a,M); % % If a is even, then the input window must be odd-centered of length 2L. % % If a is odd, then the input window must be even-centered of length 2L. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_edgtii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); N=L/a; clong=ref_gdgt([f;conj(flipud(f))],g,a,M,.5,0,floor(a/2)); c=clong(1:M*N,:); ltfat/inst/private/ref_dwilt2.m0000664000175000017500000000214513026262303016431 0ustar susnaksusnakfunction c=ref_dwilt2(f,g1,g2,M1,M2); L1=size(f,1); L2=size(f,2); c=dwilt(f,g1,M1); c=reshape(c,L1,L2); c=c.'; c=dwilt(c,g2,M2); c=reshape(c,L2,L1); c=c.'; c=reshape(c,M1*2,L1/M1/2,M2*2,L2/M2/2); %-*- texinfo -*- %@deftypefn {Function} ref_dwilt2 %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwilt2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_dtwfb2filterbank.m0000664000175000017500000001616013026262303020663 0ustar susnaksusnakfunction test_failed = test_dtwfb2filterbank %-*- texinfo -*- %@deftypefn {Function} test_dtwfb2filterbank %@verbatim % This test only %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dtwfb2filterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; disp('========= TEST DTWFB ============'); global LTFAT_TEST_TYPE; tolerance = 3e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 1e-5; end L = 1000; Larray = [1100,1701]; Warray = [1,3]; dualwt{1} = {'qshift1',1}; dualwt{2} = {'qshift3',5,'first','symorth1'}; dualwt{3} = {{'qshift3',5,'full','first','ana:symorth3','leaf','db4'},... {'qshift3',5,'full','first','syn:symorth3','leaf','db4'}}; dualwt{4} = {{'ana:oddeven1',5},{'syn:oddeven1',5}}; dualwt{5} = {'qshift3',3,'first','db4'}; dualwt{6} = {{'syn:oddeven1',2,'doubleband'},{'ana:oddeven1',2,'doubleband'}}; dualwt{7} = {dtwfbinit({'syn:oddeven1',2,'doubleband'}),dtwfbinit({'ana:oddeven1',2,'doubleband'})}; dualwt{8} = {{'dual',{'syn:oddeven1',2,'doubleband'}},{'syn:oddeven1',2,'doubleband'}}; dualwt{9} = {dtwfbinit({'syn:oddeven1',3,'full'},'nat'),dtwfbinit({'ana:oddeven1',3,'full'},'nat')}; tmp= dtwfbinit({'qshift1',6,'full'}); tmp = wfbtremove(4,0,tmp,'force'); tmp = wfbtremove(4,3,tmp,'force'); tmp = wfbtremove(3,6,tmp,'force'); dualwt{10} = {tmp,tmp}; dualwt{11} = {'dden2',3}; dualwt{12} = {'optsym3',3}; tolerance = ones(numel(dualwt),1)*tolerance; % decrease the tolerance for oddeven filters tolerance([4,6,7,8,9]) = 4e-5; for ii = 1:numel(dualwt) if isempty(dualwt{ii}) continue; end if iscell(dualwt{ii}{1}) || isstruct(dualwt{ii}{1}) && numel(dualwt{ii})==2 dualwtana = dualwt{ii}{1}; dualwtsyn = dualwt{ii}{2}; else dualwtana = dualwt{ii}; dualwtsyn = dualwtana; end for order = {'nat','freq'} [g,a,info] = dtwfb2filterbank( dualwtana, 'real', order{1}); [gd,ad] = dtwfb2filterbank( dualwtsyn, 'real', order{1}); G = filterbankfreqz(g,a,L); if strcmp(order{1},'freq') % Test if is analytic.. % Except for the lowpass and highpass filters, energy in % negative frequency region should be negligible for iii=1:size(G,2) posfreqEn = norm(G(1:end/2,iii))^2; negfreqEn = norm(G(end/2+1:end,iii))^2; dtw = dtwfbinit(dualwtana); fno = numel(dtw.nodes{1}.h); if iii==1 || any(iii == [size(G,2)-fno-1:size(G,2)]) res = negfreqEn>posfreqEn/2; % No justification else res = negfreqEn>posfreqEn/100; if res>0 % Uncomment to see frequency response % G = filterbankfreqz(g,a,L,'plot','linabs'); end end if res break; end end [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE IS ANALYTIC %i %s %0.5g %s'],ii, order{1},res,fail); disp(s) end Greal = filterbankfreqz(info.g1,a,L); Ghilb = filterbankfreqz(info.g2,a,L); G2 = (Greal+1i*Ghilb); res = norm(G(:)-G2(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE %i %s %0.5g %s'],ii, order{1},res,fail); disp(s) [gc,ac,info] = dtwfb2filterbank( dualwtana, 'complex', order{1}); [gcd,acd] = dtwfb2filterbank( dualwtsyn, 'complex', order{1}); % Compare coefficients for LL = Larray for W = Warray for cmplx = {'real','complex'} if strcmp(cmplx{1},'real') f = tester_rand(LL,W); else f = tester_crand(LL,W); end if strcmp(cmplx{1},'real') c = dtwfbreal(f,dualwtana,order{1}); cfb = filterbank(f,g,a); res = cell2mat(c)-cell2mat(cfb); res = norm(res(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE COEFF %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) fhat = 2*real(ifilterbank(c,gd,ad,LL)); res= norm(f(:)-fhat(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) cc = dtwfb(f,dualwtana,order{1}); cfbc = filterbank(f,gc,ac); res = cell2mat(cc)-cell2mat(cfbc); res = norm(res(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE COEFF COMPLEX %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) fhat = ifilterbank(cc,gcd,acd,LL); res= norm(f(:)-fhat(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC COMPLEX %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) res = cell2mat(c)-cell2mat(cc(1:end/2)); res = norm(res(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE COEFF EQ %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) else c = dtwfb(f,dualwtana,order{1}); cfb = filterbank(f,gc,ac); res = cell2mat(c)-cell2mat(cfb); res = norm(res(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE COEFF %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) fhat = ifilterbank(c,gcd,acd,LL); res= norm(f(:)-fhat(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC %i L:%i W:%i %s %s %0.5g %s'],ii,LL,W,cmplx{1}, order{1},res,fail); disp(s) end end end end end end ltfat/inst/private/test_dgts.m0000664000175000017500000000664013026262303016374 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_dgts %@verbatim % This is currently the tester for the % new TF-transforms. % % It does not do multiwindow. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgts.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %Lr=[24,144,108,144,24,135,35,77]; %ar=[ 4, 9, 9, 12, 6, 9, 5, 7]; %Mr=[ 6, 16, 12, 24, 8, 9, 7,11]; Lr=[24,20,15,12]; ar=[ 4, 4, 3, 3]; Mr=[ 6, 5, 5, 4]; Wmax=2; ref_funs={{'ref_rdgt','ref_rdgt_1'},... {'ref_rdgt3','ref_rdgt3_1'},... {'ref_edgtii','ref_edgtii_1'},... }; refinv_funs={{'ref_irdgt','ref_irdgt_1'},... {'ref_irdgt3','ref_irdgt3_1'},... {'ref_iedgtii','ref_iedgtii_1'},... }; inv_funs={{'ref_rdgt','ref_irdgt'},... {'ref_rdgt3','ref_irdgt3'},... {'ref_edgtii','ref_iedgtii'},... }; % ---------- reference testing -------------------- % Test that the transforms agree on values. for funpair=ref_funs for ii=1:length(Lr); for W=1:Wmax L=Lr(ii); M=Mr(ii); a=ar(ii); %b=L/M; N=L/a; f=tester_rand(L,W); g=ref_win(funpair{1}{1},'test',L,a,M); c1=feval(funpair{1}{1},f,g,a,M); c2=feval(funpair{1}{2},f,g,a,M); res=norm(c1(:)-c2(:)); s=sprintf('REF %10s L:%3i W:%2i a:%3i M:%3i %0.5g',funpair{1}{2},L,W,a,M,res); disp(s) %if res>1e-8 % disp('Reference comparion failed:') % [L, M, N, a, b, c, d] % end; end; end; end; % ---------- reference inverse function testing --------------- % Test that the transforms agree on values. for funpair=refinv_funs for ii=1:length(Lr); for W=1:Wmax L=Lr(ii); M=Mr(ii); a=ar(ii); %b=L/M; N=L/a; c=tester_rand(M*N,W); g=ref_win(funpair{1}{1},'test',L,a,M); f1=feval(funpair{1}{1},c,g,a,M); f2=feval(funpair{1}{2},c,g,a,M); res=norm(f1(:)-f2(:)); s=sprintf('REF %10s L:%3i W:%2i a:%3i M:%3i %0.5g',funpair{1}{2},L,W,a,M,res); disp(s) %if res>1e-8 % disp('Reference comparion failed:') % [L, M, N, a, b, c, d] % end; end; end; end; %------------ inversion testing ----------------- % Test that the transforms are invertible for funpair=inv_funs for ii=1:length(Lr); for W=1:Wmax L=Lr(ii); M=Mr(ii); a=ar(ii); %b=L/M; N=L/a; f=tester_rand(L,W); g=ref_win(funpair{1}{1},'test',L,a,M); gamma=ref_tgabdual(funpair{1}{1},g,L,a,M); c=feval(funpair{1}{1},f,g,a,M); fr=feval(funpair{1}{2},c,gamma,a,M); res=norm(f(:)-fr(:)); s=sprintf('INV %10s L:%3i W:%2i a:%3i M:%3i %0.5g',funpair{1}{1},L,W,a,M,res); disp(s) %if res>1e-8 % disp('Reference comparion failed:') % [L, M, N, a, b, c, d] % end; end; end; end; ltfat/inst/private/ref_gabglasso_onb.m0000664000175000017500000000563313026262303020031 0ustar susnaksusnakfunction [xo,N]=gabglasso(ttype,xi,lambda,group); %-*- texinfo -*- %@deftypefn {Function} ref_gabglasso_onb %@verbatim %GABGLASSO group lasso estimate (hard/soft) in time-frequency domain % Usage: xo=gabglasso(ttype,x,lambda,group); % [xo,N]=gabglasso(ttype,x,lambda,group)); % % GABGLASSO('hard',x,lambda,'time') will perform % time hard group thresholding on x, i.e. all time-frequency % columns whose norm less than lambda will be set to zero. % % GABGLASSO('soft',x,lambda,'time') will perform % time soft thresholding on x, i.e. all time-frequency % columns whose norm less than lambda will be set to zero, % and those whose norm exceeds lambda will be multiplied % by (1-lambda/norm). % % GABGLASSO(ttype,x,lambda,'frequency') will perform % frequency thresholding on x, i.e. all time-frequency % rows whose norm less than lambda will be soft or hard thresholded % (see above). % % [xo,N]=GABGLASSO(ttype,x,lambda,group) additionally returns % a number N specifying how many numbers where kept. % % The function may meaningfully be applied to output from DGT, WMDCT or % from WIL2RECT(DWILT(...)). % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabglasso_onb.html} %@seealso{gablasso, gabelasso, demo_audioshrink} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Bruno Torresani. % REFERENCE: OK error(nargchk(4,4,nargin)); NbFreqBands = size(xi,1); NbTimeSteps = size(xi,2); xo = zeros(size(xi)); switch(lower(group)) case {'time'} for t=1:NbTimeSteps, threshold = norm(xi(:,t)); mask = (1-lambda/threshold); if(strcmp(ttype,'soft')) mask = mask * (mask>0); elseif(strcmp(ttype,'hard')) mask = (mask>0); end xo(:,t) = xi(:,t) * mask; end case {'frequency'} for f=1:NbFreqBands, threshold = norm(xi(f,:)); mask = (1-lambda/threshold); mask = mask * (mask>0); if(strcmp(ttype,'soft')) mask = mask * (mask>0); elseif(strcmp(ttype,'hard')) mask = (mask>0); end xo(f,:) = xi(f,:) * mask; end otherwise error('"group" parameter must be either "time" or "frequency".'); end if nargout==2 signif_map = (abs(xo)>0); N = sum(signif_map(:)); end ltfat/inst/private/test_dgt.m0000664000175000017500000001355313026262303016212 0ustar susnaksusnakfunction test_failed=test_dgt %-*- texinfo -*- %@deftypefn {Function} test_dgt %@verbatim %TEST_DGT Test DGT % % This script runs a throrough test of the DGT routine, % testing it on a range of input parameters. % % The computational backend is tested this way, but the % interface is not. % % The script tests dgt, idgt, gabdual and gabtight. % % Use TEST_WFAC and TEST_DGT_FAC for more specific testing % of the DGT backend. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[24,16,144,108,144,24,135,35,77,20]; ar=[ 4, 4, 9, 9, 12, 6, 9, 5, 7, 1]; Mr=[ 6, 8, 16, 12, 24, 8, 9, 7,11,20]; test_failed=0; disp(' =============== TEST_DGT ================'); disp('--- Used subroutines ---'); which comp_wfac which comp_iwfac which comp_sepdgt which comp_isepdgt which comp_sepdgtreal which comp_isepdgtreal which comp_gabdual_long which comp_gabtight_long for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); b=L/M; N=L/a; c=gcd(a,M); d=gcd(b,N); p=a/c; q=M/c; for rtype=1:2 if rtype==1 rname='REAL '; g=tester_rand(L,1); else rname='CMPLX'; g=tester_crand(L,1); end; global LTFAT_TEST_TYPE; if strcmpi(LTFAT_TEST_TYPE,'single') C = gabframebounds(g,a,M); while C>1e3 % warning(sprintf(['The frame is too badly conditioned '... % 'for single precision. Cond. num. %d. '... % ' Trying again.'],C)); if rtype==1 rname='REAL '; g=tester_rand(L,1); else rname='CMPLX'; g=tester_crand(L,1); end; C = gabframebounds(g,a,M); end end gd=gabdual(g,a,M); gt=gabtight(g,a,M); % --- Test windows against their reference implementations. --- ref_gd=ref_gabdual(g,a,M); res=norm(ref_gd-gd); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['REFDUAL %s L:%3i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i '... '%0.5g %s\n'],rname,L,a,b,c,d,p,q,res,fail); ref_gt=ref_gabtight(g,a,M); res=norm(ref_gt-gt); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['REFTIGHT %s L:%3i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i '... '%0.5g %s'],rname,L,a,b,c,d,p,q,res,fail); disp(s); % ---- Test gabdualnorm -------------------------------------- res=gabdualnorm(g,gd,a,M); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['DUALNORM1 %s L:%3i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i '... '%0.5g %s'],rname,L,a,b,c,d,p,q,res,fail); disp(s); [o1,o2]=gabdualnorm(g,gd,a,M); res=o1-1+o2; [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['DUALNORM2 %s L:%3i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i '... '%0.5g %s'],rname,L,a,b,c,d,p,q,res,fail); disp(s); for W=1:3 if rtype==1 f=tester_rand(L,W); else f=tester_crand(L,W); end; % --- Test DGT against its reference implementation. --- cc=dgt(f,g,a,M); cc2=ref_dgt(f,g,a,M); cdiff=cc-cast(cc2,class(cc)); res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['REF %s L:%3i W:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i '... '%0.5g %s'],rname,L,W,a,b,c,d,p,q,res,fail); disp(s) % --- Test reconstruction of IDGT using a canonical dual window. --- r=idgt(cc,gd,a); res=norm(f-r,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['REC %s L:%3i W:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i ' ... '%0.5g %s'],rname,L,W,a,b,c,d,p,q,res,fail); disp(s) % --- Test reconstruction of IDGT using a canonical tight window. --- res=norm(f-idgt(dgt(f,gt,a,M),gt,a),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['TIG %s L:%3i W:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i ' ... '%0.5g %s'],rname,L,W,a,b,c,d,p,q,res,fail); disp(s); % Test the real valued transform if rtype==1 % --- Reference test --- ccreal=dgtreal(f,g,a,M); M2=floor(M/2)+1; cdiff=cc(1:M2,:,:)-ccreal; res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['REFREAL L:%3i W:%2i a:%3i b:%3i c:%3i d:%3i p:%3i ' ... 'q:%3i %0.5g %s'],L,W,a,b,c,d,p,q,res,fail); disp(s); % --- Reconstruction test --- rreal=idgtreal(ccreal,gd,a,M); res=norm(f-rreal,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['RECREAL L:%3i W:%2i a:%3i b:%3i c:%3i d:%3i p:%3i ' ... 'q:%3i %0.5g %s'],L,W,a,b,c,d,p,q,res,fail); disp(s) end; end; end; end; ltfat/inst/private/ref_dctiii_1.m0000664000175000017500000000311413026262303016706 0ustar susnaksusnakfunction c=ref_dctiii_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dctiii_1 %@verbatim %REF_DCTII Reference Discrete Consine Transform type III % Usage: c=ref_dctiii(f); % % The transform is computed by an FFT of 4 times the length of f. % See the Wikipedia article on "Discrete Cosine Transform" % % This is the inverse of REF_DCTII %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dctiii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if ~isreal(f) c=ref_dctiii_1(real(f))+i*ref_dctiii_1(imag(f)); else % Scale coefficients to obtain orthonormal transform. f(1,:)=sqrt(2)*f(1,:); f=f*sqrt(2*L); % Make 4x long vector lf=[f;... zeros(1,W);... -flipud(f);... -f(2:end,:);... zeros(1,W);... flipud(f(2:end,:))]; fflong=real(ifft(lf)); c=fflong(2:2:2*L,:); end ltfat/inst/private/ref_spreadop.m0000664000175000017500000000232713026262303017043 0ustar susnaksusnakfunction fout=ref_spreadop(f,c,a); %-*- texinfo -*- %@deftypefn {Function} ref_spreadop %@verbatim %REF_SPREADOP Reference Spreading operator. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_spreadop.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . W=size(f,2); M=size(c,1); N=size(c,2); L=N*a; fout=zeros(L,W,assert_classname(f,c)); for l=0:L-1 for m=0:M-1 for n=0:N-1 fout(l+1,:)=fout(l+1,:)+c(m+1,n+1)*exp(2*pi*i*l*m/M)*f(mod(l-n*a,L)+1,:); end; end; end; ltfat/inst/private/ref_lattice.m0000664000175000017500000000306013026262303016646 0ustar susnaksusnakfunction [lat]=ref_lattice(V,L); %-*- texinfo -*- %@deftypefn {Function} ref_lattice %@verbatim %REF_LATTICE List of lattice points. % Usage: lat=ref_lattice(V,L) % % Returns the lattice given by av and bv. % The output format is a 2xMxN matrix, where % each column is a point on the lattice. % % The lattice must be in lower triangular Hermite normal form. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_lattice.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . a=V(1,1); b=V(2,2); s=V(2,1); M=abs(L/b); N=abs(L/a); % Create lattice. lattice=zeros(2,M*N); for n=0:N-1 for m=0:M-1 soffset=mod(s*n,b); % Determine gridpoint in rectangular coordinates. %lat(:,m+n*M+1) = V(:,1)*n+V(:,2)*m; lat(1,m+n*M+1) = n*a; lat(2,m+n*M+1) = m*b+soffset; end; end; % Mod' the lattice. lat=mod(lat,L); ltfat/inst/private/test_pfilt.m0000664000175000017500000001077313026262303016553 0ustar susnaksusnakfunction test_failed=test_pfilt Lr =[27,100,213]; %-*- texinfo -*- %@deftypefn {Function} test_pfilt %@verbatim % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pfilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . gr{1}=randn(20,1); gr{2}=randn(21,1); gr{3}=firfilter('hanning',19); gr{4}=firfilter('hanning',20); gr{5}=randn(4,1); gr{6}=firfilter('hanning',20,'causal'); gr{7}=firfilter('hanning',20,'delay',13); gr{8}=firfilter('hanning',20,'delay',-13); gr{7}=firfilter('hanning',20,'delay',14); gr{8}=firfilter('hanning',20,'delay',-14); gr{9}=firfilter('hamming',19,.3); gr{10}=firfilter('hamming',19,.3,'real'); gr{11}=blfilter('hanning',.19); gr{12}=blfilter('hanning',.2); gr{13}=blfilter('hanning',.132304); gr{14}=blfilter('hanning',.23,'delay',13); gr{15}=blfilter('hamming',.23,.3); gr{16}=blfilter('hamming',.23,.3,'real'); % (almost) Allpass filter gr{17}=blfilter('hanning',2); gr{18}=blfilter('hanning',1); gr{19}=blfilter('hanning',2,1); gr{20}=blfilter('hanning',1,-1); gr{21}=blfilter('hamming',.1,-.3); gr{22}=blfilter('hanning',1.7); % REMARK: modcent is applied to fc test_failed=0; disp(' =============== TEST_PFILT =============='); disp('--- Used subroutines ---'); which comp_filterbank_td which comp_filterbank_fft which comp_filterbank_fftbl which comp_filterbank disp('--- Regular subsampling ---'); for ii=1:numel(gr) % Skip empry fields in gr g=gr{ii}; if isempty(g) continue; end for a=1:3 for jj=1:length(Lr) % Create input signal of proper length L=ceil(Lr(jj)/a)*a; for W=1:3 for rtype=1:2 if rtype==1 rname='REAL '; f=tester_rand(L,W); else rname='CMPLX'; f=tester_crand(L,W); end; h2=ref_pfilt(f,g,a); h1=pfilt(f,g,a); res=norm(h1-h2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PFILT %3s filtno:%3i L:%3i W:%3i a:%3i %0.5g %s',rname,ii,L,W,a,res,fail); disp(s); end; end; end; end; end; disp('--- Fractional subsampling ---'); % Pick just bl filters idx = cellfun(@(grEl) isfield(grEl,'H'),gr); tmpRange = 1:numel(gr); tmpRange = tmpRange(idx); for ii=tmpRange g = gr{ii}; for jj=1:length(Lr) L = Lr(jj); % Find support and offset of the filter tmpH = g.H(L); if numel(tmpH) == L % this is no longer a band pass filter end foff = g.foff(L); Nmin = numel(tmpH); for Nalt=[-3,-7,3,0]; % Nalt==0 painless % Nalt>0 painless % Nalt<0 not painless if Nmin + Nalt <=0 a = [L,1]; elseif Nmin + Nalt >= L % This is no longer fractional subsampling a = [L,L]; else a = [L,Nmin+Nalt]; end for W=1:3 for rtype=1:2 if rtype==1 rname='REAL '; f=tester_rand(L,W); else rname='CMPLX'; f=tester_crand(L,W); end; h2=ref_pfilt(f,g,a); h1=pfilt(f,g,a); res=norm(h1-h2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PFILT %3s filtno:%3i L:%3i W:%3i a:[%3i,%3i], fb: %i, %0.5g %s',... rname,ii,L,W,a(1),a(2),Nmin,res,fail); disp(s); end end end end end ltfat/inst/private/ref_gabdualns_3.m0000664000175000017500000000216013026262303017403 0ustar susnaksusnakfunction gamma=ref_gabdualns_3(g,V); %-*- texinfo -*- %@deftypefn {Function} ref_gabdualns_3 %@verbatim %REF_GABDUALNS_3 GABDUALNS by multiwindow method. % Usage: gamma=ref_gabdualns_3(g,V); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabdualns_3.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [gm,a,M]=ref_nonsep2multiwin(g,V); gmd=gabdual(gm,a,M); gamma=gmd(:,1); ltfat/inst/private/ref_rdgt_1.m0000664000175000017500000000236313026262303016406 0ustar susnaksusnakfunction c=ref_rdgt_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_rdgt_1 %@verbatim %REF_RDGT_1 Reference Real DGT by fac. and RDFT % Usage: c=ref_rdgt_1(f,g,a,M); % % Compute the factorization and use RDFT %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdgt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); R=size(g,2); N=L/a; gf=comp_wfac(g,a,M); % Compute the window application and the DFT modulation. c=zeros(M*N*R,W); c(:)=ref_rdft(comp_dgt_fw(f,gf,L,a,M)); ltfat/inst/private/ref_iwfac.m0000664000175000017500000000335713026262303016323 0ustar susnaksusnakfunction [g]=ref_iwfac(gf,L,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_iwfac %@verbatim %REF_IWFAC Compute inverse window factorization % Usage: g=ref_iwfac(gf,L,a,M); % % Input parameters: % gf : Factored Window % L : Length of transform. % a : Length of time shift. % M : Number of frequency bands. % Output parameters: % g : Window function. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_iwfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); % 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)=gf(k+1,l+1+q*w,:,s+1); end; end; end; end; ltfat/inst/private/test_multiwin.m0000664000175000017500000000541013026262303017275 0ustar susnaksusnakfunction test_failed=test_multiwin %-*- texinfo -*- %@deftypefn {Function} test_multiwin %@verbatim %TEST_MULTIWIN Test multiwindow gabdual and gabtight %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_multiwin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[24,16,144,108,144,24,135,35,77,20]; ar=[ 4, 4, 9, 9, 12, 6, 9, 5, 7, 1]; Mr=[ 6, 8, 16, 12, 24, 8, 9, 7,11,20]; disp(' =============== TEST_MULTIWIN ================'); disp('--- Used subroutines ---'); which comp_wfac which comp_iwfac which comp_gabdual_long which comp_gabtight_long test_failed=0; for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); r=zeros(L,1); for R=1:3 for wintype = 1:2 switch wintype case 1 g=randn(L,R); rname='REAL '; case 2 g=tester_crand(L,R); rname='CMPLX'; end; N=L/a; % ----------- test canonical dual ---------------- gd=gabdual(g,a,M); f=tester_crand(L,1); r=zeros(L,1); for ii=1:R c=dgt(f,g(:,ii),a,M); r=r+idgt(c,gd(:,ii),a); end; res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['MULTIDUAL %s L:%3i R:%3i a:%3i M:%3i %0.5g %s\n'],rname,L, ... R,a,M,res,fail); % ----------- test canonical tight ---------------- gt=gabtight(g,a,M); f=tester_crand(L,1); r=zeros(L,1); for ii=1:R c=dgt(f,gt(:,ii),a,M); r=r+idgt(c,gt(:,ii),a); end; res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['MULTITIGHT %s L:%3i R:%3i a:%3i M:%3i %0.5g %s\n'],rname,L, ... R,a,M,res,fail); % ----------- test frame bounds ---------------- B=gabframebounds(gt,a,M); res=B-1; [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['MULTIFB %s L:%3i R:%3i a:%3i M:%3i %0.5g %s\n'],rname,L, ... R,a,M,res,fail); end; end; end; ltfat/inst/private/ref_dft_1.m0000664000175000017500000000247713026262303016231 0ustar susnaksusnakfunction c=ref_dft_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dft_1 %@verbatim %REF_DFT_1 Reference DFT by doubling % Usage: c=ref_dft_1(f); % % REF_DFT_1(f) computes a DFT of f by upsampling f and inserting zeros % at the odd positions. % % This is not an efficient method, it is just meant to illustrate a % symmetry of the DFT. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dft_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); flong=zeros(2*L,W,assert_classname(f)); flong(1:2:end-1)=f; fflong=fft(flong)/sqrt(L); c=fflong(1:L,:); ltfat/inst/private/ref_idwiltiii_1.m0000664000175000017500000000425113026262303017433 0ustar susnaksusnakfunction [f]=ref_idwiltiii_1(coef,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwiltiii_1 %@verbatim %REF_IDWILTIII_1 Reference IDWILTIII by IDGT type III % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwiltiii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard L=size(coef,1); N=L/a; W=size(coef,2); coef=reshape(coef,M,N,W); coef2=zeros(2*M,N,W); if 0 % --- loop version --- for n=0:N-1 for m=0:M-1 if rem(m+n,2)==0 coef2(m+1,n+1,:) = exp(i*pi/4)/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m,n+1,:) = exp(-i*pi/4)/sqrt(2)*coef(m+1,n+1,:); else coef2(m+1,n+1,:) = exp(-i*pi/4)/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m,n+1,:) = exp(i*pi/4)/sqrt(2)*coef(m+1,n+1,:); end; end; end; else % --- Vector version --- 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/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/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/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/4)/sqrt(2)*coef(2:2:M,2:2:N,:); end; f=ref_igdgt(reshape(coef2,2*M*N,W),g,a,2*M,0,0.5,0); ltfat/inst/private/ref_rdftii.m0000664000175000017500000000255413026262303016511 0ustar susnaksusnakfunction c=ref_rdftii(f) %-*- texinfo -*- %@deftypefn {Function} ref_rdftii %@verbatim %REF_RDFTII Reference Real DFT type II % Usage: c=ref_rdftii(f); % % Compute RDFTII by explicit formulas. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdftii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=ceil(L/2); F=zeros(L); F(:,1)=ones(L,1); l=(0:L-1).'; for m=1:Lhalf-1 F(:,2*m)=sqrt(2)*cos(2*pi*m*(l+.5)/L); F(:,2*m+1)=sqrt(2)*sin(2*pi*m*(l+.5)/L); end; if mod(L,2)==0 F(:,L)=cos(pi*l); end; F=F/sqrt(L); % dot-transpose will work because F is real. c=F.'*f; ltfat/inst/private/ref_dstiv.m0000664000175000017500000000233113026262303016352 0ustar susnaksusnakfunction c=ref_dstiv(f) %-*- texinfo -*- %@deftypefn {Function} ref_dstiv %@verbatim %REF_DSTIV Reference Discrete Sine Transform type IV % Usage: c=ref_dstiv(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dstiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=sqrt(2/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w*sin(pi*(n+.5)*(m+.5)/L); end; end; % Compute coefficients. c=F*f; ltfat/inst/private/tester_sprand.m0000664000175000017500000000230613026262303017244 0ustar susnaksusnakfunction f=tester_sprand(varargin); %-*- texinfo -*- %@deftypefn {Function} tester_sprand %@verbatim %TESTER_SPRAND Sparse random numbers for testing. % Usage: f=tester_sprand(p1,p2); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/tester_sprand.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE if isempty(LTFAT_TEST_TYPE) LTFAT_TEST_TYPE='double' end; f=sprand(varargin{:}); if strcmp(LTFAT_TEST_TYPE,'single') f=single(f); end; ltfat/inst/private/ref_drihaczekdist.m0000664000175000017500000000243113026262303020052 0ustar susnaksusnakfunction R=ref_drihaczekdist(f) %-*- texinfo -*- %@deftypefn {Function} ref_drihaczekdist %@verbatim %REF_DRIHACZEKDIST Reference discrete Rihaczek distribution % Usage: R=ref_drihaczekdist(f) % % REF_DRIHACZEKDIST(f) computes the discrete Rihaczek distribution of f. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_drihaczekdist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven L = length(f); c = fft(f); for m = 0:L-1 for n=0:L-1 R(m+1, n+1) = (f(n+1).' * conj(c(m+1))) .* exp(-2*pi*i*m*n/L); end end ltfat/inst/private/ref_igdgt.m0000664000175000017500000000257613026262303016332 0ustar susnaksusnakfunction f=ref_igdgt(coef,g,a,M,c_t,c_f,c_w) %-*- texinfo -*- %@deftypefn {Function} ref_igdgt %@verbatim %REF_GDGT Reference generalized DGT % Usage: f=ref_igdgt(c,g,a,M,c_t,c_f,c_w); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_igdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . N=size(coef,1)/M; L=N*a; F=zeros(L,M*N); l=(0:L-1).'; if length(g). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if ~isreal(f) c=ref_dctii_1(real(f))+i*ref_dctii_1(imag(f)); else lf=zeros(L*4,W); lf(2:2:2*L,:)=f; lf(2*L+2:2:end,:)=flipud(f); fflong=real(fft(lf)); c=fflong(1:L,:)/sqrt(2*L); % Scale first coefficients to obtain orthonormal transform. c(1,:)=1/sqrt(2)*c(1,:); end; ltfat/inst/private/test_uwpfbt.m0000664000175000017500000001107713026262303016742 0ustar susnaksusnakfunction test_failed = test_uwpfbt(verbose) %-*- texinfo -*- %@deftypefn {Function} test_uwpfbt %@verbatim %TEST_WFBTPR % % Checks perfect reconstruction of the general wavelet transform of different % filters % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_uwpfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('========= TEST UWPFBT ============'); global LTFAT_TEST_TYPE; tolerance = 1e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 2e-6; end test_failed = 0; if(nargin>0) verbose = 1; else verbose = 0; end type = {'dec'}; ext = {'per'}; J = 4; %! Mild tree wt1 = wfbtinit({'db10',6,'full'}); wt1 = wfbtremove(1,1,wt1,'force'); wt1 = wfbtremove(2,1,wt1,'force'); %! Hardcore tree wt2 = wfbtinit({'db3',1}); wt2 = wfbtput(1,1,'mband1',wt2); wt2 = wfbtput(2,2,'mband1',wt2); wt2 = wfbtput(3,3,'mband1',wt2); wt2 = wfbtput(3,1,'db10',wt2); wt2 = wfbtput(4,1,'dgrid2',wt2); wt2 = wfbtput(5,1,'db2',wt2); % wt2 = wfbtinit(); % wt2 = wfbtput(0,0,{'db',4},wt2); % wt2 = wfbtput(1,0,{'algmband',1},wt2); % wt2 = wfbtput(1,1,{'hden',3},wt2); % wt2 = wfbtput(2,0,{'dgrid',2},wt2); % wt2 = wfbtput(2,1,{'dgrid',2},wt2); test_filters = { {'algmband1',J} % 3 filters, uniform, crit. sub. {'algmband2',J} % 4 filters, uniform, crit. sub. {'db10',J} %{{'hden',3},J} % 3 filters, non-uniform, no crit. sub. no correct {'dgrid1',J} % 4 filters. sub. fac. 2 wt1 wt2 }; scaling = {'scale','sqrt','noscale'}; scalingInv = scaling(end:-1:1); interscaling = {'intscale','intsqrt','intnoscale'}; interscalingInv = interscaling(end:-1:1); for scIdx = 1:numel(scaling) for iscIdx = 1:numel(interscaling) %testLen = 4*2^7-1;%(2^J-1); testLen = 53; f = tester_rand(testLen,1); for extIdx=1:length(ext) extCur = ext{extIdx}; for typeIdx=1:length(type) for tt=1:length(test_filters) actFilt = test_filters{tt}; if verbose, if(~isstruct(actFilt))fprintf('J=%d, filt=%s, ext=%s, inLen=%d \n',actFilt{2},actFilt{1},extCur,length(f)); else disp('Custom'); end; end; [c,info] = uwpfbt(f,actFilt,scaling{scIdx},interscaling{iscIdx}); fhat = iuwpfbt(c,actFilt,scalingInv{scIdx},interscalingInv{iscIdx}); err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~verbose) if(~isstruct(actFilt)) fprintf('J=%d, %5.5s, ext=%4.4s, %s, %s, L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,scaling{scIdx},interscaling{iscIdx},size(f,1),err,fail); else fprintf('Custom, %s, %s, err=%.4e %s\n',scaling{scIdx},interscaling{iscIdx},err,fail); end; end if strcmpi(fail,'FAILED') if verbose if(~isstruct(actFilt)) fprintf('err=%d, filt=%s, ext=%s, inLen=%d \n',err,actFilt{1},extCur,testLen);else disp('Fail. Custom'); end; figure(1);clf;stem([f,fhat]); figure(2);clf;stem([f-fhat]); break; end end fhat2 = iuwpfbt(c,info); err = norm(f-fhat2,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~isstruct(actFilt)) fprintf('INFO J=%d, %5.5s, ext=%4.4s, %s, %s, L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,scaling{scIdx},interscaling{iscIdx},size(f,1),err,fail); else fprintf('INFO Custom, %s, %s, err=%.4e %s\n',scaling{scIdx},interscaling{iscIdx},err,fail); end; if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end end end ltfat/inst/private/ref_dwiltiii_1.m0000664000175000017500000000411513026262303017261 0ustar susnaksusnakfunction [coef]=ref_dwiltiii_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwiltiii_1 %@verbatim %COMP_DWILT Compute Discrete Wilson transform. % % Do not call this function directly, use DWILT instead. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwiltiii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard. L=size(g,1); N=L/a; W=size(f,2); c=ref_gdgt(f,g,a,2*M,0,.5,0); coef2=reshape(c,2*M,N,W); % ----- Type III ------ coef=zeros(M,N,W); if 0 % --- Loop version --- for n=0:N-1 for m=0:M-1 if rem(m+n,2)==0 coef(m+1,n+1,:)= 1/sqrt(2)*(exp(-i*pi/4)*coef2(m+1,n+1,:)+exp(i*pi/4)*coef2(2*M-m,n+1,:)); else coef(m+1,n+1,:)= 1/sqrt(2)*(exp(i*pi/4)*coef2(m+1,n+1,:)+exp(-i*pi/4)*coef2(2*M-m,n+1,:)); end; end; end; else % --- Vector version--- % --- 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; coef=reshape(coef,M*N,W); ltfat/inst/private/test_fwt.m0000664000175000017500000001515413026262303016233 0ustar susnaksusnakfunction test_failed = test_fwt(verbose) %-*- texinfo -*- %@deftypefn {Function} test_fwt %@verbatim %TEST_COMP_FWTPR % % Checks perfect reconstruction of the wavelet transform of different % filters % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_fwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('========= TEST FWT ============'); global LTFAT_TEST_TYPE; tolerance = 1e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 1e-5; end test_failed = 0; if(nargin>0) verbose = 1; which comp_filterbank_td -all which comp_ifilterbank_td -all else verbose = 0; end % curDir = pwd; % mexDir = [curDir(1:strfind(pwd,'\ltfat')+5),'\mex']; % % rmpath(mexDir); % which comp_fwt_all % addpath(mexDir) % which comp_fwt_all type = {'dec'}; ext = {'per','zero','odd','even'}; format = {'pack','cell'}; test_filters = { {'db',10} % {'apr',2} % complex filter values, odd length filters, no exact PR {'algmband',2} % 4 filters, {'db',1} %{'db',3} {'spline',4,4} %{'lemaire',80} % not exact reconstruction {'hden',3} % only one with 3 filters and different %subsampling factors %{'symds',1} {'algmband',1} % 3 filters, sub sampling factor 3, even length %{'sym',4} {'sym',9} {'symds',2} {'symtight',1} {'symtight',2} % {'symds',3} % {'symds',4} % {'symds',5} {'spline',3,5} %{'spline',3,11} %{'spline',11,3} % too high reconstruction error %{'maxflat',2} %{'maxflat',11} %{'optfs',7} % bad precision of filter coefficients %{'remez',20,10,0.1} % no perfect reconstruction {'dden',2} {'dden',5} {'dgrid',1} {'dgrid',3} %{'algmband',1} {'mband',1} {'coif',1} {'coif',2} {'coif',3} {'coif',4} {'qshifta',4} {'qshiftb',4} {'oddevenb',1} %{'hden',2} %{'hden',1} %{'algmband',2} {'symorth',1} {'symorth',2} {'symorth',3} {'symdden',1} {'symdden',2} {[0.129409522551260,-0.224143868042013,-0.836516303737808,-0.482962913144534],... [-0.482962913144534,0.836516303737808,-0.224143868042013,-0.129409522551260],... 'a',[2,2]} {[0.129409522551260,-0.224143868042013,-0.836516303737808,-0.482962913144534],... [-0.482962913144534,0.836516303737808,-0.224143868042013,-0.129409522551260]} }; %ext = {'per','zpd','sym','symw','asym','asymw','ppd','sp0'}; J = 5; %testLen = 4*2^J-1;%(2^J-1); testLen = 53; for formatIdx = 1:length(format) formatCurr = format{formatIdx}; for extIdx=1:length(ext) extCur = ext{extIdx}; %for inLenRound=0:2^J-1 inLenRound = 0; for realComplex=0:1 %f = randn(14576,1); if realComplex f = tester_crand(testLen+inLenRound,1); else f = tester_rand(testLen+inLenRound,1); end %f = 1:testLen-1;f=f'; %f = 0:30;f=f'; % multiple channels %f = [2*f,f,0.1*f]; for typeIdx=1:length(type) typeCur = type{typeIdx}; for tt=1:length(test_filters) actFilt = test_filters{tt}; %fname = strcat(prefix,actFilt{1}); %w = fwtinit(test_filters{tt}); for jj=J:J if verbose, fprintf('J=%d, filt=%s, type=%s, ext=%s, inLen=%d, format=%s \n',jj,actFilt{1},typeCur,extCur,length(f),formatCurr); end; if(strcmp(formatCurr,'pack')) [c, info] = fwt(f,test_filters{tt},jj,extCur); fhat = ifwt(c,test_filters{tt},jj,size(f,1),extCur); if ~isnumeric(test_filters{tt}{1}) fhat2 = ifwt(c,info); end elseif(strcmp(formatCurr,'cell')) [c,info] = fwt(f,test_filters{tt},jj,extCur); ccell = wavpack2cell(c,info.Lc); fhat = ifwt(ccell,test_filters{tt},jj,size(f,1),extCur); if ~isnumeric(test_filters{tt}{1}) fhat2 = ifwt(c,info); end else error('Should not get here.'); end %MSE err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~verbose) if ~isnumeric(test_filters{tt}{1}) fprintf('J=%d, %6.6s, type=%s, ext=%4.4s, L=%d, fmt=%s, err=%.4e %s \n',jj,actFilt{1},typeCur,extCur,length(f),formatCurr,err,fail); else fprintf('J=%d, numeric, type=%s, ext=%4.4s, L=%d, fmt=%s, err=%.4e %s \n',jj,typeCur,extCur,length(f),formatCurr,err,fail); end end if ~isnumeric(test_filters{tt}{1}) err = norm(f-fhat2,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); fprintf('INFO J=%d, %6.6s, type=%s, ext=%4.4s, L=%d, fmt=%s, err=%.4e %s \n',jj,actFilt{1},typeCur,extCur,length(f),formatCurr,err,fail); end if strcmpi(fail,'FAILED') if verbose fprintf('err=%d, J=%d, filt=%s, type=%s, ext=%s, inLen=%d',err,jj,actFilt{1},extCur,typeCur,testLen+inLenRound); figure(1);clf;stem([f,fhat]); figure(2);clf;stem([f-fhat]); break; end end end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end ltfat/inst/private/ref_wfac.m0000664000175000017500000000327113026262303016145 0ustar susnaksusnakfunction gf=ref_wfac(g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_wfac %@verbatim %REF_WFAC Compute window factorization % Usage: gf=ref_wfac(g,a,M); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_wfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % The commented _nos code in this file can be used to test % the _nos versions of the C-library. 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); gf_nos=zeros(d,p,q*R,c); 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); %gf_nos(s+1,k+1,l+1+q*w,:)=g((1:c)+c*mod(k*q-l*p+s*p*q,d*p*q),w+1); end; end; end; end; % dft them if d>1 gf=fft(gf,[],4); %gf_nos=fft(gf_nos); end; % Scale by the sqrt(M) comming from Walnuts representation gf=gf*sqrt(M); %gf_nos=gf_nos*sqrt(M); %gf_nos=permute(gf_nos,[2, 3, 4, 1]); %norm(gf_nos(:)-gf(:)) gf=reshape(gf,p*q*R,c*d); ltfat/inst/private/test_dft.m0000664000175000017500000000265513026262303016212 0ustar susnaksusnakfunction test_failed=test_dft Lr=[1, 19, 20]; test_failed=0; disp(' =============== TEST_DFT =============='); for jj=1:length(Lr) L=Lr(jj); for n = 1:2 if (n==1) type = 'complex'; f=tester_crand(L,1); elseif (n==2) type = 'real'; f=tester_rand(L,1); end c1=dft(f); c2=ref_dft(f); res=norm(c1-c2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('DFT %6s L:%3i %0.5g %s',type,L,res,fail); disp(s); end end; end; %-*- texinfo -*- %@deftypefn {Function} test_dft %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ltfatchecktest.m0000664000175000017500000000301613026262303017376 0ustar susnaksusnakfunction [test_failed]=ltfatchecktest(res,outstr,test_failed,mode,tolerance); %-*- texinfo -*- %@deftypefn {Function} ltfatchecktest %@verbatim %LTFATCHECKTEST Did a test fail, new method % % [test_fail,fail]=LTFATCHECKTEST(res,test_fail) updates test_fail if % res is above threshhold and outputs the word FAIL in the variable % fail. Use only in testing scripts. % % mode = 0 prints all results % % mode = 1 is quiet mode to spot failures %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/ltfatchecktest.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<5 tolerance=1e-10; end; fail=0; if (abs(res)>tolerance) || isnan(res) fail=1; end; if (mode==0) || (fail==1) if (fail==1) outstr=[outstr,' FAILED']; end; disp(outstr); end; test_failed=test_failed+fail; ltfat/inst/private/ref_gaboratoms.m0000664000175000017500000000273713026262303017371 0ustar susnaksusnakfunction G=ref_gaboratoms(g,spoints); %-*- texinfo -*- %@deftypefn {Function} ref_gaboratoms %@verbatim %REF_GABORATOMS Create Gabor transformation matrix % Usage: G=ref_gaboratoms(g,spoints); % % Given a set a TF-sampling points, as returned % by REF_GABORLATTICE, returns the corresponding % Gabor matrix. Each column of the output matriorx is % a Gabor atom. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gaboratoms.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); W=size(g,2); MN=size(spoints,2); % Create Gabor matrix. G=zeros(L,MN*W); jj=(0:L-1).'; % Calculate atoms from sampling points. for w=0:W-1 for p=1:MN; G(:,p+w*MN)=exp(2*pi*i*spoints(2,p)*jj/L).*circshift(g(:,w+1),spoints(1,p)); end; end; ltfat/inst/private/test_wignervilledist.m0000664000175000017500000000344413026262303020645 0ustar susnaksusnakfunction test_failed = test_wignervilledist Lr = [1, 19, 20]; test_failed = 0; disp(' =============== TEST_WIGERVILLEDIST =============='); for ii = 1: length(Lr) L = Lr(ii); for n = 1:4 if (n==1) type1 = 'auto'; type2 = 'real'; f = tester_rand(L,1); g = f; elseif (n==2) type1 = 'auto'; type2 = 'complex'; f = tester_crand(L,1); g = f; elseif (n==3) type1 = 'cross'; type2 = 'real'; f = tester_rand(L,1); g = tester_rand(L,1); elseif (n==4) type1 = 'cross'; type2 = 'complex'; f = tester_crand(L,1); g = tester_crand(L,1); end r1 = ref_wignervilledist(f,g); r2 = wignervilledist(f,g); res = norm(r1-r2); [test_failed, fail] = ltfatdiditfail(res, test_failed); s = sprintf('DWVD %3s %3s L:%3i %0.5g %s', type1, type2, L, res, fail); disp(s); end end end %-*- texinfo -*- %@deftypefn {Function} test_wignervilledist %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wignervilledist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_dftiv_1.m0000664000175000017500000000237413026262303016564 0ustar susnaksusnakfunction c=ref_dftiv_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dftiv_1 %@verbatim %REF_DFT_1 Reference DFTIV by quadrupling % Usage: c=ref_dftii_1(f); % % REF_DFTIV_1(f) computes a DFTIV of f by upsampling f and inserting zeros % at the even positions, and then doubling this signal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dftiv_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); flong=zeros(4*L,W); flong(2:2:2*L,:)=f; fflong=fft(flong)/sqrt(L); c=fflong(2:2:2*L,:); ltfat/inst/private/test_wtfft_pr.m0000664000175000017500000000454113026262303017264 0ustar susnaksusnakfunction test_failed = test_wtfft_pr %-*- texinfo -*- %@deftypefn {Function} test_wtfft_pr %@verbatim %TEST_COMP_FWT_ALL % % Checks perfect reconstruction of the wavelet transform % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wtfft_pr.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; load vonkoch; f=vonkoch;f=f'; %f = 0:6; %f = flipud(f'); %f = ones(7,1); %f = randn(32,1); J = 7; w = fwtinit({'dden',3}); %[w.h,w.g,abase]=wfilt_hden(1); c2 = fwt(f,w,J); fhat2 = ifwt(c2,w,J,length(f)); [h,a] = wfbtmultid({w,J},'ana'); [g,a] = wfbtmultid({w,J},'syn'); figure(3);freqzfb(h,length(f)); figure(4);freqzfb(g,length(f)); H = freqzfb(h,filterbanklength(length(f),a)); G = freqzfb(g,filterbanklength(length(f),a)); c1 = wtfft(f,H,a); figure(2);clf;plotwavc(c1); fhat = iwtfft(c1,G,a,length(f)); figure(1);clf;stem([f,fhat,fhat2]); legend({'orig','iwtfft'}); title(sprintf('norm(f-fhat)=%d',norm(f-fhat2))); c2form = cell(numel(c2)-(length(w.h)-2),1); c2form{1} = c2{1}; cSformIdx = 2; for jj=2:J+1 for ii=1:length(w.h)-1 c2form{cSformIdx} = c2{jj,ii}; cSformIdx=cSformIdx+1; end end figure(5); printCoeffs( c1,c2form); function printCoeffs( x,y) [J,N1] = size(x); for j=1:J subplot(J,1,j); % err = x{j}(:) - y{j}(:); stem([x{j}(:),y{j}(:)]); lh = line([0 length(x{j})],[eps eps]); set(lh,'Color',[1 0 0]); lh =line([0 length(x{j})],[-eps -eps]); set(lh,'Color',[1 0 0]); end function coefs = coefMatToLTFAT(C,S,lo_r,hi_r,J) coefs = cell(J+1,1); coefs{1,1} = appcoef(C,S,lo_r,hi_r,J); for j=1:J [coefs{end-j+1}] = detcoef(C,S,j); end ltfat/inst/private/ref_dgt_6.m0000664000175000017500000000347313026262303016234 0ustar susnaksusnakfunction coef=ref_dgt_6(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_6 %@verbatim %REF_DGT_6 DGT algorithm 6 % % This algorithm assumes an FIR window. % % This algorithm uses OLA to compute the small convolution %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_6.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lg=size(g,1); N=L/a; b=L/M; [c,h_a,h_m]=gcd(-a,M); p=a/c; q=M/c; d=N/q; w=zeros(M,N); gwork=fir2long(g,L); % As above, but the inner convolution is now explicitly expressed for r=0:c-1 for l=0:q-1 for u=0:q-1 for k=0:p-1 psi=zeros(d,1); phi=zeros(d,1); for s=0:d-1 psi(s+1)=f(mod(r+k*M+s*p*M-l*h_a*a,L)+1); end; for s=0:d-1 offset=r+k*q*c-u*p*c; phi(s+1)=gwork(mod(offset+s*p*q*c,L)+1); end; innerconv = pconv(psi,phi,'r'); for s=0:d-1 w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)=w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)+innerconv(s+1); end; end; end; end; end; coef=fft(w); ltfat/inst/private/ref_fftreal.m0000664000175000017500000000214013026262303016642 0ustar susnaksusnakfunction c=ref_fftreal(f) %-*- texinfo -*- %@deftypefn {Function} ref_fftreal %@verbatim %REF_FFTREAL Reference FFTREAL % % FFTREAL is computed by doing an FFT, and keeping only the positive % frequencies. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_fftreal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); c=fft(f); c=c(1:floor(L/2)+1,:); ltfat/inst/private/test_spread.m0000664000175000017500000001046613026262303016712 0ustar susnaksusnakfunction test_failed=test_spread %-*- texinfo -*- %@deftypefn {Function} test_spread %@verbatim %TEST_SPREAD Test spreading function. % % This script runs a throrough test of the SPREADOP routine, % testing it on a range of input parameters. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_spread.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE; disp(' =============== TEST_SPREAD ================'); disp('--- Used subroutines ---'); which comp_col2diag Lr=[12, 13 ]; test_failed=0; condNoLim.('single') = 100; condNoLim.('double') = 100; for ii=1:length(Lr); L=Lr(ii); spfraction=.5; for rtype=1:2 if rtype==1 rname='REAL '; else rname='CMPLX'; end; for sptype=1:2 if sptype==1 spname='FULL '; else spname='SPARSE'; if ~strcmpi(LTFAT_TEST_TYPE,'double') disp(sprintf('Skipping. Cannot work with sparse matrices of type %s.',LTFAT_TEST_TYPE)); break; end end; condNo = 1e10; while condNo>condNoLim.(LTFAT_TEST_TYPE) if rtype==1 if sptype==1 coef=tester_rand(L,L); T=tester_rand(L,L); coef2=tester_rand(L,L); else coef=tester_sprand(L,L,spfraction); T=tester_sprand(L,L,spfraction); coef2=tester_sprand(L,L,spfraction); end; else if sptype==1 coef=tester_crand(L,L); T=tester_crand(L,L); coef2=tester_crand(L,L); else coef=tester_sprand(L,L,spfraction); T=tester_sprand(L,L,spfraction); coef2=tester_sprand(L,L,spfraction); end; end; coeftmp=ifft(full(coef))*L; % The following matrix is inverted in spreadinv. We want a nicer cond % number in order not to fail Ttmp=comp_col2diag(coeftmp); condNo = cond(Ttmp); end for W=1:3 if rtype==1 f=tester_rand(L,W); else f=tester_crand(L,W); end; % ---------- Reference testing ------------ fs=spreadop(f,coef); fs2=ref_spreadop(f,coef,1); fsdiff=fs-fs2; res=norm(fsdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF %s %s L:%3i W:%2i %0.5g %s',rname,spname,L,W,res,fail); disp(s) % -------- Inversion testing ------------- r=spreadinv(fs,coef); rdiff=f-r; res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('INV %s %s L:%3i W:%2i %0.5g %s',rname,spname,L,W,res,fail); disp(s) % -------- Twisted convolution ------------------- f1=spreadop(spreadop(f,coef2),coef); f2=spreadop(f,tconv(coef,coef2)); rdiff=f1-f2; res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('TWI %s %s L:%3i W:%2i %0.5g %s',rname,spname,L,W,res,fail); disp(s) % -------- Spreading function --------------------- coef=spreadfun(T); rdiff=T*f-spreadop(f,coef); res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('FUN %s %s L:%3i W:%2i %0.5g %s',rname,spname,L,W,res,fail); disp(s) % -------- Adjoint operator ----------------------- cadj=spreadadj(coef); rdiff=T'*f-spreadop(f,cadj); res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('ADJ %s %s L:%3i W:%2i %0.5g %s',rname,spname,L,W,res,fail); disp(s) end; end; end; end; ltfat/inst/private/ref_irdgt_1.m0000664000175000017500000000237713026262303016564 0ustar susnaksusnakfunction f=ref_irdgt_1(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_irdgt_1 %@verbatim %REF_IRDGT_1 Reference Inverse Real DGT by fac. and IRDFT % Usage: c=ref_rdgt_1(f,g,a,M); % % Compute the factorization and use IRDFT %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdgt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); R=size(g,2); W=size(c,2); %M=L/b; N=L/a; % Apply ifft to the coefficients. c=ref_irdft(reshape(c,M,N*R*W)); gf = comp_wfac(g,a,M); f = comp_idgt_fw(c,gf,L,a,M); ltfat/inst/private/test_wfbt2filterbank.m0000664000175000017500000001406613026262303020522 0ustar susnaksusnakfunction test_failed=test_wfbt2filterbank %-*- texinfo -*- %@deftypefn {Function} test_wfbt2filterbank %@verbatim %TEST_FILTERBANK test the equivalence of wfbt anf filterbank % Usage: test_wfbt2filterbank() % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wfbt2filterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp(' =============== TEST_WFBT2FILTERBANK ==========='); test_failed=0; L = [ 135, 211]; W = [1,2,3]; W = 1; gt = {}; gt{1} = {'db4',1,'dwt'}; gt{2} = {'db4',4,'full'}; gt{3} = {{'ana:spline4:4',3,'dwt'},{'syn:spline4:4',3,'dwt'}}; gt{4} = wfbtinit(gt{2}); gt{4} = wfbtremove(3,0,gt{4}); gt{4} = wfbtremove(3,1,gt{4}); gt{5} = {{'ana:symorth3',3,'dwt'},{'ana:symorth3',3,'dwt'}}; % This case tests different filters in nodes wt2 = wfbtinit({'db3',1}); wt2 = wfbtput(1,1,'db10',wt2); gt{5} = wt2; scaling = {'scale','sqrt','noscale'}; scalingInv = scaling(end:-1:1); crossoverval = 10000; for hh=1:2 if hh==1 testWhat = 'wfbt'; elseif hh==2 testWhat = 'wpfbt'; end fprintf(' =============== Testing %s ===========\n',testWhat); for jj=1:numel(gt) for ww=1:numel(W) for ii=1:numel(L) f = tester_rand(L(ii),1); gttmp = gt(jj); if isempty(gttmp{1}) continue; end if iscell(gt{jj}) && iscell(gt{jj}{1}) gttmp = gt{jj}{1}; else gttmp = gttmp{1}; end if strcmp(testWhat,'wfbt') refc = wfbt(f,gttmp); [g,a] = wfbt2filterbank(gttmp); elseif strcmp(testWhat,'wpfbt') refc = wpfbt(f,gttmp); [g,a] = wpfbt2filterbank(gttmp); end c = filterbank(f,g,a,'crossover',1); err = norm(cell2mat(c)-cell2mat(refc)); [test_failed,fail]=ltfatdiditfail(err,test_failed); if ~isstruct(gt{jj}) fprintf('FILT %d, COEF, FFT L= %d, W= %d, err=%.4e %s \n',jj,L(ii),W(ww),err,fail); else fprintf('FILT %d, COEF, FFT L= %d, W= %d, err=%.4e %s\n',jj,L(ii),W(ww),err,fail); end; c = filterbank(f,g,a,'crossover',crossoverval); err = norm(cell2mat(c)-cell2mat(refc)); [test_failed,fail]=ltfatdiditfail(err,test_failed); if ~isstruct(gt{jj}) fprintf('FILT %d, COEF, TD L= %d, W= %d, err=%.4e %s \n',jj,L(ii),W(ww),err,fail); else fprintf('FILT %d, COEF, TD L= %d, W= %d, err=%.4e %s\n',jj,L(ii),W(ww),err,fail); end; if iscell(gt{jj}) && iscell(gt{jj}{2}) gttmp = gt{jj}{2}; end if strcmp(testWhat,'wfbt') [g,a] = wfbt2filterbank(gttmp); elseif strcmp(testWhat,'wpfbt') [g,a] = wpfbt2filterbank(gttmp); end fhat = ifilterbank(refc,g,a,L(ii),'crossover',1); err = norm(fhat-f); [test_failed,fail]=ltfatdiditfail(err,test_failed); if ~isstruct(gt{jj}) fprintf('FILT %d, INV, FFT L= %d, W= %d, err=%.4e %s \n',jj,L(ii),W(ww),err,fail); else fprintf('FILT %d, INV, FFT L= %d, W= %d, err=%.4e %s\n',jj,L(ii),W(ww),err,fail); end; fhat = ifilterbank(refc,g,a,L(ii),'crossover',crossoverval); err = norm(fhat-f); [test_failed,fail]=ltfatdiditfail(err,test_failed); if ~isstruct(gt{jj}) fprintf('FILT %d, INV, TD L= %d, W= %d, err=%.4e %s \n',jj,L(ii),W(ww),err,fail); else fprintf('FILT %d, INV, TD L= %d, W= %d, err=%.4e %s\n',jj,L(ii),W(ww),err,fail); end; for scIdx = 1:numel(scaling) gttmp = gt(jj); if iscell(gt{jj}) && iscell(gt{jj}{1}) gttmp = gt{jj}{1}; else gttmp = gttmp{1}; end if strcmp(testWhat,'wfbt') urefc = uwfbt(f,gttmp,scaling{scIdx}); [g,a] = wfbt2filterbank(gttmp,scaling{scIdx}); elseif strcmp(testWhat,'wpfbt') urefc = uwpfbt(f,gttmp,scaling{scIdx}); [g,a] = wpfbt2filterbank(gttmp,scaling{scIdx}); end uc = ufilterbank(f,g,a,'crossover',crossoverval); err = norm(uc-urefc); [test_failed,fail]=ltfatdiditfail(err,test_failed); if ~isstruct(gt{jj}) fprintf('FILT %d, %s, COEF, FFT, UNDEC, L= %d, W= %d, err=%.4e %s \n',jj,scaling{scIdx},L(ii),W(ww),err,fail); else fprintf('FILT %d, %s, COEF, FFT, UNDEC, L= %d, W= %d, err=%.4e %s\n',jj,scaling{scIdx},L(ii),W(ww),err,fail); end; if iscell(gt{jj}) && iscell(gt{jj}{2}) gttmp = gt{jj}{2}; end if strcmp(testWhat,'wfbt') [g,a] = wfbt2filterbank(gttmp); elseif strcmp(testWhat,'wpfbt') [g,a] = wpfbt2filterbank(gttmp); end g = comp_filterbankscale(g,a,scalingInv{scIdx}); fhat = ifilterbank(urefc,g,ones(numel(g),1),L(ii),'crossover',crossoverval); err = norm(fhat-f); [test_failed,fail]=ltfatdiditfail(err,test_failed); if ~isstruct(gt{jj}) fprintf('FILT %d, %s, INV, FFT, UNDEC, L= %d, W= %d, err=%.4e %s \n',jj,scaling{scIdx},L(ii),W(ww),err,fail); else fprintf('FILT %d, %s INV, FFT, UNDEC, L= %d, W= %d, err=%.4e %s\n',jj,scaling{scIdx},L(ii),W(ww),err,fail); end; end end end end end end ltfat/inst/private/ref_pfilt.m0000664000175000017500000000775013026262303016351 0ustar susnaksusnakfunction h=ref_pfilt(f,g,a) %-*- texinfo -*- %@deftypefn {Function} ref_pfilt %@verbatim %REF_PFILT Reference pfilt handling structs % 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.github.io/doc/reference/ref_pfilt.html} %@seealso{pconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<3 a=1; end; [L,W]=size(f); l=(0:L-1).'/L; if isstruct(g) if isfield(g,'h') g_time=circshift(postpad(g.h,L),g.offset).*exp(2*pi*1i*(round(g.fc*L/2))*l); G=fft(g_time); elseif isfield(g,'H') G=circshift(postpad(g.H(L),L),g.foff(L)).*exp(-2*pi*1i*round(g.delay)*l); else error('%s: Unknown filter definition.',upper(mfilename)); end; else G=fft(fir2long(g,L)); end; if numel(a) > 1 % This is possibly a fractional subsampling afrac = a(1)/a(2); if a(1) ~= L error('%s: The length in a(1) is not equal to L.',upper(mfilename)); end N = L/afrac; if abs(N-round(N))>1e-5 error('%s: Output length is not integer.',upper(mfilename)); else N = round(N); end foff = g.foff(L); h=zeros(N,W,assert_classname(f)); for w=1:W h(:,w) = blfilt(f(:,w),G,N,foff,afrac); if isstruct(g) && isfield(g,'realonly') && g.realonly G2 = involute(G); supp = numel(g.H(L)); foff2 = -L+mod(L-foff-supp,L)+1; h(:,w) = (h(:,w) + blfilt(f(:,w),G2,N,foff2,afrac))/2; end; end; else % This is regular subsampling case if isstruct(g) && isfield(g,'realonly') && g.realonly G=(G+involute(G))/2; end; N=L/a; h=zeros(N,W,assert_classname(f)); for w=1:W F=fft(f(:,w)); h(:,w)=ifft(sum(reshape(F.*G,N,a),2))/a; end; end function h = blfilt(f,G,N,foff,afrac) L = size(f,1); align = foff - floor(foff/N)*N; F = circshift(fft(f).*G,-foff); F = postpad(F,ceil(L/N)*N); F = circshift(F,align); F = sum(reshape(F,N,numel(F)/N),2); h = ifft(F)/afrac; ltfat/inst/private/ref_dgt_fw_time.m0000664000175000017500000000725013026262303017516 0ustar susnaksusnakfunction cout=ref_dgt_fw_time(f,gf,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_fw_time %@verbatim %COMP_DGT_FW Full-window factorization of a Gabor matrix. % Usage: c=comp_dgt_fw(f,gf,a,M); % % This should be an exact copy of the comp_dgt_fw.m file in the comp/ % subdirectory in the toolbox. It is intended for timing when the original % file is masked by an oct/mex implementation. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_fw_time.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard. debug=0; if debug tic; end; L=size(f,1); W=size(f,2); LR=prod(size(gf)); R=LR/L; 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); if debug disp('Initialization done'); a M L W toc; tic; end; 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; if debug disp('First FAC done.'); toc; tic; end; % This version uses matrix-vector products and ffts % fft them if d>1 ff=fft(ff,[],4); end; if debug disp('FFT done'); toc; tic; end; C=zeros(q*R,q*W,c,d); 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; if debug disp('MatMul done'); toc; tic; end; % Inverse fft if d>1 C=ifft(C,[],4); end; if debug disp('IFFT done'); toc; tic; end; % Place the result cout=zeros(M,N,R,W); 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; if debug disp('Last FAC done'); toc; tic; end; cout=reshape(cout,M,N*W*R); function r=mymod(x,y) r=x-y*floor(x/y); ltfat/inst/private/test_ufwt.m0000664000175000017500000001214313026262303016413 0ustar susnaksusnakfunction test_failed = test_ufwt(verbose) %-*- texinfo -*- %@deftypefn {Function} test_ufwt %@verbatim %TEST_COMP_FWT_ALL % % Checks perfect reconstruction of the wavelet transform of different % filters % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_ufwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('========= TEST UFWT ============'); global LTFAT_TEST_TYPE; tolerance = 1e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 1e-5; end test_failed = 0; if(nargin>0) verbose = 1; which comp_ufwt -all which comp_iufwt -all else verbose = 0; end % curDir = pwd; % mexDir = [curDir(1:strfind(pwd,'\ltfat')+5),'\mex']; % % rmpath(mexDir); % which comp_fwt_all % addpath(mexDir) % which comp_fwt_all type = {'undec'}; ext = {'per'}; prefix = 'wfilt_'; test_filters = { {'db',1} {'db',3} {'db',10} {'spline',4,4} %{'lemaire',80} % not exact reconstruction {'hden',3} % only one with 3 filters and different %subsampling factors, not working {'algmband',2} % 4 filters, subsampling by the factor of 4!, really long identical lowpass filter %{'symds',1} {'algmband',1} % 3 filters, sub sampling factor 3, even length {'sym',4} {'sym',9} %{'symds',2} % {'symds',3} % {'symds',4} % {'symds',5} {'spline',3,5} {'spline',3,11} %{'spline',11,3} % error too high %{'maxflat',2} %{'maxflat',11} %{'optfs',7} % bad precision of filter coefficients %{'remez',20,10,0.1} % no perfect reconstruction {'dden',1} {'dden',2} % {'dden',3} {'dden',4} {'dden',5} % {'dden',6} {'dgrid',1} {'dgrid',2} {'dgrid',3} %{'algmband',1} {'mband',1} {'symorth',1} {'symtight',2} %{'hden',3} %{'hden',2} %{'hden',1} %{'algmband',2} %{'apr',1} % complex filter values, odd length filters, no perfect reconstruction }; %ext = {'per','zpd','sym','symw','asym','asymw','ppd','sp0'}; scaling = {'scale','sqrt','noscale'}; scalingInv = scaling(end:-1:1); J = 4; %testLen = 10*2^J-1;%(2^J-1); testLen = 53; for scIdx = 1:numel(scaling) for extIdx=1:length(ext) %for inLenRound=0:2^J-1 for inLenRound=0:0 %f = randn(14576,1); f = tester_rand(testLen+inLenRound,1); %f = 1:testLen-1;f=f'; %f = 0:30;f=f'; % multiple channels %f = [2*f,f,0.1*f]; for typeIdx=1:length(type) typeCur = type{typeIdx}; extCur = ext{extIdx}; for tt=1:length(test_filters) actFilt = test_filters{tt}; %fname = strcat(prefix,actFilt{1}); %w = fwtinit(test_filters{tt}); for jj=1:J if verbose, fprintf('J=%d, filt=%s, inLen=%d\n',jj,actFilt{1},length(f)); end; [c,info] = ufwt(f,test_filters{tt},jj,scaling{scIdx}); %[cvec ,Lc] = cell2pack(c); %c = pack2cell(cvec,Lc); fhat = iufwt(c,test_filters{tt},jj,scalingInv{scIdx}); err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~verbose) fprintf('J=%d, %5.5s, %s, L=%d, err=%.4e %s \n',jj,actFilt{1},scaling{scIdx},length(f),err,fail); end if strcmpi(fail,'FAILED') if verbose fprintf('err=%d, J=%d, filt=%s, inLen=%d',err,jj,actFilt{1},testLen+inLenRound); figure(1);clf;stem([f,fhat]); figure(2);clf;stem([f-fhat]); break; end end fhat2 = iufwt(c,info); err = norm(f-fhat2,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); fprintf('INFO J=%d, %5.5s, %s, L=%d, err=%.4e %s \n',jj,actFilt{1},scaling{scIdx},length(f),err,fail); end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end end ltfat/inst/private/test_gga.m0000664000175000017500000000364113026262303016167 0ustar susnaksusnakfunction test_failed=test_gga disp(' =============== TEST_GGA ================'); test_failed=0; %-*- texinfo -*- %@deftypefn {Function} test_gga %@verbatim % Goertzel algorithm has a bad precision for larger L. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gga.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE; tolerance = 2e-10; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 9e-3; end L = 36; W = 17; f=tester_crand(L,W); res = norm(fft(cast(f,'double'))-gga(f,linspace(0,1-1/L,L))); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1 cols: L:%3i, W:%3i %s\n',L,W,fail); res = norm(fft(cast(f,'double'),[],2)-gga(f,linspace(0,1-1/W,W),[],2)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1 rows: L:%3i, W:%3i %s\n',L,W,fail); res = norm(fft(cast(f,'double'),2*L)-gga(f,linspace(0,1-0.5/L,2*L))); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1/2 cols: L:%3i, W:%3i %s\n',L,W,fail); res = norm(fft(cast(f,'double'),5*L)-gga(f,linspace(0,1-0.2/L,5*L))); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1/5 cols: L:%3i, W:%3i %s\n',L,W,fail); ltfat/inst/private/test_argfirwin.m0000664000175000017500000000330013026262303017411 0ustar susnaksusnakfunction test_failed = test_argfirwin test_failed = 0; disp('---------Testing arg_firwin---------'); %-*- texinfo -*- %@deftypefn {Function} test_argfirwin %@verbatim % This test checks wheter all options from arg_firwin are actually % treated in firwin. % This is necessary as firwin itself does not use arg_firwin % Also tests for duplicates %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_argfirwin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Get window types g = getfield(getfield(arg_firwin,'flags'),'wintype'); for ii=1:numel(g) tryfailed = 0; fprintf('Testing %12s:',g{ii}); try h = firwin(g{ii},64); catch test_failed = test_failed + 1; tryfailed = 1; fprintf('FAILED'); end if ~tryfailed fprintf('SUCCESS'); end if(sum(strcmp(g{ii},g))>1) fprintf(' has DUPLICATES'); end fprintf('\n'); end ltfat/inst/private/ref_gabmulappr_1.m0000664000175000017500000000755413026262303017607 0ustar susnaksusnakfunction sym=ref_gabmulappr_1(T,p2,p3,p4,p5); %-*- texinfo -*- %@deftypefn {Function} ref_gabmulappr_1 %@verbatim %GABMULAPPR_1 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); % % 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 % % GABMULAPPR(T,g,a,M) will calculate 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. % IMPORTANT: The chosen Gabor system has to be a frame sequence! % % GABMULAPPR(T,a,M) will do the same using an optimally concentrated, % tight Gaussian as window function. % % GABMULAPPR(T,gs,ga,a) will do the same using the window ga for analysis % and gs for synthesis. % % % % References: % 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.github.io/doc/reference/ref_gabmulappr_1.html} %@seealso{gabmul, demo_gabmulappr} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: P. Balazs (XXL) % ---------- Verify the input ----------------- 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; N=L/a; b=L/M; 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; % -------- Algorithm starts here -------------------------- % Calculate the lower symbol. This is basically linear algebra part1=reshape(dgt(T',ga,a,M),M*N,L); part2=reshape(dgt(part1',gs,a,M),M*N,M*N).'; lowsym = reshape(diag(part2),M,N); % Change from lower symbol to upper symbol. This is a quick calculation % of a 2D convolution. Gramfirst = conj(dgt(ga,ga,a,M)).*dgt(gs,gs,a,M); Gramfirst = fft2(Gramfirst); lowsym = fft2(lowsym); lowsym = lowsym./Gramfirst; sym = ifft2(lowsym); ltfat/inst/private/tester_crand.m0000664000175000017500000000230713026262303017045 0ustar susnaksusnakfunction f=tester_crand(p1,p2); %-*- texinfo -*- %@deftypefn {Function} tester_crand %@verbatim %CRAND Random complex numbers for testing. % Usage: f=tester_crand(p1,p2); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/tester_crand.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE if isempty(LTFAT_TEST_TYPE) LTFAT_TEST_TYPE='double'; end; f=rand(p1,p2)-.5+i*(rand(p1,p2)-.5); if strcmp(LTFAT_TEST_TYPE,'single') f=single(f); end; ltfat/inst/private/test_signals.m0000664000175000017500000000426313026262303017072 0ustar susnaksusnakfunction test_failed=test_signals; %-*- texinfo -*- %@deftypefn {Function} test_signals %@verbatim %TEST_SIGNALS % % The script ensures that all files are correctly included by loading % the singals and checking their sizes. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_signals.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp(' =============== TEST_SIGNALS ==========='); test_failed=0; [test_failed,fail]=ltfatdiditfail(numel(bat)-400,test_failed); disp(['SIGNALS BAT ',fail]); [test_failed,fail]=ltfatdiditfail(numel(batmask)-1600,test_failed); disp(['SIGNALS BATMASK ',fail]); [test_failed,fail]=ltfatdiditfail(numel(greasy)-5880,test_failed); disp(['SIGNALS GREASY ',fail]); [test_failed,fail]=ltfatdiditfail(numel(linus)-41461,test_failed); disp(['SIGNALS LINUS ',fail]); [test_failed,fail]=ltfatdiditfail(numel(gspi)-262144,test_failed); disp(['SIGNALS GSPI ',fail]); [test_failed,fail]=ltfatdiditfail(numel(traindoppler)-157058,test_failed); disp(['SIGNALS TRAINDOPPLER',fail]); [test_failed,fail]=ltfatdiditfail(numel(otoclick)-2210,test_failed); disp(['SIGNALS OTOCLICK ',fail]); [test_failed,fail]=ltfatdiditfail(numel(cameraman)-65536,test_failed); disp(['SIGNALS CAMERAMAN ',fail]); [test_failed,fail]=ltfatdiditfail(numel(cocktailparty)-363200,test_failed); disp(['SIGNALS COCKTAILPARTY ',fail]); [test_failed,fail]=ltfatdiditfail(numel(lichtenstein)-262144*3,test_failed); disp(['SIGNALS LICHTENSTEIN ',fail]); ltfat/inst/private/ref_edgt.m0000664000175000017500000000235013026262303016145 0ustar susnaksusnakfunction c=ref_edgt(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_edgt %@verbatim %REF_EDGT Reference Even Discrete Gabor transform % Usage c=ref_edgt(f,g,a,M); % % The input window must be odd-centered. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_edgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); N=L/a; M=L/b; F=zeros(L,M*N); l=(0:L-1)'; for n=0:N-1 for m=0:M-1 F(:,1+m+n*M)=exp(2*pi*i*m.*(l+.5)*b/L).*circshift(g,n*a); end; end; c=F'*f; ltfat/inst/private/test_ptpfun.m0000664000175000017500000001273413026262303016750 0ustar susnaksusnakfunction test_failed=test_ptpfun() test_failed = 0; %-*- texinfo -*- %@deftypefn {Function} test_ptpfun %@verbatim % First, just test if functions run with various input parameters %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_ptpfun.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . M = 10; a = 8; L = 120; incrange = 0:4:80; g = ptpfun(L,[1,-1]); g = ptpfun(L,[1,-1,9]); %g = ptpfun(L,[1,-1,9],'inf'); gd = ptpfundual([1,-1],a,M,L); gd = ptpfundual([1,-1],a,M,L,10); gd = ptpfundual({[1,-1],10},a,M,L); gd = ptpfundual({[1,-1],20},a,M,L,10); % % [gd,nlen] = ptpfundual([1,-1],a,M,L,'inf'); % % [gd,nlen] = ptpfundual([1,-1],a,M,L,'inf','matchscale'); % This should fail, but be caught by some of the input checks. % We will test if the error message starts with function name in allcaps % followed by a colon e.g. PTPFUN: % Too short w try g = ptpfun(L,[1]); gd = ptpfundual([1],a,M,L); % We should have failed in g test_failed = test_failed + 1; failstr = 'FAILED'; catch err = lasterror; [test_failed,failstr]=dititfailedcorrectly(err.message,'ptpfun',test_failed); end fprintf('PTPFUN Too short w test %s\n',failstr); % This has been dealt with % % Only pos weights % try % g = ptpfun(L,[1,1]); % gd = ptpfundual(L,[1,1],a,M); % % We should have failed in g % test_failed = test_failed + 1; % failstr = 'FAILED'; % catch % err = lasterror; % [test_failed,failstr]=dititfailedcorrectly(err.message,'ptpfun',test_failed); % end % fprintf('PTPFUN Only positive w test %s\n',failstr); % % % Only neg weights % try % g = ptpfun(L,[-1,-1]); % gd = ptpfundual(L,[-1,-1],a,M); % % We should have failed in g % test_failed = test_failed + 1; % failstr = 'FAILED'; % catch % err = lasterror; % [test_failed,failstr]=dititfailedcorrectly(err.message,'ptpfun',test_failed); % end % fprintf('PTPFUN Only negative w test %s\n',failstr); % One zero in weights try g = ptpfun(L,[-1,0,1]); gd = ptpfundual([-1,0,1],a,M,L); % We should have failed in g test_failed = test_failed + 1; failstr = 'FAILED'; catch err = lasterror; [test_failed,failstr]=dititfailedcorrectly(err.message,'ptpfun',test_failed); end fprintf('PTPFUN Zero in w test %s\n',failstr); % Test if ptpfun and ptpfundual indeed fulfill the Waxler-Raz conditions % (are dual windoes up to scaling) for a range of inc parameter wcell = {[-1,1],[1,-1,3,4],[7,8,-3],[-1,-1],[1,1]}; for w = wcell for inc =incrange g = ptpfun(L,w{1}); gd = ptpfundual(w{1},a,M,L); [~,err] = gabdualnorm(g,gd,a,M,L); [test_failed,fail]=ltfatdiditfail(err,test_failed); fprintf('PTPFUN IS DUAL L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); end end % Test ptpfun and ptpfundual individually (each uses canonical dual window) f = tester_crand(L,1); for w = wcell g = ptpfun(L,w{1}); c = dgt(f,g,a,M); fhat = idgt(c,{'dual',g},a); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('PTPFUN REC L=%i,a=%i,M=%i, %s\n',L,a,M,fail); end for w = wcell g = ptpfundual(w{1},a,M,L); c = dgt(f,g,a,M); fhat = idgt(c,{'dual',g},a); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('PTPFUNDUAL REC L=%i,a=%i,M=%i, %s\n',L,a,M,fail); end % Test ptpfun and ptpfundual properly scaled for w = wcell for inc =incrange g = ptpfun(L,w{1}); gd = ptpfundual(w{1},a,M,L,inc); c = dgt(f,g,a,M); fhat = idgt(c,gd,a); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('PTPFUN PTPFUNDUAL REC ENERGY L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); end end % Disabled for now % for w = wcell % for inc =incrange % g = ptpfun(L,w{1},'inf'); % gd = ptpfundual(w{1},a,M,L,inc,'matchscale','inf'); % c = dgt(f,g,a,M); % fhat = idgt(c,gd,a); % res = norm(f-fhat); % [test_failed,fail]=ltfatdiditfail(res,test_failed); % fprintf('PTPFUN PTPFUNDUAL REC PEAK L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); % end % end % % % Test using FIR duals % wcell = {[-0.5,0.5]}; % for w = wcell % for inc =incrange % g = ptpfun(L,w{1}); % [gd,nlen] = ptpfundual(w{1},a,M,L,inc,'matchscale'); % c = dgt(f,g,a,M); % fhat = idgt(c,middlepad(gd,nlen),a); % res = norm(f-fhat); % [test_failed,fail]=ltfatdiditfail(res,test_failed); % fprintf('PTPFUN PTPFUNDUAL REC FIR L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); % end % end function [test_failed,failstr]=dititfailedcorrectly(errmsg,fname,test_failed) if isempty(strfind(errmsg,strcat(upper(fname),':'))) test_failed = test_failed + 1; failstr = 'FAILED'; else failstr = ''; end function u=WRtest(g,gamma,a,M,L); for j=1:a g1=g; for l=1:min([L/M,10]); u(j,l)=gamma(j:a:L)'*g1(j:a:L); g1=[g1(M+1:end);g1(1:M)]; end end ltfat/inst/private/test_wfilt.m0000664000175000017500000000673613026262303016566 0ustar susnaksusnakfunction test_failed = test_wfilt() %-*- texinfo -*- %@deftypefn {Function} test_wfilt %@verbatim % This function tests if tilters provided by wfilt_* % functions indeed admit a perfect reconstruction %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wfilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; w = { 'algmband1' 'algmband2' 'cmband2' 'cmband3' 'cmband4' 'cmband5' 'cmband6' 'coif1' 'coif2' 'coif3' 'coif4' 'coif5' 'db1' 'db2' 'db3' 'db4' 'db5' 'db6' 'db7' 'db8' 'db9' 'db10' 'db11' 'db12' 'db13' 'db14' 'db15' 'db16' 'db17' 'db18' 'db19' 'db20' 'dden1' 'dden2' 'dden3' 'dden4' 'dden5' 'dden6' 'dgrid1' 'dgrid2' 'dgrid3' 'hden1' 'hden2' 'hden3' 'hden4' 'lemarie10' 'lemarie20' 'lemarie30' 'lemarie40' 'mband1' 'remez10:1:0.1' 'remez20:1:0.1' 'remez40:2:0.1' 'spline1:1' 'spline2:2' 'spline3:3' 'spline4:4' 'spline5:5' 'spline6:6' 'spline7:7' 'spline8:8' 'spline1:3' 'spline1:5' 'spline1:7' 'spline1:9' 'spline3:1' 'spline5:1' 'spline7:1' 'spline9:1' 'spline2:4' 'spline2:6' 'spline2:8' 'spline4:2' 'spline6:2' 'spline8:2' 'spline3:5' 'spline3:7' 'spline3:9' 'spline5:3' 'spline7:3' 'spline9:3' 'spline4:6' 'spline4:8' 'spline6:4' 'spline8:4' 'spline5:7' 'spline5:9' 'spline7:5' 'spline9:5' 'spline6:8' 'spline8:6' 'spline7:9' 'spline9:7' 'sym1' 'sym2' 'sym3' 'sym4' 'sym5' 'sym6' 'sym7' 'sym8' 'sym9' 'sym10' 'sym11' 'sym12' 'sym13' 'sym14' 'sym15' 'symdden1' 'symdden2' 'symds1' 'symds2' 'symds3' 'symds4' 'symds5' 'symorth1' 'symorth2' 'symorth3' 'symtight1' 'symtight2' 'oddevena1' 'oddevenb1' 'qshifta1' 'qshifta2' 'qshifta3' 'qshifta4' 'qshifta5' 'qshifta6' 'qshifta7' 'qshiftb1' 'qshiftb2' 'qshiftb3' 'qshiftb4' 'qshiftb5' 'qshiftb6' 'qshiftb7' 'optsyma1' 'optsyma2' 'optsyma3' 'optsymb1' 'optsymb2' 'optsymb3' 'ddena1' 'ddena2' 'ddenb1' 'ddenb2' }; globtol = 5e-8; disp('--------------TEST_WFIL-------------------'); exttype = {'per','odd','even','zero'}; L = 128; f = tester_crand(L,1); f = f/norm(f); for wfilt = w' for ext = exttype fhat = ifwt(fwt(f,wfilt{1},1,ext{1}),wfilt{1},1,L,ext{1}); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed,globtol); fprintf('%s ext:%s %0.5g %s\n',wfilt{1},ext{1},res,fail); end end ltfat/inst/private/ref_nsdgt.m0000664000175000017500000000277313026262303016352 0ustar susnaksusnakfunction [c,Ls] = ref_nsdgt(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_nsdgt %@verbatim %NSDGT Non-stationary Discrete Gabor transform % Usage: c=nsdgt(f,g,a,M); % [c,Ls]=nsdgt(f,g,a,M); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_nsdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . timepos=cumsum(a)-a(1)+1; Ls=length(f); L=nsdgtlength(Ls,a); N=numel(g); F=zeros(L,sum(M)); % Construct the analysis operator matrix explicitly Y = 1; for n = 1:length(timepos) X = length(g{n}); win_range = mod(timepos(n)+(-floor(X/2):ceil(X/2)-1)-1,L)+1; F(win_range,Y) = fftshift(g{n}); for m = 1:M(n)-1 F(win_range,Y+m) = F(win_range,Y).*exp(2*pi*i*m*(-floor(X/2):ceil(X/2)-1)/M(n)).'; end Y=Y+M(n); end cmat=F'*f; c=mat2cell(cmat,M); ltfat/inst/private/ref_dgt.m0000664000175000017500000000275713026262303016013 0ustar susnaksusnakfunction [c]=ref_dgt(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt %@verbatim %REF_DGT Reference Discrete Gabor transform. % Usage: c=ref_dgt(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . g = double(g); f = double(f); % Calculate the parameters that was not specified. L=size(g,1); b=L/M; N=L/a; W=size(f,2); R=size(g,2); % Create 2x2 grid matrix.. V=[a,0; 0,b]; % Create lattice and Gabor matrix. lat=ref_lattice(V,L); G=ref_gaboratoms(g,lat); % Apply matrix to f. c=G'*f; % reshape to correct output format. c=reshape(c,M,N,R*W); ltfat/inst/private/ref_rdft.m0000664000175000017500000000251613026262303016165 0ustar susnaksusnakfunction c=ref_rdft(f) %-*- texinfo -*- %@deftypefn {Function} ref_rdft %@verbatim %REF_RDFT Reference Real DFT % Usage: c=ref_rdft(f); % % Compute RDFT by explicit formulas. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=ceil(L/2); F=zeros(L); F(:,1)=ones(L,1); l=(0:L-1).'; for m=1:Lhalf-1 F(:,2*m)=sqrt(2)*cos(2*pi*m*l/L); F(:,2*m+1)=sqrt(2)*sin(2*pi*m*l/L); end; if mod(L,2)==0 F(:,L)=cos(pi*l); end; F=F/sqrt(L); % dot-transpose will work because F is real. c=F.'*f; ltfat/inst/private/test_purefreq.m0000664000175000017500000001607013026262303017262 0ustar susnaksusnakfunction test_failed=test_purefreq disp(' =============== TEST_PUREFREQ ================'); disp('--- Used subroutines ---'); which comp_fftreal which comp_ifftreal which comp_dct which comp_dst %-*- texinfo -*- %@deftypefn {Function} test_purefreq %@verbatim % This script test all the pure frequency routines. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_purefreq.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % This is a list or pairs. The two functions in each pair % will be evaluated with the same parameters, and the output % should be the same. ref_funs={{'ref_dcti','dcti'},... {'ref_dcti','ref_dcti_1'},... {'ref_dctii','dctii'},... {'ref_dctiii','dctiii'},... {'ref_dctii','ref_dctii_1'},... {'ref_dctiii','ref_dctiii_1'},... {'ref_dctiv','dctiv'},... {'ref_dsti','dsti'},... {'ref_dsti','ref_dsti_1'},... {'ref_dstii','dstii'},... {'ref_dstiii','dstiii'},... {'ref_dstii','ref_dstii_1'},... {'ref_dstiii','ref_dstiii_1'},... {'ref_dstiv','dstiv'},... {'ref_dft','ref_dft_1'},... {'ref_rdft','ref_rdft_1'},... {'ref_irdft','ref_irdft_1'},... }; % This is a list or pairs. The two functions in each pair will be evaluated % on purely real input with the same parameters, and the output should be % the same. ref_realfuns={{'ref_dcti','dcti'},... {'ref_dcti','ref_dcti_1'},... {'ref_dctii','dctii'},... {'ref_dctiii','dctiii'},... {'ref_dctii','ref_dctii_1'},... {'ref_dctiii','ref_dctiii_1'},... {'ref_dctiv','dctiv'},... {'ref_dsti','dsti'},... {'ref_dsti','ref_dsti_1'},... {'ref_dstii','dstii'},... {'ref_dstiii','dstiii'},... {'ref_dstii','ref_dstii_1'},... {'ref_dstiii','ref_dstiii_1'},... {'ref_dstiv','dstiv'},... {'ref_dft','ref_dft_1'},... {'ref_fftreal','fftreal'},... {'ref_rdft','ref_rdft_1'},... {'ref_irdft','ref_irdft_1'},... }; % {'ref_dftii','ref_dftii_1'},... % {'ref_dftii','ref_dftii_2'},... % {'ref_idftii','ref_idftii_1'},... % {'ref_dftiv','ref_dftiv_1'},... % {'ref_rdftiii','ref_rdftiii_1'},... % {'ref_irdftiii','ref_irdftiii_1'},... % Each row is the size of a matrix. All the functions % mentioned above will be executed with input matrixes % of sizes mentioned below. ref_sizes=[1 1;... 2 1;... 3 2;... 4 3;... 5 3 100 1]; % As ref_funs, these functions should be inverses of each other. inv_funs={{'dcti','dcti'},... {'dctii','dctiii'},... {'dctiv','dctiv'},... {'ref_dsti','ref_dsti'},... {'dstii','dstiii'},... {'dstiv','dstiv'},... {'dft','idft'},... {'ref_rdft','ref_irdft'},... }; % As ref_funs, these functions should be inverses of each other. realinv_funs={{'fftreal','ifftreal'}}; % {'ref_rdftiii','ref_irdftiii'},... % {'ref_dftii','ref_idftii'},... % {'ref_dftiii','ref_idftiii'},... % {'ref_rdftiii','ref_irdftiii'},... % {'ref_dftiv','ref_idftiv'},... % Each function in the list should be unitary. They will be tested on % matrix of sizes correspondin to the first column in ref_sizes nrm_funs={'dctii','dctiii','dctiv','ref_dft','ref_rdft'}; % ---------- reference testing -------------------- % Test that the transforms agree on values. ref_failed=0; for funpair=ref_funs for ii=1:size(ref_sizes,1); %a=tester_rand(ref_sizes(ii,:)); a=tester_crand(ref_sizes(ii,1),ref_sizes(ii,2)); c1=feval(funpair{1}{1},a); c2=feval(funpair{1}{2},a); res=norm(c1(:)-c2(:)); [ref_failed,fail]=ltfatdiditfail(res,ref_failed); s=sprintf('REF %7s L:%2i W:%2i %0.5g %s',funpair{1}{2},ref_sizes(ii,1),ref_sizes(ii,2),res,fail); disp(s) end; end; % ---------- real valued reference testing -------------------- % Test that the transforms agree on values. ref_failed=0; for funpair=ref_realfuns for ii=1:size(ref_sizes,1); a=tester_rand(ref_sizes(ii,1),ref_sizes(ii,2)); c1=feval(funpair{1}{1},a); c2=feval(funpair{1}{2},a); res=norm(c1(:)-c2(:)); [ref_failed,fail]=ltfatdiditfail(res,ref_failed); s=sprintf('REA %7s L:%2i W:%2i %0.5g %s',funpair{1}{2},ref_sizes(ii,1),ref_sizes(ii,2),res,fail); disp(s) end; end; %------------ inversion testing ----------------- % Test that the transforms are invertible inv_failed=0; for funpair=inv_funs for ii=1:size(ref_sizes,1); %a=tester_rand(ref_sizes(ii,:)); a=tester_crand(ref_sizes(ii,1),ref_sizes(ii,2)); ar=feval(funpair{1}{2},feval(funpair{1}{1},a)); res=norm(a(:)-ar(:)); [inv_failed,fail]=ltfatdiditfail(res,inv_failed); s=sprintf('INV %7s L:%2i W:%2i %0.5g %s',funpair{1}{1},ref_sizes(ii,1),ref_sizes(ii,2),res,fail); disp(s) end; end; %----------- normalization test ---------------- % Test that the transforms are orthonormal nrm_failed=0; for funname=nrm_funs for ii=1:size(ref_sizes,1); L=ref_sizes(ii,1); F=feval(funname{1},eye(L)); res=norm(F*F'-eye(L)); [nrm_failed,fail]=ltfatdiditfail(res,nrm_failed); s=sprintf('NRM %7s L:%2i %0.5g %s',funname{1},ref_sizes(ii,1),res,fail); disp(s) end; end; %------------ test fftreal inversion ---------------- % Test that the transforms are invertible realinv_failed=0; for funpair=realinv_funs for ii=1:size(ref_sizes,1); a=tester_rand(ref_sizes(ii,1),ref_sizes(ii,2)); ar=ifftreal(fftreal(a),ref_sizes(ii,1)); res=norm(a(:)-ar(:)); [realinv_failed,fail]=ltfatdiditfail(res,realinv_failed); s=sprintf('RIN %7s L:%2i W:%2i %0.5g %s',funpair{1}{1},ref_sizes(ii,1),ref_sizes(ii,2),res,fail); disp(s) end; end; %------------ test fftreal postpad ---------------- % Test that fftreal works with different lengths realpostpad_failed=0; postpad_sizes = {ref_sizes(:,1)*2, ceil(ref_sizes(:,1)/2), ceil(ref_sizes(:,1)/(3/4)) }; for ii=1:size(ref_sizes,1); a=tester_rand(ref_sizes(ii,1),ref_sizes(ii,2)); for jj=1:numel(postpad_sizes); postpad_size = postpad_sizes{jj}; ar = fftreal(a,postpad_size(ii)); ar2 = fft(a,postpad_size(ii),1); M2 = floor(postpad_size(ii)/2) + 1; ar2 = ar2(1:M2,:); res=norm(ar(:)-ar2(:)); [realpostpad_failed,fail]=ltfatdiditfail(res,realinv_failed); s=sprintf('RPOSTPAD fftreal L:%2i L2:%2i W:%2i %0.5g %s',ref_sizes(ii,1),postpad_size(ii),ref_sizes(ii,2),res,fail); disp(s) end end; test_failed=ref_failed+inv_failed+nrm_failed + realpostpad_failed; ltfat/inst/private/test_wmdct.m0000664000175000017500000000454613026262303016554 0ustar susnaksusnakfunction test_failed=test_wmdct %-*- texinfo -*- %@deftypefn {Function} test_wmdct %@verbatim % Test the algorithm using LONG windows. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wmdct.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . which comp_dwiltiii which comp_idwiltiii disp(' =============== TEST_WMDCT ================'); Lr=[4, 6, 8,12,16,12,18,32,30]; Mr=[2, 3, 2, 3, 4, 2, 3, 4, 3]; test_failed=0; for ii=1:length(Lr); for W=1:3 for ftype=1:2 for wtype=1:2 L=Lr(ii); M=Mr(ii); a=M; if wtype==1 % Full length window g=pgauss(L); gd=wildual(g,M); wtype='LONG'; else g=firwin('sqrthann',2*M,'2'); gd=g; wtype='FIR '; end; if ftype==1 % Complex-valued test case f=tester_crand(L,W); S='CMPLX'; else % Real-valued tes f=tester_rand(L,W); S='REAL '; end; c=wmdct(f,g,M,L); a=M; c2=ref_dwiltiii(f,g,a,M); r=iwmdct(c,gd); res=norm(c(:)-c2(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s); rdiff=f-r; res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REC %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s); g=wilorth(M,L); c=wmdct(f,g,M); r=iwmdct(c,g); rdiff=f-r; res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('ORTH %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s); end; end; end; end; ltfat/inst/private/ref_pconv_ola_postpad.m0000664000175000017500000000302113026262303020730 0ustar susnaksusnakfunction h=ref_pconv_ola_postpad(f,g,Lb) %-*- texinfo -*- %@deftypefn {Function} ref_pconv_ola_postpad %@verbatim % % This function implements periodic convolution using overlap-add. The % window g is supposed to be extended by postpad, so this function % cannot do zero-delay convolution. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_pconv_ola_postpad.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=length(f); Lg=length(g); % Number of blocks Nb=L/Lb; % Length of extended block and padded g Lext=Lb+Lg; gpad=postpad(g,Lext); h=zeros(L,1); for ii=0:Nb-1 block=pconv(postpad(f(ii*Lb+1:(ii+1)*Lb),Lext),gpad); h(ii*Lb+1:(ii+1)*Lb)+=block(1:Lb); % Large block s_ii=mod(ii+1,Nb); h(s_ii*Lb+1:s_ii*Lb+Lg)+=block(Lb+1:Lext); % Small block end; ltfat/inst/private/ref_wmdct2.m0000664000175000017500000000213513026262303016423 0ustar susnaksusnakfunction c=ref_wmdct2(f,g1,g2,M1,M2); L1=size(f,1); L2=size(f,2); c=wmdct(f,g1,M1); c=reshape(c,L1,L2); c=c.'; c=wmdct(c,g2,M2); c=reshape(c,L2,L1); c=c.'; c=reshape(c,M1,L1/M1,M2,L2/M2); %-*- texinfo -*- %@deftypefn {Function} ref_wmdct2 %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_wmdct2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_idgt_fb.m0000664000175000017500000000665513026262303016634 0ustar susnaksusnakfunction [f]=ref_idgt_fb(coef,g,L,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_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. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idgt_fb.html} %@seealso{idgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: OK % REFERENCE: OK % Calculate the parameters that was not specified. N=L/a; b=L/M; R=size(g,2); W=prod(size(coef))/(M*N*R); N=L/a; b=L/M; gl=length(g); glh=floor(gl/2); % gl-half % Apply ifft to the coefficients. coef=ifft(reshape(coef,M,N*W))*sqrt(M); coef=reshape(coef,M,N,W); % The fftshift actually makes some things easier. g=fftshift(g); g f=zeros(L,W); % Make multicolumn g by replication. gw=repmat(g,1,W); ff=zeros(gl,1); % 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)+=ff(1+ii); end; for ii=0:ep 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)+=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)+=ff(1+ii); end; for ii=0:ep f(1+ii,w)+=ff(L-sp+1+ii); end; end; end; % Scale correctly. f=sqrt(M)*f; ltfat/inst/private/test_filterbankscale.m0000664000175000017500000000630713026262303020564 0ustar susnaksusnakfunction test_failed=test_filterbankscale() test_failed = 0; disp('----------FILTERBANKSCALE-----------'); gr{1}=randn(20,1); gr{2}=randn(21,1); gr{3}=firfilter('hanning',19); gr{4}=firfilter('hanning',20); gr{5}=randn(4,1); gr{6}=firfilter('hanning',20,'causal'); gr{7}=firfilter('hanning',20,'delay',13); gr{8}=firfilter('hanning',20,'delay',-13); gr{7}=firfilter('hanning',20,'delay',14); gr{8}=firfilter('hanning',20,'delay',-14); gr{9}=firfilter('hamming',19,.3); gr{10}=firfilter('hamming',19,.3,'real'); gr{11}=blfilter('hanning',.19); gr{12}=blfilter('hanning',.2); gr{13}=blfilter('hanning',.132304); gr{14}=blfilter('hanning',.23,'delay',13); gr{15}=blfilter('hamming',.23,.3); gr{16}=blfilter('hamming',.23,.3,'real'); % (almost) Allpass filter gr{17}=blfilter('hanning',2); gr{18}=blfilter('hanning',1); gr{19}=blfilter('hanning',2,1); gr{20}=blfilter('hanning',1,-1); gr{21}=blfilter('hamming',.1,-.3); gr{22}=blfilter('hanning',1.7); gr{23}=struct('H',randn(10,1),'L',100); gr{24}=crand(40,1); gr{25}=struct('h',crand(40,1)); gr{26}=struct('h',crand(40,1),'realonly',1); Larr = [100, 211]; norms = {'1','2','inf'}; for L = Larr gr{23}=struct('H',randn(10,1),'L',L); for ii = 0:1 if ii==0, freqstr = ''; freqflag = 'nofreq'; else freqstr = 'FREQ'; freqflag = 'freq'; end for nId = 1:numel(norms) g = filterbankscale(gr,L,norms{nId},freqflag); if ii == 0 [~,n] = normalize(ifft(filterbankfreqz(g,1,L)),norms{nId}); else [~,n] = normalize(filterbankfreqz(g,1,L),norms{nId}); end res = sum(abs(n-1)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('NORM: %s %s L=%d %s\n',upper(norms{nId}),freqstr,L,fail); end end end scal = 0.1; for L = Larr gr{23}=struct('H',randn(10,1),'L',L); for nId = 1:numel(norms) grfreqz = filterbankfreqz(gr,1,L); g = filterbankscale(gr,scal); gfreqz = filterbankfreqz(g,1,L); res = sum(sum(scal*grfreqz-gfreqz)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('SCALE %f L=%d %s\n',scal,L,fail); end end %-*- texinfo -*- %@deftypefn {Function} test_filterbankscale %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_filterbankscale.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_idwiltii.m0000664000175000017500000000341713026262303017045 0ustar susnaksusnakfunction f=ref_idwiltii(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwiltii %@verbatim %REF_DWILTII Reference Inverse Discrete Wilson Transform type II % Usage: f=ref_idwiltii(c,g,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwiltii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Setup transformation matrix. L=size(g,1); W=size(c,2); F=zeros(L,L); N=L/a; l=(0:L-1).'; for n=0:N/2-1 % Do the unmodulated coefficient. F(:,2*M*n+1)=circshift(g,2*a*n); % m odd case OK for m=1:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*sin(pi*m/M*(l+.5)).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*cos(pi*m/M*(l+.5)).*circshift(g,(2*n+1)*a); end; for m=2:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*cos(pi*m/M*(l+.5)).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*sin(pi*m/M*(l+.5)).*circshift(g,(2*n+1)*a); end; if rem(M,2)==0 % Do the Nyquest wave. F(:,M+2*M*n+1) = sin(pi*(l+.5)).*circshift(g,(2*n+1)*a); else F(:,M+2*M*n+1) = sin(pi*(l+.5)).*circshift(g,2*n*a); end; end; f=F*c; ltfat/inst/private/ref_wignervilledist.m0000664000175000017500000000423013026262303020434 0ustar susnaksusnakfunction W=ref_wignervilledist(f,g) %-*- texinfo -*- %@deftypefn {Function} ref_wignervilledist %@verbatim %REF_WIGNERVILLEDIST Reference wigner-Ville distribution % Usage: W=ref_wignervilledist(f) % % REF_WIGNERVILLEDIST(f,g) computes the Wigner-Ville distribution of f and g. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_wignervilledist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven if ~all(length(f)==length(g)) error('%s: f and g must have the same length.', upper(mfilename)); end; L = length(f); H = floor(L/2); R = zeros(L,L); W = zeros(L,L); % Compute the analytic representation of f if (nargin == 1) if isreal(f) z = fft(f); z(2:L-H) = 2*z(2:L-H); z(H+2:L) = 0; z1 = ifft(z); z2 = z1; else z1 = f; z2 = z1; end elseif (nargin == 2) if isreal(f) || isreal(g) z1 = fft(f); z1(2:L-H) = 2*z1(2:L-H); z1(H+2:L) = 0; z1 = ifft(z1); z2 = fft(g); z2(2:L-H) = 2*z2(2:L-H); z2(H+2:L) = 0; z2 = ifft(z2); else z1 = f; z2 = g; end end % Compute instantaneous autocorrelation matrix R for l = 0 : L-1; for m = -min([L-l, l, round(L/2)-1]) : min([L-l, l, round(L/2)-1]); R(mod(L+m,L)+1, l+1) = z1(mod(l+m, L)+1).*conj(z2(mod(l-m, L)+1)); end end % Compute the Wigner-Ville distribution for hh=0:L-1 for ii=0:L-1 for jj = 0:L-1 W(hh+1, ii+1) = W(hh+1, ii+1) + R(jj+1, ii+1) .* exp(-2*pi*i*hh*jj/L); end end end ltfat/inst/private/test_dwilts.m0000664000175000017500000000655213026262303016743 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_dwilts %@verbatim % This is currently the tester for the % new TF-transforms. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dwilts.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[4, 6, 8, 12,16,12,18,32,30]; Mr=[2, 3, 2, 3, 4, 2, 3, 4, 3]; Wmax=2; ref_funs={{'ref_dwilt','ref_dwilt_1'},... {'ref_dwiltii','ref_dwiltii_1'},... {'ref_dwiltiii','ref_dwiltiii_1'},... {'ref_dwiltiv','ref_dwiltiv_1'},... }; refinv_funs={{'ref_idwilt','ref_idwilt_1'},... {'ref_idwiltii','ref_idwiltii_1'},... {'ref_idwiltiii','ref_idwiltiii_1'},... {'ref_idwiltiv','ref_idwiltiv_1'},... }; inv_funs={{'ref_dwilt','ref_idwilt'},... {'ref_dwiltii','ref_idwiltii'},... {'ref_dwiltiii','ref_idwiltiii'},... {'ref_dwiltiv','ref_idwiltiv'},... }; % ---------- reference testing -------------------- % Test that the transforms agree on values. for funpair=ref_funs for ii=1:length(Lr); for W=1:Wmax L=Lr(ii); M=Mr(ii); a=M; N=L/a; f=tester_rand(L,W); g=ref_win(funpair{1}{1},'test',L,a,M); c1=feval(funpair{1}{1},f,g,a,M); c2=feval(funpair{1}{2},f,g,a,M); res=norm(c1(:)-c2(:)); if abs(res)>1e-10 fail='FAILED'; else fail=''; end; s=sprintf('REF %10s L:%3i W:%2i a:%3i M:%3i %0.5g %s',funpair{1}{2},L,W,a,M,res,fail); disp(s) end; end; end; % ---------- reference inverse function testing --------------- % Test that the transforms agree on values. for funpair=refinv_funs for ii=1:length(Lr); for W=1:Wmax L=Lr(ii); M=Mr(ii); a=M; N=L/a; c=tester_rand(M*N,W); g=ref_win(funpair{1}{1},'test',L,a,M); f1=feval(funpair{1}{1},c,g,a,M); f2=feval(funpair{1}{2},c,g,a,M); res=norm(f1(:)-f2(:)); if abs(res)>1e-10 fail='FAILED'; else fail=''; end; s=sprintf('REF %10s L:%3i W:%2i a:%3i M:%3i %0.5g %s',funpair{1}{2},L,W,a,M,res,fail); disp(s) end; end; end; %------------ inversion testing ----------------- % Test that the transforms are invertible for funpair=inv_funs for ii=1:length(Lr); for W=1:Wmax L=Lr(ii); M=Mr(ii); a=M; N=L/a; f=tester_rand(L,W); g=ref_win(funpair{1}{1},'test',L,a,M); gamma=ref_tgabdual(funpair{1}{1},g,L,a,M); c=feval(funpair{1}{1},f,g,a,M); fr=feval(funpair{1}{2},c,gamma,a,M); res=norm(f(:)-fr(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); if abs(res)>1e-10 fail='FAILED'; else fail=''; end; s=sprintf('INV %10s L:%3i W:%2i a:%3i M:%3i %0.5g %s',funpair{1}{1},L,W,a,M,res,fail); disp(s) end; end; end; ltfat/inst/private/ref_dgt_4.m0000664000175000017500000000405413026262303016226 0ustar susnaksusnakfunction c=ref_dgt_4(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_4 %@verbatim %REF_DGT_4 DGT algorithm 4 % % This algorithm makes the r-loop be the outermost loop, in order to % reduce the size of the intermediate buffers, and hopefully better % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_4.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; b=L/M; [c,h_a,h_m]=gcd(-a,M); p=a/c; q=M/c; d=N/q; w=zeros(M,N); % This version uses matrix-vector products and ffts F=zeros(d,p,q); C=zeros(d,q,q); % Setup G before we start G=zeros(c,d,p,q); for r=0:c-1 for s=0:d-1 for k=0:p-1 for l=0:q-1 G(r+1,s+1,k+1,l+1)=sqrt(M*d)*g(mod(r+k*M-l*a+s*p*M,L)+1); end; end; end; end; G=dft(G,[],2); % Set up the matrices for r=0:c-1 for s=0:d-1 for k=0:p-1 for l=0:q-1 F(s+1,k+1,l+1)=f(mod(r+k*M+s*p*M-l*h_a*a,L)+1); end; end; end; % fft them F=dft(F,[],1); % Multiply them for s=0:d-1 GM=reshape(G(r+1,s+1,:,:),p,q); FM=reshape(F(s+1,:,:),p,q); C(s+1,:,:)=GM'*FM; end; % Inverse fft C=idft(C,[],1); % Place the result for l=0:q-1 for u=0:q-1 for s=0:d-1 w(r+l*c+1,mod(u+s*q-l*h_a,N)+1)=C(s+1,u+1,l+1); end; end; end; end; c=dft(w); ltfat/inst/private/ref_dgtns_1.m0000664000175000017500000000561613026262303016571 0ustar susnaksusnakfunction coef=ref_dgtns_1(f,gamma,V) %-*- texinfo -*- %@deftypefn {Function} ref_dgtns_1 %@verbatim %REF_DGT_1 Reference DGTNS using P.Prinz algorithm % Usage: c=ref_dgtns_1(f,gamma,V); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgtns_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . a=V(1,1); b=V(2,2); r=-V(2,1); L=size(gamma,1); M=L/b; N=L/a; W=size(f,2); c=gcd(a,M); p=a/c; q=M/c; d=N/q; if r==0 % The grid is rectangular. Call another reference algorithm. coef=zeros(M*N,W); coef(:)=ref_dgt(f,gamma,a,M); return; end; % We can now assume that the grid is truly nonseperable, % and so d>1. % Conjugate. gammac=conj(gamma); % Level 2: Block diagonalize, and use that some blocks are % the same up to permutations. p1=stridep(M,L); p2=stridep(N,M*N); % Get shift offsets for stage 2 of the algorithm. [mll,all]=shiftoffsets(a,M); % Step 1: Permute s1 = f(p1,:); % Step 2: Multiply by DG' s2=zeros(M*N,W); % Do interpreter-language-optimized indexing. [n_big,m_big]=meshgrid(0:N-1,0:b-1); base=m_big*M-n_big*a+L; base=base.'; % Work arrays. work=zeros(b,M/c*W); wk=zeros(N,b); wkrect=zeros(N,b); % Create fixed modulation matrix (Does not change with k) fixedmod=zeros(N,b); for n=0:N-1 fixedmod(n+1,:)=exp(2*pi*i*r*n/L*(0:M:L-1)); end; % This loop iterates over the number of truly different wk's. for ko=0:c-1 % Create the wk of the rectangular-grid case. wkrect(:)=gammac(mod(base+ko,L)+1); % Create wk of skewed case. wk=(fixedmod.*wkrect); % Setup work array. for l=0:M/c-1 k=ko+l*c; rowmod=exp(2*pi*i*r*(0:b-1)/b*all(l+1)).'; work(:,l*W+1:(l+1)*W)=circshift(rowmod.*s1(1+(ko+l*c)*b:(ko+l*c+1)*b,:),-mll(l+1)); end; % Do the actual multiplication, work2=wk*work; % Place the result correctly. for l=0:M/c-1 k=ko+l*c; kmod=exp(2*pi*i*r*(0:N-1)*k/L).'; colmod=exp(2*pi*i*r*(0:N-1)/b*mll(l+1)).'; doublefac=exp(-2*pi*i*r/b*all(l+1)*mll(l+1)); s2(1+(ko+l*c)*N:(ko+l*c+1)*N,:)=doublefac*colmod.*kmod.*circshift(work2(:,l*W+1:(l+1)*W),all(l+1)); end; end; % Step 3: Permute again. coef = s2(p2,:); % Apply fft. for n=1:N coef((n-1)*M+1:n*M,:)=fft(coef((n-1)*M+1:n*M,:)); end; ltfat/inst/private/ref_irdftiii_1.m0000664000175000017500000000276113026262303017253 0ustar susnaksusnakfunction f=ref_irdftiii_1(c) %-*- texinfo -*- %@deftypefn {Function} ref_irdftiii_1 %@verbatim %REF_RDFTIII_1 Reference IRDFTIII by IDFTIII % Usage: f=ref_irdftiii(c); % % Only works for real functions. % % Compute IRDFT by doubling the signal and doing an IDFTIII % to obtain the reconstructed signal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdftiii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(c,1); Lhalf=floor(L/2); Lend=Lhalf*2; cc=zeros(size(c)); cc(1:Lhalf,:)=(c(1:2:Lend,:)- i*c(2:2:Lend,:))/sqrt(2); cc(L-Lhalf+1:end,:)= (c(Lend-1:-2:1,:) +i*c(Lend:-2:2,:))/sqrt(2); % If f has an even length, we must also copy the Nyquest-wave % (it is real) if mod(L,2)==1 cc((L+1)/2,:)=c(L,:); end; f=real(ref_idftiii(cc)); ltfat/inst/private/test_ltfatarghelper.py0000664000175000017500000001322613026262276020642 0ustar susnaksusnak#!/usr/bin/env python # -*- coding: utf-8 -*- # # This script searches all directories listed in dirs (relative to ltfatroot) # for occurrence of ltfatarghelper and replaces it with a defined code. # # from __future__ import print_function import os import sys from collections import defaultdict # Directories to search (relative to ltfat root) dirs = ('','auditory','blockproc','demos','filterbank','fourier','frames','gabor', 'nonstatgab','operators','quadratic','reference','signals','sigproc','wavelets') #dirs = ('g1','g2','g3') def query_yes_no(question, default="no"): """Ask a yes/no question via raw_input() and return their answer. "question" is a string that is presented to the user. "default" is the presumed answer if the user just hits . It must be "yes" (the default), "no" or None (meaning an answer is required of the user). The "answer" return value is one of "yes" or "no". """ valid = {"yes":True, "y":True, "ye":True, "no":False, "n":False} if default == None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " elif default == "no": prompt = " [y/N] " else: raise ValueError("invalid default answer: '%s'" % default) while 1: sys.stdout.write(question + prompt) choice = raw_input().lower() if default is not None and choice == '': return valid[default] elif choice in valid.keys(): return valid[choice] else: sys.stdout.write("Please respond with 'yes' or 'no' "\ "(or 'y' or 'n').\n") def main(): ltfatroot = os.path.join(os.path.dirname(os.path.realpath(__file__)),os.pardir) mfileswithltfatarghelper = defaultdict(list) for directory in dirs: files = list( x for x in os.listdir(os.path.join(ltfatroot,directory)) if x.endswith('.m') ) for ff in files: if ff == 'ltfatarghelper.m': continue fullpath = os.path.join(ltfatroot,os.path.join(directory,ff)) with open(fullpath,'r') as f: flines = f.readlines() for lineNo,line in enumerate(flines): if 'ltfatarghelper' in line and not line.startswith('%'): if '%MARKER' in line or 'error' in line: break # Do not use this file mfileswithltfatarghelper[fullpath].append(lineNo) print('Found in file {}:\n {}'.format(ff,line)) #for k,v in mfileswithltfatarghelper.items(): # print(k + '->' + str(v) ) for k,v in mfileswithltfatarghelper.items(): filelines = [] with open(k,'r') as f: filelines = f.readlines() for lineNo in reversed(v): print('Processing ' + k + ' with line ' + str(lineNo)) origline = filelines[lineNo] if not 'ltfatarghelper' in origline: print('This is wrong in '+k + str(v)+ '\n ' + origline) continue fcall = filelines[lineNo].split("=") toinsert = [] if len(fcall)<2: # No ret args toinsert.append("origpath = pwd;\n") toinsert.append("cd(ltfatbasepath);\n") toinsert.append(origline.rstrip()+'%MARKER\n') toinsert.append("cd([ltfatbasepath,filesep,'mex']);\n") toinsert.append(origline) toinsert.append("cd(origpath);\n") else: lhs = fcall[0] if '[' in lhs: lhs = lhs[lhs.find('[')+1:lhs.rfind(']')] rhs = fcall[1][fcall[1].find("(")+1:fcall[1].rfind(")")] lhsList = list(x.strip() for x in lhs.split(',')) lhsList2 = list(x+'2' if not x.strip()=='~' else x for x in lhsList) rhsList = rhs.split(',') #print(str(lhsList) + " ----> " + str(rhsList)) newline = '['+ ','.join(lhsList2) +']' + '=' + fcall[1] + '\n' toinsert.append("origpath = pwd;\n") toinsert.append("cd(ltfatbasepath);\n") toinsert.append("tic;\n") toinsert.append(origline.rstrip()+'%MARKER\n') toinsert.append("t0 =toc;\n") toinsert.append("fprintf('MAT: %d using %s\\n',t0,which('ltfatarghelper'));\n") toinsert.append("cd([ltfatbasepath,filesep,'mex']);\n") toinsert.append("tic;\n") toinsert.append(newline) toinsert.append("t0 =toc;\n") toinsert.append("fprintf('MEX: %d using %s\\n',t0,which('ltfatarghelper'));\n") toinsert.append("cd(origpath);\n") compareline = 'if ~(' arglist = [] for one,two in zip(lhsList,lhsList2): if one == '~': continue arglist.append('isequal('+one +','+two+')') compareline += '&&'.join(arglist) compareline += ')\n' toinsert.append(compareline); toinsert.append("error('ltfatarghelper test failed in " "%s',upper(mfilename));\n"); toinsert.append('end\n'); #print('\n'.join(filelines)) del filelines[lineNo] filelines[lineNo:lineNo] = toinsert with open(k,'w') as f: f.writelines(filelines) if __name__ == '__main__': if not query_yes_no('This will overwrite a bunch of files. Make sure you have a backup.' ' Should I continue?'): print('Quitting...') sys.exit() main() ltfat/inst/private/ref_dgt_pconv.m0000664000175000017500000000222713026262303017210 0ustar susnaksusnakfunction c=ref_dgt_pconv(f,g,a,M); %-*- texinfo -*- %@deftypefn {Function} ref_dgt_pconv %@verbatim %REF_DGT_PCONV Compute a DGT using PCONV %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_pconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); N=L/a; b=L/M; c=zeros(M,N); for m=0:M-1 work = pconv(f,involute(g).*expwave(L,m*b)); c(m+1,:) = reshape(work(1:a:L),1,N); end; c=phaseunlock(c,a); ltfat/inst/private/rand_wpe.m0000664000175000017500000000302413026262303016164 0ustar susnaksusnakfunction f=rand_wpe(varargin) %-*- texinfo -*- %@deftypefn {Function} rand_wpe %@verbatim %RAND_HPE Random WPE even function. % Usage: f=rand_wpe(s); % % RAND_WPE(s) generates an array of size s, which is WPE along the % first dimension. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/rand_wpe.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isnumeric(varargin); s=varargin; else s=cell2mat(varargin); end; if length(s)==1 error('To avoid confusion, the size must be at least two-dimensional.'); end; shalf=s; shalf(1)=floor((shalf(1)-1)/2); f=(randn(shalf)-.5)+(randn(shalf)-.5)*i; if rem(s(1),2)==0 f=[randn([1 s(2:end)])-.5; ... f; ... randn([1 s(2:end)])-.5; ... flipud(conj(f))]; else f=[randn([1 s(2:end)])-.5; ... f; ... flipud(conj(f))]; end; ltfat/inst/private/test_gabphasederiv.m0000664000175000017500000001046713026262303020241 0ustar susnaksusnakfunction test_failed = test_gabphasederiv() test_failed = 0; %-*- texinfo -*- %@deftypefn {Function} test_gabphasederiv %@verbatim % Tests whether all the algorithms return the same values %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabphasederiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('-----------------test_gabphasederiv----------------------'); L = 100; l = 0:L-1; l = l(:); f1 = exp(1i*pi*0.1*l); f2 = pchirp(L,1); f3 = expchirp(L,0.2,2.2,'fc',-1.2); f4 = exp(1i*pi*0.5*L*(l./(L)).^2); f5 = exp(1i*pi*0.1*L*(l./(L)).^2); f6 = zeros(L,1); f6(floor(L/2):floor(L/2)+5) = 1; % Compare the pahse derivatives only for coefficients bigger than % relminlvl*max(c(:)) and away from the borders.. relminlvldb = 20; relminlvl = 10^(-relminlvldb/20); a = [1,1,1,4,4, 1, 4, 2]; M = [L,L,L,L,L,L/4,L/2,L/2]; %g = {{'gauss',1},'gauss',{'hann',8}}; %g = {{'hann',8}}; g = {{'gauss',1},{'gauss',4},{'gauss',1/4},... 'gauss',{'gauss',4},{'gauss',1/4},'gauss',{'hann',8}}; f = {f3,f3,f3,f3,f3,f3,f3,f3,f3}; phaseconvCell = {'relative','freqinv','timeinv','symphase'}; dflags = {'t','f','tt','ff','tf'}; for ii =1:numel(g) for phaseconvId=1:numel(phaseconvCell) phaseconv=phaseconvCell{phaseconvId}; for dflagId = 1:numel(dflags) dflag = dflags{dflagId}; c = dgt(f{ii},g{ii},a(ii),M(ii)); [~,info]=gabwin(g{ii},a(ii),M(ii),dgtlength(numel(f{ii}),a(ii),M(ii))); minlvl = max(abs(c(:)))*relminlvl; algArgs = { {'dgt',f{ii},g{ii},a(ii),M(ii)} {'phase',angle(c),a(ii)} {'cross',f{ii},g{ii},a(ii),M(ii)} {'abs',abs(c),g{ii},a(ii)} }; algRange = 1:numel(algArgs); if ~info.gauss algRange = 1:numel(algArgs)-1; end pderivs = cell(numel(algRange),1); for algId=algRange alg = algArgs{algId}; pderivs{algId}=gabphasederiv(dflag,alg{:},phaseconv); % Make it independent of L if any(strcmp(dflag,{'t','f'})) pderivs{algId} = pderivs{algId}./L; end % Mask by big enough coefficients pderivs{algId}(abs(c). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); % Create matrix representation of the DFT F=idft(eye(L)); c=(F^order)*f; ltfat/inst/private/ref_insdgt.m0000664000175000017500000000273613026262303016522 0ustar susnaksusnakfunction f = ref_insdgt(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_insdgt %@verbatim %NSDGT Non-stationary Discrete Gabor transform % Usage: c=nsdgt(f,g,a,M); % [c,Ls]=nsdgt(f,g,a,M); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_insdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . timepos=cumsum(a)-a(1)+1; L=sum(a); N=numel(g); F=zeros(L,sum(M)); % Construct the analysis operator matrix explicitly Y = 1; for n = 1:length(timepos) X = length(g{n}); win_range = mod(timepos(n)+(-floor(X/2):ceil(X/2)-1)-1,L)+1; F(win_range,Y) = fftshift(g{n}); for m = 1:M(n)-1 F(win_range,Y+m) = F(win_range,Y).*exp(2*pi*i*m*(-floor(X/2):ceil(X/2)-1)/M(n)).'; end Y=Y+M(n); end cmat=cell2mat(c); f=F*cmat; ltfat/inst/private/test_thresh.m0000664000175000017500000001003013026262303016714 0ustar susnaksusnakfunction test_failed=test_thresh %-*- texinfo -*- %@deftypefn {Function} test_thresh %@verbatim %TEST_THRESH Compare sparse and full thesholding %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_thresh.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_THRESH ================'); global LTFAT_TEST_TYPE; if ~strcmpi(LTFAT_TEST_TYPE,'double') disp(sprintf('Skipping. Cannot work with sparse matrices of type %s.',LTFAT_TEST_TYPE)); return; end lambda=0.1; ttypes={'hard','soft','wiener'}; for ii=1:2 if ii==1 g=tester_rand(3,4); field='REAL '; g(2,2)=lambda; else g=tester_crand(3,4); field='CMPLX '; g(2,2)=lambda; end; for jj=1:3 ttype=ttypes{jj}; [xo_full, Nfull] = thresh(g,lambda,ttype,'full'); [xo_sparse, Nsp] = thresh(g,lambda,ttype,'sparse'); res = xo_full-xo_sparse; res = norm(res(:)); res2 = Nfull-Nsp; [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['THRESH %s %s %0.5g %s'],field,ttype,res,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res2,test_failed); s=sprintf(['THRESH N %s %s %0.5g %s'],field,ttype,res2,fail); disp(s); % Extend lambda to: % a) Vector lambdavec = lambda*ones(numel(g),1); [xo_full2, Nfull2] = thresh(g,lambdavec,ttype,'full'); [xo_sparse2, Nsp2] = thresh(g,lambdavec,ttype,'sparse'); res_full = xo_full2-xo_full; res_sparse = xo_sparse2-xo_sparse; res_full = norm(res_full(:)); res_sparse = norm(res_sparse(:)); res_nfull = Nfull2-Nfull; res_nsparse = Nfull2-Nfull; [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['THRESH VEC FULL %s %s %0.5g %s'],field,ttype,res_full,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['THRESH VEC SPARSE %s %s %0.5g %s'],field,ttype,res_sparse,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res2,test_failed); s=sprintf(['THRESH VEC N FULL %s %s %0.5g %s'],field,ttype,res_nfull,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res2,test_failed); s=sprintf(['THRESH VEC N SPARSE %s %s %0.5g %s'],field,ttype,res_nsparse,fail); disp(s); % b) Same shape as g lambdamat = lambda*ones(size(g)); [xo_full3, Nfull3] = thresh(g,lambdamat,ttype,'full'); [xo_sparse3, Nsp3] = thresh(g,lambdamat,ttype,'sparse'); res_full = xo_full3-xo_full; res_sparse = xo_sparse3-xo_sparse; res_full = norm(res_full(:)); res_sparse = norm(res_sparse(:)); res_nfull = Nfull3-Nfull; res_nsparse = Nfull3-Nfull; [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['THRESH MAT FULL %s %s %0.5g %s'],field,ttype,res_full,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['THRESH MAT SPARSE %s %s %0.5g %s'],field,ttype,res_sparse,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res2,test_failed); s=sprintf(['THRESH MAT N FULL %s %s %0.5g %s'],field,ttype,res_nfull,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res2,test_failed); s=sprintf(['THRESH MAT N SPARSE %s %s %0.5g %s'],field,ttype,res_nsparse,fail); disp(s); end; end; ltfat/inst/private/ref_dstii_1.m0000664000175000017500000000262613026262303016564 0ustar susnaksusnakfunction c=ref_dstii_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dstii_1 %@verbatim %REF_DSTII Reference Discrete Sine Transform type II % Usage: c=ref_dstii(f); % % The transform is computed by an FFT of 4 times the length of f. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dstii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if ~isreal(f) c=ref_dstii_1(real(f)) + i*ref_dstii_1(imag(f)); else lf=zeros(L*4,W); lf(2:2:2*L,:)=f; lf(2*L+2:2:end,:)=-flipud(f); fflong=imag(fft(lf)); c=-fflong(2:L+1,:)/sqrt(2*L); % Scale last coefficients to obtain orthonormal transform. c(end,:)=1/sqrt(2)*c(end,:); end ltfat/inst/private/ref_col2diag_1.m0000664000175000017500000000265713026262303017140 0ustar susnaksusnakfunction cout=ref_col2diag_1(cin); %-*- texinfo -*- %@deftypefn {Function} ref_col2diag_1 %@verbatim %REF_COL2DIAG_1 Compute matrix represenation from spreading symbol % % This function is its own inverse. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_col2diag_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(cin,1); cout=zeros(L); for jj=0:L-1 for ii=0:jj-1 cout(ii+1,jj+1)=cin(ii+1,ii-jj+L+1); end; for ii=jj:L-1 cout(ii+1,jj+1)=cin(ii+1,ii-jj+1); end; end; % The second code also works. if 0 for ii=0:L-1 for jj=0:ii cout(ii+1,jj+1)=cin(ii+1,ii-jj+1); end; for jj=ii+1:L-1 cout(ii+1,jj+1)=cin(ii+1,ii-jj+L+1); end; end; end; ltfat/inst/private/test_ambiguityfunction.m0000664000175000017500000000345413026262303021173 0ustar susnaksusnakfunction test_failed = test_ambiguityfunction Lr = [1, 19, 20]; test_failed = 0; disp(' =============== TEST_AMBIGUITYFUNCTION =============='); for ii = 1: length(Lr) L = Lr(ii); for n = 1:4 if (n==1) type1 = 'auto'; type2 = 'real'; f = tester_rand(L,1); g = f; elseif (n==2) type1 = 'auto'; type2 = 'complex'; f = tester_crand(L,1); g = f; elseif (n==3) type1 = 'cross'; type2 = 'real'; f = tester_rand(L,1); g = tester_rand(L,1); elseif (n==4) type1 = 'cross'; type2 = 'complex'; f = tester_crand(L,1); g = tester_crand(L,1); end r1 = ref_ambiguityfunction(f,g); r2 = ambiguityfunction(f,g); res = norm(r1-r2); [test_failed, fail] = ltfatdiditfail(res, test_failed); s = sprintf('DAF %3s %3s L:%3i %0.5g %s', type1, type2, L, res, fail); disp(s); end end %-*- texinfo -*- %@deftypefn {Function} test_ambiguityfunction %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_ambiguityfunction.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_sfac.m0000664000175000017500000000611513026262303016141 0ustar susnaksusnakfunction [ff]=ref_sfac(f,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_sfac %@verbatim %REF_SFAC Reference signal factorization % Usage: gf=ref_sfac(g,a,M); % % Input parameters: % f : Input signal. % a : Length of time shift. % b : Length of frequency shift. % Output parameters: % ff : Factored signal % % This function cannot handle multidimensional arrays. % Reshape to matrix BEFORE you call this. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_sfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Calculate the parameters that was not specified L=size(f,1); W=size(f,2); N=L/a; b=L/M; % The four factorization parameters. [c,h_a,h_m]=gcd(a,M); p=a/c; q=M/c; d=N/q; permutation=zeros(q*b,1); for k=0:p-1 for s=0:d-1 P(1+s+k*d)=s*p+k; end; end; P2=stridep(d,b)-1; % Create permutation for l=0:q-1 for k=0:p-1 for s=0:d-1 %permutation(l*b+s+k*d+1)=mod(P(s+k*d+1)*M-h_m*l*M+l*c,L)+1; %permutation(l*b+s*p+k+1)=mod(P2(s+k*d+1)*M-h_m*l*M+l*c,L)+1; permutation(l*p*d+s+k*d+1)=mod(s*c*p*q+(k-h_m*l)*c*q+l*c,L)+1; end; end; end; %ff=ref_fac(f,W,c,d,p,q,permutation); fffull=zeros(p,q,d,c); pr=reshape(permutation,d,p*q); p2=zeros(p*q,d); for l=0:q-1 for k=0:p-1 for s=0:d-1 %p2(l*p+k+1,s+1)=mod(s*c*p*q+(k-h_m*l)*c*q+l*c,L)+1; %p2(l*p+k+1,s+1)=mod(s*p*M+k*M-h_m*l*M+l*c,L)+1; p2(l*p+k+1,s+1)=mod(s*p*M+k*M+(c-h_m*M)*l,L)+1; end; end; end; % Output ff=zeros(p*q,c*d); % If d==1, it is not possible to further reduce the size of % wk. Actually, some of the following code produces an % error, because Matlab interprets an fft of a 1x q*p as a % a row operation ! if d>1 % This loop iterates over the number of truly different wk's. for ko=0:c-1 % Execute the fft and place transposed in ff. % The reshape done below is a dummy used to fix inconsistency in % octaves and matlabs handling of indices. wt=fft(reshape(f(p2+ko),p*q,d),[],2); for s=0:d-1 ff(:,1+ko*d+s)=wt(:,s+1); end; for s=0:d-1 fffull(:,:,s+1,ko+1)=reshape(wt(:,s+1),p,q,1,1); end; end; else % Work arrays. work=zeros(p*q,1); for ko=0:c-1 % Permute input. work(:)=f(pr+ko,:); % Write the block. ff(:,ko+1)=work; end end; %norm(ff(:)-fffull(:)) ltfat/inst/private/ref_iedgt_1.m0000664000175000017500000000372013026262303016540 0ustar susnaksusnakfunction f=ref_iedgt_1(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_iedgt_1 %@verbatim %REF_IEDGT_1 Reference Inverse Even DGT by IDGTII % Usage c=ref_edgt(f,g,a,M); % % The input window must be odd-centered of length 2L. % % a must be divisable by 2. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_iedgt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1)/2; W=size(c,2); N=L/a; M=L/b; clong=zeros(M,2*N,W); % Copy the first M/2 coefficients of the first/last time shift. clong(1:M/2,1,:)=c(1:M/2,:); clong(1:M/2,N+1,:)=c(1+(N-1)*M+M/2:N*M,:); % Scale the first coefficients correctly clong(1,1,:)=clong(1,1,:)*sqrt(2); clong(1,N+1,:)=clong(1,N+1,:)*sqrt(2); % Copy the remaining coefficients to the first/last time shift, such % that we get an odd symmetry. clong(M:-1:M/2+2,1,:) = -clong(2:M/2,1,:); clong(M:-1:M/2+2,N+1,:) = -clong(2:M/2,N+1,:); % Copy the body of the coefficients clong(:,2:N,:)=c(M/2+1:M/2+M*(N-1),:); % Copy the unmodulated coefficients for the second half clong(1,N+2:2*N,:)=clong(1,N:-1:2,:); % Copy the modulated coefficients for the second half clong(2:M,N+2:2*N,:)=-clong(M:-1:2,N:-1:2,:); clong=reshape(clong,2*M*N,W); fdouble=ref_idgtii(clong,g,a,2*b); f=fdouble(1:L,:); ltfat/inst/private/ref_dwiltii_1.m0000664000175000017500000000517413026262303017116 0ustar susnaksusnakfunction [coef]=ref_dwiltii_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwiltii_1 %@verbatim %COMP_DWILT Compute Discrete Wilson transform. % % Do not call this function directly, use DWILT instead. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwiltii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard. L=size(g,1); N=L/a; W=size(f,2); c=ref_gdgt(f,g,a,2*M,.5,0,0); coef2=reshape(c,2*M,N,W); % ----- Type II ------ %coef2=dgt(f,g,a,2*M); coef=zeros(2*M,N/2,W); if 0 % --- Loop version --- for n=0:N/2-1 % ---- m is zero --------- coef(1,n+1,:)=coef2(1,2*n+1,:); for m=1:2:M-1 % --- m is odd ---------- coef(m+1,n+1,:)= i/sqrt(2)*(coef2(m+1,2*n+1,:)+coef2(2*M-m+1,2*n+1,:)); coef(M+m+1,n+1,:)= 1/sqrt(2)*(coef2(m+1,2*n+2,:)-coef2(2*M-m+1,2*n+2,:)); end; for m=2:2:M-1 % --- m is even --------- coef(m+1,n+1,:)= 1/sqrt(2)*(coef2(m+1,2*n+1,:)-coef2(2*M-m+1,2*n+1,:)); coef(M+m+1,n+1,:)= i/sqrt(2)*(coef2(m+1,2*n+2,:)+coef2(2*M-m+1,2*n+2,:)); end; % --- m is nyquest ------ if mod(M,2)==0 coef(M+1,n+1,:) = i*coef2(M+1,2*n+2,:); else coef(M+1,n+1,:) = i*coef2(M+1,2*n+1,:); end; end; else % --- Vector version--- % ---- 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; end; coef=reshape(coef,M*N,W); ltfat/inst/private/test_nsdgt.m0000664000175000017500000001410413026262303016544 0ustar susnaksusnakfunction test_failed=test_nsdgt() %-*- texinfo -*- %@deftypefn {Function} test_nsdgt %@verbatim %TEST_NSDGT Simple test of nsdgt and associated functions % Usage: test_nsdgt() % % This function checks the exact reconstruction (up to numeric precision) % of the functions nsdgt and insdgt, when using dual windows computed with % nsgabdual, or tight windows computed with nsgabtight. % % This test is done on a single short random signal, for only one given set % of windows. % A more systematic testing would be required for a complete validation of % these functions (in particular for inclusion of the functions in LTFAT) %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_nsdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author: Florent Jaillet, 2009-05 test_failed=0; disp(' =============== TEST_NSDGT ================'); % First case is even numbers, painless % Second case is even numbers, non-painless % Third case has odd numbers, painless % Fouth case has odd numbers, non-painless % Fifth case is even numbers, painless, window length less than M ar ={[20,30,40],[20,30,40],[5,11,19],[5,11,19],[20,30,40]}; Mr ={[30,40,50],[30,40,50],[7,12,29],[7,12,29],[35,40,50]}; Lgr={[30,40,50],[60,80,60],[7,12,29],[9,19,33],[30,40,50]}; for tc=1:numel(ar) N=numel(ar{tc}); M=Mr{tc}; a=ar{tc}; Lg=Lgr{tc}; L=sum(a); g=cell(N,1); for ii=1:N g{ii}=randn(Lg(ii),1); end; % ----- non-uniform dual and inversion ----- ispainless=all(cellfun(@length,g)<=M.'); if ispainless gd=nsgabdual(g,a,M); gt=nsgabtight(g,a,M); end; for W=1:3 f=randn(L,W); c=nsdgt(f,g,a,M); % ----- reference --------------------- c_ref=ref_nsdgt(f,g,a,M); res=sum(cellfun(@(x,y) norm(x-y,'fro'),c,c_ref)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['NSDGT REF tc:%3i W:%3i %0.5g %s\n'],tc,W,res,fail); % ----- reference inverse --------------- f_syn=insdgt(c,g,a); f_ref=ref_insdgt(c,g,a,M); res=norm(f_ref-f_syn,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['NSDGT INV REF tc:%3i W:%3i %0.5g %s\n'],tc,W,res,fail); % ----- inversion --------------------- if ispainless r=insdgt(c,gd,a); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['NSDGT DUAL tc:%3i W:%3i %0.5g %s\n'],tc,W,res,fail); % ----- tight and inversion ----------------- ct=nsdgt(f,gt,a,M); rt=insdgt(ct,gt,a); res=norm(f-rt); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['NSDGT TIGHT tc:%3i %0.5g %s\n'],tc,res,fail); % ----- non-uniform inversion, real ----- c=nsdgtreal(f,g,a,M); r=insdgtreal(c,gd,a,M); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['NSDGTREAL DUAL tc:%3i %0.5g %s\n'],tc,res,fail); end; end; end; ar ={[25,30,45],[25,30,45]}; Mr =[50,50]; Lgr={[50,50,50],[40,50,60]}; % Second test is disabled, it does not work yet. for tc=1:1 %numel(ar) N=numel(ar{tc}); M=Mr(tc); a=ar{tc}; Lg=Lgr{tc}; L=sum(a); g=cell(N,1); for ii=1:N g{ii}=randn(Lg(ii),1); end; gd=nsgabdual(g,a,M); gt=nsgabtight(g,a,M); for W=1:3 L=sum(a); f=randn(L,1); % ----- uniform dual and inversion ----- c=unsdgt(f,g,a,M); r=insdgt(c,gd,a); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['UNSDGT DUAL tc:%3i W:%3i %0.5g %s\n'],tc,W,res,fail); % ----- uniform inversion, real ----- cr=unsdgtreal(f,g,a,M); r=insdgtreal(cr,gd,a,M); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['UNSDGTREAL DUAL tc:%3i W:%3i %0.5g %s\n'],tc,W,res,fail); % ----- uniform tight and inversion ----------------- ct=unsdgt(f,gt,a,M); rt=insdgt(ct,gt,a); res=norm(f-rt); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['UNSDGT TIGHT tc:%3i W:%3i %0.5g %s\n'],tc,W,res,fail); % ----- framebounds ----------------- if 0 FB=nsgabframebounds(gt,a,M); res=norm(FB-1); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['UNSDGT FRAMEBOUNDS tc:%3i %0.5g %s\n'],tc,res,fail); end; end; end; % ------ Reference DGT ---------------------- if 0 a1=3; M1=4; N=8; a=a1*ones(1,N); M=M1*ones(1,N); L=a1*N; f=tester_crand(L,1); g1=tester_crand(L,1); for ii=1:N g{ii}=g1; end; c = nsdgt(f,g,a,M); c_ref = dgt(f,g1,a1,M1,'timeinv'); res=norm(reshape(cell2mat(c),M1,N)-c_ref,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['NSDGT REF %0.5g %s\n'],res,fail); end; ltfat/inst/private/spcrand.m0000664000175000017500000000234613026262303016025 0ustar susnaksusnakfunction f=spcrand(n1,n2,p); %-*- texinfo -*- %@deftypefn {Function} spcrand %@verbatim %SPCRAND Sparse Random complex numbers for testing. % Usage: f=sptester_crand(n1,n2,p); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/spcrand.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Make a random real valued matrix, extract the indices, put complex % numbers in and recollect. f=sprand(n1,n2,p); [row,col,val]=find(f); L=numel(val); val=rand(L,1)-.5+i*(rand(L,1)-.5); f=sparse(row,col,val,n1,n2); ltfat/inst/private/ref_irdftii.m0000664000175000017500000000261013026262303016653 0ustar susnaksusnakfunction c=ref_irdftii(f) %-*- texinfo -*- %@deftypefn {Function} ref_irdftii %@verbatim %REF_IRDFTII Reference Inverse Real DFT type II % Usage: c=ref_irdftii(f); % % Compute IRDFTII by explicit formulas. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdftii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=ceil(L/2); Lend=Lhalf*2-1; F=zeros(L); F(:,1)=ones(L,1); l=(0:L-1).'; for m=1:Lhalf-1 F(:,2*m)=sqrt(2)*cos(2*pi*m*(l+.5)/L); F(:,2*m+1)=sqrt(2)*sin(2*pi*m*(l+.5)/L); end; if mod(L,2)==0 F(:,L)=cos(pi*l); end; F=F/sqrt(L); % dot-transpose will work because F is real. c=F*f; ltfat/inst/private/ref_pfilt_1.m0000664000175000017500000000254013026262303016561 0ustar susnaksusnakfunction h=ref_pfilt_1(f,g,a) %-*- texinfo -*- %@deftypefn {Function} ref_pfilt_1 %@verbatim %REF_PFILT_1 Reference PFILT implementation by FFT % % This is the old reference pfilt from before the struct filters where % introduced. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_pfilt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [L W]=size(f); g=fir2long(g,L); % Force FFT along dimension 1, since we have permuted the dimensions % manually if isreal(f) && isreal(g) h=ifftreal(fftreal(f,L,1).*repmat(fftreal(g,L,1),1,W),L,1); else h=ifft(fft(f,L,1).*repmat(fft(g,L,1),1,W),L,1); end; h=h(1:a:end,:); ltfat/inst/private/ref_gdgt.m0000664000175000017500000000251413026262303016151 0ustar susnaksusnakfunction c=ref_gdgt(f,g,a,M,c_t,c_f,c_w) %-*- texinfo -*- %@deftypefn {Function} ref_gdgt %@verbatim %REF_GDGT Reference generalized DGT % Usage: c=ref_dgtiv(f,g,a,M,c_t,c_f,c_w); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); N=L/a; F=zeros(L,M*N); l=(0:L-1).'; for n=0:N-1 for m=0:M-1 F(:,M*n+m+1)=exp(2*pi*i*(m+c_f)*(l+c_t)/M).*circshift(g,n*a+c_w); end; end; c=F'*f; ltfat/inst/private/test_wpfbt.m0000664000175000017500000001115313026262303016550 0ustar susnaksusnakfunction test_failed = test_wpfbt(verbose) %-*- texinfo -*- %@deftypefn {Function} test_wpfbt %@verbatim %TEST_WFBTPR % % Checks perfect reconstruction of the general wavelet transform of different % filters % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wpfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('========= TEST WPFBT ============'); global LTFAT_TEST_TYPE; tolerance = 1e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 2e-6; end test_failed = 0; if(nargin>0) verbose = 1; else verbose = 0; end type = {'dec'}; ext = {'per','zero','odd','even'}; format = {'pack','cell'}; J = 3; %! Mild tree wt1 = wfbtinit({'db10',6,'full'}); wt1 = wfbtremove(2,1,wt1,'force'); wt1 = wfbtremove(2,3,wt1,'force'); %! Hardcore tree wt2 = wfbtinit({'db3',1}); wt2 = wfbtput(1,1,'mband1',wt2); wt2 = wfbtput(2,2,'mband1',wt2); wt2 = wfbtput(3,3,'mband1',wt2); wt2 = wfbtput(3,1,'db10',wt2); wt2 = wfbtput(4,1,'dgrid2',wt2); wt2 = wfbtput(5,1,'db3',wt2); %! Another tree wt3 = wfbtinit(); wt3 = wfbtput(0,0,'cmband4',wt3); wt3 = wfbtput(1,0,'cmband6',wt3); wt3 = wfbtput(1,1,'cmband6',wt3); wt3 = wfbtput(2,0,'cmband4',wt3); wt3 = wfbtput(2,1,'cmband4',wt3); wt3 = wfbtput(3,1,'cmband4',wt3); wt3 = wfbtput(3,2,'cmband4',wt3); wt3 = wfbtput(3,3,'cmband4',wt3); wt3 = wfbtput(3,4,'cmband4',wt3); % wt2 = wfbtinit(); % wt2 = wfbtput(0,0,{'db',4},wt2); % wt2 = wfbtput(1,0,{'algmband',1},wt2); % wt2 = wfbtput(1,1,{'hden',3},wt2); % wt2 = wfbtput(2,0,{'dgrid',2},wt2); % wt2 = wfbtput(2,1,{'dgrid',2},wt2); test_filters = { {'algmband2',J} % 4 filters, uniform, crit. sub. {'db4',J} {'algmband1',J} % 3 filters, uniform, crit. sub. %{{'hden',3},J} % 3 filters, non-uniform, no crit. sub. no correct {'dgrid1',J} % 4 filters. sub. fac. 2 wt1 wt2 wt3 }; scaling = {'intscale','intsqrt','intnoscale'}; scalingInv = scaling(end:-1:1); %testLen = 4*2^7-1;%(2^J-1); testLen = 53; f = tester_rand(testLen,1); for scIdx = 1:numel(scaling) for extIdx=1:length(ext) extCur = ext{extIdx}; for typeIdx=1:length(type) for tt=1:length(test_filters) actFilt = test_filters{tt}; if verbose, if(~isstruct(actFilt))fprintf('J=%d, filt=%s, ext=%s, inLen=%d \n',actFilt{2},actFilt{1},extCur,size(f,1)); else disp('Custom'); end; end; [c,info] = wpfbt(f,actFilt,extCur,scaling{scIdx}); fhat = iwpfbt(c,actFilt,size(f,1),extCur,scalingInv{scIdx}); %MSE err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~verbose) if(~isstruct(actFilt))fprintf('J=%d, %5.5s, ext=%4.4s, %s, L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,scaling{scIdx},size(f,1),err,fail); else fprintf('Custom, %s, err=%.4e %s \n',scaling{scIdx},err,fail); end; end if strcmpi(fail,'FAILED') if verbose if(~isstruct(actFilt)) fprintf('err=%d, filt=%s, ext=%s, inLen=%d \n',err,actFilt{1},extCur,testLen); else disp('Custom'); end; figure(1);clf;stem([f,fhat]); figure(2);clf;stem([f-fhat]); break; end end fhat2 = iwpfbt(c,info); err = norm(f-fhat2,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~isstruct(actFilt)) fprintf('INFO J=%d, %5.5s, ext=%4.4s, %s, L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,scaling{scIdx},size(f,1),err,fail); else fprintf('INFO Custom, %s, err=%.4e %s \n',scaling{scIdx},err,fail); end; if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end end ltfat/inst/private/test_frft.m0000664000175000017500000000412713026262303016372 0ustar susnaksusnakfunction test_failed=test_frft disp(' =============== TEST_FRFT ==========='); Lr=[9,10,11,12]; test_failed=0; %-*- texinfo -*- %@deftypefn {Function} test_frft %@verbatim % Test the hermite functions and discrete frft %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_frft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . for ii=1:length(Lr) L=Lr(ii); F=fft(eye(L))/sqrt(L); % check if hermite functions are eigenfunctions of F V=hermbasis(L,4); res=norm(abs(F*V)-abs(V)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=fprintf('HERMBASIS L:%3i %0.5g %s\n',L,res,fail); % Frft of order 1 becomes ordinary DFT f1=tester_crand(L,1); f2=tester_crand(1,L); p=4; frf1=dfracft(f1,1,[],p); frf2=dfracft(f2,1,2,p); res=norm(F*f1-frf1); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=fprintf('DFRACFT L:%3i, %0.5g %s\n',L,res,fail); res=norm(f2*F-frf2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=fprintf('DFRACFT L:%3i, %0.5g %s\n',L,res,fail); frf1=dfracft(f1,1); frf2=dfracft(f2,1,2); res=norm(F*f1-frf1); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=fprintf('DFRACFT L:%3i %0.5g %s\n',L,res,fail); res=norm(f2*F-frf2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=fprintf('DFRACFT L:%3i %0.5g %s\n',L,res,fail); end ltfat/inst/private/test_dtwfb.m0000664000175000017500000001271013026262303016534 0ustar susnaksusnakfunction test_failed = test_dtwfb() test_failed = 0; disp('========= TEST DTWFB ============'); global LTFAT_TEST_TYPE; tolerance = 2e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 1e-5; end Larray = [603]; Warray = [1,3]; dualwt{1} = {'qshift1',1}; dualwt{2} = {'qshift3',5,'first','symorth1'}; dualwt{3} = {{'qshift3',5,'full','first','ana:symorth3','leaf','db4'},... {'qshift3',5,'full','first','syn:symorth3','leaf','db4'}}; dualwt{4} = {{'ana:oddeven1',5},{'syn:oddeven1',5}}; dualwt{5} = {'qshift3',3,'first','db4'}; dualwt{6} = {{'syn:oddeven1',2,'doubleband'},{'ana:oddeven1',2,'doubleband'}}; dualwt{7} = {dtwfbinit({'syn:oddeven1',2,'doubleband'}),dtwfbinit({'ana:oddeven1',2,'doubleband'})}; dualwt{8} = {{'dual',{'syn:oddeven1',2,'doubleband'}},{'syn:oddeven1',2,'doubleband'}}; dualwt{9} = {dtwfbinit({'syn:oddeven1',3,'full'},'nat'),dtwfbinit({'ana:oddeven1',3,'full'},'nat')}; dualwt{10} = {'dden2',3}; dualwt{11} = {'optsym3',3}; tolerance = ones(numel(dualwt),1)*tolerance; %-*- texinfo -*- %@deftypefn {Function} test_dtwfb %@verbatim % decrease the tolerance for oddeven filters %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dtwfb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . tolerance([4,6,7,8,9]) = 1e-5; % Perfect reconstruction for ii = 1:numel(dualwt) if isempty(dualwt{ii}) continue; end if iscell(dualwt{ii}{1}) || isstruct(dualwt{ii}{1}) && numel(dualwt{ii})==2 dualwtana = dualwt{ii}{1}; dualwtsyn = dualwt{ii}{2}; else dualwtana = dualwt{ii}; dualwtsyn = dualwtana; end for cmplx = {'real','complex'} for order = {'freq','nat'} for L = Larray for W = Warray if strcmp(cmplx{1},'real') f = tester_rand(L,W); else f = tester_crand(L,W); end if strcmp(cmplx{1},'real') [c,info] = dtwfbreal(f,dualwtana,order{1}); fhat1 = idtwfbreal(c,dualwtsyn,L,order{1}); fhat2 = idtwfbreal(c,info); res = norm(f-fhat1); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC %i L:%i W:%i %s %s %0.5g %s'],ii,L,W,cmplx{1},order{1}, res,fail); disp(s) res = norm(f-fhat2); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC INFO %i L:%i W:%i %s %s %0.5g %s'],ii,L,W,cmplx{1},order{1}, res,fail); disp(s) end [c,info] = dtwfb(f,dualwtana,order{1}); fhat1 = idtwfb(c,dualwtsyn,L,order{1}); fhat2 = idtwfb(c,info); res = norm(f-fhat1); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC %i L:%i W:%i %s %s %0.5g %s'],ii,L,W,cmplx{1},order{1}, res,fail); disp(s) res = norm(f-fhat2); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance(ii)); s=sprintf(['DUAL-TREE REC INFO %i L:%i W:%i %s %s %0.5g %s'],ii,L,W,cmplx{1},order{1}, res,fail); disp(s) if strcmp(order{1},'freq') cnat = dtwfb(f,dualwtana,'nat'); % Is there a subband in c with exactly the same % coefficients? for cnatId=1:numel(cnat) for cId=1:numel(c) if numel(c{cId}) == numel(cnat{cnatId}) res = norm(c{cId}-cnat{cnatId}); if res<1e-10 break; end end end if any(res)<1e-10 continue; else [test_failed,fail]=ltfatdiditfail(1,test_failed); s=sprintf(['DUAL-TREE FREQ NAT %i L:%i W:%i %s %s %s'],ii,L,W,cmplx{1},order{1}, fail); disp(s) break; end end end end end end end end % Nat vs. freq (Are te actual subbands equal?) ltfat/inst/private/ref_dwiltiii.m0000664000175000017500000000375213026262303017047 0ustar susnaksusnakfunction c=ref_dwiltiii(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwiltiii %@verbatim %REF_DWILTIII Reference DWILT type III % Usage: c=ref_dwiltiii(f,g,a,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwiltiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Possibly zero-extend the window if necessary. g=fir2long(g,L); N=L/a; F=zeros(L,M*N); l=(0:L-1)'; pif=pi/4; if 0 % This is the definition where the odd and even indices are split for n=0:floor(N/2)-1 for m=0:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*pi*l/M+pif); F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*sin((m+.5)*pi*l/M+pif); end; for m=1:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*sin((m+.5)*pi*l/M+pif); F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*cos((m+.5)*pi*l/M+pif); end; end; else % Combined definition % This is the definition where the odd and even indices are split for n=0:N-1 for m=0:M-1 if rem(m+n,2)==0 F(:,1+m+n*M)=sqrt(2)*circshift(g,n*a).*cos((m+.5)*pi*l/M+1/4*pi+(m+n)*pi); else F(:,1+m+n*M)=sqrt(2)*circshift(g,n*a).*cos((m+.5)*pi*l/M+3/4*pi+(m+n)*pi); end; end; end; end; c=F.'*f; ltfat/inst/private/test_firwin.m0000664000175000017500000000502413026262303016724 0ustar susnaksusnakfunction test_failed=test_firwin %-*- texinfo -*- %@deftypefn {Function} test_firwin %@verbatim %TEST_FIRWIN Test the firwin windows % % This test script verifies the properties listed in the help of firwin %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_firwin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . allwins = getfield(arg_firwin,'flags','wintype'); test_failed=0; disp(' =============== TEST_FIRWIN ================'); for L=[18,19,20,21] for cent=0:1 if cent==0 centtype='wp'; else centtype='hp'; end; for ii=1:length(allwins); winname=allwins{ii}; [g,info]=firwin(winname,L,centtype); res = 1-isevenfunction(fir2long(g,2*L),centtype); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['SYMM %10s %s L: %i %0.5g %s'],winname,centtype,L,res,fail); disp(s); if cent==0 res=1-g(1); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['PEAK %10s %s L: %i %0.5g %s'],winname,centtype,L,res,fail); disp(s); end; if mod(L,2)==0 if info.ispu gpu=g+fftshift(g); res=norm(gpu-gpu(1)*ones(L,1)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['PU %10s %s L: %i %0.5g %s'],winname,centtype,L,res,fail); disp(s); end; if info.issqpu gpu=g.^2+fftshift(g.^2); res=norm(gpu-gpu(1)*ones(L,1)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['SQPU %10s %s L: %i %0.5g %s'],winname,centtype,L,res,fail); disp(s); end; end; end; end; end; ltfat/inst/private/test_dgt_fb_alg.m0000664000175000017500000000443213026262303017500 0ustar susnaksusnakfunction test_failed=test_dgt_fb %-*- texinfo -*- %@deftypefn {Function} test_dgt_fb_alg %@verbatim %TEST_DGT_FB Test the filter bank algorithms in DGT % % This script runs a throrough test of the DGT routine, % testing it on a range of input parameters. % % The script test the filter bank algorithms in DGT, IDGT, GABDUAL and % GABTIGHT by comparing with the full window case. % % The computational backend is tested this way, but the % interfaces is not. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt_fb_alg.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr = [24, 35, 35, 24,144,108,144,135,77,77]; ar = [ 6, 5, 5, 4, 9, 9, 12, 9, 7, 7]; Mr = [ 8, 7, 7, 6, 16, 12, 24, 9,11,11]; glr = [16, 14, 21, 12, 48, 12, 24, 18,22,11]; test_failed=0; disp(' =============== TEST_DGT_FB_ALG ================'); disp('--- Used subroutines ---'); for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); gl=glr(ii); b=L/M; N=L/a; for rtype=1:2 if rtype==1 rname='REAL '; g=tester_rand(gl,1); else rname='CMPLX'; g=tester_crand(gl,1); end; if rtype==1 rname='REAL '; f=tester_rand(L,1); else rname='CMPLX'; f=tester_crand(L,1); end; cc = dgt(f,fir2long(g,L),a,M); cc_ref = ref_dgt_6(f,g,a,M); cdiff=cc-cc_ref; res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF %s L:%3i a:%3i M:%3i gl:%3i %0.5g %s',rname,L,a,M,gl,res,fail); disp(s) end; end; ltfat/inst/private/test_involute.m0000664000175000017500000000242513026262303017275 0ustar susnaksusnakfunction test_failed=test_involute Lr=[9,10]; test_failed=0; disp(' =============== TEST_INVOLUTE ==========='); for ii=1:length(Lr) L=Lr(ii); f=tester_crand(L,1); r1=conj(dft(f)); r2=dft(involute(f)); res=norm(r1-r2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('INVOLUTE L:%3i %0.5g %s',L,res,fail); disp(s); end; %-*- texinfo -*- %@deftypefn {Function} test_involute %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_involute.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_dctiii_2.m0000664000175000017500000000272313026262303016714 0ustar susnaksusnakfunction c=ref_dctiii_2(f) %-*- texinfo -*- %@deftypefn {Function} ref_dctiii_2 %@verbatim %DCTII Reference Discrete Consine Transform type III % Usage: c=ref_dctiii_2(f); % % The transform is real (only works for real input data) and % it is orthonormal. % % The transform is computed as the exact inverse of DCTII, i.e. all % steps in the DCTII are reversed in order of computation. % % NOT WORKING %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dctiii_2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); 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 R(1,1)=1; c=real(R'*fft([f;flipud(f)])/sqrt(L)/2); ltfat/inst/private/ref_spreadfun.m0000664000175000017500000000265213026262303017216 0ustar susnaksusnakfunction coef=ref_spreadfun(T) %-*- texinfo -*- %@deftypefn {Function} ref_spreadfun %@verbatim %REF_SPREADFUN Spreading function. % Usage: c=ref_spreadfun(T); % % REF_SPREADFUN(T) computes the spreading function of the operator T. 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. % % SEE ALSO: SPREADOP, TCONV, SPREADINV, SPREADADJ %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_spreadfun.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(T,1); coef=zeros(L); for ii=0:L-1 for jj=0:L-1 coef(ii+1,jj+1)=T(ii+1,mod(ii-jj,L)+1); end; end; coef=fft(coef)/L; ltfat/inst/private/ref_dwiltiv.m0000664000175000017500000000273213026262303016710 0ustar susnaksusnakfunction c=ref_dwiltiv(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwiltiv %@verbatim %REF_DWILTIV Reference DWILT type iv % Usage: c=ref_dwiltiv(f,g,a,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwiltiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; F=zeros(L,M*N); k=(0:L-1)'; pif=pi/4; for n=0:floor(N/2)-1 for m=0:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*pi*(k+.5)/M+pif); F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*sin((m+.5)*pi*(k+.5)/M+pif); end; for m=1:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*sin((m+.5)*pi*(k+.5)/M+pif); F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*cos((m+.5)*pi*(k+.5)/M+pif); end; end; c=F.'*f; ltfat/inst/private/test_chirpzt.m0000664000175000017500000000422313026262303017111 0ustar susnaksusnakfunction test_failed=test_chirpzt disp(' =============== TEST_CHIRPZT ================'); test_failed=0; %-*- texinfo -*- %@deftypefn {Function} test_chirpzt %@verbatim % Goertzel algorithm has a bad precision for larger L. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_chirpzt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE; tolerance = 2e-10; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 2e-4; end L = 36; W = 17; f=tester_crand(L,W); res = norm(fft(cast(f,'double'))-chirpzt(f,L)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1 cols: L:%3i, W:%3i %s\n',L,W,fail); res = norm(fft(cast(f,'double'),[],2)-chirpzt(f,[],[],[],[],2)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1 rows: L:%3i, W:%3i %s\n',L,W,fail); res = norm(fft(cast(f,'double'),2*L)-chirpzt(f,2*L,0.5/L)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1/2 cols: L:%3i, W:%3i %s\n',L,W,fail); res = norm(fft(cast(f,'double'),5*L)-chirpzt(f,5*L,0.2/L)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1/5 cols: L:%3i, W:%3i %s\n',L,W,fail); offset = 10; c = chirpzt(f,5*L-offset,0.2/L,offset*0.2/L); cfft = fft(cast(f,'double'),5*L); res = norm(cfft(offset+1:end,:)-c); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); fprintf('RES 1/5, offset, cols: L:%3i, W:%3i %s\n',L,W,fail); ltfat/inst/private/ref_dcti_1.m0000664000175000017500000000227213026262303016370 0ustar susnaksusnakfunction c=ref_dcti_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dcti_1 %@verbatim %REF_DCTI_1 Reference Discrete Consine Transform type I % Usage: c=ref_dcti_1(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dcti_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if L==1 c=f; return; end; R=1/sqrt(2)*[eye(L);... [zeros(L-2,1),flipud(eye(L-2)),zeros(L-2,1)]]; R(1,1)=1; R(L,L)=1; c=R'*dft(R*f); ltfat/inst/private/test_pebfun.m0000664000175000017500000001244013026262303016705 0ustar susnaksusnakfunction test_failed = test_pebfun test_failed = 0; %-*- texinfo -*- %@deftypefn {Function} test_pebfun %@verbatim % First, just test if functions run with various input parameters %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pebfun.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . M = 10; a = 8; L = 120; incrange = 0:4:80; g = pebfun(L,[1,-1]); g = pebfun(L,[1,-1,9]); %g = ptpfun(L,[1,-1,9],'inf'); gd = pebfundual([1,-1],a,M,L); gd = pebfundual([1,-1],a,M,L,10); gd = pebfundual({[1,-1],10},a,M,L); gd = pebfundual({[1,-1],5},a,M,L,10); % % [gd,nlen] = ptpfundual([1,-1],a,M,L,'inf'); % % [gd,nlen] = ptpfundual([1,-1],a,M,L,'inf','matchscale'); % This should fail, but be caught by some of the input checks. % We will test if the error message starts with function name in allcaps % followed by a colon e.g. PTPFUN: % Too short w try g = pebfun(L,[1]); gd = pebfundual([1],a,M,L); % We should have failed in g test_failed = test_failed + 1; failstr = 'FAILED'; catch err = lasterror; [test_failed,failstr]=dititfailedcorrectly(err.message,'pebfun',test_failed); end fprintf('PEBFUN Too short w test %s\n',failstr); % This has been dealt with % % Only pos weights % try % g = ptpfun(L,[1,1]); % gd = ptpfundual(L,[1,1],a,M); % % We should have failed in g % test_failed = test_failed + 1; % failstr = 'FAILED'; % catch % err = lasterror; % [test_failed,failstr]=dititfailedcorrectly(err.message,'ptpfun',test_failed); % end % fprintf('PTPFUN Only positive w test %s\n',failstr); % % % Only neg weights % try % g = ptpfun(L,[-1,-1]); % gd = ptpfundual(L,[-1,-1],a,M); % % We should have failed in g % test_failed = test_failed + 1; % failstr = 'FAILED'; % catch % err = lasterror; % [test_failed,failstr]=dititfailedcorrectly(err.message,'ptpfun',test_failed); % end % fprintf('PTPFUN Only negative w test %s\n',failstr); % One zero in weights try g = pebfun(L,[-1,0,1]); gd = pebfundual([-1,0,1],a,M,L); % We should have failed in g test_failed = test_failed + 1; failstr = 'FAILED'; catch err = lasterror; [test_failed,failstr]=dititfailedcorrectly(err.message,'pebfun',test_failed); end fprintf('PEBFUN Zero in w test %s\n',failstr); % Test if ptpfun and ptpfundual indeed fulfill the Waxler-Raz conditions % (are dual windoes up to scaling) for a range of inc parameter wcell = {[-1,1],[1,-1,3,4],[-1,-1],[1,1]}; for w = wcell for inc =incrange g = pebfun(L,w{1}); gd = pebfundual(w{1},a,M,L); [~,err] = gabdualnorm(g,gd,a,M,L); [test_failed,fail]=ltfatdiditfail(err,test_failed); fprintf('PEBFUN IS DUAL L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); end end % Test ptpfun and ptpfundual individually (each uses canonical dual window) f = tester_crand(L,1); for w = wcell g = pebfun(L,w{1}); c = dgt(f,g,a,M); fhat = idgt(c,{'dual',g},a); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('PEBFUN REC L=%i,a=%i,M=%i, %s\n',L,a,M,fail); end for w = wcell g = pebfundual(w{1},a,M,L); c = dgt(f,g,a,M); fhat = idgt(c,{'dual',g},a); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('PEBFUNDUAL REC L=%i,a=%i,M=%i, %s\n',L,a,M,fail); end % Test ptpfun and ptpfundual properly scaled for w = wcell for inc =incrange g = pebfun(L,w{1}); gd = pebfundual(w{1},a,M,L,inc); c = dgt(f,g,a,M); fhat = idgt(c,gd,a); res = norm(f-fhat); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('PEBFUN PEBFUNDUAL REC L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); end end % Disabled for now % for w = wcell % for inc =incrange % g = ptpfun(L,w{1},'inf'); % gd = ptpfundual(w{1},a,M,L,inc,'matchscale','inf'); % c = dgt(f,g,a,M); % fhat = idgt(c,gd,a); % res = norm(f-fhat); % [test_failed,fail]=ltfatdiditfail(res,test_failed); % fprintf('PTPFUN PTPFUNDUAL REC PEAK L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); % end % end % % % Test using FIR duals % wcell = {[-0.5,0.5]}; % for w = wcell % for inc =incrange % g = ptpfun(L,w{1}); % [gd,nlen] = ptpfundual(w{1},a,M,L,inc,'matchscale'); % c = dgt(f,g,a,M); % fhat = idgt(c,middlepad(gd,nlen),a); % res = norm(f-fhat); % [test_failed,fail]=ltfatdiditfail(res,test_failed); % fprintf('PTPFUN PTPFUNDUAL REC FIR L=%i,a=%i,M=%i, inc=%i %s\n',L,a,M,inc,fail); % end % end function [test_failed,failstr]=dititfailedcorrectly(errmsg,fname,test_failed) if isempty(strfind(errmsg,strcat(upper(fname),':'))) test_failed = test_failed + 1; failstr = 'FAILED'; else failstr = ''; end ltfat/inst/private/ref_ifac.m0000664000175000017500000000253413026262303016130 0ustar susnaksusnakfunction f=ref_ifac(ff,W,c,d,p,q,permutation); %-*- texinfo -*- %@deftypefn {Function} ref_ifac %@verbatim %REF_IFAC Reference inverse factorization. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_ifac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Output array f=zeros(c*d*p*q,W); work=zeros(p*q*d,W); if d>1 for ko=0:c-1 work(:) = ifft(reshape(ff(:,1+ko*d:(ko+1)*d),q*W*p,d).'); % Permute again. f(permutation+ko,:)=work; end; else for ko=0:c-1 % Multiply work(:)=ff(:,ko+1); % Permute again. f(permutation+ko,:)=work; end; end; ltfat/inst/private/ref_zak.m0000664000175000017500000000257113026262303016014 0ustar susnaksusnakfunction coef=ref_zak(f,K) %-*- texinfo -*- %@deftypefn {Function} ref_zak %@verbatim %REF_ZAK Reference Zak-transform. % Usage: c=ref_zak(f,K); % % This function computes a reference Zak-transform by % an explicit summation. % % It returns the coefficients in the rectangular layout. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_zak.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); % Slow, explicit method % Workspace coef=zeros(K,L/K); for jj=0:K-1 for kk=0:L/K-1 for ll=0:L/K-1 coef(jj+1,kk+1)=coef(jj+1,kk+1)+f(mod(jj-ll*K,L)+1)*exp(2*pi*i*kk*ll*K/L); end; end; end; coef=coef*sqrt(K/L); ltfat/inst/private/test_audfilters.m0000664000175000017500000000706113026262303017573 0ustar susnaksusnakfunction test_failed=test_audfilters() %-*- texinfo -*- %@deftypefn {Function} test_audfilters %@verbatim % Testing script for audfilters %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_audfilters.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; [f,fs]=greasy; % Get the test signal Ls=length(f); %% Generate a fractional ERBlet FB with V= 1 and a Hann window disp('--- Fractional non-uniform ERBlet FB, V=1, Hann window ---') [g_erb,a_erb,fc_erb]=audfilters(fs,Ls,'erb','fractional'); c_erb=filterbank(f,{'realdual',g_erb},a_erb); r_erb=2*real(ifilterbank(c_erb,g_erb,a_erb)); disp('Reconstruction error:') norm(f-r_erb) % Plot the FB response figure(1); R1=filterbankresponse(g_erb,a_erb,Ls,fs,'real','plot'); title('ERBlet FB response') ylabel('Magnitude'); % Plot frequency responses of individual filters gd_erb=filterbankrealdual(g_erb,a_erb,Ls); figure(2); subplot(2,1,1); filterbankfreqz(g_erb,a_erb,Ls,fs,'plot','linabs','posfreq'); title('ERBlet analysis filters') subplot(2,1,2); filterbankfreqz(gd_erb,a_erb,Ls,fs,'plot','linabs','posfreq'); title('Synthesis, dual filters') %% Generate a fractional uniform Barklet FB with V= 3 and a cosine window, band-limited analysis disp('--- Uniform Barklet FB, V=3, cosine window, frequency range = 100-6000 Hz ---') [g_bark,a_bark,fc_bark]=audfilters(fs,Ls,'fmin',100,'fmax',6000,'bark','fractionaluniform','spacing',1/3,'cosine'); c_bark=filterbank(f,{'realdual',g_bark},a_bark); r_bark=2*real(ifilterbank(c_bark,g_bark,a_bark)); disp('Reconstruction error:') norm(f-r_bark) % Plot the FB response figure(3); R2=filterbankresponse(g_bark,a_bark,Ls,fs,'real','plot'); title('Barklet FB response') ylabel('Magnitude'); % Plot frequency responses of individual filters gd_bark=filterbankrealdual(g_bark,a_bark,Ls); figure(4); subplot(2,1,1); filterbankfreqz(g_bark,a_bark,Ls,fs,'plot','linabs','posfreq'); title('Barklet analysis filters') subplot(2,1,2); filterbankfreqz(gd_bark,a_bark,Ls,fs,'plot','linabs','posfreq'); title('Synthesis, dual filters') %% Generate a uniform Mel FB with 30 filters and a triangular window disp('--- Uniform Mel FB, M=30, triangular window ---') [g_mel,a_mel,fc_mel,L_mel]=audfilters(fs,Ls,'mel','uniform','M',30,'tria'); if L_mel > Ls f = postpad(f,L_mel); end c_mel=filterbank(f,{'realdual',g_mel},a_mel); r_mel=2*real(ifilterbank(c_mel,g_mel,a_mel)); disp('Reconstruction error:') norm(f-r_mel) % Plot the FB response figure(5); R3=filterbankresponse(g_mel,a_mel,Ls,fs,'real','plot'); title('Mel FB response') ylabel('Magnitude'); % Plot frequency responses of individual filters gd_mel=filterbankrealdual(g_mel,a_mel,L_mel); figure(6); subplot(2,1,1); filterbankfreqz(g_mel,a_mel,Ls,fs,'plot','linabs','posfreq'); title('Mel analysis filters') subplot(2,1,2); filterbankfreqz(gd_mel,a_mel,L_mel,fs,'plot','linabs','posfreq'); title('Synthesis, dual filters') ltfat/inst/private/test_drihaczekdist.m0000664000175000017500000000274013026262303020260 0ustar susnaksusnakfunction test_failed = test_drihaczekdist Lr = [1, 19, 20]; test_failed = 0; disp(' =============== TEST_DRIHACZEKDIST =============='); for ii = 1: length(Lr) L = Lr(ii); for type = {'real', 'complex'} if strcmp(type{1}, 'real') f = tester_rand(L,1); else f = tester_crand(L,1); end r1 = ref_drihaczekdist(f); r2 = drihaczekdist(f); res = norm(r1-r2); [test_failed, fail] = ltfatdiditfail(res, test_failed); s = sprintf('DRIHACZEKDIST %3s L:%3i %0.5g %s', type{1}, L, res, fail); disp(s); end end %-*- texinfo -*- %@deftypefn {Function} test_drihaczekdist %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_drihaczekdist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_ola.m0000664000175000017500000000220213026262303016174 0ustar susnaksusnak L=24; Lg=4; Lb=8; f=randn(L,1); g=randn(Lg,1); ref1=pconv(f,postpad(g,L)); ola1=ref_pconv_ola_postpad(f,g,Lb); norm(ref1-ola1) ref2=pconv(f,fir2long(g,L)); ola2=ref_pconv_ola_fir2long(f,g,Lb); norm(ref2-ola2) [ref2,ola2,ref2-ola2] %-*- texinfo -*- %@deftypefn {Function} test_ola %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_ola.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_blockfwt.m0000664000175000017500000000475313026262303017251 0ustar susnaksusnakfunction test_failed = test_blockfwt() test_failed = 0; disp('-------------TEST_BLOCKFWT--------------'); L = 567; W = [1,3]; Lb = [78,64,58,1021]; wa = {'dden3','ana:symorth1'}; ws = {'dden3','syn:symorth1'}; J = [5]; for wId = 1:numel(W) for lId = 1:numel(L) f = tester_rand(L(lId),W(wId)); for lbId = 1:numel(Lb) for waId=1:numel(wa) Fa = blockframeaccel(frame('fwt',wa{waId},J),Lb(lbId),'segola'); Fs = blockframeaccel(frame('fwt',ws{waId},J),Lb(lbId),'segola'); a = Fa.g.a(1); m = numel(Fa.g.g{1}.h); rmax = (a^J-1)/(a-1)*(m-1); f = postpad(f,L(lId)+rmax); block(f,'offline','L',Lb(lbId)); colC = {}; colfhat = {}; for ii=1:ceil(L(lId)/Lb(lbId)) fb = blockread(); c = blockana(Fa,fb); ccell = comp_fwtpack2cell(Fa,c); colC{end+1} = ccell; chat = cell2mat(ccell); fhat = blocksyn(Fs,chat,size(fb,1)); colfhat{end+1} = fhat; end err = 0; cwhole = fwt(f,wa{waId},J,'zero','cell'); for ii=1:numel(colC{1}) cc{ii} = cell2mat(cellfun(@(cEl) cEl{ii},colC','UniformOutput',0)); Ltmp = min([size(cwhole{ii},1),size(cc{ii},1)]); err = err + norm(cwhole{ii}(1:Ltmp,:)-cc{ii}(1:Ltmp,:)); end [test_failed,fail]=ltfatdiditfail(err,test_failed); fprintf('COEFS L:%3i, W:%3i, Lb=%3i, %s, err=%.4e %s\n',L(lId),W(wId),Lb(lbId),wa{waId},err,fail); fhat = cell2mat(colfhat.'); fhat = fhat(rmax+1:end,:); Lcrop = min([size(fhat,1),size(f,1)]); res = norm([f(1:Lcrop,:)-fhat(1:Lcrop,:)]); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('REC L:%3i, W:%3i, Lb=%3i, %s, err=%.4e %s\n',L(lId),W(wId),Lb(lbId),wa{waId},res,fail); end end end end %-*- texinfo -*- %@deftypefn {Function} test_blockfwt %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_blockfwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_tgabdual.m0000664000175000017500000000221213026262303017002 0ustar susnaksusnakfunction gd=ref_tgabdual(ttype,g,L,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_tgabdual %@verbatim %REF_WIN Compute appropriate dual window for transform % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_tgabdual.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<5 error('Too few input parameters.'); end; info=ref_transforminfo(ttype,L,a,M); gd=info.winscale*gabdual(g,info.a,info.M); ltfat/inst/private/ref_iedgtii_1.m0000664000175000017500000000276713026262303017074 0ustar susnaksusnakfunction f=ref_iedgtii_1(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_iedgtii_1 %@verbatim %REF_EDGTII_1 Reference Inverse Even DGT type II by DGT % Usage c=ref_edgt(f,g,a,M); % % The input window must be odd-centered of length 2L. % % a must be divisable by 2. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_iedgtii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1)/2; W=size(c,2); N=L/a; clong=zeros(M,2*N,W); cr=reshape(c,M,N,W); % Copy the first half unchanged clong(:,1:N,:)=cr; % Copy the non modulated coefficients. clong(1,N+1:2*N,:)=cr(1,N:-1:1,:); % Copy the modulated coefficients. clong(2:M,N+1:2*N,:)=-cr(M:-1:2,N:-1:1,:); clong=reshape(clong,2*M*N,W); fdouble=ref_igdgt(clong,g,a,M,.5,0,floor(a/2)); f=fdouble(1:L,:); ltfat/inst/private/ref_adaptlasso.m0000664000175000017500000000611713026262303017362 0ustar susnaksusnakfunction [xo,N]=ref_adaptlasso(ttype,xi,lambda,group); %-*- texinfo -*- %@deftypefn {Function} ref_adaptlasso %@verbatim %TF_ADAPTLASSO adaptive lasso estimate (hard/soft) in time-frequency domain % Usage: xo=tf_adaptlasso(ttype,x,lambda,group); % [xo,N]=tf_grouplasso(ttype,x,lambda,group)); % % TF_ADAPTLASSO('hard',x,lambda,'time') will perform % time hard adaptive thresholding on x, i.e. coefficients % below a column dependent threshold are set to zero. The % threshold is computed from the l-1 norm of its % time-frequency column. % % TF_ADAPTLASSO('soft',x,lambda,'time') will perform % time soft adaptive thresholding on x, i.e. all coefficients % below a column dependent threshold are set to zero. % The threshold value is substracted from coefficients above % the threshold % % TF_ADAPTLASSO(ttype,x,lambda,'frequency') will perform % frequency adaptive thresholding on x, i.e. coefficients % below a row dependent threshold are set to zero. The % threshold is computed from the l-1 norm of its % time-frequency row. % % [xo,N]=TF_ADAPTLASSO(ttype,x,lambda,group) additionally returns % a number N specifying how many numbers where kept. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_adaptlasso.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . error(nargchk(4,4,nargin)); group=lower(group); ttype=lower(ttype); tmp = size(xi); NbFreqBands = tmp(1); NbTimeSteps = tmp(2); xo = zeros(size(xi)); if (strcmp(group,'time')), for t=1:NbTimeSteps, threshold = norm(xi(:,t),1); threshold = lambda*threshold /(1+NbFreqBands*lambda); mask = abs(xi(:,t)) >= threshold; if(strcmp(ttype,'soft')) xo(mask,t) = sign(xi(mask,t)) .* (abs(xi(mask,t))-threshold); elseif(strcmp(ttype,'hard')) xo(mask,t) = sign(xi(mask,t)) .* abs(xi(mask,t)); end end elseif (strcmp(group,'frequency')), for f=1:NbFreqBands, threshold = norm(xi(f,:),1); threshold = lambda*threshold /(1+NbTimeSteps*lambda); mask = abs(xi(f,:)) >= threshold; if(strcmp(ttype,'soft')) xo(f,mask) = sign(xi(f,mask)) .* (abs(xi(f,mask))-threshold); elseif(strcmp(ttype,'hard')) xo(f,mask) = sign(xi(f,mask)) .* abs(xi(f,mask)); end end end if nargout==2 signif_map = (abs(xo)>0); N = sum(signif_map(:)); end ltfat/inst/private/ref_ufilterbank.m0000664000175000017500000000226513026262303017535 0ustar susnaksusnakfunction c=ref_ufilterbank(f,g,a); %-*- texinfo -*- %@deftypefn {Function} ref_ufilterbank %@verbatim %REF_UFILTERBANK Uniform filterbank by pconv % Usage: c=ref_ufilterbank(f,g,a); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_ufilterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [L,W]=size(f); N=L/a; M=numel(g); c=zeros(N,M,W,assert_classname(f)); for w=1:W for m=1:M c(:,m,w)=pfilt(f(:,w),g{m},a); end; end; ltfat/inst/private/ref_dsti_1.m0000664000175000017500000000236013026262303016406 0ustar susnaksusnakfunction c=ref_dsti_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dsti_1 %@verbatim %REF_DSTI_1 Reference Discrete Sine Transform type I % Usage: c=ref_dsti_1(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dsti_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if L==1 c=f; return; end; R=1/sqrt(2)*[zeros(1,L,assert_classname(f));... eye(L); zeros(1,L,assert_classname(f));... -flipud(cast(eye(L),assert_classname(f)))]; c=i*R'*dft(R*f); ltfat/inst/private/test_gabphasederivinterface.m0000664000175000017500000000540113026262303022112 0ustar susnaksusnakfunction test_falied = test_gabphasederivinterface test_failed = 0; %-*- texinfo -*- %@deftypefn {Function} test_gabphasederivinterface %@verbatim %Test whether the batch interface does the same thing as indivisual calls %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabphasederivinterface.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % TODO: test also wrong number of input arguments disp('---------------test_gabphasederivinterface---------------------'); f = tester_rand(128,1); a = 4; M = 8; g = 'gauss'; c = dgt(f,g,a,M); algCell = {'dgt','abs','phase','cross'}; algArgs = {{'dgt',f,g,a,M} {'abs',abs(c),g,a} {'phase',angle(c),a} {'cross',f,g,a,M} }; phaseconvCell = {'freqinv','timeinv','symphase','relative'}; dtypecombCell = { {'t','t'},... {'t','f'},... {'f','t'},... {'t','f','t'},... {'tt','t'},... {'ff','f'},... {'tf','f'},... {'tf','f','tt'},... {'tf','f','tt','tf'},... {'t','f','tt','ff','ft','tf'},... {'t','f','t','ff','tt','tt','tt'},... }; for algId=1:numel(algArgs) alg = algArgs{algId}; for dtypecombId=1:numel(dtypecombCell) dtypecomb = dtypecombCell{dtypecombId}; for phaseconvId=1:numel(phaseconvCell) phaseconv=phaseconvCell{phaseconvId}; individual = cell(1,numel(dtypecomb)); for dtypecompId = 1:numel(dtypecomb) individual{dtypecompId} = ... gabphasederiv(dtypecomb{dtypecompId},alg{:},phaseconv); end batch = gabphasederiv(dtypecomb,alg{:},phaseconv); res = sum(cellfun(@(iEl,bEl) norm(iEl(:)-bEl(:)),individual,batch))/numel(batch); [test_failed,failstring]=ltfatdiditfail( res,... test_failed,1e-8); flagcompString = sprintf('%s, ',dtypecomb{:}); fprintf('GABPHASEDERIV BATCH EQ alg:%s order:{%s} phaseconv:%s %d %s\n',alg{1},flagcompString(1:end-2),phaseconv,res,failstring); end end end ltfat/inst/private/test_fbreassign.m0000664000175000017500000001002513026262303017546 0ustar susnaksusnakfunction test_failed = test_fbreassign(varargin) test_failed = 0; try do_time = any(strcmp('time',varargin)); do_all = any(strcmp('all',varargin)); L = 44100; %-*- texinfo -*- %@deftypefn {Function} test_fbreassign %@verbatim %f = exp(2*pi*1i*((0:44099)/168))'; %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_fbreassign.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . f = sin(2*pi*((0:44099)/35+((0:44099)/300).^2)) + ... sin(2*pi*((0:44099)/10+((0:44099)/300).^2)) + ... sin(2*pi*((0:44099)/5-((0:44099)/450).^2)); f = 0.7*f'; %f=gspi; %f = zeros(L,1); %f(10000) = 1; % wavwrite(f,44100,16,'testclean.wav'); % f = gspi; % f = f(44101:88200); % fn = rand(44100,1)-.5; % fn = fn/norm(fn)*norm(f); % f = f+fn; % wavwrite(f,44100,16,'testnoisy.wav'); % f = gspi; % f = f(44101:88200); fs = 44100; [g,a,fc,L]=erbfilters(fs,44100,'fractional','spacing',1/12,'warped','complex'); if length(a) < length(g) a = [a;a(end-1:-1:2,:)]; end if do_time, tic; end [tgrad,fgrad,cs0,c]=filterbankphasegrad(f,g,a); if do_time, PGtime = toc; fprintf('PGtime=%d\n',PGtime); end if do_time, tic; end fc = cent_freqs(fs,fc); if do_time, CFtime = toc; fprintf('CFtime=%d\n',CFtime); end if do_time, tic; end [sr0,arg1,arg2]=filterbankreassign(cs0,tgrad,fgrad,a,fc); if do_time, RAtime = toc; fprintf('RAtime=%d\n',RAtime); end figure(1); clf; subplot(211); plotfilterbank(cs0,a,'fc',fs/2*fc,'db','dynrange',60); title('ERBlet spectrogram of 3 chirps'); subplot(212); plotfilterbank(sr0,a,'fc',fs/2*fc,'db','dynrange',60); title('Reassigned ERBlet spectrogram of 3 chirps'); colormap(flipud(gray)); %% clear g g2 g3 Lg = 28; a0 = 8*ones(168,1); cfreq0 = [0:84,-83:-1].'/84; gg = fftshift(firwin('hann',Lg)); for kk = 0:167 g{kk+1}.h = gg; g{kk+1}.fc = modcent(kk/84,2); g{kk+1}.offset = -Lg/2; g{kk+1}.realonly = 0; end if do_time, tic; end [tgrad,fgrad,c_s]=filterbankphasegrad(f,g,a0,filterbanklength(L,a0)); if do_time, PGtimeFIR = toc; fprintf('PGtimeFIR=%d\n',PGtimeFIR); end if do_time, tic; end [sr,arg0,arg1]=filterbankreassign(c_s,tgrad,fgrad,a0,cfreq0); if do_time, RAtimeFIR = toc; fprintf('RAtimeFIR=%d\n',RAtimeFIR); end Lg = 882; a = 90*ones(882,1); cfreq1 = [0:441,-440:-1].'/441; gg = fftshift(firwin('hann',Lg));%.*exp(-2*pi*1i*100*(-Lg/2:Lg/2-1).'./L); for kk = 0:881 g2{kk+1}.H = gg; g2{kk+1}.L = L; g2{kk+1}.foff = kk*L/882-Lg/2; g2{kk+1}.realonly = 0; g3{kk+1}.L = L; g3{kk+1}.H = comp_transferfunction(g2{kk+1},L); g3{kk+1}.foff = 0; g3{kk+1}.realonly = 0; end figure(2); clf; subplot(311); plotfilterbank(sr,a0,'fc',fs/2*cfreq0,'linabs'); if do_time, tic; end [tgrad,fgrad,c_s2]=filterbankphasegrad(f,g2,a,L); if do_time, PGtimeBL = toc; fprintf('PGtimeBL=%d\n',PGtimeBL); end if do_time, tic; end [sr2,arg0,arg1]=filterbankreassign(c_s2,tgrad,fgrad,a,cfreq1); if do_time, RAtimeBL = toc; fprintf('RAtimeBL=%d\n',RAtimeBL); end figure(2); subplot(312); plotfilterbank(sr2,a,'fc',fs/2*cfreq1,'linabs'); if do_all if do_time, tic; end [tgrad,fgrad,c_s3]=filterbankphasegrad(f,g3,a,L); if do_time, PGtimeL = toc; fprintf('PGtimeL=%d\n',PGtimeL); end if do_time, tic; end [sr3,arg0,arg1]=filterbankreassign(c_s3,tgrad,fgrad,a,cfreq1); if do_time, RAtimeL = toc; fprintf('RAtimeL=%d\n',RAtimeL); end figure(2); subplot(313); plotfilterbank(sr3,a,'fc',fs/2*cfreq1,'linabs'); end % % clear all catch test_failed = 1; end ltfat/inst/private/test_dwilt2.m0000664000175000017500000000424313026262303016635 0ustar susnaksusnakfunction test_failed=test_dwilt2 test_failed=0; disp(' =============== TEST_DWILT2 ================'); %-*- texinfo -*- %@deftypefn {Function} test_dwilt2 %@verbatim % Run some fixed test to test the interface. % This is not a thourough tester. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dwilt2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % --- test 1 ---------------- L=64; M=8; Lf=63; W=3; f=tester_rand(Lf,Lf,W); g=pgauss(L,1); gd=wildual(g,M); [c,Ls]=dwilt2(f,g,M); r=idwilt2(c,gd,Ls); res=r-f; nres=norm(res(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); % failed=''; % if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; % end; s=sprintf('DWILT2 Lf:%3i L:%3i %0.5g %s',Lf,L,nres,fail); disp(s) % --- test 2 ------------------- L=256; M1=16; M2=32; W=1; f=tester_rand(L,L,1); g=pgauss(L,1); gd1=wildual(g,M1); gd2=wildual(g,M2); c=dwilt2(f,g,[M1,M2]); c2=ref_dwilt2(f,g,g,M1,M2); rc=c-c2; nres=norm(rc(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); % failed=''; % if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; % end; s=sprintf('DWILT2 REF M1:%3i M2:%3i %0.5g %s',M1,M2,nres,fail); disp(s) r=idwilt2(c,gd1,gd2); res=r-f; nres=norm(res(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); % failed=''; % if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; % end; s=sprintf('DWILT2 INV M1:%3i M2:%3i %0.5g %s',M1,M2,nres,fail); disp(s) ltfat/inst/private/test_windrivers.m0000664000175000017500000000265513026262303017631 0ustar susnaksusnakfunction test_failed=test_windrivers %-*- texinfo -*- %@deftypefn {Function} test_windrivers %@verbatim %TEST_WINDRIVERS Test if the window drivers pass certain construction %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_windrivers.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_WINDRIVERS ================'); a=5; M=6; L=60; % We expect that if the following commands finish, they produce the correct % output, so we only test that they do not generate fatal errors. g=gabwin('gauss',a,M,L); g=gabwin({'gauss',1},a,M,L); gd=gabwin('gaussdual',a,M,L); gd=gabwin({'tight','gauss'},a,M,L); g=gabwin({'dual',{'hann',M}},a,M,L); ltfat/inst/private/test_idft.m0000664000175000017500000000266413026262303016363 0ustar susnaksusnakfunction test_failed=test_idft Lr=[1, 19, 20]; test_failed=0; disp(' =============== TEST_IDFT =============='); for jj=1:length(Lr) L=Lr(jj); for n = 1:2 if (n==1) type = 'complex'; c=tester_crand(L,1); elseif (n==2) type = 'real'; c=tester_rand(L,1); end f1=idft(c); f2=ref_idft(c); res=norm(f1-f2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('IDFT %6s L:%3i %0.5g %s',type,L,res,fail); disp(s); end end; end; %-*- texinfo -*- %@deftypefn {Function} test_idft %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_idft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_wmdct.m0000664000175000017500000000201213026262303016333 0ustar susnaksusnakfunction c=ref_wmdct(f,g,M) %-*- texinfo -*- %@deftypefn {Function} ref_wmdct %@verbatim %REF_WMDCT Reference WMDCT % Usage: c=ref_wmdct(f,g,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_wmdct.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . c=ref_dwiltiii(f,g,M,M); ltfat/inst/private/test_uwfbt.m0000664000175000017500000000743413026262303016564 0ustar susnaksusnakfunction test_failed = test_uwfbt(verbose) %-*- texinfo -*- %@deftypefn {Function} test_uwfbt %@verbatim %TEST_UWFBTPR % % Checks perfect reconstruction of the general wavelet transform of different % filters % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_uwfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp('========= TEST UWPFBT ============'); global LTFAT_TEST_TYPE; tolerance = 1e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 4e-6; end scaling = {'scale','sqrt','noscale'}; scalingInv = scaling(end:-1:1); test_failed = 0; if(nargin>0) verbose = 1; else verbose = 0; end type = {'dec'}; ext = {'per'}; J = 4; %! Mild tree wt1 = wfbtinit({'db10',6,'full'}); wt1 = wfbtremove(1,1,wt1,'force'); wt1 = wfbtremove(2,1,wt1,'force'); %! Hardcore tree wt2 = wfbtinit({'db3',1}); wt2 = wfbtput(1,1,'mband1',wt2); wt2 = wfbtput(2,2,'mband1',wt2); wt2 = wfbtput(3,3,'mband1',wt2); wt2 = wfbtput(3,1,'db10',wt2); wt2 = wfbtput(4,1,'dgrid2',wt2); wt2 = wfbtput(5,1,'db2',wt2); % wt2 = wfbtinit(); % wt2 = wfbtput(0,0,{'db',4},wt2); % wt2 = wfbtput(1,0,{'algmband',1},wt2); % wt2 = wfbtput(1,1,{'hden',3},wt2); % wt2 = wfbtput(2,0,{'dgrid',2},wt2); % wt2 = wfbtput(2,1,{'dgrid',2},wt2); test_filters = { {'algmband1',J} % 3 filters, uniform, crit. sub. {'algmband2',J} % 4 filters, uniform, crit. sub. {'db10',J} %{{'hden',3},J} % 3 filters, non-uniform, no crit. sub. no correct {'dgrid1',J} % 4 filters. sub. fac. 2 wt1 wt2 }; %testLen = 4*2^7-1;%(2^J-1); testLen = 53; f = tester_rand(testLen,1); for scIdx = 1:numel(scaling) for extIdx=1:length(ext) extCur = ext{extIdx}; for typeIdx=1:length(type) for tt=1:length(test_filters) actFilt = test_filters{tt}; if verbose, if(~isstruct(actFilt))fprintf('J=%d, filt=%s, ext=%s, inLen=%d \n',actFilt{2},actFilt{1},extCur,length(f)); else disp('Custom'); end; end; c = uwfbt(f,actFilt,scaling{scIdx}); fhat = iuwfbt(c,actFilt,scalingInv{scIdx}); err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); if(~verbose) if(~isstruct(actFilt)) fprintf('J=%d, %5.5s, ext=%s, %s L=%d, err=%.4e %s \n',actFilt{2},actFilt{1},extCur,scaling{scIdx},size(f,1),err,fail); else fprintf('Custom, %s, err=%.4e %s\n',scaling{scIdx},err,fail); end; end if strcmpi(fail,'FAILED') if verbose if(~isstruct(actFilt)) fprintf('err=%d, filt=%s, ext=%s, inLen=%d \n',err,actFilt{1},extCur,testLen);else disp('Fail. Custom'); end; figure(1);clf;stem([f,fhat]); figure(2);clf;stem([f-fhat]); break; end end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end if test_failed && verbose, break; end; end end ltfat/inst/private/ref_ambiguityfunction.m0000664000175000017500000000442613026262303020770 0ustar susnaksusnakfunction A=ref_ambiguityfunction(f, g) %-*- texinfo -*- %@deftypefn {Function} ref_ambiguityfunction %@verbatim %REF_AMBIGUITYFUNCTION Reference ambiguity function % Usage: A=ref_ambiguityfunction(f) % A=ref_ambiguityfunction(f,g) % % REF_AMBIGUITYFUNCTION(f) computes the ambiguity function of f. % REF_AMBIGUITYFUNCTION(f,g) computes the cross-ambiguity function of f and g. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_ambiguityfunction.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven if ~all(length(f)==length(g)) error('%s: f and g must have the same length.', upper(mfilename)); end; L = length(f); H = floor(L/2); R = zeros(L,L); A = zeros(L,L); % Compute the analytic representation of f if (nargin == 1) if isreal(f) z = fft(f); z(2:L-H) = 2*z(2:L-H); z(H+2:L) = 0; z1 = ifft(z); z2 = z1; else z1 = f; z2 = z1; end elseif (nargin == 2) if isreal(f) || isreal(g) z1 = fft(f); z1(2:L-H) = 2*z1(2:L-H); z1(H+2:L) = 0; z1 = ifft(z1); z2 = fft(g); z2(2:L-H) = 2*z2(2:L-H); z2(H+2:L) = 0; z2 = ifft(z2); else z1 = f; z2 = g; end end % Compute instantaneous autocorrelation matrix R for l = 0 : L-1; for m = -min([L-l, l, round(L/2)-1]) : min([L-l, l, round(L/2)-1]); R(mod(L+m,L)+1, l+1) = z1(mod(l+m, L)+1).*conj(z2(mod(l-m, L)+1)); end end % Compute ambiguity function A for hh=0:L-1 for ii=0:L-1 for jj = 0:L-1 A(hh+1, ii+1) = A(hh+1, ii+1) + R(jj+1, ii+1) .* exp(-2*pi*i*hh*jj/L); end end end A = fftshift(fft2(A)); ltfat/inst/private/test_freqorder.m0000664000175000017500000000446713026262303017431 0ustar susnaksusnakfunction test_failed = test_freqorder test_failed = 0; disp('------------TEST_FREQORDER--------------'); %-*- texinfo -*- %@deftypefn {Function} test_freqorder %@verbatim % This tests whether subbands of a wavelet filterbank tree are % ordered according to frequency %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_freqorder.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . wt = wfbtinit({'cmband3',1},'nat'); wt = wfbtput(1,1:2,'cmband3',wt); wt = wfbtput(2,0,'cmband3',wt); % Bark-like filterbank tree % Creating tree depicted in Figure 8 in the reference. w = wfbtinit({'cmband3',1}); w = wfbtput(1,0,'cmband6',w); w = wfbtput(1,1,'cmband3',w); w = wfbtput(2,0:1,'cmband5',w); w = wfbtput(2,2:3,'cmband2',w); % Well-tempered musical scale filterbank tree % Creating tree depicted in Figure 9 in the reference. w2 = wfbtinit({'cmband4',1}); w2 = wfbtput(1,0:1,'cmband6',w2); w2 = wfbtput(2,0:1,'cmband4',w2); w2 = wfbtput(3,1:4,'cmband4',w2); w3 = wfbtinit({'cmband3',5,'full'}); w3 = wfbtremove(4,0,w3,'force'); w3 = wfbtremove(3,9,w3,'force'); testcases = { {'cmband3',5,'full'},... {'cmband2',5,'full'},... {'cmband5',4,'full'},... wt,w,w2,w3}; for ii = 1:numel(testcases) [g,a]=wfbt2filterbank(testcases{ii},'freq'); glmax = max(cellfun(@(gEl)numel(gEl.h),g)); F = filterbankfreqz(g,a,2*glmax); [~,Fidpeaks] = max(abs(F)); fprintf('Tree %i:',ii) if any(Fidpeaks(2:end)-Fidpeaks(1:end-1) < 0) fprintf(' FAILED'); test_failed=test_failed +1; else fprintf(' OK'); end fprintf('\n'); end ltfat/inst/private/test_filterbank.m0000664000175000017500000001275013026262303017553 0ustar susnaksusnakfunction test_failed=test_filterbank %-*- texinfo -*- %@deftypefn {Function} test_filterbank %@verbatim %TEST_FILTERBANK test the filterbank codes % Usage: test_filterbank() % % This function checks the exact reconstruction (up to numeric precision) % of the functions ufilterbank and ifilterbank, when using dual windows computed with % filterbankdual / filterbankrealdual, or tight windows computed with % filterbanktight / filterbankrealtight %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_filterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_FILTERBANK ================'); which comp_filterbank_td which comp_filterbank_fft which comp_filterbank which comp_ifilterbank_td which comp_ifilterbank_fft which comp_ifilterbank M=6; a=3; N=4; L=a*N; g=cell(1,M); for ii=1:M g{ii}=tester_crand(L,1); end; gd = filterbankdual(g,a,L); gt = filterbanktight(g,a,L); gtreal=filterbankrealtight(g,a,L); %% Check that filterbankbounds detect the tight frame [AF,BF]=filterbankbounds(gt,a,L); [test_failed,fail]=ltfatdiditfail(BF-1,test_failed); s=sprintf(['FB FB B %0.5g %s'],BF-1,fail); disp(s) [test_failed,fail]=ltfatdiditfail(AF-1,test_failed); s=sprintf(['FB FB A %0.5g %s'],AF-1,fail); disp(s) %% check filterbankrealbounds [AF,BF]=filterbankrealbounds(gtreal,a,L); [test_failed,fail]=ltfatdiditfail(BF-1,test_failed); s=sprintf(['FB FBR B %0.5g %s'],BF-1,fail); disp(s) [test_failed,fail]=ltfatdiditfail(AF-1,test_failed); s=sprintf(['FB FBR A %0.5g %s'],AF-1,fail); disp(s) for w=1:3 f=tester_crand(L,w); c_u_td = ufilterbank(f,g,a,'crossover',0); c_u_ref = ref_ufilterbank(f,g,a); c_nu_td = filterbank(f,g,a,'crossover',0); c_u_fft = ufilterbank(f,g,a,'crossover',1e20); c_nu_fft = filterbank(f,g,a,'crossover',1e20); %% check that filterbank and ufilterbank produce the same results. res=0; for m=1:M res=res+norm(c_nu_td{m}-squeeze(c_u_td(:,m,:))); end; [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB MATCH W:%2i %0.5g %s'],w,res,fail); disp(s) %% check that ufilterbank match its reference res=c_u_td-c_u_ref; res=norm(res(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB RES W:%2i %0.5g %s'],w,res,fail); disp(s) %% check that filterbank in time-side and frequency side match res=norm(cell2mat(c_nu_fft)-cell2mat(c_nu_td)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB TD FD W:%2i %0.5g %s'],w,res,fail); disp(s) %% check that ufilterbank in time-side and frequency side match res=norm(c_u_fft(:)-c_u_td(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['UFB TD FD W:%2i %0.5g %s'],w,res,fail); disp(s) %% Check that ufilterbank is invertible using dual window r=ifilterbank(c_u_td,gd,a); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB DUAL W:%2i %0.5g %s'],w,res,fail); disp(s) %% Test that ifilterbank returns the same for the uniform and non-uniform %% case %To avoid warning whrn w==1 if w==1 c_nu_td=mat2cell(c_u_td,size(c_u_td,1),ones(1,M)); else c_nu_td=mat2cell(c_u_td,size(c_u_td,1),ones(1,M),w); end c_nu_td=cellfun(@squeeze,c_nu_td,'UniformOutput',false); r_nu=ifilterbank(c_nu_td,gd,a); res=norm(r_nu-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB INV MATCH W:%2i %0.5g %s'],w,res,fail); disp(s) %% Check that filterbanktight gives a tight filterbank c_ut = ufilterbank(f,gt,a); r=ifilterbank(c_ut,gt,a); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB TIGHT W:%2i %0.5g %s'],w,res,fail); disp(s) %% Check the real valued systems, dual fr=tester_rand(L,1); gdreal=filterbankrealdual(g,a,L); c_ur=ufilterbank(fr,g,a); rreal=2*real(ifilterbank(c_ur,gdreal,a)); res=norm(fr-rreal); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB RDUAL W:%2i %0.5g %s'],w,res,fail); disp(s) %% Check the real valued systems, tight ct = ufilterbank(fr,gtreal,a); rrealt = 2*real(ifilterbank(ct,gtreal,a)); res=norm(fr-rrealt); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB RTIGHT W:%2i %0.5g %s'],w,res,fail); disp(s) %% check filterbankwin r=ifilterbank(c_u_td,{'dual',g},a); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['FB WIN DUAL %0.5g %s'],res,fail); disp(s) end; ltfat/inst/private/ref_idwiltiv_1.m0000664000175000017500000000425613026262303017304 0ustar susnaksusnakfunction [f]=ref_idwiltiv_1(coef,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwiltiv_1 %@verbatim %REF_IDWILTIV_1 Reference IDWILTIV by IDGT type IV % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwiltiv_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard L=size(g,1); N=L/a; W=size(coef,2); coef=reshape(coef,M,N,W); coef2=zeros(2*M,N,W); if 0 % --- loop version --- for n=0:N-1 for m=0:M-1 if rem(m+n,2)==0 coef2(m+1,n+1,:) = exp(i*pi/4)/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m,n+1,:) = exp(i*pi*3/4)/sqrt(2)*coef(m+1,n+1,:); else coef2(m+1,n+1,:) = exp(-i*pi/4)/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m,n+1,:) = exp(-i*pi*3/4)/sqrt(2)*coef(m+1,n+1,:); end; end; end; else % --- Vector version --- 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,:); end; f=ref_igdgt(reshape(coef2,2*M*N,W),g,a,2*M,0.5,0.5,0); ltfat/inst/private/ref_dgtns.m0000664000175000017500000000255413026262303016347 0ustar susnaksusnakfunction [c]=ref_dgtns(f,gamma,V) %-*- texinfo -*- %@deftypefn {Function} ref_dgtns %@verbatim %REF_DGT Reference Discrete Gabor transform for non-separable lattices. % Usage: c=ref_dgtns(f,gamma,V); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transfpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgtns.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Calculate the parameters that was not specified. L=size(gamma,1); % Create lattice and Gabor matrix. lat=ref_lattice(V,L); G=ref_gaboratoms(gamma,lat); % Apply matrix to f. c=G'*f; ltfat/inst/private/test_zak.m0000664000175000017500000000330713026262303016215 0ustar susnaksusnakfunction test_failed=test_zak disp(' =============== TEST_ZAK ================'); Lr=[1,12,12,12,12,12,15,15,15]; Kr=[1, 1, 2, 3, 4, 6, 3, 5,15]; ref_failed=0; inv_failed=0; W=1; for ii=1:length(Lr) L=Lr(ii); K=Kr(ii); f=tester_rand(L,W)+i*rand(L,W)-.5-i*.5; ccref=ref_zak(f,K); cc=zak(f,K); r=izak(cc); res=ccref-cc; nres=norm(res(:)); ninv=norm(f-r); s=sprintf('REF L:%3i K:%3i %0.5g',L,K,nres); disp(s) [ref_failed,fail]=ltfatdiditfail(nres,ref_failed); % if nres>10e-10 % disp('FAILED'); % ref_failed=ref_failed+1; % end; s=sprintf('INV L:%3i K:%3i %0.5g',L,K,ninv); disp(s) [inv_failed,fail]=ltfatdiditfail(ninv,inv_failed); % if nres>10e-10 % disp('FAILED'); % inv_failed=inv_failed+1; % end; end; test_failed=ref_failed+inv_failed; %-*- texinfo -*- %@deftypefn {Function} test_zak %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_zak.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_iedgt.m0000664000175000017500000000340313026262303016316 0ustar susnaksusnakfunction f=ref_iedgt(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_iedgt %@verbatim %REF_IEDGT Reference Inverse Even DGT % Usage f=ref_edgt(c,g,a,M); % % The input window must be odd-centered of length 2L. % % M must be even. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_iedgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L2=size(g,1); W=size(c,2); L=L2/2; M=L/b; N=L/a; F=zeros(L,M*N); l=(0:L-1).'; lsecond=(2*L-1:-1:L).'; for m=0:M/2-1 F(:,m+1) = exp(2*pi*i*m*b*(l+.5)/L).*g(l+1) + ... exp(-2*pi*i*m*b*(l+.5)/L).*g(lsecond+1); gshift=circshift(g,L); F(:,m+1+M*(N-1)+M/2) = exp(2*pi*i*m*b*(l+.5)/L).*gshift(l+1) + ... exp(-2*pi*i*m*b*(l+.5)/L).*gshift(lsecond+1); end; % Scale the first modulations correctly F(:,1)=F(:,1)/sqrt(2); F(:,M*(N-1)+M/2+1)=F(:,M*(N-1)+M/2+1)/sqrt(2); %for n=0:N-1 % for m=0:M-1 % gshift=circshift(gnew,n*a); % F(:,M*n+m+1)=exp(2*pi*i*m*b*(l+.5)/L).*gshift(l+1) + ... % exp(-2*pi*i*m*b*(l+.5)/L).*gshift(lsecond+1); % end; %end; f=F*c; ltfat/inst/private/ref_dstiii_1.m0000664000175000017500000000274113026262303016733 0ustar susnaksusnakfunction c=ref_dstiii_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_dstiii_1 %@verbatim %REF_DSTII Reference Discrete Sine Transform type III % Usage: c=ref_dstiii(f); % % This is the inverse of REF_DSTII %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dstiii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if ~isreal(f) c=ref_dstiii_1(real(f))+i*ref_dstiii_1(imag(f)); else % Scale coefficients to obtain orthonormal transform. f(end,:)=sqrt(2)*f(end,:); f=-f*sqrt(2*L); % Make 4x long vector lf=[zeros(1,W);... i*f;... i*flipud(f(1:end-1,:));... zeros(1,W);... -i*f;... -i*flipud(f(1:end-1,:));... ]; fflong=real(ifft(lf)); c=fflong(2:2:2*L,:); end ltfat/inst/private/ref_spreadop_1.m0000664000175000017500000000251513026262303017262 0ustar susnaksusnakfunction fout=ref_spreadop_1(f,c,a); %-*- texinfo -*- %@deftypefn {Function} ref_spreadop_1 %@verbatim %REF_SPREADOP_1 Ref. Spreading function % Usage: h=ref_spreadfun_1(f,c,a); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_spreadop_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %XXX Wrong sign convention W=size(f,2); M=size(c,1); N=size(c,2); L=N*a; [c,h_a,h_m]=gcd(a,M); h_a=-h_a; p=a/c; q=M/c; d=N/q; fout=zeros(L,W); cf1=fft(coef); for j=0:M-1 for m=0:b-1 for n=0:N-1 fout(j+m*M+1,:)=fout(j+m*M+1,:)+cf1(j+1,n+1)*f(mod(j+m*M-n*a,L)+1,:); end; end; end; ltfat/inst/private/ref_dctiv.m0000664000175000017500000000233213026262303016333 0ustar susnaksusnakfunction c=ref_dctiv(f) %-*- texinfo -*- %@deftypefn {Function} ref_dctiv %@verbatim %REF_DCTIV Reference Discrete Consine Transform type IV % Usage: c=ref_dctiv(f); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dctiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=sqrt(2/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w*cos(pi*(n+.5)*(m+.5)/L); end; end; % Compute coefficients. c=F*f; ltfat/inst/private/rand_rhpe.m0000664000175000017500000000267713026262303016344 0ustar susnaksusnakfunction f=rand_rhpe(varargin) %-*- texinfo -*- %@deftypefn {Function} rand_rhpe %@verbatim %RAND_HPE Random real HPE even function. % Usage: f=rand_rhpe(s); % % RAND_RHPE(s) generates an array of size s, which is real and HPE along the % first dimension. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/rand_rhpe.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isnumeric(varargin); s=varargin; else s=cell2mat(varargin); end; if length(s)==1 error('To avoid confusion, the size must be at least two-dimensional.'); end; shalf=s; shalf(1)=floor(shalf(1)/2); f=tester_rand(shalf)-.5; if rem(s(1),2)==0 f=[f;flipud(f)]; else f=[f; ... tester_rand([1 s(2:end)])-.5; ... flipud(f)]; end; ltfat/inst/private/test_extended_ltfat.m0000664000175000017500000000336213026262303020423 0ustar susnaksusnakfunction test_extended_ltfat() %-*- texinfo -*- %@deftypefn {Function} test_extended_ltfat %@verbatim % This test suite runs extended tests which either: % % Take long time to finish % % Their failure can only be checked by inspecting plots % % We do not care whether they work with single precision or not. % % Any that should be run at least before doing the release % but do not fit to be included in test_all_ltfat % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_extended_ltfat.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . tests_todo = { 'erbfilters',... 'fbreassign',... 'fbwarped_framebounds',... 'wfilt',... 'argfirwin',... 'gabphasederiv',... 'audfilters',... 'demos' }; total_tests_failed=0; list_of_failed_tests={}; for name = tests_todo tmpfailed = feval(['test_',name{1}]); if tmpfailed>0 list_of_failed_tests{end+1} = ['test_',name{1}]; total_tests_failed = total_tests_failed + tmpfailed; end end ltfat/inst/private/test_undeceq.m0000664000175000017500000000442013026262303017051 0ustar susnaksusnakfunction test_failed=test_undeceq %-*- texinfo -*- %@deftypefn {Function} test_undeceq %@verbatim % This function test whether fwt is just a subsampled version of ufwt, wfbt % of uwfbt etc. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_undeceq.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; J = 5; L = 128; f = tester_rand(L,1); wav = {'db4','spline4:4'}; for ii = 1:numel(wav) w = fwtinit(wav{ii}); [c,info] = fwt(f,wav{ii},J,'cell'); cu = ufwt(f,wav{ii},J,'noscale'); err = 0; suFac = size(cu,1)./info.Lc; for jj = 1:numel(c) err = err + norm(c{jj}-cu(1:suFac(jj):end,jj)); end [test_failed,fail]=ltfatdiditfail(err,test_failed); fprintf('DWT J=%d, %6.6s, L=%d, err=%.4e %s \n',J,wav{ii},length(f),err,fail); end for ii = 1:numel(wav) [c,info] = wfbt(f,{wav{ii},J}); cu = uwfbt(f,{wav{ii},J},'noscale'); err = 0; suFac = size(cu,1)./info.Lc; for jj = 1:numel(c) err = err + norm(c{jj}-cu(1:suFac(jj):end,jj)); end [test_failed,fail]=ltfatdiditfail(err,test_failed); fprintf('WFBT J=%d, %6.6s, L=%d, err=%.4e %s \n',J,wav{ii},length(f),err,fail); end for ii = 1:numel(wav) [c,info] = wpfbt(f,{wav{ii},J}); cu = uwpfbt(f,{wav{ii},J},'noscale'); err = 0; suFac = size(cu,1)./info.Lc; for jj = 1:numel(c) err = err + norm(c{jj}-cu(1:suFac(jj):end,jj)); end [test_failed,fail]=ltfatdiditfail(err,test_failed); fprintf('WPFBT J=%d, %6.6s, L=%d, err=%.4e %s \n',J,wav{ii},length(f),err,fail); end ltfat/inst/private/test_dsft.m0000664000175000017500000000315613026262303016372 0ustar susnaksusnakfunction test_failed = test_dsft Lr = [2, 19, 20]; test_failed = 0; disp(' =============== TEST_DSFT =============='); for ii = 1: length(Lr) L = Lr(ii); for n = 1:4 if (n == 1) type = 'real'; L2 = L; F = tester_rand(L,L); elseif (n == 2) type = 'real'; L2 = L+1; F = tester_rand(L,L2); elseif (n == 3) type = 'complex'; L2 = L; F = tester_crand(L,L); else type = 'complex'; L2 = L+1; F = tester_crand(L,L2); end r1 = ref_dsft(F); r2 = dsft(F); res = norm(r1-r2); [test_failed, fail] = ltfatdiditfail(res, test_failed); s = sprintf('DSFT %3s size: %dx%d %0.5g %s', type, L, L2, res, fail); disp(s); end end %-*- texinfo -*- %@deftypefn {Function} test_dsft %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dsft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_hermbasis.m0000664000175000017500000000530113026262303017401 0ustar susnaksusnakLr=[100,101,102,103]; test_failed=0; highordercoef=0.80; disp(' =============== TEST_HERMBASIS =========='); for ii=1:length(Lr) for n=2:4 L=Lr(ii); highorder=round(L*highordercoef); [H,D]=hermbasis(L,n); r1=(H*H')-eye(L); res=norm(r1,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('HERMBASIS orth L:%3i n:%3i %0.5g %s',L,n,res,fail); disp(s); f=tester_crand(L,1); res=norm(dft(f)-H*diag(D)*H'*f); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('HERMBASIS DFT L:%3i n:%3i %0.5g %s',L,n,res,fail); disp(s); [H,D]=pherm(L,0:highorder-1,'fast'); res=norm(dft(H)-H*diag(D)); [test_failed,fail]=ltfatdiditfail(res,test_failed); end; s=sprintf('PHERM DFT L:%3i %0.5g %s',L,res,fail); disp(s); [H,D]=pherm(L,0:highorder-1,'fast','qr'); res=norm(dft(H)-H*diag(D)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PHERM QR DFT L:%3i %0.5g %s',L,res,fail); disp(s); r1=(H'*H)-eye(highorder); res=norm(r1,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PHERM QR orth L:%3i %0.5g %s',L,res,fail); disp(s); [H,D]=pherm(L,0:highorder-1,'fast','polar'); res=norm(dft(H)-H*diag(D)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PHERM POL DFT L:%3i %0.5g %s',L,res,fail); disp(s); r1=(H'*H)-eye(highorder); res=norm(r1,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PHERM POL orth L:%3i %0.5g %s',L,res,fail); disp(s); end; %-*- texinfo -*- %@deftypefn {Function} test_hermbasis %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_hermbasis.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ltfatdiditfail.m0000664000175000017500000000263713026262303017362 0ustar susnaksusnakfunction [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); %-*- texinfo -*- %@deftypefn {Function} ltfatdiditfail %@verbatim %LTFATDIDITFAIL Did a test fail % % [test_fail,fail]=LTFATDIDITFAIL(res,test_fail) updates test_fail if % res is above threshhold and outputs the word FAIL in the variable % fail. Use only in testing scripts. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/ltfatdiditfail.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE; if nargin<3 tolerance=1e-10; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance=2e-4; end end; fail=''; if (abs(res)>tolerance) || isnan(res) fail='FAILED'; test_failed=test_failed+1; end; ltfat/inst/private/test_pconv.m0000664000175000017500000000420413026262303016552 0ustar susnaksusnakfunction test_failed=test_pconv Lf=[9, 10 9, 9, 1]; Wf=[1, 1, 3, 1, 1]; Lg=[9, 10 9, 9, 1]; Wg=[1, 1, 1, 3, 1]; ctypes={'default','r','rr'}; test_failed=0; disp(' =============== TEST_PCONV =============='); for jj=1:length(Lf) for ii=1:3 for type = {'real','complex'} ctype=ctypes{ii}; if strcmp(type{1},'complex') f=tester_crand(Lf(jj), Wf(jj)); g=tester_crand(Lg(jj), Wg(jj)); else f=tester_rand(Lf(jj), Wf(jj)); g=tester_rand(Lg(jj), Wg(jj)); end h1=pconv(f,g,ctype); h2cell = {}; if Wf(jj) == 1 for wId = 1:Wg(jj) h2cell{end+1}=ref_pconv(f,g(:,wId),ctype); end else for wId = 1:Wf(jj) h2cell{end+1}=ref_pconv(f(:,wId),g,ctype); end end h2 = cell2mat(h2cell); res=norm(h1(:)-h2(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PCONV %3s %6s %0.5g %s',ctype,type{1},res,fail); disp(s); end end end %-*- texinfo -*- %@deftypefn {Function} test_pconv %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_pherm.m0000664000175000017500000000242413026262303016542 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_pherm %@verbatim % This script test the quality of the Hermite implementation. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pherm.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % There seem to be some numerical problems for ii>66 L=200; H=pherm(L,0:159,'fast','qr'); H1=H(:,1:4:end); H2=H(:,2:4:end); H3=H(:,3:4:end); H4=H(:,4:4:end); norm(H1'*H1) norm(H2'*H2) norm(H3'*H3) norm(H4'*H4) norm(H1'*H2) norm(H1'*H3) norm(H1'*H4) norm(H2'*H3) norm(H2'*H4) norm(H3'*H4) norm(abs(H./dft(H))-1) ltfat/inst/private/ref_dctiii.m0000664000175000017500000000237713026262303016500 0ustar susnaksusnakfunction c=ref_dctiii(f) %-*- texinfo -*- %@deftypefn {Function} ref_dctiii %@verbatim %REF_DCTII Reference Discrete Consine Transform type III % Usage: c=ref_dctii(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dctiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=ones(L,1); w(1)=1/sqrt(2); w=w*sqrt(2/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w(n+1)*cos(pi*n*(m+.5)/L); end; end; % Compute coefficients. c=F*f; ltfat/inst/private/ref_gabmulappr.m0000664000175000017500000001052513026262303017357 0ustar susnaksusnakfunction sym=ref_gabmulappr(T,p2,p3,p4,p5); %-*- texinfo -*- %@deftypefn {Function} ref_gabmulappr %@verbatim %GABMULMAT 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); % % 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 % % GABMULAPPR(T,g,a,M) will calculate 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. % IMPORTANT: The chosen Gabor system has to be a frame sequence! % % GABMULAPPR(T,a,M) will do the same using an optimally concentrated, % tight Gaussian as window function. % % GABMULAPPR(T,gs,ga,a) will do the same using the window ga for analysis % and gs for synthesis. % % SEE ALSO: GABMUL, GABMULINV % % In this algorithm first the 'lower symbol' is calcualted, then the % so-called 'upper symbol'. % % The lower symbol is the inner product < T , P_lambda > where P_lambda % are the projections gamma_lambda otimes g_lambda . These operators % form a Bessel sequence and the lower symbol, the lower symbol is the % analysis sequence of T using this Bessel sequence. % % The upper symbol is the inner product < T , Q_lambda > where % Q_lambda are the dual projections operator. Therefore the upper % symbol is the analysis with the dual sequence (if the P have formed a % frame). Because the % % References : % P. Balazs, Basic Definition and Properties of Bessel Multipliers, % Journal of Mathematical Analysis and Applications 325(1):571--585, % January 2007. % P.~Balazs, Hilbert-Schmidt operators and frames - classification, best % approximation by multipliers and algorithms, International Journal % of Wavelets, Multiresolution and Information Processing, accepted, % to appear. % H. G. Feichtinger, M. Hampjes, G. Kracher, "Approximation of matrices % by Gabor multipliers" , IEEE Signal Procesing Letters Vol. 11, % Issue 11, pp 883-- 886 (2004) % % Author: P. Balazs (XXL) %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabmulappr.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; N=L/a; b=L/M; % gg = GBa(:,ii+jj*M); % Element of analysis frame % hh = GBs(:,ii+jj*M); % Element of synthesis frame % HS inner product : < T , g \tensor h> = < T h , g > = part1=reshape(dgt(T',ga,a,M),M*N,L); part2=reshape(dgt(part1',gs,a,M),M*N,M*N).'; lowsym = reshape(diag(part2),M,N); GBa = frsynmatrix(frame('dgt',ga,a,M),length(ga)); % Gabor frame synthesis matrix if ga ~= gs GBs = frsynmatrix(frame('dgt',gs,a,M),length(gs)); else GBs = GBa; end if ga == gs % HS Gram matrix Gram = abs(GBa'*GBa).^2; else Gram = (GBs'*GBs) .* conj(GBa'*GBa); end % The Gram matrix is square and Toeplitz. %iGram=inv(Gram); sym = reshape(Gram\lowsym(:),M,N); % sym = involute(sym); % strange but true ? ltfat/inst/private/test_dgt_fb.m0000664000175000017500000001061613026262303016656 0ustar susnaksusnakfunction test_failed=test_dgt_fb %-*- texinfo -*- %@deftypefn {Function} test_dgt_fb %@verbatim %TEST_DGT_FB Test the filter bank algorithms in DGT % % This script runs a throrough test of the DGT routine, % testing it on a range of input parameters. % % The script test the filter bank algorithms in DGT, IDGT, GABDUAL and % GABTIGHT by comparing with the full window case. % % The computational backend is tested this way, but the % interfaces is not. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt_fb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr = [24, 35, 35, 24,144,108,144,135,77,77]; ar = [ 6, 5, 5, 4, 9, 9, 12, 9, 7, 7]; Mr = [ 8, 7, 7, 6, 16, 12, 24, 9,11,11]; glr = [16, 14, 21, 12, 48, 12, 24, 18,22,11]; test_failed=0; disp(' =============== TEST_DGT_FB ================'); disp('--- Used subroutines ---'); which comp_dgt_fb which comp_idgt_fb which comp_dgtreal_fb which comp_idgtreal_fb for phase = {'freqinv','timeinv'} for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); gl=glr(ii); b=L/M; N=L/a; for rtype=1:2 if rtype==1 rname='REAL '; g=tester_rand(gl,1); else rname='CMPLX'; g=tester_crand(gl,1); end; % Test following test only makes sense if the dual is also % FIR. Otherwise the code will fail because of a missing parameter. if gl<=M gd = gabdual(g,a,M); gd_long = gabdual(fir2long(g,L),a,M,L); res = norm(fir2long(gd,L)-gd_long); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('DUAL %s L:%3i a:%3i M:%3i gl:%3i %0.5g %s',rname,L,a,M,gl,res,fail); disp(s) gt = gabtight(g,a,M); gt_long = gabtight(fir2long(g,L),a,M,L); res = norm(fir2long(gt,L)-gt_long); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('TIGHT %s L:%3i a:%3i M:%3i gl:%3i %0.5g %s',rname,L,a,M,gl,res,fail); disp(s) end; for W=1:3 if rtype==1 rname='REAL '; f=tester_rand(L,W); else rname='CMPLX'; f=tester_crand(L,W); end; cc = dgt(f,g,a,M,phase{1}); cc2 = dgt(f,fir2long(g,L),a,M,phase{1}); cdiff=cc-cc2; res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF %s, %s L:%3i W:%2i a:%3i M:%3i gl:%3i %0.5g %s',rname,phase{1},L,W,a,M,gl,res,fail); disp(s) f1 = idgt(cc2,g,a,phase{1}); f2 = idgt(cc2,fir2long(g,L),a,phase{1}); cdiff=f1-f2; res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('IREF %s, %s L:%3i W:%2i a:%3i M:%3i gl:%3i %0.5g %s',rname,phase{1},L,W,a,M,gl,res,fail); disp(s) % Test the real valued transform if rtype==1 % --- Reference test --- ccreal=dgtreal(f,g,a,M,phase{1}); M2=floor(M/2)+1; cdiff=cc(1:M2,:,:)-ccreal; res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REFREAL %s L:%3i W:%2i a:%3i M:%3i gl:%3i %0.5g %s',... phase{1},L,W,a,M,gl,res,fail); disp(s); % --- Reconstruction test --- % Test following test only makes sense if the dual is also FIR. if gl<=M rreal=idgtreal(ccreal,gd,a,M,phase{1}); res=norm(f-rreal,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('RECREAL %s L:%3i W:%2i a:%3i M:%3i gl:%3i %0.5g %s',... phase{1},L,W,a,M,gl,res,fail); disp(s) end; end; end; end; end; end ltfat/inst/private/test_fwt2.m0000664000175000017500000000332313026262303016310 0ustar susnaksusnakfunction test_failed = test_fwt2 disp('========= TEST FWT2 ============'); global LTFAT_TEST_TYPE; tolerance = 1e-8; if strcmpi(LTFAT_TEST_TYPE,'single') tolerance = 1e-4; end test_failed = 0; dims = { [20,30], [150,151],[226,253], }; flags = {'standard','tensor'}; filt = {{'mband1',2},{'db10',4},{'sym8',4},{'spline4:4',4},}; for ii=1:numel(dims) f = tester_rand(dims{ii}); for jj=1:numel(flags) for ff=1:numel(filt) c = fwt2(f,filt{ff}{1},filt{ff}{2},flags{jj}); fhat = ifwt2(c,filt{ff}{1},filt{ff}{2},dims{ii},flags{jj}); err = norm(f-fhat,'fro'); [test_failed,fail]=ltfatdiditfail(err,test_failed,tolerance); fprintf('J=%d, %5.5s, dim=[%3.d,%3.d], flag=%8.8s, err=%.4e %s\n',filt{ff}{2},filt{ff}{1},size(f,1),size(f,2),flags{jj},err,fail); end end end %-*- texinfo -*- %@deftypefn {Function} test_fwt2 %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_fwt2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/test_framemulappr.m0000664000175000017500000000407013026262303020121 0ustar susnaksusnak %-*- texinfo -*- %@deftypefn {Function} test_framemulappr %@verbatim % This test example is taken from demo_gabmulappr %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_framemulappr.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 N=L/a; 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,:)=(tester_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*(tester_rand(1,L)-0.5)); end; A = A/norm(A)*0.99; % normalize matrix % perform best approximation by gabor multiplier g=gabtight(a,M,L); sym1=gabmulappr(A,g,a,M); % Now do the same using the general frame algorithm. F=frame('dgt',g,a,M); sym2=framemulappr(F,F,A); norm(sym1-reshape(sym2,M,N)) % Test for exactness testsym=tester_crand(M,N); FT=frsynmatrix(F,L); T=FT*diag(testsym(:))*FT'; sym1b=gabmulappr(T,g,a,M); sym2b=framemulappr(F,F,T); norm(testsym-sym1b) norm(testsym-reshape(sym2b,M,N)) ltfat/inst/private/ref_rdftiii.m0000664000175000017500000000256513026262303016664 0ustar susnaksusnakfunction c=ref_rdftiii(f) %-*- texinfo -*- %@deftypefn {Function} ref_rdftiii %@verbatim %REF_RDFTIII Reference Real DFT type III % Usage: c=ref_rdftiii(f); % % Compute RDFTIII by explicit formulas. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdftiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=floor(L/2); F=zeros(L); F(:,1)=ones(L,1); l=(0:L-1).'/L; for m=0:Lhalf-1 F(:,2*m+1)=sqrt(2)*cos(2*pi*(m+.5)*l); F(:,2*m+2)=sqrt(2)*sin(2*pi*(m+.5)*l); end; if mod(L,2)==1 F(:,L)=cos(pi*L*l); end; F=F/sqrt(L); % dot-transpose will work because F is real. c=F.'*f; ltfat/inst/private/test_gabmulappr.m0000664000175000017500000001005513026262303017560 0ustar susnaksusnakfunction test_failed=test_gabmulappr %-*- texinfo -*- %@deftypefn {Function} test_gabmulappr %@verbatim %TEST_GABMULAPPR % % This script runs a thorough test of the GABMULAPPR routine, comparting % it to a reference implementation, using canonical tight Gaussian % window, random complex window for both analysis and synthesis, and % using two different randowm complex windows. % % Secondly, the script calculates the best approximation by a Gabor % multiplier to a Gabor multiplier using the same window. % % The script tests TFMAT and GABMULAPPR. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabmulappr.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[24,16,36]; ar=[ 4, 4, 4]; Mr=[ 6, 8, 9]; test_failed=0; disp(' =============== TEST_GABMULAPPR ========='); for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); N=L/a; % Random matrix T=tester_crand(L,L); % Random multiplier symbol. sym=tester_crand(M,N); % ---- Reference test, tight Gaussian window ------------ sym1=ref_gabmulappr(T,a,M); sym2=gabmulappr(T,a,M); res=norm(sym1-sym2,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF GAUSS L:%3i a:%3i M:%3i %0.5g',L,a,M,res); disp(s) % ---- Reconstruction test, tight Gaussian window ------------ Tr = gabmulmatrix(frame('dgt',gabtight(a,M,L),a,M),sym); %Tr=tfmat('gabmul',sym,a); symnew=gabmulappr(Tr,a,M); res=norm(sym-symnew,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REC GAUSS L:%3i a:%3i M:%3i %0.5g',L,a,M,res); disp(s) % ---- Reference test, same window for analysis and synthesis ------------ g=tester_crand(L,1); sym1=ref_gabmulappr(T,g,a,M); sym2=gabmulappr(T,g,a,M); res=norm(sym1-sym2,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); % if res>10e-10 % disp('FAILED'); % test_failed=test_failed+1; % end; s=sprintf('REF 1 WIN L:%3i a:%3i M:%3i %0.5g',L,a,M,res); disp(s) % ---- Reconstruction test, same window for analysis and synthesis ------------ Tr = gabmulmatrix(frame('dgt',g,a,M),sym); %Tr=tfmat('gabmul',sym,g,a); symnew=gabmulappr(Tr,g,a,M); res=norm(sym-symnew,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REC 1 WIN L:%3i a:%3i M:%3i %0.5g',L,a,M,res); disp(s) % ---- Reference test, two different windows for analysis and synthesis ------------ ga=tester_crand(L,1); gs=tester_crand(L,1); sym1=ref_gabmulappr(T,ga,gs,a,M); sym2=gabmulappr(T,ga,gs,a,M); res=norm(sym1-sym2,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF 2 WIN L:%3i a:%3i M:%3i %0.5g',L,a,M,res); disp(s) % ---- Reconstruction test, two different windows for analysis and synthesis --------- Tr = gabmulmatrix2(frame('dgt',ga,a,M),frame('dgt',gs,a,M),sym); %Tr=tfmat('gabmul',sym,ga,gs,a); symnew=gabmulappr(Tr,ga,gs,a,M); res=norm(sym-symnew,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REC 2 WIN L:%3i a:%3i M:%3i %0.5g %s',L,a,M,res,fail); disp(s) end; function T = gabmulmatrix(F,sym) T = operatormatrix(operatornew('framemul',F,F,framenative2coef(F,sym))); function T = gabmulmatrix2(Fa,Fs,sym) T = operatormatrix(operatornew('framemul',Fa,Fs,framenative2coef(Fs,sym))); ltfat/inst/private/test_nonsepdgt_shearola.m0000664000175000017500000000572313026262303021313 0ustar susnaksusnakfunction test_failed=test_nonsepdgt_shearola %-*- texinfo -*- %@deftypefn {Function} test_nonsepdgt_shearola %@verbatim %TEST_NONSEPDGT Test non-separable DGT % % This script runs a throrough test of the DGT routine, % testing it on a range of input parameters. % % The computational backend is tested this way, but the % interface is not. % % The script tests dgt, idgt, gabdual and gabtight. % % Use TEST_WFAC and TEST_DGT_FAC for more specific testing % of the DGT backend. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_nonsepdgt_shearola.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ar =[ 4, 4, 3, 4, 4, 4]; Mr =[ 6, 6, 5, 6, 6, 6]; lt1=[ 0, 1, 1, 1, 2, 1]; lt2=[ 1, 2, 2, 3, 3, 4]; test_failed=0; testmode=0; disp(' =============== TEST_NONSEPDGT_SHEAROLA ================'); disp('--- Used subroutines ---'); which comp_nonsepdgt_shear which comp_nonsepdgt_shearola which comp_nonsepwin2multi for ii=1:length(ar); M=Mr(ii); a=ar(ii); lt=[lt1(ii), lt2(ii)]; minL=dgtlength(1,a,M,lt); gl=minL; g=tester_crand(gl,1); bl=minL*10; Lext=bl+gl; % sanity check if Lext~=dgtlength(Lext,a,M,lt) error('Incorrect parameters.'); end for Lidx=2:3 L=bl*Lidx; if L~=dgtlength(L,a,M,lt) error('Incorrect parameters.'); end for W=1:3 f=tester_crand(L,W); % --------- test reference comparison ------------ cc_ref = dgt(f,g,a,M,'lt',lt); if 1 [s0,s1,br]=shearfind(Lext,a,M,lt); cc_ola = comp_nonsepdgt_shearola(f,g,a,M,s0,s1,br,bl); else [s0,s1,br]=shearfind(L,a,M,lt); cc_ola = comp_nonsepdgt_shear(f,fir2long(g,L),a,M,s0,s1,br); end; res = norm(cc_ref(:)-cc_ola(:))/norm(cc_ref(:)); stext=sprintf(['REF L:%3i W:%2i gl:%3i a:%3i M:%3i lt1:%2i lt2:%2i' ... ' s0:%2i s1:%2i bl:%2i Lext:%2i %0.5g'], L,W,gl,a,M,lt(1),lt(2),s0,s1,bl,Lext,res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); end; end; end; ltfat/inst/private/test_dwilt.m0000664000175000017500000000543013026262303016552 0ustar susnaksusnakfunction test_failed=test_dwilt which comp_dwilt which comp_idwilt Lr=[4, 6, 8,12,16,12,18,32,30]; Mr=[2, 3, 2, 3, 4, 2, 3, 4, 3]; disp(' =============== TEST_DWILT ================'); test_failed=0; for ii=1:length(Lr); for W=1:3 for ftype=1:2 for wtype=1:2 L=Lr(ii); M=Mr(ii); a=M; if wtype==1 % Full length window g=pgauss(L); gd=wildual(g,M); wtype='LONG'; else g=firwin('sqrthann',2*M,'2'); gd=g; wtype='FIR'; end; if ftype==1 % Complex-valued test case f=tester_crand(L,W); S='CMPLX'; else % Real-valued tes f=tester_rand(L,W); S='REAL '; end; c=dwilt(f,g,M,L); a=M; c2=ref_dwilt(f,g,a,M); r=idwilt(c,gd); res=norm(c(:)-c2(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s) rdiff=f-r; res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REC %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s) g=wilorth(M,L); c=dwilt(f,g,M); r=idwilt(c,g); rdiff=f-r; res=norm(rdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('ORTH %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s) c=dwilt(f,'gauss',M); r=idwilt(c,{'dual','gauss'}); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('WIN %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s) c=dwilt(f,{'tight','gauss'},M); r=idwilt(c,{'tight','gauss'}); res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('WIN TIGHT %s %s L:%3i W:%2i a:%3i M:%3i %0.5g %s',S,wtype,L,W,a,M,res,fail); disp(s) end; end; end; end; %-*- texinfo -*- %@deftypefn {Function} test_dwilt %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dwilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_nonsepdgt.m0000664000175000017500000000302613026262303017224 0ustar susnaksusnakfunction [c]=ref_nonsepdgt(f,g,a,M,lt) %-*- texinfo -*- %@deftypefn {Function} ref_nonsepdgt %@verbatim %REF_NONSEPDGT Reference non-sep Discrete Gabor transform. % Usage: c=ref_dgt(f,g,a,M,lt); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_nonsepdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Calculate the parameters that was not specified. L=size(f,1); g=fir2long(g,L); b=L/M; N=L/a; W=size(f,2); R=size(g,2); % Create 2x2 grid matrix.. V=[a,0;... b/lt(2)*lt(1),b]; % Create lattice and Gabor matrix. lat=ref_lattice(V,L); G=ref_gaboratoms(g,lat); % Apply matrix to f. c=G'*f; % reshape to correct output format. c=reshape(c,M,N,R*W); ltfat/inst/private/test_fbwarped_framebounds.m0000664000175000017500000000513213026262303021605 0ustar susnaksusnakfunction test_failed=test_fbwarped_framebounds test_failed = 0; Ls = 44100; fs = 44100; fmax = fs/2; bins = 1; fac = [1,7/8,3/4,5/8,1/2]; eigstol = 1e-4; eigsmaxit = 100; pcgmaxit = 150; pcgtol = 1e-4; warpfun = cell(4,1); invfun = cell(4,1); %-*- texinfo -*- %@deftypefn {Function} test_fbwarped_framebounds %@verbatim % ERBlet warping %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_fbwarped_framebounds.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warpfun{3} = @freqtoerb; invfun{3} = @erbtofreq; % constant-Q warping warpfun{4} = @(x) 10*log(x); invfun{4} = @(x) exp(x/10); % sqrt-warping warpfun{2} = @(x) sign(x).*((1+abs(x)).^(1/2)-1); invfun{2} = @(x) sign(x).*((1+abs(x)).^2-1); % Linear warping warpfun{1} = @(x) x/100; invfun{1} = @(x) 100*x; fmin = [0,0,0,50]; A = zeros(4,length(fac)); B = ones(4,length(fac)); red = A; for jj = 1:4 [g,a,fc,L]=warpedfilters(warpfun{jj},invfun{jj},fs,fmin(jj),fmax,bins,Ls,'bwmul',1.5,'fractional','complex'); gf=filterbankresponse(g,a,Ls); framebound_ratio = max(gf)/min(gf); disp(['Painless system frame bound ratio: ', num2str(framebound_ratio)]); for kk = 1:length(fac) %[jj,kk] atemp = a; idx = [2:length(fc)/2,length(fc)/2+2:length(fc)]; atemp(idx,2) = ceil(atemp(idx,2).*fac(kk)); red(jj,kk) = sum(atemp(:,2)./atemp(:,1)); [g,asan]=filterbankwin(g,atemp,L,'normal'); gtemp=comp_filterbank_pre(g,asan,L,10); gtemp{1}.H = gtemp{1}.H.*sqrt(fac(kk)); gtemp{length(fc)/2+1}.H = gtemp{length(fc)/2+1}.H.*sqrt(fac(kk)); F = frame('filterbank',gtemp,asan,numel(gtemp)); [A(jj,kk),B(jj,kk)] = framebounds(F,Ls,'tol',eigstol,'pcgtol',pcgtol,'maxit',eigsmaxit,'pcgmaxit',pcgmaxit); end end disp('This is a ratio B/A. Rows - warping sunction, Cols - redundancy compared to te minimal painless case') B./A ltfat/inst/private/test_gdgt.m0000664000175000017500000000531413026262303016355 0ustar susnaksusnakfunction test_failed=test_gdgt %-*- texinfo -*- %@deftypefn {Function} test_gdgt %@verbatim %TEST_GDGT Test GDGT % % This script runs a throrough test of the COMP_GDGT routine, testing it on % a range of input parameters. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[24,144,108,144,24,135,35,77,20]; ar=[ 4, 9, 9, 12, 6, 9, 5, 7, 1]; Mr=[ 6, 16, 12, 24, 8, 9, 7,11,20]; R=1; test_failed=0; disp(' =============== TEST_GDGT ================'); for ii=1:length(Lr); for ctii=0:1 c_t=ctii*.5; for cfii=0:1 c_f=cfii*.5; for W=1:3 L=Lr(ii); M=Mr(ii); a=ar(ii); b=L/M; N=L/a; c=gcd(a,M); d=gcd(b,N); p=a/c; q=M/c; %g=(1:L)'; %g=i*gabtight(a,b,L); f=tester_crand(L,W); g=tester_crand(L,R); gd=gabdual(g,a,M); gt=gabtight(g,a,M); cc=comp_gdgt(f,g,a,M,L,c_t,c_f,0,0); cc2=reshape(ref_gdgt(f,g,a,M,c_t,c_f,0),M,N,W); cdiff=cc-cc2; res=norm(cdiff(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['REF L:%3i c_t: %0.5g c_f %0.5g ', ... 'W:%2i R:%2i a:%3i b:%3i c:%3i ', ... 'd:%3i p:%3i q:%3i %0.5g %s'],... L,c_t,c_f,W,R,a,b,c,d,p,q,res,fail); disp(s) r=comp_igdgt(cc,gd,a,M,L,c_t,c_f,0,0); res=norm(f-r,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['REC L:%3i c_t: %0.5g c_f %0.5g ',... 'W:%2i R:%2i a:%3i b:%3i c:%3i ',... 'd:%3i p:%3i q:%3i %0.5g %s'],... L,c_t,c_f,W,R,a,b,c,d,p,q,res,fail); disp(s) res=norm(f-idgt(dgt(f,gt,a,M),gt,a),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['TIG L:%3i c_t: %0.5g c_f %0.5g ',... 'W:%2i R:%2i a:%3i b:%3i c:%3i ',... 'd:%3i p:%3i q:%3i %0.5g %s'],... L,c_t,c_f,W,R,a,b,c,d,p,q,res,fail); disp(s); end; end; end; end; ltfat/inst/private/ref_dstiii.m0000664000175000017500000000244113026262303016510 0ustar susnaksusnakfunction c=ref_dstiii(f) %-*- texinfo -*- %@deftypefn {Function} ref_dstiii %@verbatim %REF_DSTIII Reference Discrete Sine Transform type III % Usage: c=ref_dstiii(f); % % This is the inverse of DSTII %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dstiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=ones(L,1); w(L)=1/sqrt(2); w=w*sqrt(2/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w(n+1)*sin(pi*(n+1)*(m+.5)/L); end; end; % Compute coefficients. c=F*f; ltfat/inst/private/ref_dwilt_1.m0000664000175000017500000000503513026262303016570 0ustar susnaksusnakfunction [coef]=ref_dwilt_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwilt_1 %@verbatim %COMP_DWILT Compute Discrete Wilson transform by DGT % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwilt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; W=size(f,2); coef2=dgt(f,g,a,2*M); coef=zeros(2*M,N/2,W); if 1 % Loop version for n=0:N/2-1 % ---- m is zero --------- coef(1,n+1,:)=coef2(1,2*n+1,:); for m=1:2:M-1 % --- m is odd ---------- coef(m+1,n+1,:)= i/sqrt(2)*(coef2(m+1,2*n+1,:)-coef2(2*M-m+1,2*n+1,:)); coef(M+m+1,n+1,:)=1/sqrt(2)*(coef2(m+1,2*n+2,:)+coef2(2*M-m+1,2*n+2,:)); end; for m=2:2:M-1 % --- m is even --------- coef(m+1,n+1,:)= 1/sqrt(2)*(coef2(m+1,2*n+1,:)+coef2(2*M-m+1,2*n+1,:)); coef(M+m+1,n+1,:)=i/sqrt(2)*(coef2(m+1,2*n+2,:)-coef2(2*M-m+1,2*n+2,:)); end; % --- m is nyquest ------ if mod(M,2)==0 coef(M+1,n+1,:) = coef2(M+1,2*n+1,:); else coef(M+1,n+1,:) = coef2(M+1,2*n+2,:); end; end; else % Vector version % ---- m is zero --------- coef(1,:,:)=coef2(1,2*n+1,:); % --- m is odd ---------- % sine, first column. coef(2:2:M,:,:)=1/sqrt(2)*i*(coef2(2:2:M,1:2:N,:)-coef2(2*M:-2:M+2,1:2:N,:)); % cosine, second column 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 --------- % cosine, first column. coef(3:2:M,:,:)=1/sqrt(2)*(coef2(3:2:M,1:2:N,:)+coef2(2*M-1:-2:M+2,1:2:N,:)); % sine, second column 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,:)); % --- m is nyquest ------ 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; coef=reshape(coef,M*N,W); ltfat/inst/private/ref_irdgt.m0000664000175000017500000000311613026262303016334 0ustar susnaksusnakfunction f=ref_irdgt(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_irdgt %@verbatim %REF_IRDGT Reference Inverse Real DGT % Usage: c=ref_rdgt(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); b=L/M; N=L/a; Mhalf=ceil(M/2); F=zeros(L,M*N); l=(0:L-1).'; for n=0:N-1 % Do the unmodulated coefficient. F(:,M*n+1)=circshift(g,n*a); for m=1:Mhalf-1 F(:,M*n+2*m)=sqrt(2)*cos(2*pi*m*l/M).*circshift(g,n*a);; F(:,M*n+2*m+1)=sqrt(2)*sin(2*pi*m*l/M).*circshift(g,n*a);; end; if mod(M,2)==0 F(:,M*(n+1))=cos(pi*l).*circshift(g,n*a);; end; end; % dot-transpose will work because F is real. f=F*c; ltfat/inst/private/ref_rdgt3_1.m0000664000175000017500000000256313026262303016473 0ustar susnaksusnakfunction c=ref_rdgt3_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_rdgt3_1 %@verbatim %REF_RDGT3_1 Reference Real DGT type 3 % Usage: c=ref_rdgt3_1(f,g,a,M); % % Compute a DGT3 and pick out the coefficients %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdgt3_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); R=size(g,2); N=L/a; Mhalf=floor(M/2); cc=ref_gdgt(f,g,a,M,0,.5,0); cc=reshape(cc,M,N,W); c=zeros(M,N,W); for m=0:Mhalf-1 c(2*m+1,:,:)=sqrt(2)*real(cc(m+1,:,:)); c(2*m+2,:,:)=-sqrt(2)*imag(cc(m+1,:,:)); end; if mod(M,2)==1 c(M,:,:)=cc((M+1)/2,:,:); end; c=reshape(c,M*N,W); ltfat/inst/private/test_demos.m0000664000175000017500000000253313026262303016537 0ustar susnaksusnakfunction test_failed=test_demos %-*- texinfo -*- %@deftypefn {Function} test_demos %@verbatim %TEST_DEMOS Test if all the demos runs without errors. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_demos.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; s=dir([ltfatbasepath,filesep,'demos',filesep,'demo_*.m']); for ii=1:numel(s) filename = s(ii).name; disp(filename); % The demo is run in separate function to avoid % variable name clash rundemo(filename(1:end-2)); end; function rundemo(demoname) close all; eval(demoname); ltfat/inst/private/ref_pchirp.m0000664000175000017500000000467613026262303016524 0ustar susnaksusnakfunction g=ref_pchirp(L,n) %-*- texinfo -*- %@deftypefn {Function} ref_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.github.io/doc/reference/ref_pchirp.html} %@seealso{dft, expwave} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard % TESTING: OK % REFERENCE: OK error(nargchk(2,2,nargin)); % Compute normalized chirp % Old code, has low numerical precision and do not work correctly for odd legths. %g=(exp((0:L-1).^2/L*pi*i*n)/sqrt(L)).'; % Compute normalized chirp m = (0:L-1).'; %X = mod(n*(m-ceil(L/2)).^2*(L+1),2*L); X = mod(n*m.^2*(L+1),2*L); g = exp(pi*1i*X/L); ltfat/inst/private/ref_edgtii.m0000664000175000017500000000334613026262303016475 0ustar susnaksusnakfunction c=ref_edgtii(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_edgtii %@verbatim %REF_EDGTII Reference Even Discrete Gabor transform type II % Usage c=ref_edgt(f,g,a,M); % % If a is even, then the input window must be odd-centered of length 2L. % % If a is odd, then the input window must be even-centered of length 2L. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_edgtii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); N=L/a; b=L/M; %Fold=zeros(2*L,M*N); F=zeros(L,M*N); %l2=(0:2*L-1).'; l=(0:L-1).'; %lfirst=(0:L-1).'; lsecond=(2*L-1:-1:L).'; gnew=circshift(g,floor(a/2)); for n=0:N-1 for m=0:M-1 %Fold(:,M*n+m+1)=exp(2*pi*i*m*(l2+.5)/M).*circshift(gnew,n*a); gshift=circshift(gnew,n*a); %F(:,M*n+m+1)=exp(2*pi*i*m*(lfirst+.5)/M).*gshift(l+1) + ... % exp(2*pi*i*m*(lsecond+.5)/M).*gshift(lsecond+1); F(:,M*n+m+1)=exp(2*pi*i*m*(l+.5)/M).*gshift(l+1) + ... exp(-2*pi*i*m*(l+.5)/M).*gshift(lsecond+1); end; end; c=F'*f; ltfat/inst/private/test_pfilt_1.m0000664000175000017500000000343613026262303016771 0ustar susnaksusnakfunction test_failed=test_pfilt %-*- texinfo -*- %@deftypefn {Function} test_pfilt_1 %@verbatim % % % This is the old test_pfilt from before the struct filters was % introduced. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pfilt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr =[9,9,10,10,10,12]; Lgr=[9,4,10, 7,10,12]; ar =[3,3, 5, 5, 1, 3]; test_failed=0; disp(' =============== TEST_PFILT =============='); disp('--- Used subroutines ---'); which comp_pfilt for jj=1:length(Lr) L=Lr(jj); Lg=Lgr(jj); a=ar(jj); for W=1:3 for rtype=1:2 if rtype==1 rname='REAL '; f=tester_rand(L,W); g=tester_rand(Lg,1); else rname='CMPLX'; f=tester_crand(L,W); g=tester_crand(Lg,1); end; h1=pfilt(f,g,a); h2=ref_pfilt(f,g,a); res=norm(h1-h2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PFILT %3s L:%3i W:%3i Lg:%3i a:%3i %0.5g %s',rname,L,W,Lg,a,res,fail); disp(s); end; end; end; ltfat/inst/private/test_dgt2.m0000664000175000017500000000432113026262303016265 0ustar susnaksusnakfunction test_failed=test_dgt2 test_failed=0; disp(' =============== TEST_DGT2 ================'); %-*- texinfo -*- %@deftypefn {Function} test_dgt2 %@verbatim % Run some fixed test to test the interface. % This is not a thourough tester. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % --- first test a=6; M=8; Lf=71; L=72; W=3; f=tester_rand(Lf,Lf,W); g=pgauss(L,a*M/L); gd=gabdual(g,a,M); [c,Ls]=dgt2(f,g,a,M); r=idgt2(c,gd,a,Ls); res=f-r; nres=norm(res(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); %failed=''; %if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; %end; s=sprintf('DGT2 Lf:%3i L:%3i %0.5g %s',Lf,L,nres,fail); disp(s) % --- second test a1=6; M1=8; a2=5; M2=10; L1=a1*M1; L2=a2*M2; W=1; f=tester_rand(L1,L2,W); g1=pgauss(L1,a1*M1/L1); g2=pgauss(L2,a2*M2/L2); gd1=gabdual(g1,a1,M1); gd2=gabdual(g2,a2,M2); c=dgt2(f,g1,g2,[a1,a2],[M1,M2]); c2=ref_dgt2(f,g1,g2,a1,a2,M1,M2); rc=c-c2; nres=norm(rc(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); %failed=''; %if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; %end; s=sprintf('DGT2 REF L1:%3i L2:%3i %0.5g %s',L1,L2,nres,fail); disp(s) r=idgt2(c,gd1,gd2,[a1,a2]); res=r-f; nres=norm(res(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); %failed=''; %if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; %end; s=sprintf('DGT2 INV L1:%3i L2:%3i %0.5g %s',L1,L2,nres,fail); disp(s) ltfat/inst/private/ref_isfac.m0000664000175000017500000000310013026262303016301 0ustar susnaksusnakfunction [f]=ref_isfac(ff,L,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_isfac %@verbatim %REF_ISFAC Reference inverse signal factorization % Usage: f=ref_sfac(ff,a,M); % % Input parameters: % ff : Factored signal % a : Length of time shift. % b : Length of frequency shift. % Output parameters: % f : Output signal. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_isfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Calculate the parameters that was not specified W=prod(size(ff))/L; N=L/a; M=L/b; % The four factorization parameters. [c,h_a,h_m]=gcd(a,M); p=a/c; q=M/c; d=N/q; permutation=zeros(q*b,1); P=stridep(p,b); % Create permutation for l=0:q-1 for s=0:b-1 permutation(l*b+1+s)=mod(P(s+1)-1-h_m*l,b)*M+l*c+1; end; end; f=ref_ifac(ff,W,c,d,p,q,permutation); ltfat/inst/private/test_phaselock.m0000664000175000017500000000574013026262303017404 0ustar susnaksusnakfunction test_failed=test_phaselock %-*- texinfo -*- %@deftypefn {Function} test_phaselock %@verbatim %TEST_PHASELOCK Test phaselock and phaseunlock % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_phaselock.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_PHASELOCK ================'); % set up parameters L=420; f=tester_rand(L,1); g=pgauss(L); a=10;b=30;M=L/b; c = dgt(f,g,a,M); cp1 = ref_phaselock(c,a); cp2 = phaselock(c,a,'lt',[0 1]); % compare original phaselock with mine for rectangular case res=norm(cp1-cp2,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASELOCK REF RECT %0.5g %s\n'],res,fail); % comparisons for non-separable case c_big = dgt(f,g,a,2*M); c_quin = dgt(f,g,a,M,'lt',[1 2]); c_bigp = phaselock(c_big,a); c_quinp= phaselock(c_quin,a,'lt',[1 2]); % compare the quincunx lattice with twice transform on twice as many % chanels res=norm(c_bigp(1:2:end,1)-c_quinp(:,1),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASELOCK QUIN 1 %0.5g %s\n'],res,fail); res=norm(c_bigp(2:2:end,2)-c_quinp(:,2),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASELOCK QUIN 2 %0.5g %s\n'],res,fail); % testing of phaseunlock routine res=norm(c_big - phaseunlock(c_bigp,a),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASEUNLOCK RECT %0.5g %s\n'],res,fail); res=norm(c_quin - phaseunlock(c_quinp,a,'lt',[1 2]),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASEUNLOCK QUIN %0.5g %s\n'],res,fail); cfi = dgtreal(f,g,a,M); cti = dgtreal(f,g,a,M,'timeinv'); res=norm(cfi - phaseunlockreal(cti,a,M),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASEUNLOCKREAL %0.5g %s\n'],res,fail); res=norm(phaselockreal(cfi,a,M) - cti,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASELOCKREAL %0.5g %s\n'],res,fail); res=norm(cfi - phaseunlockreal(cti,a,M,'precise'),'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASEUNLOCKREAL PREC %0.5g %s\n'],res,fail); res=norm(phaselockreal(cfi,a,M,'precise') - cti,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PHASELOCKREAL PREC %0.5g %s\n'],res,fail); ltfat/inst/private/test_constructphase.m0000664000175000017500000001013513026262303020472 0ustar susnaksusnakfunction test_failed=test_constructphase %-*- texinfo -*- %@deftypefn {Function} test_constructphase %@verbatim %TEST_CONSTRUCTPHASE % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_constructphase.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; disp(' =================== TEST_CONSTRUCTPHASE ====================== '); forig = greasy; g = 'gauss'; a = 16; M = 1024; tolcell = {1e-10,[1e-1 1e-10],[1e-1 1e-3 1e-10]}; Warray = [1, 3]; for W=Warray f = repmat(forig,1,W); f = bsxfun(@times,f,[1:W]); global LTFAT_TEST_TYPE; if strcmpi(LTFAT_TEST_TYPE,'single') f = cast(f,'single'); end for pcId = 1:2 % Complex case phaseconv = getat({'timeinv','freqinv'},pcId); for tId = 1:numel(tolcell) tol = getat(tolcell,tId); tolstr = sprintf('%.2e, ',tol); tolstr = tolstr(1:end-2); tra = @(f) dgt(f,g,a,M,phaseconv); itra = @(c) idgt(c,{'dual',g},a,phaseconv); proj = @(c) tra(itra(c)); c = tra(f); s = abs(c); % Normal call chat = constructphase(s,g,a,tol,phaseconv); E = comperr(s,proj(chat)); fail = ''; if E>-19 test_failed = test_failed + 1; fail = 'FAILED'; end fprintf('CONSTRUCTPHASE %s tol=[%s] W=%d E=%.2f %s\n',phaseconv,tolstr,W,E,fail); % Known part mask = zeros(size(s)); mask(:,1:floor(size(s,2)/2),:) = 1; chat = constructphase(s,g,a,tol,mask,angle(c),phaseconv); E = comperr(s,proj(chat)); chat2 = constructphase(c,g,a,tol,mask,phaseconv); E2 = comperr(s,proj(chat2)); fail = ''; if E>-19 || abs(E-E2) > 0.1 test_failed = test_failed + 1; fail = 'FAILED'; end fprintf('CONSTRUCTPHASE MASK %s tol=[%s] W=%d E=%.2f %s\n',phaseconv,tolstr,W,E,fail); tra = @(f) dgtreal(f,g,a,M,phaseconv); itra = @(c) idgtreal(c,{'dual',g},a,M,phaseconv); proj = @(c) tra(itra(c)); c = tra(f); s = abs(c); chat = constructphasereal(s,g,a,M,tol,phaseconv); E = comperr(s,proj(chat)); fail = ''; if E>-18 test_failed = test_failed + 1; fail = 'FAILED'; end fprintf('CONSTRUCTPHASEREAL %s tol=[%s] W=%d E=%.2f %s\n',phaseconv,tolstr,W,E,fail); % Known part mask = zeros(size(s)); mask(:,1:floor(size(s,2)/2),:) = 1; chat = constructphasereal(s,g,a,M,tol,mask,angle(c),phaseconv); E = comperr(s,proj(chat)); chat2 = constructphasereal(c,g,a,M,tol,mask,phaseconv); E2 = comperr(s,proj(chat2)); fail = ''; if E>-19 || abs(E-E2) > 0.1 test_failed = test_failed + 1; fail = 'FAILED'; end fprintf('CONSTRUCTPHASEREAL MASK %s tol=[%s] W=%d E=%.2f %s\n',phaseconv,tolstr,W,E,fail); end end end function el = getat(collection,id) if iscell(collection) el = collection{id}; else el = collection(id); end function E = comperr(s,c) E = 20*log10(norm(abs(s(:))-abs(c(:)),'fro')/norm(abs(s(:)),'fro')); ltfat/inst/private/ref_idwiltiii.m0000664000175000017500000000471613026262303017221 0ustar susnaksusnakfunction f=ref_idwiltiii(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwiltiii %@verbatim %REF_IDWILTIII Reference Inverse DWILT type III % Usage: f=ref_idwiltiii(c,g,a,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwiltiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); W=size(c,2); N=L/a; F=zeros(L,M*N); l=(0:L-1)'; pif=pi/4; for n=0:floor(N/2)-1 for m=0:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*pi*l/M+pif); F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*sin((m+.5)*pi*l/M+pif); end; for m=1:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*sin((m+.5)*pi*l/M+pif); F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*cos((m+.5)*pi*l/M+pif); end; end; f=F*c; if 0 pif=pi/4; for n=0:floor(N/2)-1 for m=0:2:M-1 %F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*(pi/M.*l-pi/2)); %F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos( ... % m*pi*l/M -m*pi/2+pi*l/(2*M)-pi/4); F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*pi*l/M+pif); end; for m=1:2:M-1 %F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*(pi/M.*l-pi/2)); %F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos( ... % m*pi*l/M -m*pi/2+pi*l/(2*M)-pi/4); F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*sin((m+.5)*pi*l/M+pif); end; %for m=0:M-1 % F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*sin((m+.5)*(pi/M.*l-pi/2)); %end; for m=0:2:M-1 F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*sin((m+.5)*pi*l/M+pif); end; for m=1:2:M-1 F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*cos((m+.5)*pi*l/M+pif); end; end; end; ltfat/inst/private/ref_tconv.m0000664000175000017500000000250513026262303016355 0ustar susnaksusnakfunction h=ref_tconv(f,g,a) %-*- texinfo -*- %@deftypefn {Function} ref_tconv %@verbatim %REF_PCONV Reference TCONV % Usage: h=ref_tconv(f,g,a) % % TCONV(f,g,a) computes the twisted convolution of f and g. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_tconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard M=size(f,1); N=size(f,2); h=zeros(M,N); theta=a/M; for m=0:M-1 for n=0:N-1 for l=0:N-1 for k=0:M-1 h(m+1,n+1)=h(m+1,n+1)+f(k+1,l+1)*g(mod(m-k,M)+1,mod(n-l,N)+1)*... exp(2*pi*i*theta*(m-k)*l); end; end; end; end; ltfat/inst/private/ref_gabtight.m0000664000175000017500000000223113026262303017011 0ustar susnaksusnakfunction gd=ref_gabtight(g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_gabtight %@verbatim %REF_GABTIGHT Reference GABTIGHT % Usage: gd=ref_gabtight(g,a,M); % % Calculate the canonical tight window by simple linear algebra %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabtight.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . g = double(g); G=frsynmatrix(frame('dgt',g,a,M),length(g)); gd=(G*G')^(-1/2)*g; ltfat/inst/private/ref_rdgtii.m0000664000175000017500000000321113026262303016501 0ustar susnaksusnakfunction c=ref_rdgtii(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_rdgtii %@verbatim %REF_RDGTII Reference Real DGT type II % Usage: c=ref_rdgt(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdgtii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); b=L/M; N=L/a; Mhalf=ceil(M/2); F=zeros(L,M*N); l=(0:L-1).'; for n=0:N-1 % Do the unmodulated coefficient. F(:,M*n+1)=circshift(g,n*a+floor(a/2)); for m=1:Mhalf-1 F(:,M*n+2*m)=sqrt(2)*cos(2*pi*m*(l+.5)/M).*circshift(g,n*a+floor(a/2)); F(:,M*n+2*m+1)=sqrt(2)*sin(2*pi*m*(l+.5)/M).*circshift(g,n*a+floor(a/2)); end; if mod(M,2)==0 F(:,M*(n+1))=cos(pi*l).*circshift(g,n*a+floor(a/2)); end; end; % dot-transpose will work because F is real. c=F.'*f; ltfat/inst/private/ref_lconv.m0000664000175000017500000000322313026262303016343 0ustar susnaksusnakfunction h = ref_lconv(f,g,ctype) %-*- texinfo -*- %@deftypefn {Function} ref_lconv %@verbatim %REF_LCONV Reference linear convolution % Usage: h=ref_lconv(f,g) % % PCONV(f,g) computes the linear convolution of f and g. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_lconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven Lf = length(f); Lg = length(g); Lh = Lf+Lg-1; f = [f; zeros(Lh - Lf, 1)]; g = [g; zeros(Lh - Lg, 1)]; h = zeros(Lf+Lg-1, 1); switch(lower(ctype)) case {'default'} for ii = 0 : Lh-1 for jj = 0 : Lh-1 h(ii+1)=h(ii+1)+f(jj+1)*g(mod(ii-jj,Lh)+1); end end case {'r'} for ii=0:Lh-1 for jj=0:Lh-1 h(ii+1)=h(ii+1)+f(jj+1)*conj(g(mod(jj-ii, Lh)+1)); end; end; case {'rr'} for ii=0:Lh-1 for jj=0:Lh-1 h(ii+1)=h(ii+1)+conj(f(mod(-jj, Lh)+1))*conj(g(mod(jj-ii,Lh)+1)); end; end; end ltfat/inst/private/ref_fac.m0000664000175000017500000000355413026262303015762 0ustar susnaksusnakfunction ff=ref_fac(f,W,c,d,p,q,permutation) %-*- texinfo -*- %@deftypefn {Function} ref_fac %@verbatim %REF_FAC Reference factorization. % % This function cannot handle multidimensional arrays. % Reshape to matrix BEFORE you call this. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_fac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Output ff=zeros(p*q*W,c*d); % If d==1, it is not possible to further reduce the size of % wk. Actually, some of the following code produces an % error, because Matlab interprets an fft of a 1x q*W*p as a % a row operation ! if d>1 % Shape to match first fft pass. work=zeros(d,q*W*p); % This loop iterates over the number of truly different wk's. for ko=0:c-1 % Permute and copy into work array. % Format is suited for fft. work(:)=f(permutation+ko,:); % Execute the fft and place transposed in ff. ff(:,1+ko*d:(ko+1)*d)=fft(work.',[],2); end; else % Work arrays. work=zeros(p*q*W,1); for ko=0:c-1 % Permute input. work(:)=f(permutation+ko,:); % Write the block. ff(:,ko+1)=work; end end; ltfat/inst/private/ref_dftiv.m0000664000175000017500000000237613026262303016346 0ustar susnaksusnakfunction c=ref_dftiv(f) %-*- texinfo -*- %@deftypefn {Function} ref_dftiv %@verbatim %REF_DFT Reference Discrete Fourier Transform Type IV % Usage: c=ref_dftiv(f); % % This is highly experimental! %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dftiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create weights. w=sqrt(1/L); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w*exp(2*pi*i*(m+.5)*(n+.5)/L); end; end; % Compute coefficients. c=F'*f; ltfat/inst/private/test_wfac.m0000664000175000017500000000420713026262303016350 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_wfac %@verbatim %TEST_WFAC Test COMP_WFAC % % This script runs a test of only the comp_wfac and comp_iwfac procedures. % % The script TEST_DGT will test the complete DGT implementation. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr=[24,16,144,108,144,24,135,35,77,20]; ar=[ 4, 4, 9, 9, 12, 6, 9, 5, 7, 1]; Mr=[ 6, 8, 16, 12, 24, 8, 9, 7,11,20]; test_failed=0; which comp_wfac which comp_iwfac for ii=1:length(Lr); for R=1:3 L=Lr(ii); M=Mr(ii); a=ar(ii); b=L/M; N=L/a; c=gcd(a,M); d=gcd(b,N); p=a/c; q=M/c; g=tester_crand(L,R); gf1=comp_wfac(g,a,M); gf2=ref_wfac(g,a,M); cdiff=gf1-gf2; res=norm(cdiff(:)); if res>10e-10 disp('FAILED WFAC'); test_failed=test_failed+1; end; s=sprintf('WFAC L:%3i R:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i %0.5g',L,R,a,b,c,d,p,q,res); disp(s) gf=tester_crand(p*q*R,c*d); g1=comp_iwfac(gf,L,a,M); g2=ref_iwfac(gf,L,a,M); cdiff=g1-g2; res=norm(cdiff(:)); if res>10e-10 disp('FAILED IWFAC'); test_failed=test_failed+1; end; s=sprintf('IWFAC L:%3i R:%2i a:%3i b:%3i c:%3i d:%3i p:%3i q:%3i %0.5g',L,R,a,b,c,d,p,q,res); disp(s) end; end; test_failed ltfat/inst/private/test_gabmul.m0000664000175000017500000001300613026262303016674 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} test_gabmul %@verbatim % Compare approximation by Gabor Multiplier by LTFAT and XXL % % using % LTFAT - this toolbox % XXL - the collection of MATLAB files by P. Balazs found at % http://www.kfs.oeaw.ac.at/xxl/Dissertation/matlabPhDXXL.html % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabmul.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . clear; if exist('gabbaspIrr','file') ~= 2 disp('In this test file the LTFAT implementation is compared to the one found at'); disp('http://www.kfs.oeaw.ac.at/xxl/Dissertation/matlabPhDXXL.html .'); disp('Please download and put in search path!'); return else disp(' '); disp(' Compare approximation by Gabor Multiplier by LTFAT and XXL '); disp(' '); end L = 144; % vector length a = 8; % time parameter, hop size b = 9; % frequency parameter usetargetmult = 1; % use a multiplier as target? N = L/a; M = L/b; % number of filters red = L/(a*b); % redundancy n_fram = N*M; % number of frame elements xpo = lattp(L,a,b); % time-frequency sampling points % Creation of Windows: g = gabtight(a,M,L); g = [zeros(1,ceil(L/3)) fftshift(gaussnk(floor(2*L/3)))].'; g = g + i*g; % here tight, so dual = primal % gs = pgauss(L); % gs = gabdual(g,a,M); % gs = eye(L,1); % gs = [1 1 1 0 0 0]; % gs = g+10*eps; gs = randc(L,1); gd = gabdual(g,a,M); gsd = gabdual(gs,a,M); % Creation of target system if usetargetmult == 0 % random matrix as target T = randc(L,L)+i*randc(L,L); else % random multiplier as target origsym = randc(M,N)+i*randc(M,N); T = gabmulmat(origsym,g,gs,a); end % Frame synthesis matrices: G_xxl = gabbaspIrr(g,xpo); % XXL Ga = tfmat('dgt',g,a,M); Gs = tfmat('dgt',gs,a,M); Gd = tfmat('dgt',gd,a,M); % check frame condition if cond(Ga) == Inf disp('The analysis filterbank does not form a frame!'); else disp(sprintf('The analysis filterbank forms a frame with frame bound ratio %g.',cond(Ga)^2)); end if cond(Gs) == Inf disp('The synthesis filterbank does not form a frame!'); % check if gabmulappr gives error! else disp(sprintf('The synthesis filterbank forms a frame with frame bound ratio %g.',cond(Gs)^2)); end Gram = (Gs'*Gs) .* conj(Ga'*Ga); % Frame matrix for tensor products S_tensor = []; for ii = 1:n_fram P = Ga(:,ii)*Gs(:,ii)'; S_tensor = [S_tensor P(:)]; end; % % Gram matrix in HS if cond(S_tensor) == Inf disp('The tensor products do not form a frame sequence!'); else disp(sprintf('The tensor products form a frame sequence with frame bound ratio %g.',cond(S_tensor))); if det(Gram) ~= 0 disp('They form a Riesz sequence!'); end end disp(' '); disp('--- Comparing Gabor systems: ---'); compnorm(G_xxl.',Ga); lowsym_direct = zeros(M*N,1); %lower symbol as in GMAPPIR for ii=1:n_fram lowsym_direct(ii) = (Gs(:,ii)')*(T*Ga(:,ii)); end; lowsym_direct = reshape(lowsym_direct,M,N); % reordering (conj/invol.) due to TF structure lowsym_xxl = reshape(diag(Gs'*(T*Ga)),M,N); lowsym_ltfat = mat2low(T.',g,gs,a,M); % lowsym_ltfat(T) = lowsym_xxl(T).' = lowsym_ltfat ( T.') disp('--- Comparing lower symbols: ---'); compnorm(lowsym_xxl,lowsym_direct); compnorm(lowsym_ltfat,lowsym_xxl); % % upper symbol: pinvGram = pinv(Gram); uppsym_xxl = reshape(pinvGram*(lowsym_xxl(:)),M,N); uppsym_direct = reshape(pinvGram*(lowsym_direct(:)),M,N); % uppsym_new = low2upp(lowsym_xxl,g,gs,a); uppsym_ltfat = gabmulappr(T,g,gs,a,M); % new idea % we know: reshape(dgt(T,g,a,M),M,N)-Ga'*T == 0 % so later use (also above) the faster dgt [GM_irr,uppsym_irr] = GMAPPir(T.',xpo,g,gs); uppsym_irr = reshape(uppsym_irr,M,N); disp('--- Comparing upper symbols: ---'); compnorm(uppsym_xxl,uppsym_ltfat); compnorm(uppsym_xxl,uppsym_direct); compnorm(uppsym_irr,uppsym_direct); % compnorm(uppsym_ltfat,uppsym_new); % compnorm(uppsym_ltfat,uppsym_xxl); if usetargetmult == 1 disp(' - Comparing to original symbol: -'); compnorm(uppsym_ltfat,origsym); end % XXL GM_ltfat = gabmulmat(uppsym_ltfat,g,gs,a); % conjugation works for Gabor multiplier!! GM_test = zeros(L,L); for ii = 1:N*M P = Ga(:,ii)*Gs(:,ii)'; GM_test = GM_test + uppsym_direct(ii)*P; end; % direct GM_direct = Gs*(diag(uppsym_direct(:))*Ga'); disp('--- Comparing matrices: ---'); compnorm(GM_direct,GM_ltfat); compnorm(GM_ltfat,GM_irr.'); % !!!!!!!!!!!!!!!! % compnorm(GM_irr,GM_direct); disp('--- Approximation error: ---'); compnorm(GM_ltfat,T); compnorm(GM_irr.',T); compnorm(GM_direct,T); % %-------------------- % % new idea: % % use matrix representation of operator % % take the diagonal for multiplier: % uppsym_soend = diag(reshape(dgt(T*Gd,g,a,M),9,9)); % GM_soend = Gs*(diag(uppsym_soend(:))*Ga'); % % disp('----- Comparing new idea: -------'); % compnorm(uppsym_direct,uppsym_soend); % compnorm(GM_direct,GM_soend); % compnorm(GM_soend,T); ltfat/inst/private/ref_idwiltiv.m0000664000175000017500000000304213026262303017054 0ustar susnaksusnakfunction f=ref_idwiltiv(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwiltiv %@verbatim %REF_IDWILTIV Reference Inverse DWILT type IV % Usage: c=ref_idwiltiv(f,g,a,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwiltiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); W=size(c,2); N=L/a; F=zeros(L,M*N); k=(0:L-1)'; pif=pi/4; for n=0:floor(N/2)-1 for m=0:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*cos((m+.5)*pi*(k+.5)/M+pif); end; for m=1:2:M-1 F(:,1+m+2*n*M)=sqrt(2)*circshift(g,2*n*a).*sin((m+.5)*pi*(k+.5)/M+pif); end; for m=0:2:M-1 F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*sin((m+.5)*pi*(k+.5)/M+pif); end; for m=1:2:M-1 F(:,1+m+(2*n+1)*M)=sqrt(2)*circshift(g,(2*n+1)*a).*cos((m+.5)*pi*(k+.5)/M+pif); end; end; f=F*c; ltfat/inst/private/test_wmdct2.m0000664000175000017500000000424513026262303016632 0ustar susnaksusnakfunction test_failed=test_wmdct2 test_failed=0; disp(' =============== TEST_WMDCT2 ================'); %-*- texinfo -*- %@deftypefn {Function} test_wmdct2 %@verbatim % Run some fixed test to test the interface. % This is not a thourough tester. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wmdct2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % --- test 1 ---------------- L=64; M=8; Lf=63; W=3; f=tester_rand(Lf,Lf,W); g=pgauss(L,1); gd=wildual(g,M); [c,Ls]=wmdct2(f,g,M); r=iwmdct2(c,gd,Ls); res=r-f; nres=norm(res(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); % failed=''; % if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; % end; s=sprintf('WMDCT2 Lf:%3i L:%3i %0.5g %s',Lf,L,nres,fail); disp(s) % --- test 2 ------------------- L=256; M1=16; M2=32; W=1; f=tester_rand(L,L,1); g=pgauss(L,1); gd1=wildual(g,M1); gd2=wildual(g,M2); c=wmdct2(f,g,[M1,M2]); c2=ref_wmdct2(f,g,g,M1,M2); rc=c-c2; nres=norm(rc(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); % failed=''; % if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; % end; s=sprintf('WMDCT2 REF M1:%3i M2:%3i %0.5g %s',M1,M2,nres,fail); disp(s) r=iwmdct2(c,gd1,gd2); res=r-f; nres=norm(res(:)); [test_failed,fail]=ltfatdiditfail(nres,test_failed); % failed=''; % if nres>10e-10 % failed='FAILED'; % test_failed=test_failed+1; % end; s=sprintf('WMDCT2 INV M1:%3i M2:%3i %0.5g %s',M1,M2,nres,fail); disp(s) ltfat/inst/private/ref_dcti.m0000664000175000017500000000262013026262303016145 0ustar susnaksusnakfunction c=ref_dcti(f) %-*- texinfo -*- %@deftypefn {Function} ref_dcti %@verbatim %REF_DCTI Reference Discrete Consine Transform type I % Usage: c=ref_dcti(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dcti.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); if L==1 % Doing the algorithm explicitly for L=1 does a division by % zero, so we exit here instead. c=f; return; end; % Create weights. w=ones(L,1); w(1)=1/sqrt(2); w(L)=1/sqrt(2); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=w(n+1)*w(m+1)*cos(pi*n*m/(L-1)); end; end; F=F*sqrt(2/(L-1)); % Compute coefficients. c=F'*f; ltfat/inst/private/test_frametf.m0000664000175000017500000000351013026262303017050 0ustar susnaksusnakfunction test_failed=test_frametf %-*- texinfo -*- %@deftypefn {Function} test_frametf %@verbatim %TEST_FRAMETF Test the frames tf-plane conversion % % This tests if framecoef2tf and frametf2coef work. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_frametf.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; L = 456; W = 3; f = tester_rand(L,W); Fr{1} = frame('dgt','gauss',10,20); Fr{1} = frame('dgtreal','gauss',10,20); Fr{3} = frame('dwilt','gauss',20); Fr{4} = frame('wmdct','gauss',20); gfilt={tester_rand(30,1),... tester_rand(20,1),... tester_rand(15,1),... tester_rand(10,1)}; Fr{5} = frame('ufilterbank', gfilt,3,4); Fr{6} = frame('ufwt','db4',4); Fr{7} = frame('uwfbt',{'db4',4}); Fr{8} = frame('uwpfbt',{'db4',4}); for ii=1:numel(Fr) F=Fr{ii}; % To avoid holes in Fr if isempty(F) continue; end; c = frana(F,f); ctf = framecoef2tf(F,c); c2 = frametf2coef(F,ctf); res = norm(c-c2); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('COEFEQ %s %0.5g %s\n',F.type,res,fail); end ltfat/inst/private/ref_irdgt3.m0000664000175000017500000000276713026262303016432 0ustar susnaksusnakfunction f=ref_irdgt3(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_irdgt3 %@verbatim %REF_IRDGT3 Reference Inverse Real DGT type 3 % Usage: c=ref_irdgt3(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdgt3.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); b=L/M; N=L/a; Mhalf=floor(M/2); F=zeros(L,M*N); l=(0:L-1).'/L; for n=0:N-1 for m=0:Mhalf-1 F(:,M*n+2*m+1)=sqrt(2)*cos(2*pi*(m+.5)*b*l).*circshift(g,n*a); F(:,M*n+2*m+2)=sqrt(2)*sin(2*pi*(m+.5)*b*l).*circshift(g,n*a); end; if mod(M,2)==1 F(:,M*(n+1))=cos(pi*L*l).*circshift(g,n*a); end; end; f=F*c; ltfat/inst/private/ref_dgtns_2.m0000664000175000017500000001123213026262303016561 0ustar susnaksusnakfunction coef = ref_dgtns_2(f,g,V); %-*- texinfo -*- %@deftypefn {Function} ref_dgtns_2 %@verbatim %REF_DGTNS_2 DGTNS by A.v.Leests Zak-transform method % Usage: coef = ref_dgtns_2(f,g,V); % % This function calculates the Gabor coefficients C_mk for a given % signal phi and synthesis window w, on a lattice that is described by % the parameters A, p, q, J, and L (see calcg for a description of % these parameters). The function gives only the non-zero elements. % (cf. C = reshape(phi*G',K,M) = Cmk.' with G=gabbas(w,xpo), % K = p*J, M = p*L*det(A) and Cmk the Gabor coefficients calculated % with this function % % The method is based on the Zak transform. % % % % Authors: % Marc Geilen, 1995. (rectangular lattice) % Arno J. van Leest, 1998. (non-separable lattice) % Peter L. Soendergaard, 2006 (change of variable names) %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgtns_2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Conversion of parameters. phi=f; w=g; % V is on Peters normal form. a=V(1,1); b=V(2,2); Lpeter=size(g,1); Mpeter=Lpeter/b; Npeter=Lpeter/a; c=gcd(a,Mpeter); d=gcd(b,Npeter); ppeter=a/c; qpeter=Mpeter/c; % Conversion, part 1 -------------------------- qarno=ppeter; parno=qpeter; J=c; % --------------------------------------------- % 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; [gg,h0,h1] = gcd(A(1,1),A(1,2)); D = det(A); % Stupid, but needed in Octave D=round(D); % ---------- more conversion ------------- Larno=d/D; % --------------------------------------- x = A(2,:)*[h0;h1]; x = mod(x,D); A = [1 0;x D]; %function [g,nrm]=calcg(A,p,q,J,L,w); % Bereken de nodige variabelen. %A = eqform(A); swap = 0; %D=det(A); Marno=parno*Larno*D; Narno=qarno*J; K=parno*J; r=-A(2,1); h=gcd(D,qarno); f=D/h; % Conversion, part 2 ----------- Narno=a; K=Mpeter; Marno=Npeter; % ------------------------------ clear p clear q clear M clear N clear L clear a clear b clear c clear d %function a = calca(A,p,q,J,L,w,phi); %A = eqform(A); %N = q*J; %M = p*L*D; %h = gcd(D,q); %f = D/h; %r = -A(2,1); w = reshape(w,Narno,Marno); phi = reshape(phi,f*parno*Narno,h*Larno); % Bereken de zak-getransformeerde van phi en w. phiz = fft(phi,[],2); wz = fft(w,[],2); % Bereken de matrix lmwz bestaande uit p 'quasi'-periodes van de % zakgetransformeerde van w(n). size(lmwz)=(p*N,M) lmwz = zeros(f*parno*Narno,Marno); O = (0:Marno-1)/Marno; O = O(ones([1 Narno]),:); for n = 0:f*parno-1, lmwz(n*Narno+1:n*Narno+Narno,:) = wz.*exp(j*2*pi*n*O); end % Doe de nodige verschuivingen die nodig zijn voor non-separable lattices. for i = 0:f*qarno-1, lmwz(i*K+1:i*K+K,:) = circshift(lmwz(i*K+1:i*K+K,:),i*r*parno*Larno); phiz(i*K+1:i*K+K,:) = circshift(phiz(i*K+1:i*K+K,:),i*r*parno*Larno); end; % Bereken de fouriergetransformeerde van a_mk m.b.h. de vergelijking % af(n,l)= som over s= K* zphi(n+sK,l;fpN) wz*(n+sK,l;N) af = zeros(K,Marno); for n = 0:K-1, for s = 0:f*parno-1, af(n+1,s*h*Larno+1:s*h*Larno+h*Larno)= ... ... %K*diag(lmwz(n+1:K:f*parno*Narno,s*h*Larno+1:s*h*Larno+h*Larno)'*phiz(n+1:K:f*parno*Narno,:)).'; K*sum(conj(lmwz(n+1:K:f*parno*Narno,s*h*Larno+1:s*h*Larno+h*Larno)).*phiz(n+1:K:f*parno*Narno,:)); end; end; % Doe wat voorbereidingen om de array a te kunnen berekenen. O1 = (0:parno*Larno-1)/Marno; O1 = O1(ones([1 K]),:); O2 = (0:K-1).'/D/K; O2 = O2(:,ones([1 parno*Larno])); af2 = zeros(D*K,parno*Larno); for i = 0:D-1 for v = 0:D-1, af2(i*K+1:i*K+K,:) = af2(i*K+1:i*K+K,:)+af(:,v*parno*Larno+1:v*parno*Larno+parno*Larno).*exp(j*2*pi*i*v/D); end; af2(i*K+1:i*K+K,:) = af2(i*K+1:i*K+K,:).*exp(j*2*pi*(i*O1+mod(i*r,-D)*O2)); end; % Bereken de array a uit de fouriergetransformeerde af2 at = af2; a = at; for i = 0:D-1, at(i*K+1:i*K+K,:) = fft(af2(i*K+1:i*K+K,:),[],1)/K; a(i*K+1:i*K+K,:) = ifft(at(i*K+1:i*K+K,:),[],2)/D; end; a = reshape(a,K,Marno); coef=a(:); ltfat/inst/private/test_pgauss.m0000664000175000017500000000344313026262303016733 0ustar susnaksusnakfunction test_failed=test_pgauss %-*- texinfo -*- %@deftypefn {Function} test_pgauss %@verbatim %TEST_PGAUSS Test PGAUSS %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pgauss.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_PGAUSS ================'); L=19; % Test that tfr=1 works res=norm(pgauss(L)-dft(pgauss(L))); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PGAUSS 1 %0.5g %s\n'],res,fail); % Test dilation property res=norm(pgauss(L,7)-dft(pgauss(L,1/7))); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PGAUSS 2 %0.5g %s\n'],res,fail); % Test norm res=norm(pgauss(L))-1; [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PGAUSS 3 %0.5g %s\n'],res,fail); % Test that dft(freq shift) == time shift res=norm(dft(pgauss(L,'cf',5))-pgauss(L,'delay',5)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['PGAUSS 3 %0.5g %s\n'],res,fail); ltfat/inst/private/test_realout.m0000664000175000017500000000614413026262303017105 0ustar susnaksusnakfunction test_failed=test_realout %-*- texinfo -*- %@deftypefn {Function} test_realout %@verbatim %TEST_REALOUT Test if functions produce real-valued output %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_realout.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_REALOUT ================'); a = 7; M = 19; W = 3; L = a*M*4; Nwil = L/(2*M); Nmd = L/M; Ngab = L/a; Nfft = 19; test_failed=realhelper(test_failed,'dwilt',randn(L,W),randn(L,1),M); test_failed=realhelper(test_failed,'dwilt',randn(L,W),randn(2*M,1),M); test_failed=realhelper(test_failed,'wmdct',randn(L,W),randn(L,1),M); test_failed=realhelper(test_failed,'wmdct',randn(L,W),randn(2*M,1),M); test_failed=realhelper(test_failed,'idwilt',randn(2*M,Nwil),randn(L,1)); test_failed=realhelper(test_failed,'idwilt',randn(2*M,Nwil),randn(2*M,1)); test_failed=realhelper(test_failed,'iwmdct',randn(M,Nmd),randn(L,1)); test_failed=realhelper(test_failed,'iwmdct',randn(M,Nmd),randn(2*M,1)); test_failed=realhelper(test_failed,'gabdual',randn(L,1),a,M); test_failed=realhelper(test_failed,'gabdual',randn(L,1),a,M); test_failed=realhelper(test_failed,'gabtight',randn(M,1),a,M); test_failed=realhelper(test_failed,'gabtight',randn(M,1),a,M); test_failed=realhelper(test_failed,'dcti',randn(Nfft,1)); test_failed=realhelper(test_failed,'dctii',randn(Nfft,1)); test_failed=realhelper(test_failed,'dctiii',randn(Nfft,1)); test_failed=realhelper(test_failed,'dctiv',randn(Nfft,1)); test_failed=realhelper(test_failed,'dsti',randn(Nfft,1)); test_failed=realhelper(test_failed,'dstii',randn(Nfft,1)); test_failed=realhelper(test_failed,'dstiii',randn(Nfft,1)); test_failed=realhelper(test_failed,'dstiv',randn(Nfft,1)); test_failed=realhelper(test_failed,'pfilt',randn(L,1),randn(L,1)); c=dgtreal(randn(L,W),randn(L,1),a,M); test_failed=realhelper(test_failed,'idgtreal',c,randn(L,1),a,M); test_failed=realhelper(test_failed,'idgtreal',c,randn(M,1),a,M); c=fftreal(randn(Nfft,1)); test_failed=realhelper(test_failed,'ifftreal',c,Nfft); function test_failed=realhelper(test_failed,funname,varargin) outres=feval(funname,varargin{:}); res=~isreal(outres); if res>0 outres end; [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('REAL %s %i %s\n',funname,res,fail); ltfat/inst/private/ref_rdgt3.m0000664000175000017500000000303213026262303016243 0ustar susnaksusnakfunction c=ref_rdgt3(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_rdgt3 %@verbatim %REF_RDGT3 Reference Real DGT type 3 % Usage: c=ref_rdgtiii(f,g,a,M); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdgt3.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); b=L/M; N=L/a; Mhalf=floor(M/2); F=zeros(L,M*N); l=(0:L-1).'/L; for n=0:N-1 for m=0:Mhalf-1 F(:,M*n+2*m+1)=sqrt(2)*cos(2*pi*(m+.5)*b*l).*circshift(g,n*a); F(:,M*n+2*m+2)=sqrt(2)*sin(2*pi*(m+.5)*b*l).*circshift(g,n*a); end; if mod(M,2)==1 F(:,M*(n+1))=cos(pi*L*l).*circshift(g,n*a); end; end; % dot-transpose will work because F is real. c=F.'*f; ltfat/inst/private/test_pbspline.m0000664000175000017500000000426413026262303017247 0ustar susnaksusnakfunction test_failed=test_pbspline Lr=[15,16,18,20]; ar=[ 3, 4, 6, 5]; or=[1, 1.5, 2,3]; %-*- texinfo -*- %@deftypefn {Function} test_pbspline %@verbatim %btypes={'ed','xd','stard','ec','xc','starc'}; %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_pbspline.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . btypes={'ed','xd','stard'}; centtypes={'wp','hp'}; test_failed=0; disp(' =============== TEST_PBSPLINE ============'); for ii=1:length(Lr) L=Lr(ii); a=ar(ii); N=L/a; for jj=1:length(or) order=or(jj); for kk=1:numel(btypes) btype=btypes{kk}; for ll=1:2 centstring=centtypes{ll}; [g,nlen]=pbspline(L,order,a,btype,centstring); A=zeros(L,1); for n=0:N-1 A=A+circshift(g,n*a); end; res=max(abs(A-1/sqrt(a))); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PBSPLINE PU %2s %s L:%3i a:%3i o:%3.5g %0.5g %s', ... btype,centstring,L,a,order,res,fail); disp(s); gcutextend=middlepad(middlepad(g,nlen,centstring),L,centstring); res=norm(g-gcutextend); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PBSPLINE NLEN %2s %s L:%3i a:%3i o:%3.5g %0.5g %s', ... btype,centstring,L,a,order,res,fail); disp(s); end; end; end; end; ltfat/inst/private/test_dgt_ola.m0000664000175000017500000000424313026262303017041 0ustar susnaksusnakfunction test_failed=test_dgt_ola %-*- texinfo -*- %@deftypefn {Function} test_dgt_ola %@verbatim %TEST_DGT_OLA Test DGT Overlap-add implementation % % This script runs a throrough test of the DGT using the OLA algorithm, % testing it on a range of input parameters. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_dgt_ola.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr = [48,420, 4, 8,240]; ar = [ 2, 3, 2, 2, 4]; Mr = [ 4, 4, 4, 4, 6]; glr = [ 8, 24, 4, 4, 12]; blr = [16, 60, 4, 4,120]; test_failed=0; disp(' =============== TEST_DGT_OLA ================'); disp('--- Used subroutines ---'); which comp_dgt_ola which comp_dgtreal_ola for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); gl=glr(ii); bl=blr(ii); b=L/M; N=L/a; for W=1:3 for rtype=1:2 if rtype==1 rname='REAL '; f=randn(L,W); g=randn(gl,1); c1 = comp_dgtreal_ola(f,g,a,M,bl); c2 = dgtreal(f,g,a,M); else rname='CMPLX'; f=tester_crand(L,W); g=tester_crand(gl,1); c1 = comp_dgt_ola(f,g,a,M,bl); c2 = dgt(f,g,a,M); end; res = c1-c2; res = norm(res(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('REF %s L:%3i W:%3i a:%3i M:%3i gl:%3i bl:%3i %0.5g %s',... rname,L,W,a,M,gl,bl,res,fail); disp(s) end; end; end; ltfat/inst/private/test_gabfirtight.m0000664000175000017500000000466213026262303017727 0ustar susnaksusnakfunction test_failed = test_gabfirtight() %-*- texinfo -*- %@deftypefn {Function} test_gabfirtight %@verbatim %TEST_GABFIRTIGHT Some of the windows returned from firwin are tight % immediatelly. This function tests for that %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabfirtight.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; disp(' =============== TEST_GABFIRTIGHT ================'); disp('--- Used subroutines ---'); which gabwin which comp_window shouldBeTight = [... struct('g','sine','a',10,'M',40,'L',[]),... struct('g',{{'sine',40}},'a',10,'M',40,'L',[]),... struct('g',{{'sine',28}},'a',14,'M',40,'L',[]),... struct('g','sine','a',20,'M',40,'L',[]),... struct('g',{{'sine',60}},'a',20,'M',60,'L',[]),... struct('g',{{'sine',54}},'a',18,'M',60,'L',[]),... struct('g',{{'sine',54,'inf'}},'a',18,'M',60,'L',[]),... struct('g','sine','a',5,'M',40,'L',[]),... struct('g','sqrttria','a',5,'M',40,'L',[]),... ]; shouldNotBeTight = [... struct('g','sine','a',16,'M',40,'L',[]),... struct('g',{{'sine',41}},'a',10,'M',40,'L',[]),... struct('g',{{'sine',26}},'a',10,'M',40,'L',[]),... struct('g','sqrttria','a',40,'M',40,'L',[]),... ]; for ii=1:numel(shouldBeTight) gw = shouldBeTight(ii); [~,info] = gabwin(gw.g,gw.a,gw.M,gw.L); [test_failed,fail]=ltfatdiditfail(~info.istight,test_failed,0); fprintf(['GABFIRISTIGHT g= a=%i M=%i %s\n'],gw.a,gw.M,fail); end for ii=1:numel(shouldNotBeTight) gw = shouldNotBeTight(ii); [~,info] = gabwin(gw.g,gw.a,gw.M,gw.L); [test_failed,fail]=ltfatdiditfail(info.istight,test_failed,0); fprintf(['GABFIRISNOTTIGHT g= a=%i M=%i %s\n'],gw.a,gw.M,fail); end ltfat/inst/private/ref_dwiltiv_1.m0000664000175000017500000000412713026262303017130 0ustar susnaksusnakfunction [coef]=ref_dwiltiv_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwiltiv_1 %@verbatim %COMP_DWILT Compute Discrete Wilson transform. % % Do not call this function directly, use DWILT instead. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwiltiv_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard. L=size(g,1); N=L/a; W=size(f,2); c=ref_gdgt(f,g,a,2*M,0.5,.5,0); coef2=reshape(c,2*M,N,W); % ----- Type IV ------ coef=zeros(M,N,W); if 0 % --- Loop version --- for n=0:N-1 for m=0:M-1 if rem(m+n,2)==0 coef(m+1,n+1,:)= 1/sqrt(2)*(exp(-i*pi/4)*coef2(m+1,n+1,:)+exp(-i*pi*3/4)*coef2(2*M-m,n+1,:)); else coef(m+1,n+1,:)= 1/sqrt(2)*(exp(i*pi/4)*coef2(m+1,n+1,:)+exp(i*pi*3/4)*coef2(2*M-m,n+1,:)); end; end; end; else % --- Vector version--- % --- 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,:)); end; coef=reshape(coef,M*N,W); ltfat/inst/private/testinginit.m0000664000175000017500000000164313026262303016733 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} testinginit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/testinginit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/crand.m0000664000175000017500000000203313026262303015453 0ustar susnaksusnakfunction f=crand(p1,p2); %-*- texinfo -*- %@deftypefn {Function} crand %@verbatim %CRAND Random complex numbers for testing. % Usage: f=tester_crand(p1,p2); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/crand.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . f=rand(p1,p2)-.5+i*(rand(p1,p2)-.5); ltfat/inst/private/ref_wilbounds.m0000664000175000017500000000204213026262303017226 0ustar susnaksusnakfunction [A,B]=ref_wilbounds(g,a,M); L=length(g); N=L/a; F=ref_idwilt(eye(M*N),g,a,M); S=F'*F; d=eig(S); A=min(d); B=max(d); %-*- texinfo -*- %@deftypefn {Function} ref_wilbounds %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_wilbounds.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_iedgtii.m0000664000175000017500000000276213026262303016647 0ustar susnaksusnakfunction f=ref_iedgtii(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_iedgtii %@verbatim %REF_IEDGTII Inverse Reference Even DGT type II % Usage f=ref_edgt(c,g,a,M); % % If a is even, then the input window must be odd-centered of length 2L. % % If a is odd, then the input window must be even-centered of length 2L. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_iedgtii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L2=size(g,1); W=size(c,2); L=L2/2; b=L/M; N=L/a; F=zeros(L,M*N); l=(0:L-1).'; lsecond=(2*L-1:-1:L).'; gnew=circshift(g,floor(a/2)); for n=0:N-1 for m=0:M-1 gshift=circshift(gnew,n*a); F(:,M*n+m+1)=exp(2*pi*i*m*(l+.5)/M).*gshift(l+1) + ... exp(-2*pi*i*m*(l+.5)/M).*gshift(lsecond+1); end; end; f=F*c; ltfat/inst/private/ref_pconv_ola_fir2long.m0000664000175000017500000000304613026262303021007 0ustar susnaksusnakfunction h=ref_pconv_ola_fir2long(f,g,Lb) %-*- texinfo -*- %@deftypefn {Function} ref_pconv_ola_fir2long %@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.github.io/doc/reference/ref_pconv_ola_fir2long.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=length(f); Lg=length(g); % Number of blocks Nb=L/Lb; % Length of extended block and padded g Lext=Lb+Lg; gpad=fir2long(g,Lext); b2=Lg/2; h=zeros(L,1); for ii=0:Nb-1 block=pconv(postpad(f(ii*Lb+1:(ii+1)*Lb),Lext),gpad); h(ii*Lb+1:(ii+1)*Lb)+=block(1:Lb); % Large block s_ii=mod(ii+1,Nb); h(s_ii*Lb+1:s_ii*Lb+b2)+=block(Lb+1:Lb+b2); % Small block + s_ii=mod(ii-1,Nb)+1; h(s_ii*Lb-b2+1:s_ii*Lb)+=block(Lb+b2+1:Lext); % Small block - end; ltfat/inst/private/test_nonsepdgt.m0000664000175000017500000002322213026262303017427 0ustar susnaksusnakfunction test_failed=test_nonsepdgt %-*- texinfo -*- %@deftypefn {Function} test_nonsepdgt %@verbatim %TEST_NONSEPDGT Test non-separable DGT % % This script runs a throrough test of the DGT routine, % testing it on a range of input parameters. % % The computational backend is tested this way, but the % interface is not. % % The script tests dgt, idgt, gabdual and gabtight. % % Use TEST_WFAC and TEST_DGT_FAC for more specific testing % of the DGT backend. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_nonsepdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . Lr =[24,24,30,36,36,48,72]; ar =[ 4, 4, 3, 4, 4, 4, 4]; Mr =[ 6, 6, 5, 6, 6, 6, 6]; lt1=[ 0, 1, 1, 1, 2, 1, 1]; lt2=[ 1, 2, 2, 3, 3, 4, 2]; test_failed=0; testmode=0; disp(' =============== TEST_NONSEPDGT ================'); disp('--- Used subroutines ---'); which comp_nonsepdgt_multi which comp_nonsepdgt_shear which comp_nonsepwin2multi for ii=1:length(Lr); L=Lr(ii); M=Mr(ii); a=ar(ii); lt=[lt1(ii), lt2(ii)]; b=L/M; N=L/a; c=gcd(a,M); d=gcd(b,N); p=a/c; q=M/c; for gtype=1:2 if gtype==1 Lw=L; else Lw=M; end; for rtype=1:2 if rtype==1 rname='REAL'; g=tester_rand(Lw,1); else rname='CMPLX'; g=tester_crand(Lw,1); end; gd=gabdual(g,a,M,'lt',lt); gd_multi=gabdual(g,a,M,'lt',lt,'nsalg',1); gd_shear=gabdual(g,a,M,'lt',lt,'nsalg',2); gt=gabtight(g,a,M,'lt',lt); gt_multi=gabtight(g,a,M,'lt',lt,'nsalg',1); gt_shear=gabtight(g,a,M,'lt',lt,'nsalg',2); % For testing, we need to call some computational subroutines directly. gsafe=fir2long(g,L); gdsafe=fir2long(gd,L); for W=1:3 if rtype==1 f=tester_rand(L,W); else f=tester_crand(L,W); end; % --------- test reference comparison ------------ cc = dgt(f,g,a,M,'lt',lt); cc_ref = ref_nonsepdgt(f,g,a,M,lt); res = norm(cc(:)-cc_ref(:))/norm(cc(:)); stext=sprintf(['REF %s L:%3i W:%2i LW:%3i a:%3i M:%3i lt1:%2i lt2:%2i' ... ' %0.5g'], rname,L,W,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % --------- test multiwindow --------------------- cc = comp_dgt(f,gsafe,a,M,lt,0,0,1); res = norm(cc(:)-cc_ref(:))/norm(cc(:)); stext=sprintf('DGT MULTIW %s L:%3i W:%2i LW:%3i a:%3i M:%3i lt1:%2i lt2:%2i %0.5g ',... rname,L,W,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % --------- test shear DGT ------------------------------- cc = comp_dgt(f,gsafe,a,M,lt,0,0,2); res = norm(cc(:)-cc_ref(:))/norm(cc(:)); stext=sprintf(['DGT SHEAR %s L:%3i W:%2i LW:%3i a:%3i ' ... 'M:%3i lt1:%2i lt2:%2i %0.5g'], rname,L,W, ... Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test reconstruction using canonical dual ------- r=idgt(cc,gd,a,'lt',lt); res=norm(f-r,'fro')/norm(f,'fro'); stext=sprintf(['REC D %s L:%3i W:%2i LW:%3i a:%3i M:%3i ' ... 'lt1:%2i lt2:%2i %0.5g'], rname,L,W,Lw,a,M, ... lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test reconstruction using canonical dual, multiwin algorithm ------- r=comp_idgt(cc,gdsafe,a,lt,0,1); res=norm(f-r,'fro')/norm(f,'fro'); stext=sprintf(['REC MULTIW D %s L:%3i W:%2i LW:%3i a:%3i ' ... 'M:%3i lt1:%2i lt2:%2i %0.5g ' ], rname,L,W, ... Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test reconstruction using canonical dual, shear algorithm ------- r=comp_idgt(cc,gdsafe,a,lt,0,2); res=norm(f-r,'fro')/norm(f,'fro'); stext=sprintf(['REC SHEAR D %s L:%3i W:%2i LW:%3i a:%3i ' ... 'M:%3i lt1:%2i lt2:%2i %0.5g ' ], rname,L,W, ... Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test reconstruction using canonical tight ------- cc_t = dgt(f,gt,a,M,'lt',lt); r=idgt(cc_t,gt,a,'lt',lt); res=norm(f-r,'fro')/norm(f,'fro'); stext=sprintf(['REC T %s L:%3i W:%2i LW:%3i a:%3i M:%3i ' ... 'lt1:%2i lt2:%2i %0.5g ' ], rname,L,W,Lw,a, ... M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test dgtreal----------------------- if (rtype==1) && (lt(2)<=2) M2=floor(M/2)+1; cc_r = dgtreal(f,g,a,M,'lt',lt); res=cc_r-cc(1:M2,:,:); res=norm(res(:))/norm(cc_r(:));; stext=sprintf(['REFREAL L:%3i W:%2i LW:%3i a:%3i ' ... 'M:%3i lt1:%2i lt2:%2i %0.5g' ], ... L,W,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); r_real = idgtreal(cc_r,gd,a,M,'lt',lt); res=norm(f-r_real,'fro')/norm(f,'fro'); stext=sprintf(['RECREAL L:%3i W:%2i LW:%3i a:%3i ' ... 'M:%3i lt1:%2i lt2:%2i %0.5g '], ... L,W,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); end; end; % -------- test frame bounds for tight frame ------- B=gabframebounds(gt,a,M,'lt',lt); res=B-1; stext=sprintf(['FRB %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i lt2:%2i ' ... '%0.5g'], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test multiwin dual ------- res=norm(gd-gd_multi)/norm(g); stext=sprintf(['DUAL MULTI %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i ' ... 'lt2:%2i %0.5g' ], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test shear dual ------- res=norm(gd-gd_shear)/norm(g); stext=sprintf(['DUAL SHEAR %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i ' ... 'lt2:%2i %0.5g'], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test shear tight ------- res=norm(gt-gt_multi)/norm(g); stext=sprintf(['TIGHT MULTI %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i ' ... 'lt2:%2i %0.5g' ], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % -------- test shear tight ------- res=norm(gt-gt_shear)/norm(g); stext=sprintf(['TIGHT SHEAR %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i ' ... 'lt2:%2i %0.5g' ], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); % ---- Test gabdualnorm -------------------------------------- res=gabdualnorm(g,gd,a,M,'lt',lt); stext=sprintf(['DUALNORM1 %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i ' ... 'lt2:%2i %0.5g' ], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); [o1,o2]=gabdualnorm(g,gd,a,M,'lt',lt); res=o1-1+o2; stext=sprintf(['DUALNORM2 %s L:%3i LW:%3i a:%3i M:%3i lt1:%2i ' ... 'lt2:%2i %0.5g' ], rname,L,Lw,a,M,lt(1),lt(2),res); test_failed=ltfatchecktest(res,stext,test_failed,testmode); end; end; end; ltfat/inst/private/test_lconv.m0000664000175000017500000000420413026262303016546 0ustar susnaksusnakfunction test_failed=test_lconv Lf=[9, 10 9, 9, 1]; Wf=[1, 1, 3, 1, 1]; Lg=[9, 10 9, 9, 1]; Wg=[1, 1, 1, 3, 1]; ctypes={'default','r','rr'}; test_failed=0; disp(' =============== TEST_LCONV =============='); for jj=1:length(Lf) for ii=1:3 for type = {'real','complex'} ctype=ctypes{ii}; if strcmp(type{1},'complex') f=tester_crand(Lf(jj), Wf(jj)); g=tester_crand(Lg(jj), Wg(jj)); else f=tester_rand(Lf(jj), Wf(jj)); g=tester_rand(Lg(jj), Wg(jj)); end h1=lconv(f,g,ctype); h2cell = {}; if Wf(jj) == 1 for wId = 1:Wg(jj) h2cell{end+1}=ref_lconv(f,g(:,wId),ctype); end else for wId = 1:Wf(jj) h2cell{end+1}=ref_lconv(f(:,wId),g,ctype); end end h2 = cell2mat(h2cell); res=norm(h1(:)-h2(:)); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('PCONV %3s %6s %0.5g %s',ctype,type{1},res,fail); disp(s); end end end %-*- texinfo -*- %@deftypefn {Function} test_lconv %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_lconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/private/ref_irdftiii.m0000664000175000017500000000260113026262303017024 0ustar susnaksusnakfunction c=ref_irdftiii(f) %-*- texinfo -*- %@deftypefn {Function} ref_irdftiii %@verbatim %REF_IRDFTIII Reference Inverse Real DFT type III % Usage: c=ref_irdftiii(f); % % Compute IRDFTIII by explicit formulas. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdftiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=floor(L/2); F=zeros(L); F(:,1)=ones(L,1); l=(0:L-1).'/L; for m=0:Lhalf-1 F(:,2*m+1)=sqrt(2)*cos(2*pi*(m+.5)*l); F(:,2*m+2)=sqrt(2)*sin(2*pi*(m+.5)*l); end; if mod(L,2)==1 F(:,L)=cos(pi*L*l); end; F=F/sqrt(L); % dot-transpose will work because F is real. c=F*f; ltfat/inst/private/test_frames.m0000664000175000017500000001753613026262303016716 0ustar susnaksusnakfunction test_failed=test_frames %-*- texinfo -*- %@deftypefn {Function} test_frames %@verbatim %TEST_FRAMES Test the frames methods %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_frames.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_FRAMES ================'); global LTFAT_TEST_TYPE; tolchooser.double=1e-9; tolchooser.single=2e-4; tolerance = tolchooser.(LTFAT_TEST_TYPE); % Iterative algorithms need a bigger tolerance tolchooseriter.double=1e-1; tolchooseriter.single=1e-1; toleranceiter = tolchooseriter.(LTFAT_TEST_TYPE); Fr=cell(1,32); L=200; Fr{1} = frame('dgt','gauss',10,20); Fr{2} = frame('dgtreal','gauss',10,20); Fr{3} = frame('dwilt','gauss',20); Fr{4} = frame('wmdct','gauss',20); Fr{5} = frame('gen',tester_crand(200,300),20); Fr{6} = frametight(frame('dgt','gauss',10,20)); Fr{7} = frametight(frame('dgtreal','gauss',10,20)); Fr{8} = frametight(frame('dwilt','gauss',20)); Fr{9} = frametight(frame('wmdct','gauss',20)); Fr{10} = frametight(frame('gen',tester_crand(200,300),20)); Fr{11} = frame('dft'); Fr{12} = frame('dcti'); Fr{13} = frame('dctii'); Fr{14} = frame('dctiii'); Fr{15} = frame('dctiv'); Fr{16} = frame('dsti'); Fr{17} = frame('dstii'); Fr{18} = frame('dstiii'); Fr{19} = frame('dstiv'); % Repeat generation of the filters until they have a nice condition number condnum = 1e10; while condnum > 1e3 gfilt={tester_rand(30,1),... tester_rand(20,1),... tester_rand(15,1),... tester_rand(10,1)}; gfilt=cellfun(@(gEl) cast(gEl,'double'),gfilt,'UniformOutput',0); % These two frames might be badly conditioned, Fr{20} = frame('ufilterbank', gfilt,3,4); Fr{21} = frame('ufilterbankreal',gfilt,3,4); condnum = framebounds(Fr{20},128); end Fr{22} = frame('dgt','gauss',4,6,'lt',[1 2]); Fr{23} = frame('identity'); Fr{24} = frame('fusion',[1 1],Fr{1},Fr{1}); Fr{25} = frametight(frame('dgt','hamming',10,20)); Fr{26} = frametight(frame('wmdct','hamming',20)); g={randn(30,1),randn(50,1),randn(70,1),randn(90,1)}; a=[20,40,60,80]; M=[30,50,70,100]; Fr{27} = frametight(frame('nsdgt',g,a,M)); Fr{28} = frametight(frame('unsdgt',g,a,100)); Fr{29} = frametight(frame('nsdgtreal',g,a,M)); Fr{30} = frametight(frame('unsdgtreal',g,a,100)); Fr{31} = frametight(frame('dftreal')); Fr{32} = frame('fwt','ana:spline2:2',5); Fr{33} = frame('wfbt',{'syn:spline2:2',5}); %Fr{34} = frame('wpfbt',{'db4',5}); %Fr{35} = frame('wpfbt',{'db4',5}); %Fr{36} = frame('wpfbt',{'db4',5}); Fr{37} = frame('ufwt','db4',4); Fr{38} = frame('ufwt','db4',4,'scale'); Fr{39} = frame('ufwt','db4',4,'noscale'); Fr{40} = frame('uwfbt',{'db4',4}); Fr{41} = frame('uwfbt',{'db4',4},'scale'); Fr{42} = frame('uwfbt',{'db4',4},'noscale'); Fr{43} = frame('uwpfbt',{'db4',4}); Fr{44} = frame('uwpfbt',{'db4',4},'scale'); Fr{45} = frame('uwpfbt',{'db4',4},'noscale'); %Fr{36} = frame('uwfbt',{'db4',5}); %Fr{37} = frame('uwpfbt',{'db4',5}); % The tensor frame implementation is currenly broken %Fr{33} = frame('tensor',Fr{11}); %Fr{31} = frame('filterbank', gfilt,[4 3 2 2],4); %Fr{32} = frame('filterbankreal', gfilt,[4 3 2 2],4); Fr{60} = frame('erbletfb',44100,L,'real','regsampling'); Fr{61} = frame('erbletfb',44100,L,'complex','regsampling'); Fr{62} = frame('erbletfb',44100,L,'real','fractional'); Fr{63} = frame('erbletfb',44100,L,'complex','fractional'); Fr{64} = frametight(Fr{60}); Fr{65} = frametight(Fr{62}); Fr{66} = frame('cqtfb',44100,200,20000,20,L,'real','regsampling'); Fr{67} = frame('cqtfb',44100,200,20000,20,L,'complex','regsampling'); Fr{68} = frame('cqtfb',44100,200,20000,20,L,'real','fractional'); Fr{69} = frame('cqtfb',44100,200,20000,20,L,'complex','fractional'); Fr{70} = frametight(Fr{66}); Fr{71} = frametight(Fr{67}); for cmpx = {'real','complex'} if strcmp(cmpx{1},'real') f=tester_rand(L,1); else f=tester_crand(L,1); end for ii=1:numel(Fr) F=Fr{ii}; % To avoid holes in Fr if isempty(F) continue; end; % Do not test real-only frames with complex arrays if strcmp(cmpx{1},'complex') && F.realinput continue; end Fd=framedual(F); c=frana(F,f); r=frsyn(Fd,c); res=norm(r(1:L)-f); lendiff = size(c,1) - frameclength(F,L); [test_failed,fail]=ltfatdiditfail(lendiff ,test_failed); s=sprintf(['FRAMES CLENGTH frameno:%3i %s %0.5g %s'],ii,F.type,lendiff,fail); disp(s); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); s=sprintf(['FRAMES DUAL REC frameno:%3i %s %0.5g %s'],ii,F.type,res,fail); disp(s); % Checking equality F == framedual(framedual(F)) Fdd = framedual(framedual(F)); cdd = frana(Fdd,f); res_dd = norm(cdd-c); [test_failed,fail]=ltfatdiditfail(res_dd,test_failed,tolerance); s=sprintf(['FRAMES DUAL DUAL frameno:%3i %s %0.5g %s'],ii,F.type,res_dd,fail); disp(s); F2=frameaccel(F,L); F2d=frameaccel(Fd,L); c=frana(F2,f); r=frsyn(F2d,c); res=norm(r(1:L)-f); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); s=sprintf(['FRAMES ACCEL DUAL REC frameno:%3i %s %0.5g %s'],ii,F.type,res,fail); disp(s); % Checking equality F == framedual(framedual(F)) after acceleration F2dd = framedual(framedual(F2)); c2dd = frana(Fdd,f); res2_dd = norm(c2dd-c); [test_failed,fail]=ltfatdiditfail(res2_dd,test_failed,tolerance); s=sprintf(['FRAMES ACCEL DUAL DUAL frameno:%3i %s %0.5g %s'],ii,F.type,res2_dd,fail); disp(s); % Test that framebounds are able to run, not actual resting is done on % the values. [A,B]=framebounds(F,L); %% Test iterative analysis and synthesis r=frsyniter(F,c); res=norm(r(1:L)-f); [test_failed,fail]=ltfatdiditfail(res,test_failed,toleranceiter); s=sprintf(['FRSYNITER frameno:%3i %s %0.5g %s'],ii,F.type,res,fail); disp(s); c2=franaiter(Fd,f); res=norm(c2-c); [test_failed,fail]=ltfatdiditfail(res,test_failed,toleranceiter); s=sprintf(['FRANAITER frameno:%3i %s %0.5g %s'],ii,F.type,res,fail); disp(s); %% Test matrix representations if (~F.realinput) LL=framelength(F,L); G=frsynmatrix(F,LL); res=norm(c-G'*postpad(f,LL)); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); s=sprintf(['FRAMES ANA MATRIX frameno:%3i %s %0.5g %s'],ii,F.type,res,fail); disp(s); % We create a different set of coefficients here. % The old code used c and failed the test for some filterbank frames ctmp = tester_crand(numel(c),1); res=norm(frsyn(F,ctmp)-G*ctmp); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); s=sprintf(['FRAMES SYN MATRIX frameno:%3i %s %0.5g %s'],ii,F.type,res,fail); disp(s); end; %% Test the frame multipliers: test framemul, framemuladj and %% iframemul if F.realinput m=1+0.01*tester_rand(size(c,1),1); else m=1+1i+0.01*tester_crand(size(c,1),1); end; ff=framemul(f,F,Fd,m); fr=iframemul(ff,F,Fd,m); res=norm(f-fr(1:L))/norm(f); [test_failed,fail]=ltfatdiditfail(res,test_failed,tolerance); s=sprintf('IFRAMEMUL frameno:%3i %s %0.5g %s',ii, ... F.type,res,fail); disp(s); end; end ltfat/inst/private/ref_dwiltii.m0000664000175000017500000000340613026262303016672 0ustar susnaksusnakfunction c=ref_dwiltii(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwiltii %@verbatim %REF_DWILT Reference Discrete Wilson Transform type II % Usage: c=ref_dwiltii(f,g,M); % % M must be even. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwiltii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Setup transformation matrix. L=size(f,1); N=L/M; F=zeros(L); l=(0:L-1).'; for n=0:N/2-1 % Do the unmodulated coefficient. F(:,2*M*n+1)=circshift(g,2*a*n); % m odd case OK for m=1:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*sin(pi*m/M*(l+.5)).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*cos(pi*m/M*(l+.5)).*circshift(g,(2*n+1)*a); end; for m=2:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*cos(pi*m/M*(l+.5)).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*sin(pi*m/M*(l+.5)).*circshift(g,(2*n+1)*a); end; if rem(M,2)==0 % Do the Nyquest wave. F(:,M+2*M*n+1) = sin(pi*(l+.5)).*circshift(g,(2*n+1)*a); else F(:,M+2*M*n+1) = sin(pi*(l+.5)).*circshift(g,2*n*a); end; end; c=F'*f; ltfat/inst/private/ref_gabdual_fac_time.m0000664000175000017500000000244413026262303020454 0ustar susnaksusnakfunction ff=ref_gabdual_fac_time(gf,L,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_gabdual_fac_time %@verbatim %REF_GABDUAL_FAC_TIME Computes factorization of canonical dual window % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabdual_fac_time.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ff=zeros(p*q*R,c*d); G=zeros(p,q*R); for ii=1:c*d % This essentially computes pinv of each block. G(:)=gf(:,ii); S=G*G'; Gpinv=(S\G); ff(:,ii)=Gpinv(:); end; ltfat/inst/private/ref_phaselock.m0000664000175000017500000000250613026262303017176 0ustar susnaksusnakfunction c = ref_phaselock(c,a) %-*- texinfo -*- %@deftypefn {Function} ref_phaselock %@verbatim %REF_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. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_phaselock.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: M=size(c,1); N=size(c,2); L=N*a; b=L/M; TimeInd = (0:(N-1))*a; FreqInd = (0:(M-1))*b; phase = FreqInd'*TimeInd; phase = exp(2*1i*pi*phase/L); c=bsxfun(@times,c,phase); ltfat/inst/private/ref_idwilt.m0000664000175000017500000000563513026262303016527 0ustar susnaksusnakfunction f=ref_idwilt(c,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwilt %@verbatim %REF_DWILT Reference Inverse Discrete Wilson Transform % Usage: f=ref_idwilt(c,g,a,M); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Setup transformation matrix. L=size(g,1); W=size(c,2); N=L/a; F=zeros(L,M*N); % Weight coefficients. l=(0:L-1).'; pif=0; if 1 % This version uses sines and cosines to express the basis functions. for n=0:N/2-1 % Do the unmodulated coefficient. F(:,2*M*n+1)=circshift(g,2*a*n); % Setting this to -n*a should produce a time-invariant transform. timeinv=0; %-n*a; % m odd case for m=1:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*sin(pi*m/M*(l+timeinv)+pif).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*cos(pi*m/M*(l+timeinv)+pif).*circshift(g,(2*n+1)*a); end; % m even case for m=2:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*cos(pi*m/M*(l+timeinv)+pif).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*sin(pi*m/M*(l+timeinv)+pif).*circshift(g,(2*n+1)*a); end; % Most modulated coefficient, Nyquest frequency. if mod(M,2)==0 F(:,M+2*M*n+1)=(-1).^(l+timeinv).*circshift(g,2*n*a); else F(:,M+2*M*n+1)=(-1).^(l+timeinv).*circshift(g,(2*n+1)*a); end; end; else % This version uses a cosine, for n=0:N/2-1 % Do the unmodulated coefficient. F(:,2*M*n+1)=circshift(g,2*a*n); timeinv=-n*a; % m odd case for m=1:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*cos(pi*m/M*(l+timeinv-M/2)+pif).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*sin(pi*m/M*(l+timeinv-M/2-a)+pif).*circshift(g,(2*n+1)*a); end; % m even case for m=2:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*cos(pi*m/M*(l+timeinv-M/2)+pif).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*sin(pi*m/M*(l+timeinv-M/2-a)+pif).*circshift(g,(2*n+1)*a); end; % Most modulated coefficient, Nyquest frequency. if mod(M,2)==0 F(:,M+2*M*n+1)=(-1).^(l+timeinv).*circshift(g,2*n*a); else F(:,M+2*M*n+1)=(-1).^(l+timeinv-a).*circshift(g,(2*n+1)*a); end; end; end; f=F*c; ltfat/inst/private/ref_dgt_2.m0000664000175000017500000000351313026262303016223 0ustar susnaksusnakfunction c=ref_dgt_2(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_2 %@verbatim %REF_DGT_2 DGT algorithm 2 %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; b=L/M; [c,h_a,h_m]=gcd(-a,M); p=a/c; q=M/c; d=N/q; w=zeros(M,N); % mt = m-tilde if 0 % This version uses the definition for r=0:c-1 for l=0:q-1 for n=0:N-1 for mt=0:b-1 w(r+l*c+1,mod(n-l*h_a,N)+1)=w(r+l*c+1,mod(n-l*h_a,N)+1)+f(mod(r+l*c+(mt-l*h_m)*M,L)+1)*... conj(g(mod(r+mt*M-n*a,L)+1)); end; end; end; end; else % This version uses matrix-vector products. W=zeros(b,N); V=zeros(b,q); for r=0:c-1 % Setup the matrix and vector for mt=0:b-1 for n=0:N-1 W(mt+1,n+1)=g(mod(r+mt*M-n*a,L)+1); end; for l=0:q-1 V(mt+1,l+1)=f(mod(r+mt*M+l*(c-h_m*M),L)+1); end; end; % do the product. s1=W'*V; % Arrange in w for n=0:N-1 for l=0:q-1 w(r+l*c+1,mod(n-l*h_a,N)+1)=s1(n+1,l+1); end; end; end; end; c=fft(w); ltfat/inst/private/ref_gabdualns_2.m0000664000175000017500000001035213026262303017404 0ustar susnaksusnakfunction gd=ref_gabdualns_2(g,V); %-*- texinfo -*- %@deftypefn {Function} ref_gabdualns_2 %@verbatim %REF_GABDUALNS_2 GABDUALNS by A.v.Leest's Zak-transform method. % Usage: g=ref_gabdualns_2(gamma,V); % % This function calculates the dual window g of the given window % w for the Gabor expansion on a lattice that is described by the % parameters A, p, q, J, and L. Furthermore, the l_2 norm of the % difference of the (normalized) dual window and the (normalized) % window is calculated. % % The method is based on the Zak transform. % % Marc Geilen, 1995. (rectangular lattice) % Arno J. van Leest, 1998. (non-separable lattice) % Peter L. Soendergaard, 2006 (change of variable names) %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabdualns_2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % This documents Arno's variable names % % D the determinant of the matrix A and the number of time shifts % in each time segment (segment between two points on the % time-axis) % K=pJ the number of samples in the freq. domain after each time shift. % N=qJ the size of the time shift. % DN length of a time segment. % p/q the oversampling. % M=pLD the number of time shifts. % pL the number of points on the time-axis. % MN length of the signal. % MK the number of lattice points (MK/MN=K/N=p/q is the oversampling). % % (note that MN must be equal to the length of the window w). % % V is on Peters normal form. a=V(1,1); b=V(2,2); Lpeter=size(g,1); Mpeter=Lpeter/b; Npeter=Lpeter/a; c=gcd(a,Mpeter); d=gcd(b,Npeter); ppeter=a/c; qpeter=Mpeter/c; % Conversion, part 1 -------------------------- qarno=ppeter; parno=qpeter; J=c; % --------------------------------------------- % 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; [gg,h0,h1] = gcd(A(1,1),A(1,2)); D = det(A); % Stupid, but needed in Octave D=round(D); % ---------- more conversion ------------- Larno=d/D; % --------------------------------------- x = A(2,:)*[h0;h1]; x = mod(x,D); A = [1 0;x D]; %function [g,nrm]=calcg(A,p,q,J,L,w); % Bereken de nodige variabelen. %A = eqform(A); swap = 0; %D=det(A); Marno=parno*Larno*D; Narno=qarno*J; K=parno*J; r=-A(2,1); h=gcd(D,qarno); f=D/h; % Conversion, part 2 ----------- Narno=a; K=Mpeter; Marno=Npeter; % ------------------------------ clear p clear q clear M clear N clear L clear a clear b clear c clear d g=reshape(g,Narno,Marno); wz = fft(g,[],2); % gz zal de zakgetransformeerde van g bevatten gz=zeros(Narno,Marno); mgz=zeros(f*Narno,Marno); mwz=zeros(f*Narno,Marno); % The circshifts work along the rows! O = (0:Marno-1); O = O(ones([1 J]),:); for n=0:qarno-1, i=rem(n*parno,qarno); k=fix(n*parno/qarno); for l=0:f-1, mwz((n+l*qarno)*J+1:(n+l*qarno)*J+J,:)= ... circshift(wz(i*J+1:i*J+J,:).*exp(j*2*pi*(k+parno*l)/Marno*O),... [0 (n+l*qarno)*r*parno*Larno]); end; end for n=0:J-1, for l=0:Larno*h-1, mgz(n+1:J:f*Narno,l+1:Larno*h:Marno)=... f*parno/K*(pinv(mwz(n+1:J:f*Narno,l+1:Larno*h:Marno)))'; end; end; % Voer nu de omgekeerde bewerkingen uit van de verschuivingen en phase % correcties om gz te verkrijgen uit mgz for n=0:qarno-1, i=rem(n*parno,qarno); k=fix(n*parno/qarno); gz(i*J+1:i*J+J,:)=circshift(mgz(n*J+1:n*J+J,:),[0 -n*r*parno*Larno]) ... .*exp(-j*2*pi*k/Marno*O); end % Bereken de functie g uit gz gd = ifft(gz(1:Narno,:),[],2); gd = gd(:); if swap gd=parno/qarno*gd; end; ltfat/inst/private/ref_pbspline.m0000664000175000017500000001017513026262303017042 0ustar susnaksusnakfunction [out,nlen] = ref_pbspline(splinetype,L,order,a,centering) %-*- texinfo -*- %@deftypefn {Function} ref_pbspline %@verbatim %PBSPLINE Periodized B-spline. % Usage: out=pbspline(splinetype,L,order,a); % [out,nlen]=pbspline(splinetype,L,order,a); % % Input parameters: % splinetype : type of spline % L : Length of window. % order : Order of B-spline. % a : Time-shift parameter for partition of unity. % Output parameters: % out : Almost B-spline. % nlen : Number of non-zero elements in out. % % % Types are: % 0 - as pspline, real formed from DFT product % 1 - forced even by taking ABS value of fft. % 2 - New even % 3 - computed from continous case %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_pbspline.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. error(nargchk(4,5,nargin)); if nargin==4 centering=0; end; % Matlab and Octave uses the following definition of a fractional % power of a complex number. This is consistant with what Unser uses. % zp=abs(z).^alpha.*exp(i*alpha*angle(z)); % This is always WPE s1=middlepad([ones(a,1)],L); nlen=0; switch splinetype case 0 % (Possibly) unsymmeteric spline % If a=3,7,11,... then the Nyquest frequency will have a negative % coefficient, and generate a complex spline. if centering==0 % Method 1 out = real(ifft(fft(s1).^(order+1))); % Method 2 % Create FFT of spline. Flip over top part, to make it strickly real. % This method is more robust against a bad FFT implementation. %sf=fft(s1).^(order+1); %if rem(L,2)==0 % sf(L/2+2:L)=conj(flipud(sf(2:L/2))); %else % sf((L+3)/2:L)=conj(flipud(sf(2:(L+1)/2))); %end; %sf(L/2+1) %out = real(ifft(sf)); else s2=middlepad([ones(a,1)],L,.5); out = real(ifft(fft(s1).^order.*fft(s2))); end; case 1 % Symmetric spline if centering==0 out = real(ifft(abs(fft(s1)).^(order+1))); else s2=middlepad([ones(a,1)],L,.5); out = real(ifft(abs(fft(s1)).^order.*abs(fft(s2)))); end; case 2 % Mild symmetric intorder=floor(order); fracorder=order-intorder; if centering==0 out = real(ifft(abs(fft(s1)).^order.*fft(s1))); else s2=middlepad([ones(a,1)],L,.5); out = real(ifft(abs(fft(s1)).^order.*fft(s2))); end; case 3 Llong=ceil(a*(order+2)/L)*L; x=((0:Llong-1).')/a; x out=zeros(Llong,1); for k=0:order+1 out=out+(-1)^k*ref_bincoeff(order+1,k)*onesidedpower(x-k,order); out end; out=out/factorial(order); end; % Scale such that the elements will form a partition of unity. out=out./a.^order; % nlen cannot be larger that L nlen=min(L,nlen); % If order is a fraction nlen==L if rem(order,1)~=0 nlen=L; end; if use_row_layout out=out.'; end; % Normalize out=out/sqrt(a); % This code verifies that we have obtained a partition of unity. %pu=zeros(L,1); %for ii=0:L/a-1 % pu=pu+circshift(out,a*ii); %end; %pu % Verify middlepad claim %norm(out-middlepad(middlepad(out,nlen),L)) function xa=onesidedpower(x,a) % Compute a one-sided power. See Unser and Blu "Fractional Spline and % Wavelets", section 1.1.2 % Zero all negative values x=x.*(x>=0) % Raise xa=x.^a; ltfat/inst/private/ref_rdftiii_1.m0000664000175000017500000000303013026262303017070 0ustar susnaksusnakfunction c=ref_rdftiii_1(f) %-*- texinfo -*- %@deftypefn {Function} ref_rdftiii_1 %@verbatim %REF_RDFTIII_1 Reference RDFT by FFT % Usage: c=ref_rdftiii_1(f); % % Compute RDFTII by doing a DFTIII and returning half the coefficients. % Only works for real functions. % % The transform is orthonormal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_rdftiii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); Lhalf=floor(L/2); Lend=Lhalf*2; cc=ref_dftiii(f); c=zeros(size(f)); % Copy the cosine-part of the coefficients. c(1:2:Lend,:)=sqrt(2)*real(cc(1:Lhalf,:)); % Copy the sine-part of the coefficients. c(2:2:Lend,:)=-sqrt(2)*imag(cc(1:Lhalf,:)); % If f has an odd length, we must also copy the Niquest-wave % (it is real) if mod(L,2)==1 c(end,:)=real(cc((L+1)/2,:)); end; ltfat/inst/private/ref_pconv.m0000664000175000017500000000300113026262303016341 0ustar susnaksusnakfunction h=ref_pconv(f,g,ctype) %-*- texinfo -*- %@deftypefn {Function} ref_pconv %@verbatim %REF_PCONV Reference PCONV % Usage: h=ref_pconv(f,g) % % PCONV(f,g) computes the periodic convolution of f and g. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_pconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard L=length(f); h=zeros(L,1); switch(lower(ctype)) case {'default'} for ii=0:L-1 for jj=0:L-1 h(ii+1)=h(ii+1)+f(jj+1)*g(mod(ii-jj,L)+1); end; end; case {'r'} for ii=0:L-1 for jj=0:L-1 h(ii+1)=h(ii+1)+f(jj+1)*conj(g(mod(jj-ii,L)+1)); end; end; case {'rr'} for ii=0:L-1 for jj=0:L-1 h(ii+1)=h(ii+1)+conj(f(mod(-jj,L)+1))*conj(g(mod(jj-ii,L)+1)); end; end; end; ltfat/inst/private/test_erbfilters.m0000664000175000017500000001171013026262303017566 0ustar susnaksusnakfunction test_failed=test_erbfilters %-*- texinfo -*- %@deftypefn {Function} test_erbfilters %@verbatim %TEST_ERBFILTERS Test the erbfilters filter generator %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_erbfilters.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warpname={'warped','symmetric'}; Ls = 10000; %warpname={'symmetric'}; test_failed=0; for realcomplexidx=1:2 if realcomplexidx==1 realcomplex='real'; isreal=1; else realcomplex='complex'; isreal=0; end; for warpidx=1:2 warping=warpname{warpidx}; for fracidx=2:-1:1 if fracidx==1 fractional={'regsampling'}; fracname='regsamp'; else fractional={'fractional'}; fracname='fractional'; end; for uniformidx=1:2 if uniformidx==1 isuniform=0; uniform='regsampling'; else isuniform=1; uniform='uniform'; end; [g,a]=audfilters(16000,Ls,fractional{:},warping,uniform,... 'redmul',1,realcomplex,'nuttall30'); L=filterbanklength(Ls,a); f=randn(L,1); % Test it if 0 f=[1;zeros(L-1,1)]; ff=fft(f); ff(1999:2003)=0; f=ifft(ff); end; if 0 % Inspect it: Dual windows, frame bounds and the response disp('Frame bounds:') [A,B]=filterbankrealbounds(g,a,L); A B B/A filterbankresponse(g,a,L,'real','plot'); end; if isreal gd=filterbankrealdual(g,a,L); else gd=filterbankdual(g,a,L); end; if isuniform c=ufilterbank(f,g,a); else c=filterbank(f,g,a); end; cind = cell(numel(g),1); for ii = 1:numel(g) %clear comp_filterbank_fftbl; cind{ii} = pfilt(f,g{ii},a(ii,:)); end if isuniform cind = cell2mat(cind); res = norm(c(:) - cind(:)); else res = sum(cellfun(@(c1El,c2El) norm(c1El-c2El),cind,c)); end [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['ERBFILTER PFILT %s %s %s %s L:%3i %0.5g %s'],realcomplex,warping,fracname,uniform,L,res,fail); disp(s); r=ifilterbank(c,gd,a); if isreal r=2*real(r); end; res=norm(f-r); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['ERBFILTER DUAL %s %s %s %s L:%3i %0.5g %s'],realcomplex,warping,fracname,uniform,L,res,fail); disp(s); if isreal gt=filterbankrealtight(g,a,L); else gt=filterbanktight(g,a,L); end; if isuniform c=ufilterbank(f,gt,a); else c=filterbank(f,gt,a); end; rt=ifilterbank(c,gt,a); if isreal rt=2*real(rt); end; res=norm(f-rt); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf(['ERBFILTER TIGHT %s %s %s %s L:%3i %0.5g %s'],realcomplex,warping,fracname,uniform,L,res,fail); disp(s); end; end; end; end; ltfat/inst/private/ref_dft.m0000664000175000017500000000240413026262303015777 0ustar susnaksusnakfunction c=ref_dft(f) %-*- texinfo -*- %@deftypefn {Function} ref_dft %@verbatim %REF_DFT Reference Discrete Fourier Transform % Usage: c=ref_dft(f); % % REF_DFT(f) computes the unitary discrete Fourier transform of f. % % AUTHOR: Jordy van Velthoven %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); c= zeros(L,W); for w=1:W for k=0:L-1 for l=0:L-1 c(k+1,w) = c(k+1,w) + f(l+1,w) * exp(-2*pi*i*k*l/L); end; end; end c = c./sqrt(L); ltfat/inst/private/test_wtfft_undec.m0000664000175000017500000000473213026262303017743 0ustar susnaksusnakfunction test_failed = test_wtfft_undec; %-*- texinfo -*- %@deftypefn {Function} test_wtfft_undec %@verbatim %TEST_COMP_FWT_ALL % % Checks perfect reconstruction of the wavelet transform % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_wtfft_undec.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed = 0; load vonkoch; f=vonkoch; f = 0:2^7-1; f = f'; J = 3; w = waveletfb('db',2); wh = w.h; for ii=1:numel(wh) wh{ii}=w.h{ii}./sqrt(w.a(ii)); end [h,a] = multid(wh,J); H = freqzfb(h,length(f),a,'wtfft'); tic; c1 = wtfft(f,H,[]);toc; tic; c2 = fwt(f,w,J,'undec'); toc; printCoeffs(c1,c2); wg = w.g; for ii=1:numel(wh) wg{ii}=w.g{ii}./sqrt(w.a(ii)); end [g,a] = multid(wg,J); G = freqzfb(g,length(f),a,'syn','wtfft'); fhat = iwtfft(c1,G,[],length(f));toc; stem([f,fhat]); hlens = zeros(numel(h),1); for jj = 1:numel(h) hlens(jj) = length(h{jj}); end shifts=zeros(numel(c1),1); % check coefficients and find for jj = 1:numel(c1) if(norm(c1{jj}-c2{jj})>1e-6) for sh=1:floor(length(c1{jj})/2) if(norm(c1{jj}-circshift(c2{jj},sh))<1e-6) shifts(jj)=sh; continue; end if(norm(c1{jj}-circshift(c2{jj},-sh))<1e-6) shifts(jj)=-sh; continue; end end if(shifts(jj)~=0) continue; end; % even all coefficients shifts are not equal shifts(jj)=Inf; end end shifts function printCoeffs( x,y) [J,N1] = size(x); for j=1:J subplot(J,1,j); % err = x{j}(:) - y{j}(:); stem([x{j}(:),y{j}(:)]); lh = line([0 length(x{j})],[eps eps]); set(lh,'Color',[1 0 0]); lh =line([0 length(x{j})],[-eps -eps]); set(lh,'Color',[1 0 0]); end ltfat/inst/private/test_rangecompress.m0000664000175000017500000000274513026262303020305 0ustar susnaksusnakfunction test_failed=test_rangecompress %-*- texinfo -*- %@deftypefn {Function} test_rangecompress %@verbatim %TEST_RANGECOMPRESS Test range compression and expansion %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_rangecompress.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp(' =============== TEST_RANGECOMPRESS ================'); x=tester_crand(5,11); y=rangecompress(x,'mulaw'); x_r=rangeexpand(y,'mulaw'); res=norm(x-x_r,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['RANGECOMPRESS MULAW %0.5g %s\n'],res,fail); y=rangecompress(x,'alaw'); x_r=rangeexpand(y,'alaw'); res=norm(x-x_r,'fro'); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf(['RANGECOMPRESS ALAW %0.5g %s\n'],res,fail); ltfat/inst/private/ref_spreadadj.m0000664000175000017500000000254513026262303017165 0ustar susnaksusnakfunction cadj=ref_spreadadj(coef); %-*- texinfo -*- %@deftypefn {Function} ref_spreadadj %@verbatim %REF_SPREADADJ Symbol of adjoint preading function. % Usage: cadj=ref_spreadadj(c); % % cadj=SPREADADJ(c) will compute the symbol cadj of the spreading % operator that is the adjoint of the spreading operator with symbol c. % % The algorithm converts the symbol to the matrix representation, % adjoints its, and finds its spreading function. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_spreadadj.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(coef,1); T=tfmat('spread',coef); cadj=spreadfun(T'); ltfat/inst/private/ref_idwilt_1.m0000664000175000017500000000540113026262303016736 0ustar susnaksusnakfunction [f]=ref_idwilt_1(coef,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwilt_1 %@verbatim %REF_IDWILT_1 Reference IDWILT by IDGT % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwilt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard L=size(g,1); N=L/a; W=size(coef,2); coef=reshape(coef,M*2,N/2,W); coef2=zeros(2*M,N,W); if 1 % ----- Loop version --- for n=0:N/2-1 % m=0 coef2(1,2*n+1,:) = coef(1,n+1,:); for m=0:M-1 % m odd for m=1:2:M-1 coef2(m+1,2*n+1,:) = -i/sqrt(2)*coef(m+1,n+1,:); coef2(m+1,2*n+2,:) = 1/sqrt(2)*coef(M+m+1,n+1,:); coef2(2*M-m+1,2*n+1,:) = i/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m+1,2*n+2,:) = 1/sqrt(2)*coef(M+m+1,n+1,:); end; % m even for m=2:2:M-1 coef2(m+1,2*n+1,:) = 1/sqrt(2)*coef(m+1,n+1,:); coef2(m+1,2*n+2,:) = -i/sqrt(2)*coef(M+m+1,n+1,:); coef2(2*M-m+1,2*n+1,:) = 1/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m+1,2*n+2,:) = i/sqrt(2)*coef(M+m+1,n+1,:); end; end; % m=nyquest if mod(M,2)==0 coef2(M+1,2*n+1,:) = coef(M+1,n+1,:); else coef2(M+1,2*n+2,:) = coef(M+1,n+1,:); end; end; else % ----- Vector version --- % 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 coef2(3:2:M,1:2:N,:) = 1/sqrt(2)*coef(3:2:M,:,:); coef2(3:2:M,2:2:N,:) = -1/sqrt(2)*i*coef(M+3:2:2*M,:,:); coef2(2*M-1:-2:M+2,1:2:N,:) = 1/sqrt(2)*coef(3: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:2:M,2:2:N,:) = 1/sqrt(2)*coef(M+2:2:2*M,:,:); coef2(2*M:-2:M+2,1:2:N,:) = 1/sqrt(2)*i*coef(2:2:M,:,:); coef2(2*M:-2:M+2,2:2:N,:) = 1/sqrt(2)*coef(M+2:2:2*M,:,:); end; f=idgt(reshape(coef2,2*M,N,W),g,a); ltfat/inst/private/ref_irdft_1.m0000664000175000017500000000322013026262303016547 0ustar susnaksusnakfunction f=ref_irdft_1(c) %-*- texinfo -*- %@deftypefn {Function} ref_irdft_1 %@verbatim %REF_RDFT_1 Reference IRDFT by IFFT % Usage: f=ref_irdft(c); % % Compute IRDFT by doubling the signal and doing an IDFT % to obtain the reconstructed signal %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_irdft_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(c,1); Lhalf=ceil(L/2); Lend=Lhalf*2-1; if ~isreal(c) f=ref_irdft_1(real(c))+i*ref_irdft_1(imag(c)); else % Make it an orthonal transform. c=c*sqrt(L/2); cc=zeros(size(c),assert_classname(c)); % Copy the first coefficient, it is real cc(1,:)=c(1,:)*sqrt(2); cc(2:Lhalf,:)=c(2:2:Lend,:)- i*c(3:2:Lend,:); cc(L-Lhalf+2:end,:)= c(Lend-1:-2:2,:) +i*c(Lend:-2:3,:); % If f has an even length, we must also copy the Nyquest-wave % (it is real) if mod(L,2)==0 cc(L/2+1,:)=c(end,:)*sqrt(2); end; f=real(ifft(cc)); end; ltfat/inst/private/ref_spreadadj_1.m0000664000175000017500000000264213026262303017403 0ustar susnaksusnakfunction cadj=ref_spreadadj_1(coef); %-*- texinfo -*- %@deftypefn {Function} ref_spreadadj_1 %@verbatim %REF_SPREADADJ Symbol of adjoint preading function. % Usage: cadj=ref_spreadadj_1(c); % % cadj=SPREADADJ(c) will compute the symbol cadj of the spreading % operator that is the adjoint of the spreading operator with symbol c. % % The algorithm uses an explit algorithm to compute the entries. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_spreadadj_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(coef,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; ltfat/inst/private/ref_dsti.m0000664000175000017500000000230713026262303016167 0ustar susnaksusnakfunction c=ref_dsti(f) %-*- texinfo -*- %@deftypefn {Function} ref_dsti %@verbatim %REF_DSTI Reference Discrete Sine Transform type I % Usage: c=ref_dsti(f); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dsti.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); W=size(f,2); % Create transform matrix. F=zeros(L); for m=0:L-1 for n=0:L-1 F(m+1,n+1)=sin(pi*(n+1)*(m+1)/(L+1)); end; end; F=F*sqrt(2/(L+1)); % Compute coefficients. c=F'*f; ltfat/inst/private/ref_gabdual.m0000664000175000017500000000224313026262303016622 0ustar susnaksusnakfunction gd=ref_gabdual(g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_gabdual %@verbatim %REF_GABDUAL Reference GABDUAL % Usage: gd=ref_gabdual(g,a,M); % % Calculate the canonical dual window by simple linear algebra %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_gabdual.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . g = double(g); % To avoid inacuraces G=frsynmatrix(frame('dgt',g,a,M),length(g)); gd=(G*G')\g; ltfat/inst/private/ref_hermbasis.m0000664000175000017500000000442013026262303017177 0ustar susnaksusnakfunction [V]=ref_hermbasis(L) %-*- texinfo -*- %@deftypefn {Function} ref_hermbasis %@verbatim %REF_HERMBASIS Orthonormal basis of discrete Hermite functions. % Usage: V=hermbasis(L); % % HERMBASIS(L) will compute an orthonormal basis of discrete Hermite % functions of length L. The vectors are returned as columns in the % output. % % All the vectors in the output are eigenvectors of the discrete Fourier % transform, and resemble samplings of the continuous Hermite functions % to some degree. % % % References: % 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.github.io/doc/reference/ref_hermbasis.html} %@seealso{dft, pherm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard % TESTING: TEST_HERMBASIS % REFERENCE: OK % Create tridiagonal sparse matrix A=ones(L,3); A(:,2)=(2*cos((0:L-1)*2*pi/L)-4).'; H=spdiags(A,-1:1,L,L); H(1,L)=1; H(L,1)=1; H=H*pi/(i*2*pi)^2; % Blow it to a full matrix, and use the linear algebra % implementation. This always works. [V,D]=eig(full(H)); % If L is not a factor of 4, then all the eigenvalues of the tridiagonal % matrix are distinct. If L IS a factor of 4, then one eigenvalue has % multiplicity 2, and we must split the eigenspace belonging to this % eigenvalue into a an even and an odd subspace. if mod(L,4)==0 x=V(:,L/2); x_e=(x+involute(x))/2; x_o=(x-involute(x))/2; x_e=x_e/norm(x_e); x_o=x_o/norm(x_o); V(:,L/2)=x_o; V(:,L/2+1)=x_e; end; ltfat/inst/private/test_nonu2ufilterbank.m0000664000175000017500000000520313026262303020715 0ustar susnaksusnakfunction test_failed = test_nonu2ufilterbank %-*- texinfo -*- %@deftypefn {Function} test_nonu2ufilterbank %@verbatim % This tests equality of coefficients of a non uniform and % an identical uniform filterbanks %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_nonu2ufilterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . test_failed=0; disp('-------------TEST_NONU2UFILTERBANK-------------'); for ftypeCell = {'time','freq'} ftype = ftypeCell{1}; disp(sprintf('--------------- %s ------------',ftype)); for M=[1,6]; for aCell = {(1:M)',(M:-1:1)',ones(M,1), M*ones(M,1)} a = aCell{1}; N=10; L=filterbanklength(1,a)*N; for W = 1:3 g=cell(1,M); if strcmp(ftype,'time') for ii=1:M g{ii}=tester_crand(L/2,1); end; elseif strcmp(ftype,'freq') for ii=1:M g{ii}=struct('H',tester_crand(L,1),'foff',0,'L',L); end; end f = tester_crand(L,W); % Target coefficients c_non = filterbank(f,g,a); % Do a uniform filterbank [gu,au,pk] = nonu2ufilterbank(g,a); % Identical cell-array c_u = filterbank(f,gu,au); % Identical matrix c_uu = ufilterbank(f,gu,au); res=0; for m=1:M res=res+norm(c_u{m}-squeeze(c_uu(:,m,:))); end; [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('COEFEQ L:%3i,W:%3i,M:%3i, %0.5g %s\n',L,W,M,res,fail); % Convert back to nonuniform format c = u2nonucfmt(c_u,pk); res = norm(cell2mat(c_non) - cell2mat(c)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('FORMAT CELL L:%3i,W:%3i,M:%3i, %0.5g %s\n',L,W,M,res,fail); % Convert back to nonuniform format c = u2nonucfmt(c_uu,pk); res = norm(cell2mat(c_non) - cell2mat(c)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('FORMAT MAT L:%3i,W:%3i,M:%3i, %0.5g %s\n',L,W,M,res,fail); % Convert c_uuu = nonu2ucfmt(c_non,pk); res = norm(cell2mat(c_uuu) - cell2mat(c_u)); [test_failed,fail]=ltfatdiditfail(res,test_failed); fprintf('FORMATBACK L:%3i,W:%3i,M:%3i, %0.5g %s\n',L,W,M,res,fail); end end end end ltfat/inst/private/ref_dgt_1.m0000664000175000017500000000315113026262303016220 0ustar susnaksusnakfunction c=ref_dgt_1(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_1 %@verbatim %REF_DGT_1 DGT by Poisson summation. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(g,1); N=L/a; b=L/M; w=zeros(M,N); if 0 % This version uses the definition for jj=0:M-1 for nn=0:N-1 for kk=0:b-1 w(jj+1,nn+1)=w(jj+1,nn+1)+f(jj+kk*M+1)*conj(g(mod(jj+kk*M-nn*a,L)+1)); end; end; end; else % This version uses matrix-vector products. W=zeros(b,N); v=zeros(b,1); for jj=0:M-1 % Setup the matrix and vector for kk=0:b-1 for nn=0:N-1 W(kk+1,nn+1)=g(mod(jj+kk*M-nn*a,L)+1); end; v(kk+1)=f(mod(jj+kk*M,L)+1); end; % do the product. s1=W'*v; % Arrange in w for nn=0:N-1 w(jj+1,nn+1)=s1(nn+1); end; end; end; c=fft(w); ltfat/inst/private/ref_dgt_fb.m0000664000175000017500000000637213026262303016457 0ustar susnaksusnakfunction [coef]=ref_dgt_fb(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dgt_fb %@verbatim %REF_DGT_FB Filter bank DGT % Usage: c=ref_dgt_fb(f,g,a,M); % % This should be an exact copy of comp_dgt_fb to serve for testing % the oct/mex routines and for timings. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dgt_fb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard. % Calculate the parameters that was not specified. L=size(f,1); b=L/M; 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); % 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 %disp(["ref: begin: ",num2str(n)]); % This code does the same using a circshift. It will also work for % the last boundary part. %fpart=circshift(f,glh-n*a); %fg=fpart(1:gl,:).*gw; 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); % Make it frequency invariant coef(:,n+1,:)=circshift(coef(:,n+1,:),n*a-glh); end; % ----- Handle the middle case. --------------------- for n=ceil(glh/a):floor((L-ceil(gl/2))/a) %disp(["ref: middle: ",num2str(n)]); 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); coef(:,n+1,:)=circshift(coef(:,n+1,:),n*a-glh); end; % ----- Handle the last boundary using periodic boundary conditions. --- for n=floor((L-ceil(gl/2))/a)+1:N-1 %disp(["ref: end: ",num2str(n)]); 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); 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; ltfat/inst/private/ref_fcdgt.m0000664000175000017500000000317413026262303016316 0ustar susnaksusnakfunction c=ref_fcdgt(f,g,a,M,m_t,m_f,w_t,w_f) %-*- texinfo -*- %@deftypefn {Function} ref_fcdgt %@verbatim %REF_CDGT Reference centered DGT % Usage: c=ref_dgtiv(f,g,a,M,c_t,c_f,c_w); % % Linear algebra version of the algorithm. Create big matrix % containing all the basis functions and multiply with the transpose. % % For easy work, m_t,m_f,w_t,w_f are all just 0/1 indicator variables. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_fcdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . L=size(f,1); N=L/a; b=L/M; m_t=m_t*.5; w_t=w_t*floor(a/2); w_f=w_f*ceil(b/2); F=zeros(L,M*N); l=(0:L-1).'; if m_f==0 for n=0:N-1 for m=0:M-1 F(:,M*n+m+1)=exp(2*pi*i*(m*b+w_f)*(l+m_t)/L).*circshift(g,n*a+w_t); end; end; else for n=0:N-1 for m=0:M-1 F(:,M*n+m+1)=exp(2*pi*i*(m*b+.5+w_f)*(l+m_t-n*a)/L).*circshift(g,n*a+w_t); end; end; end; c=F'*f; ltfat/inst/private/ref_idwiltii_1.m0000664000175000017500000000550313026262303017263 0ustar susnaksusnakfunction [f]=ref_idwiltii_1(coef,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_idwiltii_1 %@verbatim %REF_IDWILTII_1 Reference IDWILTII by IDGT type II % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_idwiltii_1.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author : Peter L. Soendergaard L=size(g,1); N=L/a; W=size(coef,2); coef=reshape(coef,M*2,N/2,W); coef2=zeros(2*M,N,W); if 0 % --- loop version --- for n=0:N/2-1 % m=0 coef2(1,2*n+1,:) = coef(1,n+1,:); % m odd for m=1:2:M-1 coef2(m+1,2*n+1,:) = -i/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m+1,2*n+1,:) = -i/sqrt(2)*coef(m+1,n+1,:); coef2(m+1,2*n+2,:) = 1/sqrt(2)*coef(M+m+1,n+1,:); coef2(2*M-m+1,2*n+2,:) = -1/sqrt(2)*coef(M+m+1,n+1,:); end; % m even for m=2:2:M-1 coef2(m+1,2*n+1,:) = 1/sqrt(2)*coef(m+1,n+1,:); coef2(2*M-m+1,2*n+1,:) = -1/sqrt(2)*coef(m+1,n+1,:); coef2(m+1,2*n+2,:) = -i/sqrt(2)*coef(M+m+1,n+1,:); coef2(2*M-m+1,2*n+2,:) = -i/sqrt(2)*coef(M+m+1,n+1,:); end; % m=nyquest if mod(M,2)==0 coef2(M+1,2*n+2,:) = -i*coef(M+1,n+1,:); else coef2(M+1,2*n+1,:) = -i*coef(M+1,n+1,:); end; end; else % --- Vector version --- % 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; end; f=ref_igdgt(reshape(coef2,2*M*N,W),g,a,2*M,.5,0,0); %if norm(imag(f(:)))<1e-10 % f=real(f); %end; ltfat/inst/private/test_gabmuleigs.m0000664000175000017500000000306213026262303017545 0ustar susnaksusnakfunction test_failed=test_gabmuleigs %-*- texinfo -*- %@deftypefn {Function} test_gabmuleigs %@verbatim %TEST_GABMULEIGS Test GABMULEIGS % % Test GABMULEIGS by comparing the output from the iterative and full algorithm. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_gabmuleigs.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . disp(' =============== TEST_GABMULEIGS ================'); test_failed=0; a=20; M=30; L=a*M; N=L/a; c=randn(M,N); g=gabtight(a,M,L); % [V1,D1]=gabmuleigs(10,c,g,a,'iter'); % [V2,D2]=gabmuleigs(10,c,g,a,'full'); F = frame('dgt',g,a,M); c = framenative2coef(F,c); [V1,D1]=framemuleigs(F,F,c,10,'iter'); [V2,D2]=framemuleigs(F,F,c,10,'full'); res=norm(D1-D2); [test_failed,fail]=ltfatdiditfail(res,test_failed); s=sprintf('GABMULEIGS L:%3i a:%3i M:%3i %0.5g %s',L,a,M,res,fail); disp(s); ltfat/inst/private/tester_rand.m0000664000175000017500000000226313026262303016703 0ustar susnaksusnakfunction f=tester_rand(varargin); %-*- texinfo -*- %@deftypefn {Function} tester_rand %@verbatim %RAND Random numbers for testing. % Usage: f=tester_rand(p1,p2); %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/tester_rand.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . global LTFAT_TEST_TYPE if isempty(LTFAT_TEST_TYPE) LTFAT_TEST_TYPE='double'; end; f=rand(varargin{:}) - 0.5; if strcmp(LTFAT_TEST_TYPE,'single') f=single(f); end; ltfat/inst/private/ref_dwilt.m0000664000175000017500000000344213026262303016350 0ustar susnaksusnakfunction c=ref_dwilt(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} ref_dwilt %@verbatim %REF_DWILT Reference Discrete Wilson Transform % Usage: c=ref_dwilt(f,g,a,M); % % M must be even. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/reference/ref_dwilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Setup transformation matrix. L=size(f,1); N=L/a; F=zeros(L,M*N); % Zero-extend g if necessary g=fir2long(g,L); l=(0:L-1).'; for n=0:N/2-1 % Do the unmodulated coefficient. F(:,2*M*n+1)=circshift(g,2*n*a); % m odd case for m=1:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*sin(pi*m/M*l).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*cos(pi*m/M*l).*circshift(g,(2*n+1)*a); end; % m even case for m=2:2:M-1 F(:,m+2*M*n+1) = sqrt(2)*cos(pi*m/M*l).*circshift(g,2*n*a); F(:,m+2*M*n+M+1) = sqrt(2)*sin(pi*m/M*l).*circshift(g,(2*n+1)*a); end; % Most modulated coefficient, Nyquest frequency. if mod(M,2)==0 F(:,M+2*M*n+1)=(-1).^l.*circshift(g,2*n*a); else F(:,M+2*M*n+1)=(-1).^l.*circshift(g,(2*n+1)*a); end; end; c=F'*f; ltfat/inst/deprecated/0000775000175000017500000000000013026262303014636 5ustar susnaksusnakltfat/inst/deprecated/gabelitistlasso.m0000664000175000017500000001305013026262303020204 0ustar susnaksusnakfunction [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.github.io/doc/deprecated/gabelitistlasso.html} %@seealso{gablasso, gabframebounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning(['LTFAT: GABELITISTLASSO has been deprecated, please use FRANAGROUPLASSO ' ... 'instead. See the help on FRANAGROUPLASSO for more details.']); 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; ltfat/inst/deprecated/framematrix.m0000664000175000017500000000631713026262303017342 0ustar susnaksusnakfunction 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.github.io/doc/deprecated/framematrix.html} %@seealso{frame, frana, frsyn} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/deprecated/gablasso.m0000664000175000017500000000315413026262303016612 0ustar susnaksusnakfunction [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.github.io/doc/deprecated/gablasso.html} %@seealso{frame, franalasso} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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{:}); ltfat/inst/deprecated/gabmul.m0000664000175000017500000000616713026262303016275 0ustar susnaksusnakfunction 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.github.io/doc/deprecated/gabmul.html} %@seealso{dgt, idgt, gabdual, gabtight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/deprecated/iunsdgtreal.m0000664000175000017500000000441013026262303017334 0ustar susnaksusnakfunction f=iunsdgtreal(c,g,a,M,Ls) %-*- texinfo -*- %@deftypefn {Function} iunsdgtreal %@verbatim %IUNSDGTREAL Inverse uniform non-stationary 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 non-stationary 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.github.io/doc/deprecated/iunsdgtreal.html} %@seealso{unsdgt, nsgabdual, nsgabtight, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Florent Jaillet and Peter L. Soendergaard % TESTING: TEST_NSDGT % REFERENCE: OK warning(['LTFAT: IUNSDGTREAL has been deprecated, use INSDGTREAL instead.']); f=insdgtreal(varargin{:}); ltfat/inst/deprecated/demo_gablasso.m0000664000175000017500000000375313026262303017623 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_gablasso %@verbatim %DEMO_GABLASSO Sparse regression by Lasso method %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/deprecated/demo_gablasso.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning('LTFAT: DEMO_GABLASSO has been deprecated.'); % 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.1; maxit=500; tol=1e-2; 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*sqrt(M),'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') ltfat/inst/deprecated/gabgrouplasso.m0000664000175000017500000000331113026262303017662 0ustar susnaksusnakfunction [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.github.io/doc/deprecated/gabgrouplasso.html} %@seealso{frame, franagrouplasso} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning(['LTFAT: GABGROUPLASSO has been deprecated, please use FRANAGROUPLASSO ' ... 'instead. See the help on FRANAGROUPLASSO for more details.']); F=newframe('dgt',[],g,a,M); [tc,relres,iter,xrec] = framegrouplasso(F,lambda,varargin{:}); ltfat/inst/deprecated/tfmat.m0000664000175000017500000001340113026262303016126 0ustar susnaksusnakfunction 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.github.io/doc/deprecated/tfmat.html} %@seealso{frsynmatrix, operatormatrix} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/deprecated/gabmuleigs.m0000664000175000017500000001314413026262303017136 0ustar susnaksusnakfunction [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.github.io/doc/deprecated/gabmuleigs.html} %@seealso{gabmul, dgt, idgt, gabdual, gabtight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning(['LTFAT: GABMULEIGS has been deprecated, please use FRAMEMULEIGS ' ... 'instead. See the help on FRAMEMULEIGS for more details.']); % 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; ltfat/inst/deprecated/convolve.m0000664000175000017500000000401513026262303016647 0ustar susnaksusnakfunction h=convolve(f,g,varargin) %-*- texinfo -*- %@deftypefn {Function} convolve %@verbatim %CONVOLVE Convolution % Usage: h=convolve(f,g); % % CONVOLVE has been deprecated. Please use LCONV instead. % % A call to CONVOLVE(f,g) can be replaced by : % % lconv(f,g); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/deprecated/convolve.html} %@seealso{lconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning(['LTFAT: CONVOLVE has been deprecated, please use LCONV ' ... 'instead. See the help on LCONV for more details.']); 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/deprecated/deprecatedinit.m0000664000175000017500000000165413026262303020006 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} deprecatedinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/deprecated/deprecatedinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/deprecated/iunsdgt.m0000664000175000017500000000422613026262303016475 0ustar susnaksusnakfunction f=iunsdgt(c,g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} iunsdgt %@verbatim %IUNSDGT Inverse uniform non-stationary 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 non-stationary 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.github.io/doc/deprecated/iunsdgt.html} %@seealso{unsdgt, nsgabdual, nsgabtight, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Florent Jaillet % TESTING: TEST_NSDGT % REFERENCE: % Last changed 2009-05 warning(['LTFAT: IUNSDGT has been deprecated, use INSDGT instead.']); f=insdgt(varargin{:}); ltfat/inst/deprecated/uwpfbtbounds.m0000664000175000017500000000461613026262303017545 0ustar susnaksusnakfunction [AF,BF]=uwpfbtbounds(wt,varargin) %-*- texinfo -*- %@deftypefn {Function} uwpfbtbounds %@verbatim %UWPFBTBOUNDS Frame bounds of Undecimated WPFBT % Usage: fcond=uwpfbtbounds(wt,L); % [A,B]=uwpfbtbounds(wt,L); % % UWPFBTBOUNDS(wt,L) calculates the ratio B/A of the frame bounds % of the undecimated wavelet packet filterbank specified by wt for a % system of length L. The ratio is a measure of the stability of the % system. % % [A,B]=uwfbtbounds(wt,L) returns the lower and upper frame bounds % explicitly. % % See WFBT for explanation of parameter wt. % % Additionally, the function accepts the following flags: % % 'intsqrt'(default),'intnoscale', 'intscale' % The filters in the filterbank tree are scaled to reflect the % behavior of UWPFBT and IUWPFBT with the same flags. % % 'sqrt'(default),'noscale','scale' % The filters in the filterbank tree are scaled to reflect the % behavior of UWPFBT and IUWPFBT with the same flags. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/deprecated/uwpfbtbounds.html} %@seealso{uwpfbt, filterbankbounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa warning('UWPFBTBOUNDS is deprecated. Instead, use WPFBTBOUNDS with appropriate flags'); complainif_notenoughargs(nargin,1,'UWPFBTBOUNDS'); definput.keyvals.L = []; definput.flags.scaling={'sqrt','scale','noscale'}; definput.flags.interscaling = {'intsqrt', 'intscale', 'intnoscale'}; [flags,~,L]=ltfatarghelper({'L'},definput,varargin); if nargout<2 AF = wpfbtbounds(wt,L,flags.scaling,flags.interscaling); elseif nargout == 2 [AF, BF] = wpfbtbounds(wt,L,flags.scaling,flags.interscaling); end ltfat/inst/deprecated/uwfbtbounds.m0000664000175000017500000000457413026262303017370 0ustar susnaksusnakfunction [AF,BF]=uwfbtbounds(wt,varargin) %-*- texinfo -*- %@deftypefn {Function} uwfbtbounds %@verbatim %UWFBTBOUNDS Frame bounds of Undecimated WFBT % Usage: fcond=uwfbtbounds(wt,L); % [A,B]=uwfbtbounds(wt,L); % [...]=uwfbtbounds(wt); % % UWFBTBOUNDS(wt,L) calculates the ratio B/A of the frame bounds % of the undecimated filterbank specified by wt for a system of length % L. The ratio is a measure of the stability of the system. % % UWFBTBOUNDS({w,J,'dwt'},L) calculates the ratio B/A of the frame % bounds of the undecimated DWT (|UFWT|) filterbank specified by w and % J for a system of length L. % % UWFBTBOUNDS(wt) does the same thing, but L is the length of the % longest filter in the identical filterbank. % % [A,B]=UWFBTBOUNDS(...) returns the lower and upper frame bounds % explicitly. % % See WFBT for explanation of parameter wt and FWT for explanation % of parameters w and J. % % The function supports the following flags: % % 'sqrt'(default),'noscale','scale' % The filters in the filterbank tree are scaled to reflect the % behavior of UWFBT and IUWFBT with the same flags. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/deprecated/uwfbtbounds.html} %@seealso{uwfbt, filterbankbounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning('UWFBTBOUNDS is deprecated. Please use WFBTBOUNDS with a appropriate flag.'); complainif_notenoughargs(nargin,1,'UWFBTBOUNDS'); definput.keyvals.L = []; definput.import = {'uwfbtcommon'}; [flags,~,L]=ltfatarghelper({'L'},definput,varargin); if nargout<2 AF = wfbtbounds(wt,L,flags.scaling); elseif nargout == 2 [AF,BF] = wfbtbounds(wt,L,flags.scaling); end ltfat/inst/deprecated/iufilterbank.m0000664000175000017500000000250313026262303017473 0ustar susnaksusnakfunction 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.github.io/doc/deprecated/iufilterbank.html} %@seealso{ifilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . warning(['LTFAT: IUFILTERBANK has been deprecated, please use IFILTERBANK ' ... 'instead.']); f=ifilterbank(varargin{:}); ltfat/inst/AUTHORS0000664000175000017500000000046313026262276013622 0ustar susnaksusnakPeter Soendergaard Zdenek Prusa Nicki Holighaus Christoph Wiesmeyr Peter Balazs Bruno Torresani ltfat/inst/INDEX0000664000175000017500000001224513026262276013345 0ustar susnaksusnakltfat >> Time-frequency analysis and Wavelets signals ctestfun noise pinknoise expchirp bat batmask greasy cocktailparty gspi linus ltfatlogo otoclick traindoppler cameraman lichtenstein ltfattext quadratic ambiguityfunction wignervilledist drihaczekdist quadtfdist plotquadtfdist operators operatornew operator ioperator operatoradj operatorappr operatoreigs operatormatrix framemul iframemul framemuladj framemulappr framemuleigs gabmulappr spreadop spreadinv spreadadj spreadfun spreadeigs deprecated convolve gabelitistlasso gabgrouplasso gablasso gabmuleigs gabmul framematrix iufilterbank iunsdgt iunsdgtreal tfmat uwfbtbounds uwpfbtbounds sigproc rms normalize gaindb crestfactor uquant firwin firkaiser fir2long long2fir freqwin firfilter blfilter warpedblfilter freqfilter pfilt magresp transferfunction pgrpdelay 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 projkern 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 gabphasederiv gabreassign gabreassignadjust constructphase constructphasereal phaselock phaseunlock phaselockreal phaseunlockreal symphase matrix2latticetype latticetype2matrix shearfind noshearlength tfplot plotdgt plotdgtreal plotdwilt plotwmdct sgram gabimagepars resgram instfreqplot phaseplot blockproc block blockdevices blockread blockplay blockpanel blockpanelget blockdone blockwrite blockframeaccel blockframepairaccel blockana blocksyn blockfigure blockplot ltfatplay demos demo_dgt demo_gabfir demo_wavelets demo_imagecompression demo_audiocompression demo_audiodenoise demo_ofdm demo_audioshrink demo_gabmulappr demo_bpframemul demo_frsynabs demo_filterbanksynchrosqueeze demo_nsdgt demo_pgauss demo_pbspline demo_gabmixdual demo_framemul demo_phaseplot demo_phaseret demo_nextfastfft demo_filterbanks demo_audscales demo_auditoryfilterbank demo_wfbt demo_blockproc_basicloop demo_blockproc_paramequalizer demo_blockproc_denoising demo_blockproc_slidingsgram demo_blockproc_slidingcqt demo_blockproc_slidingerblets demo_blockproc_dgtequalizer demo_blockproc_effects 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 wfbtclength wpfbtclength dtwfb idtwfb dtwfbreal idtwfbreal wfbtinit dtwfbinit wfbtput wfbtremove wfbt2filterbank wpfbt2filterbank dtwfb2filterbank fwtinit wfbtbounds wpfbtbounds dtwfbbounds plotwavelets wfiltinfo wfiltdtinfo wavfun wavcell2pack wavpack2cell wfilt_algmband wfilt_cmband wfilt_coif wfilt_db wfilt_dden wfilt_dgrid wfilt_hden wfilt_lemarie wfilt_matlabwrapper wfilt_mband wfilt_remez wfilt_symds wfilt_spline wfilt_sym wfilt_symdden wfilt_symorth wfilt_symtight wfilt_qshifta wfilt_qshiftb wfilt_oddevena wfilt_oddevenb wfilt_optsyma wfilt_optsymb wfilt_ddena wfilt_ddenb wfiltdt_qshift wfiltdt_optsym wfiltdt_oddeven wfiltdt_dden filterbank filterbank ufilterbank ifilterbank ifilterbankiter filterbankwin filterbanklength filterbanklengthcoef cqt icqt erblett ierblett cqtfilters erbfilters warpedfilters audfilters filterbankdual filterbanktight filterbankrealdual filterbankrealtight filterbankbounds filterbankrealbounds filterbankresponse filterbankfreqz filterbankscale nonu2ufilterbank u2nonucfmt nonu2ucfmt plotfilterbank filterbankphasegrad filterbankreassign filterbanksynchrosqueeze fourier fftindex modcent floor23 floor235 ceil23 ceil235 nextfastfft dft idft fftreal ifftreal gga chirpzt fftgram plotfft plotfftreal involute peven podd pconv pxcorr lconv lxcorr isevenfunction middlepad expwave pchirp pgauss psech pbspline shah pheaviside prect psinc ptpfun pebfun ptpfundual pebfundual pherm hermbasis dfracft ffracft fftresample dctresample pderiv fftanalytic dcti dctii dctiii dctiv dsti dstii dstiii dstiv frames frame framepair framedual frametight frameaccel frana frsyn frsynmatrix frgramian frameoperator framediag franaiter frsyniter plotframe framegram framebounds framered framelength framelengthcoef frameclength framecoef2native framenative2coef framecoef2tf frametf2coef framecoef2tfplot franabp franalasso franagrouplasso frsynabs base ltfatstart ltfatstop ltfathelp ltfatmex ltfatbasepath isoctave ltfatarghelper ltfatgetdefaults ltfatsetdefaults scalardistribute mulaclab ltfat/inst/sigproc/0000775000175000017500000000000013026262303014204 5ustar susnaksusnakltfat/inst/sigproc/gaindb.m0000664000175000017500000000463013026262303015611 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/gaindb.html} %@seealso{rms} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/sigproc/largestn.m0000664000175000017500000000560313026262303016205 0ustar susnaksusnakfunction [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.github.io/doc/sigproc/largestn.html} %@seealso{largestr} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/sigproc/blfilter.m0000664000175000017500000001522113026262303016166 0ustar susnaksusnakfunction 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. 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 filter bank. % % '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.github.io/doc/sigproc/blfilter.html} %@seealso{firfilter, firwin, pfilt, filterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/sigproc/thresh.m0000664000175000017500000001516013026262303015662 0ustar susnaksusnakfunction [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 scalar 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. % % The lambda parameter can also be a vector with number of elements % equal to numel(xi) or it can be a numeric array of the same shape % as xi. lambda is then applied element-wise and in a column major % order if lambda is a vector. % % [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.github.io/doc/sigproc/thresh.html} %@seealso{largestr, largestn} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Kai Siedenburg, Bruno Torresani and Peter L. Soendergaard. % TESTING: OK % REFERENCE: OK complainif_notenoughargs(nargin,2,'THRESH'); is_sameshape = ndims(lambda)==ndims(xi) && all(size(lambda)==size(xi)); if ~isnumeric(lambda) || ... ~isscalar(lambda) && ... % lambda is not scalar numel(lambda)~=numel(xi) && ... % lambda does not have the same number of elements ~(is_sameshape) % lambda does not have the same shape error(['%s: lambda must be a scalar, a vector with ',... 'numel(lambda)==numel(xi) or whatever shape xi has such that ',... 'all(size(lambda)==size(xi))'],upper(mfilename)); 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(['%s: Sparse output is only supported for 1D/2D input. This ',... 'is a limitation of Matlab/Octave.'],upper(mfilename)); end; if ~isa(xi,'double') error(['%s: Input is not double prec. data array and sparse output can,'... 'be double precision data type only. This is a ',... 'Matlab/Octave limitation.'],upper(mfilename)); end end; % Reshape lambda if it is a vector if ~is_sameshape && ~isscalar(lambda) lambda = reshape(lambda,size(xi)); end if flags.do_sparse xo=sparse(size(xi,1),size(xi,2)); if flags.do_hard if isscalar(lambda) % Create a significance map pointing to the non-zero elements. signifmap=find(abs(xi)>=lambda); else signifmap=abs(xi)>=lambda; end xo(signifmap)=xi(signifmap); else if isscalar(lambda) % Create a significance map pointing to the non-zero elements. signifmap=find(abs(xi)>lambda); else signifmap=abs(xi)>lambda; end if flags.do_wiener if isscalar(lambda) xo(signifmap) = 1 - (lambda./abs(xi(signifmap))).^2; else xo(signifmap) = 1 - (lambda(signifmap)./abs(xi(signifmap))).^2; end xo(signifmap) = xi(signifmap).*xo(signifmap); end; if flags.do_soft if isscalar(lambda) % xo(signifmap)=xi(signifmap) - sign(xi(signifmap))*lambda; xo(signifmap)=(abs(xi(signifmap)) - lambda) .* ... exp(i*angle(xi(signifmap))); else xo(signifmap)=(abs(xi(signifmap)) - lambda(signifmap)) .* ... exp(i*angle(xi(signifmap))); end % 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; end if nargout==2 N=numel(signifmap); end; else % Dense case xo=zeros(size(xi),assert_classname(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; ltfat/inst/sigproc/groupthresh.m0000664000175000017500000001016013026262303016732 0ustar susnaksusnakfunction [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.github.io/doc/sigproc/groupthresh.html} %@seealso{thresh, demo_audioshrink} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/sigproc/dynlimit.m0000664000175000017500000000242213026262303016213 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/dynlimit.html} %@seealso{thresh, largestr, largestn} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . xmax=max(xi(:)); xo=xi; xo(xo. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); asan = comp_filterbank_a(a,1); 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 ltfat/inst/sigproc/warpedblfilter.m0000664000175000017500000001414313026262303017373 0ustar susnaksusnakfunction 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,scaletofreq); % % 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,fc,fs,freqtoscale,scaletofreq) 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 and scaletofreq doing the inverse. % % 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. This is the default. % % 'real' Make the filter real-valued if the centre frequency % is non-zero. % % 'symmetric' The filters with fc<0 (or fc>fs/2) will be created % on the positive frequencies and mirrored. This allows % using freqtoscale defined only for the positive % numbers. % % '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.github.io/doc/sigproc/warpedblfilter.html} %@seealso{blfilter, firwin, pfilt, filterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . capmname = upper(mfilename); complainif_notenoughargs(nargin,6,capmname); complainif_notposint(fs,'fs',capmname); if isempty(freqtoscale) || ~isa(freqtoscale,'function_handle') error('%s: freqtoscale must be a function handle',capmname); end if isempty(scaletofreq) || ~isa(scaletofreq,'function_handle') error('%s: scaletofreq must be a function handle',capmname); end if isempty(fc) || ~isnumeric(fc) error('%s: fc must be numeric',capmname); end if isempty(fsupp) || ~isnumeric(fsupp) error('%s: fc must be numeric',capmname); end % 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'}; definput.flags.symmetry = {'nonsymmetric','symmetric'}; [flags,kv]=ltfatarghelper({},definput,varargin); if ~isscalar(kv.scal) error('%s: scal must be a scalar',capmname); end if ~isscalar(kv.delay) error('%s: delay must be a scalar',capmname); end [fsupp,fc,kv.delay,kv.scal]=scalardistribute(fsupp,fc,kv.delay,kv.scal); 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) comp_warpedfreqresponse( wn{1},fc(ii), ... fsupp(ii),fs,L,freqtoscale, ... scaletofreq, flags.norm,... flags.symmetry)*kv.scal(ii)*L; end; if flags.do_2 || flags.do_energy g.H=@(L) comp_warpedfreqresponse(wn{1},fc(ii), ... fsupp(ii),fs,L,freqtoscale,scaletofreq, ... flags.norm,flags.symmetry)*kv.scal(ii)*sqrt(L); end; if flags.do_inf || flags.do_peak g.H=@(L) comp_warpedfreqresponse(wn{1},fc(ii), ... fsupp(ii),fs,L,freqtoscale,scaletofreq, ... flags.norm,flags.symmetry)*kv.scal(ii); end; g.foff=@(L) comp_warpedfoff(fc(ii),fsupp(ii),fs,L,freqtoscale,... scaletofreq,flags.do_symmetric); g.realonly=flags.do_real; if kv.delay~=0 g.delay=kv.delay(ii); end g.fs=fs; gout{ii}=g; end; if Nfilt==1 gout=g; end; ltfat/inst/sigproc/crestfactor.m0000664000175000017500000000227313026262303016705 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/crestfactor.html} %@seealso{rms, gaindb} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . c=20*log10(norm(insig,Inf)/rms(insig)); ltfat/inst/sigproc/normalize.m0000664000175000017500000000760213026262303016367 0ustar susnaksusnakfunction [f,fnorm]=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. % % [f,fnorm]=NORMALIZE(f,...) does the same thing, but in addition % returns norm fnorm of a signal f. % % 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.github.io/doc/sigproc/normalize.html} %@seealso{rms, s0norm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 || flags.do_norm_notset || 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)); fnorm = zeros(W,1); for ii=1:W if flags.do_1 || flags.do_area fnorm(ii) = norm(f(:,ii),1); f(:,ii)=f(:,ii)/fnorm(ii); end; if flags.do_2 || flags.do_energy fnorm(ii) = norm(f(:,ii),2); f(:,ii)=f(:,ii)/fnorm(ii); end; if flags.do_inf || flags.do_peak fnorm(ii) = norm(f(:,ii),Inf); f(:,ii)=f(:,ii)/fnorm(ii); end; if flags.do_rms fnorm(ii) = rms(f(:,ii)); f(:,ii)=f(:,ii)/fnorm(ii); end; if flags.do_s0 fnorm(ii) = s0norm(f(:,ii)); f(:,ii)=f(:,ii)/fnorm(ii); end; if flags.do_wav if isa(f,'float') fnorm(ii) = norm(f(:,ii),Inf); f(:,ii) = 0.99*f(:,ii)/fnorm(ii); 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); ltfat/inst/sigproc/iqam4.m0000664000175000017500000000347413026262303015405 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/iqam4.html} %@seealso{qam4, demo_ofdm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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(:); ltfat/inst/sigproc/firwin.m0000664000175000017500000003077313026262303015672 0ustar susnaksusnakfunction [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 if the order is odd. % Alias: 'square' % % '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. % % 'truncgauss' Gaussian window truncated at 1% of its height. % Alternatively, a custom percentage can be appended to % 'truncgauss' e.g. 'truncgauss0.1' will create Gaussian % window truncated at 0.1% of its height. % % 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.github.io/doc/sigproc/firwin.html} %@seealso{freqwin, pgauss, pbspline, firkaiser, normalize} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 if ~isnumeric(M) error('%s: M must be numeric.',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 complainif_notposint(M,'M',mfilename); % 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; startswith = 'truncgauss'; if regexpi(name,['^',startswith]) percent = 1; if numel(name) > numel(startswith) suffix = name(numel(startswith)+1:end); percent = str2double(suffix); if isnan(percent) error('%s: Passed "%s" and "%s" cannot be parsed to a number.',... upper(mfilename),name,suffix); end end name = startswith; 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 {'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)); case {'truncgauss'} g = exp(4*log(percent/100)*x.^2); 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); ltfat/inst/sigproc/qam4.m0000664000175000017500000000354713026262303015235 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/qam4.html} %@seealso{iqam4, demo_ofdm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/sigproc/sigprocinit.m0000664000175000017500000000164313026262303016720 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} sigprocinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/sigproc/sigprocinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/sigproc/rgb2jpeg.m0000664000175000017500000000566613026262303016101 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/rgb2jpeg.html} %@seealso{jpeg2rgb} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/sigproc/firkaiser.m0000664000175000017500000000741313026262303016346 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/firkaiser.html} %@seealso{firwin, normalize} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/sigproc/fir2long.m0000664000175000017500000000415013026262303016104 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/fir2long.html} %@seealso{long2fir, middlepad} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/sigproc/pgrpdelay.m0000664000175000017500000000440413026262303016353 0ustar susnaksusnakfunction ggd = pgrpdelay(g,L) %-*- texinfo -*- %@deftypefn {Function} pgrpdelay %@verbatim %PGRPDELAY Group delay of a filter with periodic boundaries % Usage: ggd = pgrpdelay(g,L); % % PGRPDELAY(g,L) computes group delay of filter g as a negative % derivative of the phase frequency response of filter g assuming % periodic (cyclic) boundaries i.e. the delay may be a negative number. % The derivative is calculated using the second order centered difference % approximation. % The resulting group delay is in samples. % % Example: % -------- % % The following example shows a group delay of causal, moving average % 6tap FIR filter and it's magnitude frequency response for comparison. % The dips in the group delay correspond to places where modulus of the % frequency response falls to zero.: % % g = struct(struct('h',ones(6,1),'offset',0)); % L = 512; % figure(1); % subplot(2,1,1); % plot(-L/2+1:L/2,fftshift(pgrpdelay(g,512))); % axis tight;ylim([0,4]); % % subplot(2,1,2); % magresp(g,L,'nf'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/sigproc/pgrpdelay.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . g = comp_fourierwindow(g,L,upper(mfilename)); H = comp_transferfunction(g,L); Harg = angle(H); % Forward approximation tgrad_1 = Harg-circshift(Harg,-1); tgrad_1 = tgrad_1 - 2*pi*round(tgrad_1/(2*pi)); % Backward approximation tgrad_2 = circshift(Harg,1)-Harg; tgrad_2 = tgrad_2 - 2*pi*round(tgrad_2/(2*pi)); % Average ggd = (tgrad_1+tgrad_2)/2; ggd = ggd/(2*pi)*L; ltfat/inst/sigproc/rampsignal.m0000664000175000017500000000601713026262303016523 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/rampsignal.html} %@seealso{rampdown, rampsignal, firwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/sigproc/largestr.m0000664000175000017500000000563713026262303016220 0ustar susnaksusnakfunction [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.github.io/doc/sigproc/largestr.html} %@seealso{largestn} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/sigproc/rampup.m0000664000175000017500000000320213026262303015663 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/rampup.html} %@seealso{rampdown, rampsignal, firwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . error(nargchk(1,2,nargin)) if nargin==1 wintype='hann'; end; win=firwin(wintype,2*L,'inf'); outsig=win(L+1:2*L); ltfat/inst/sigproc/jpeg2rgb.m0000664000175000017500000000414513026262303016070 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/jpeg2rgb.html} %@seealso{rgb2jpeg} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/sigproc/long2fir.m0000664000175000017500000000502413026262303016105 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/long2fir.html} %@seealso{fir2long, middlepad} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 Wmaxval*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; ltfat/inst/sigproc/Contents.m0000664000175000017500000000530713026262303016164 0ustar susnaksusnak% LTFAT - Signal processing tools % % Peter L. Soendergaard, 2007 - 2016. % % 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. % % Window functions % 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. % FREQWIN - Freq responses (Gauss,Gammatone,Butterworth,...) % % Filtering % FIRFILTER - Construct an FIR filter. % BLFILTER - Construct a band-limited filter. % WARPEDBLFILTER - Warped, band-limited filter. % FREQFILTER - Construct a full length frequency side filter. % PFILT - Apply filter with periodic boundary conditions. % MAGRESP - Magnitude response plot. % TRANSFERFUNCTION - Compute the transfer function of a filter. % PGRPDELAY - Periodic Group Delay % % 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 colour model % JPEG2RGB - Convert values from the JPEG colour 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 visit % http://github.com/ltfat/ltfat/issues % % % Url: http://ltfat.github.io/doc/sigproc/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/sigproc/rampdown.m0000664000175000017500000000325113026262303016212 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/rampdown.html} %@seealso{rampup, rampsignal, firwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . error(nargchk(1,2,nargin)) if nargin==1 wintype='hann'; end; win=firwin(wintype,2*L,'inf'); outsig=win(1:L); ltfat/inst/sigproc/transferfunction.m0000664000175000017500000000240713026262303017757 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/transferfunction.html} %@seealso{pfilt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . error(nargchk(2,2,nargin)); [g,info] = comp_fourierwindow(g,L,upper(mfilename)); H=comp_transferfunction(g,L); ltfat/inst/sigproc/magresp.m0000664000175000017500000001175513026262303016031 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/magresp.html} %@seealso{demo_gabfir} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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'); if ymax-ymin~=0 axis(axisvec); end ylabel('Magnitude response (dB)'); if isempty(fs) xlabel('Frequency (normalized) '); else xlabel('Frequency (Hz)'); end; legend('off'); ltfat/inst/sigproc/firfilter.m0000664000175000017500000000722013026262303016351 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/firfilter.html} %@seealso{blfilter, firwin, pfilt, filterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/sigproc/uquant.m0000664000175000017500000000615113026262303015702 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/uquant.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 xmax0); xo=round(xi/bucksize)*bucksize; end; ltfat/inst/sigproc/freqwin.m0000664000175000017500000001100413026262303016031 0ustar susnaksusnakfunction H = freqwin(name,L,bw,varargin) %-*- texinfo -*- %@deftypefn {Function} freqwin %@verbatim %FREQWIN Frequency response window % Usage: H = freqwin(name,L,bw); % % FREQWIN(name,L,bw) returns a frequency window name of length L % with the mainlobe -6dB (half height) bandwidth bw. It is intended to % represent frequency response of a band-pass filter/window with % bandwidth bw. The bandwidth is given in normalised frequencies. % % The function is not periodically wrapped should it be nonzero outside % of the L samples (as opposed to e.g. PGAUSS). % % The following windows can be used in place of name*: % % 'gauss' Gaussian window % % 'gammatone' Gammatone window. The default order is 4. Custom order % can be set by {'gammatone',order}. % % 'butterworth' Butterworth window. The default order is 4. Custom % order can be set by {'butterworth',order}. % % FREQWIN(name,L,bw,fs) does the same as above except bw is expected % to be in Hz given sampling frequency fs. % % FREQWIN understands the following key-value pairs and flags at the end of % the list of input parameters: % % 'fs',fs If the sampling frequency fs is specified then the bw* % is expected to be in Hz. % % '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 % % Additionally, the function accepts flags to normalize the output. Please see % the help of NORMALIZE. Default is to use 'peak' normalization. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/sigproc/freqwin.html} %@seealso{firwin, normalize, plotfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Nicki Holighaus complainif_notenoughargs(nargin,3,upper(mfilename)); if ~isscalar(L) error('%s: L must be a scalar',upper(mfilename)); end if ~isscalar(bw) error('%s: bw must be a scalar',upper(mfilename)); end freqwintypes = arg_freqwin(struct); freqwintypes = freqwintypes.flags.wintype; if ~iscell(name), name = {name}; end if ~ischar(name{1}) || ~any(strcmpi(name{1},freqwintypes)) error('%s: First input argument must the name of a supported window.',... upper(mfilename)); end; winArgs = name(2:end); winName = lower(name{1}); definput.import={'normalize'}; definput.importdefaults={'null'}; definput.flags.centering={'wp','hp','shift'}; definput.keyvals.shift = 0; definput.keyvals.fs = 2; definput.keyvals.atheight = 10^(-3/10); [flags,kv,fs]=ltfatarghelper({'fs'},definput,varargin); if flags.do_wp kv.shift=0; end; if flags.do_hp kv.shift=0.5; end; if ( kv.shift >= .5 || kv.shift < -.5 ) error('%s: Parameter shift must be in ]-.5,.5].',upper(mfilename)); end if ( bw > fs || bw < eps ) error('%s: Parameter bw must be in ]0,fs].',upper(mfilename)); end step = fs/L; bwrelheight = kv.atheight; H = (-kv.shift+[0:1:ceil(L/2)-1,-floor(L/2):-1]'); switch winName case 'gauss' H = exp(4*H.^2*log(bwrelheight)/(bw/step)^2); case 'butterworth' definputbutter.keyvals.order=4; [~,~,order]=ltfatarghelper({'order'},definputbutter,winArgs); H = 1./(sqrt(1 + (H/(bw/step/2)).^(2*order))); case 'gammatone' definputgamma.keyvals.order=4; [~,~,order]=ltfatarghelper({'order'},definputgamma,winArgs); gtInverse = @(yn) sqrt(yn^(-2/order)-1); dilation = bw/2/gtInverse(bwrelheight)/step; H = (1+1i*abs(H)/dilation).^(-order); otherwise error('%s: SENTINEL. Unknown window.',upper(mfilename)); end H=normalize(H,flags.norm); ltfat/inst/sigproc/freqfilter.m0000664000175000017500000001106513026262303016530 0ustar susnaksusnakfunction gout=freqfilter(winname,bw,varargin) %-*- texinfo -*- %@deftypefn {Function} freqfilter %@verbatim %FREQFILTER Construct filter in frequency domain % Usage: g=freqfilter(winname,bw); % g=freqfilter(winname,bw,fc); % % Input parameters: % winname : Name of prototype % bw : Effective support length of the prototype % fc : Center frequency % % FREQFILTER(winname,bw) creates a full-length frequency response % filter. The parameter winname specifies the shape of the frequency % response. For accepted shape please see FREQWIN. bw defines a % -6dB bandwidth of the filter in normalized frequencies. % % FREQFILTER(winname,bw,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. % % FREQFILTER accepts the following optional parameters: % % 'fs',fs If the sampling frequency fs is specified then the % bandwidth bw and the centre frequency fc are % specified 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. % % 'scal',s Scale the filter by the constant s. This can be % useful to equalize channels in a filter bank. % % 'pedantic' Force window frequency offset (g.foff) to a subsample % precision by a subsample shift of the window. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/sigproc/freqfilter.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Authors: Nicki Holighaus & Zdenek Prusa % Date: September 15, 2016 if ~iscell(winname), winname = {winname}; end % 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=2; %definput.keyvals.order=4; definput.keyvals.scal=1; definput.keyvals.min_win=1; %definput.keyvals.trunc_at=10^(-5); definput.keyvals.bwtruncmul = 4; definput.flags.pedantic = {'pedantic','nopedantic'}; definput.flags.real={'complex','real'}; [flags,kv]=ltfatarghelper({'fc'},definput,varargin); [bw,kv.fc,kv.delay,kv.scal]=scalardistribute(bw,kv.fc,kv.delay,kv.scal); % Sanitize kv.fc=modcent(2*kv.fc/kv.fs,2); Lw = @(L,bw) min(ceil(bw*kv.bwtruncmul*L/kv.fs),L); fsRestricted = @(L,bw) kv.fs/L*Lw(L,bw); if flags.pedantic fc_offset = @(L,fc) L/2*fc-round(L/2*fc); else fc_offset = @(L,fc) 0; end Nfilt = numel(bw); gout = cell(Nfilt,1); for ii=1:Nfilt g=struct(); if flags.do_1 || flags.do_area g.H=@(L) fftshift(freqwin(winname,Lw(L,bw(ii)),bw(ii),fsRestricted(L,bw(ii)),'shift',fc_offset(L,kv.fc(ii))))*kv.scal(ii)*L; end; if flags.do_2 || flags.do_energy g.H=@(L) fftshift(freqwin(winname,Lw(L,bw(ii)),bw(ii),fsRestricted(L,bw(ii)),'shift',fc_offset(L,kv.fc(ii))))*kv.scal(ii)*sqrt(L); end; if flags.do_inf || flags.do_peak g.H=@(L) fftshift(freqwin(winname,Lw(L,bw(ii)),bw(ii),fsRestricted(L,bw(ii)),'shift',fc_offset(L,kv.fc(ii))))*kv.scal(ii); end; g.foff=@(L) round(L/2*kv.fc(ii)) - floor(Lw(L,bw(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; ltfat/inst/sigproc/rms.m0000664000175000017500000000540013026262303015162 0ustar susnaksusnakfunction 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.github.io/doc/sigproc/rms.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/INSTALL-Matlab0000664000175000017500000001232413026262276015000 0ustar susnaksusnak-------- 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 ------------------------------------------- The GCC compiler is needed to compile the LTFAT on Mac OS X. When the Xcode Command Line Tools are installed the compilation of the LTFAT should work without any problem. Alternatively, Clang could be used to compile the LTFAT. The BLAS, LAPACK and FFTW libraries are taken directly from the Matlab installation and doesn’t have to be installed separately. --------- 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. - Ensure there is not another MinGW/MSYS toolchain in PATH and, expecially, that there is no sh.exe in PATH. - 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. This step is necessary since the FFTW lib shipped with Matlab does not contain some of the routines we need. - 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 taken directly from Matlab installation and you should not need to install anything. Just typing "ltfatmex" should do the trick. ----------------------------------------------------------------------- --------- 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 ------------ It is recommended to compile PortAudio v19 to use with the block processing framework. PortAudio v19 only compiles on OS X version 10.4 or later. Several versions of the Java Development Kit, which is needed to compile the JAVA classes, could be downloaded through the Apple Developer Downloads. --------- 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. To use a custom (or system) portaudio lib, adjust the symbolic link found here >>[matlabroot, filesep, 'bin', filesep, computer('arch')] ltfat/inst/INSTALL0000664000175000017500000000143013026262276013576 0ustar susnaksusnak --------- 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 ltfat/inst/gabor/0000775000175000017500000000000013026262303013630 5ustar susnaksusnakltfat/inst/gabor/gabdual.m0000664000175000017500000001341413026262303015410 0ustar susnaksusnakfunction 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.github.io/doc/gabor/gabdual.html} %@seealso{gabtight, gabwin, fir2long, dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 LM*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; ltfat/inst/gabor/wildual.m0000664000175000017500000000637613026262303015463 0ustar susnaksusnakfunction [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.github.io/doc/gabor/wildual.html} %@seealso{dwilt, wilwin, wmdct, wilorth, isevenfunction} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/gabor/idgt.m0000664000175000017500000001334013026262303014736 0ustar susnaksusnakfunction [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.github.io/doc/gabor/idgt.html} %@seealso{dgt, gabwin, dwilt, gabtight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ~isnumeric(g) && 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]); ltfat/inst/gabor/dwiltlength.m0000664000175000017500000000400413026262303016331 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dwiltlength.html} %@seealso{dwilt, wmdct} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/gabor/plotdgt.m0000664000175000017500000000472413026262303015472 0ustar susnaksusnakfunction 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.github.io/doc/gabor/plotdgt.html} %@seealso{dgt, tfplot, sgram, plotdgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: NA % REFERENCE: NA complainif_notenoughargs(nargin,2,mfilename); complainif_notposint(a,'a',mfilename); 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); if nargout<1 clear coef; end ltfat/inst/gabor/gabreassign.m0000664000175000017500000001006113026262303016271 0ustar susnaksusnakfunction sr=gabreassign(s,tgrad,fgrad,a) %-*- texinfo -*- %@deftypefn {Function} gabreassign %@verbatim %GABREASSIGN Reassign time-frequency distribution % Usage: sr = gabreassign(s,tgrad,fgrad,a); % % 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.github.io/doc/gabor/gabreassign.html} %@seealso{resgram, gabphasegrad} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, 2008. thisname = upper(mfilename); complainif_notenoughargs(nargin,4,thisname); complainif_notposint(a,'a',thisname); % Basic checks if any(cellfun(@(el) isempty(el) || ~isnumeric(el),{s,tgrad,fgrad})) error('%s: s, tgrad, fgrad must be non-empty and numeric.',... upper(mfilename)); end % Check if argument sizes are consistent if ~isequal(size(s),size(tgrad),size(fgrad)) error('%s: s, tgrad, fgrad must all have the same size.',... upper(mfilename)); end % Check if any argument is not real if any(cellfun(@(el) ~isreal(el),{tgrad,fgrad})) error('%s: tgrad, fgrad must be real.',... upper(mfilename)); end % if any(s<0) % error('%s: s must contain positive numbers only.',... % upper(mfilename)); % end 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; ltfat/inst/gabor/gabimagepars.m0000664000175000017500000000620013026262303016426 0ustar susnaksusnakfunction [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 % 600 x800 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 (M/2)+1 xN equal to 601 x700 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.github.io/doc/gabor/gabimagepars.html} %@seealso{dgt, dgtreal, sgram} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/gabor/gabphasegrad.m0000664000175000017500000001307413026262303016423 0ustar susnaksusnakfunction [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 relative 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 absolute time and % frequency positions can be obtained as % % tgradabs = bsxfun(@plus,tgrad,fftindex(M)*L/M); % fgradabs = bsxfun(@plus,fgrad,(0:L/a-1)*a); % % 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 four different methods. % % 'dgt' Directly from the signal using algorithm by Auger and % Flandrin. % % 'cross' Directly from the signal using algorithm by Nelson. % % '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('cross',f,g,a,M) does the same as above % but this time using algorithm by Nelson which is based on computing % several DGTs. % % [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 using the default phase convention ('freqinv') e.g.: % % [tgrad,fgrad]=gabphasegrad('phase',angle(dgt(f,g,a,M)),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 e.g.: % % [tgrad,fgrad]=gabphasegrad('abs',abs(dgt(f,g,a,M)),g,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.github.io/doc/gabor/gabphasegrad.html} %@seealso{resgram, gabreassign, dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, 2008; Zdenek Průša 2015 %error(nargchk(4,6,nargin)); % If no phaseconv flag was passed, add 'relative' definput = arg_gabphasederivconv; if ~any(cellfun(@(el) any(strcmpi(el,varargin)),definput.flags.phaseconv)) varargin{end+1} = 'relative'; end if nargout<3 phased = gabphasederiv({'t','f'},method,varargin{:}); else [phased,c] = gabphasederiv({'t','f'},method,varargin{:}); end [tgrad,fgrad] = deal(phased{:}); ltfat/inst/gabor/col2diag.m0000664000175000017500000000337513026262303015502 0ustar susnaksusnakfunction 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.github.io/doc/gabor/col2diag.html} %@seealso{spreadop, spreadfun, tconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)); ltfat/inst/gabor/gabmixdual.m0000664000175000017500000000573313026262303016133 0ustar susnaksusnakfunction 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.github.io/doc/gabor/gabmixdual.html} %@seealso{gabdual, gabprojdual, demo_gabmixdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/gabwin.m0000664000175000017500000001075013026262303015260 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabwin.html} %@seealso{pgauss, firwin, wilwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/idwilt2.m0000664000175000017500000000560313026262303015370 0ustar susnaksusnakfunction [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.github.io/doc/gabor/idwilt2.html} %@seealso{dwilt2, dgt2, wildual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/dgtreal.m0000664000175000017500000001233313026262303015432 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dgtreal.html} %@seealso{dgt, idgtreal, gabwin, dwilt, gabtight, plotdgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,~,Ls] = gabpars_from_windowsignal(f,g,a,M,kv.L); if ~isreal(g) error('%s: The window must be real-valued.',upper(mfilename)); end; if kv.lt(2)>2 error('%s: Only rectangular or quinqux lattices are supported.',... upper(mfilename)); end; if kv.lt(2)~=1 && flags.do_timeinv error(['%s: Time-invariant phase for quinqux lattice is not ',... 'supported.'],upper(mfilename)); end c=comp_dgtreal(f,g,a,M,kv.lt,flags.do_timeinv); ltfat/inst/gabor/rect2wil.m0000664000175000017500000000327413026262303015547 0ustar susnaksusnakfunction 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.github.io/doc/gabor/rect2wil.html} %@seealso{wil2rect, dwilt, idwilt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/dgt2.m0000664000175000017500000000712413026262303014652 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dgt2.html} %@seealso{dgt, idgt2, gabdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/gabor/wil2rect.m0000664000175000017500000000353313026262303015545 0ustar susnaksusnakfunction 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.github.io/doc/gabor/wil2rect.html} %@seealso{rect2wil, dwilt, wmdct} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/gabor/wmdct2.m0000664000175000017500000000653213026262303015214 0ustar susnaksusnakfunction [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.github.io/doc/gabor/wmdct2.html} %@seealso{wmdct, iwmdct2, dgt2, wildual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/dgt.m0000664000175000017500000001602113026262303014564 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dgt.html} %@seealso{idgt, gabwin, dwilt, gabdual, phaselock, demo_dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 L2) && size(c,1)==1 c = squeeze(c); end ltfat/inst/gabor/gabfirdual.m0000664000175000017500000001321513026262303016110 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabfirdual.html} %@seealso{gaboptdual, gabdual, gabtight, gabfirtight, gaboptdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/plotdgtreal.m0000664000175000017500000000437013026262303016333 0ustar susnaksusnakfunction 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.github.io/doc/gabor/plotdgtreal.html} %@seealso{dgtreal, tfplot, sgram, plotdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: NA % REFERENCE: NA complainif_notenoughargs(nargin,3,mfilename); complainif_notposint(a,'a',mfilename); complainif_notposint(M,'M',mfilename); 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); if nargout<1 clear coef; end ltfat/inst/gabor/izak.m0000664000175000017500000000354213026262303014750 0ustar susnaksusnakfunction 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.github.io/doc/gabor/izak.html} %@seealso{zak} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/isgramreal.m0000664000175000017500000001733013026262303016140 0ustar susnaksusnakfunction [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. % % The BFGS method makes use of the minFunc software. 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.github.io/doc/gabor/isgramreal.html} %@seealso{dgtreal, idgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 L1 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). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/phaseunlock.m0000664000175000017500000000461713026262303016332 0ustar susnaksusnakfunction 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. % % Phase locking the coefficients modifies them so as if they were obtained % from a time-invariant Gabor system. A filter bank produces phase locked % coefficients. % % % 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.github.io/doc/gabor/phaseunlock.html} %@seealso{dgt, phaselock, symphase} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/wilorth.m0000664000175000017500000000770313026262303015505 0ustar susnaksusnakfunction [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.github.io/doc/gabor/wilorth.html} %@seealso{dwilt, wmdct, wildual, isevenfunction} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/gabframediag.m0000664000175000017500000000501013026262303016373 0ustar susnaksusnakfunction 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.github.io/doc/gabor/gabframediag.html} %@seealso{dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/gabor/gabphasederiv.m0000664000175000017500000010076213026262303016620 0ustar susnaksusnakfunction [phased,c]=gabphasederiv(type,method,varargin) %-*- texinfo -*- %@deftypefn {Function} gabphasederiv %@verbatim %GABPHASEDERIV DGT phase derivatives % Usage: [phased,c] = gabphasederiv(dflag,'dgt',f,g,a,M); % phased = gabphasederiv(dflag,'cross',f,g,a,M) % phased = gabphasederiv(dflag,'phase',cphase,a,difforder); % phased = gabphasederiv(dflag,'abs',s,g,a); % [{phased1,phased2,...}] = gabphasederiv({dflag1,dflag2,...},...); % [{phased1,phased2,...},c] = gabphasederiv({dflag1,dflag2,...},'dgt',...); % % phased=GABPHASEDERIV(dflag,method,...) computes the time-frequency % derivative dflag of the phase of the DGT of a signal using algorithm % method. % % The following strings can be used in place of dflag: % % 't' First phase derivative in time. % % 'f' First phase derivative in frequency. % % 'tt' Second phase derivative in time. % % 'ff' Second phase derivative in frequency. % % 'tf' or 'ft' Second order mixed phase derivative. % % phased is scaled such that (possibly non-integer) distances are measured % in samples. Similarly, the frequencies are scaled such that the Nyquist % frequency (the highest possible frequency) corresponds to a value of L/2. % % The computation of phased 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, phased attain very large random values when abs(c) % is close to zero. % % The phase derivative computation can be done using four different methods % depending on the string method: % % 'dgt' Directly from the signal using algorithm by Auger and % Flandrin. % % 'cross' Directly from the signal using algorithm by Nelson. % % 'phase' From the unwrapped phase of a DGT of the signal using a % finite differences scheme. This is the classic method used % in the phase vocoder. % % 'abs' From the absolute value of the DGT exploiting explicit % dependency between partial derivatives of log-magnitudes and % phase. % Currently this method works only for Gaussian windows. % % phased=GABPHASEDERIV(dflag,'dgt',f,g,a,M) computes the time-frequency % derivative 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. % % [phased,c]=GABPHASEDERIV(dflag,'dgt',f,g,a,M) additionally returns % the Gabor coefficients c, as they are always computed as a byproduct % of the algorithm. % % phased=GABPHASEDERIV(dflag,'cross',f,g,a,M) does the same as above % but this time using algorithm by Nelson which is based on computing % several DGTs. % % phased=GABPHASEDERIV(dflag,'phase',cphase,a) computes the phase % derivative 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 using the default phase convention ('freqinv') e.g.: % % phased=gabphasederiv(dflag,'phase',angle(dgt(f,g,a,M)),a) % % phased=GABPHASEDERIV(dflag,'abs',s,g,a) computes the phase derivative % from the absolute values of DGT coefficients s. The spectrogram must have % been computed using the window g and time-shift a e.g.: % % phased=gabphasederiv(dflag,'abs',abs(dgt(f,g,a,M)),g,a) % % Currently the 'abs' method only works if the window g is a Gaussian % window specified as a string or a cell array. % % phased=GABPHASEDERIV(dflag,'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. % % Phase conventions % ----------------- % % First derivatives in either direction are subject to phase convention. % The following additional flags define the phase convention the original % phase would have had: % % 'freqinv' Derivatives reflect the frequency-invariant phase of dgt. % This is the default. % % 'timeinv' Derivatives reflect the time-invariant phase of dgt. % % 'symphase' Derivatives reflect the symmetric phase of dgt. % % 'relative' This is a combination of 'freqinv' and 'timeinv'. % It uses 'timeinv' for derivatives along frequency and % and 'freqinv' for derivatives along time and for the % mixed derivative. % This is usefull for the reassignment functions. % % Please see ltfatnote042 for the description of relations between the % phase derivatives with different phase conventions. Note that for the % 'relative' convention, the following holds: % % gabphasederiv('t',...,'relative') == gabphasederiv('t',...,'freqinv') % gabphasederiv('f',...,'relative') == -gabphasederiv('f',...,'timeinv') % gabphasederiv('tt',...,'relative') == gabphasederiv('tt',...) % gabphasederiv('ff',...,'relative') == -gabphasederiv('ff',...) % gabphasederiv('tf',...,'relative') == gabphasederiv('tf',...,'freqinv') % % Several derivatives at once % --------------------------- % % phasedcell=GABPHASEDERIV({dflag1,dflag2,...},...) computes several % phase derivatives at once while reusing some temporary computations thus % saving computation time. % {dflag1,dflag2,...} is a cell array of the derivative flags and % cell elements of the returned phasedcell contain the corresponding % derivatives i.e.: % % [pderiv1,pderiv2,...] = deal(phasedcell{:}); % % [phasedcell,c]=GABPHASEDERIV({dflag1,dflag2,...},'dgt',...) works the % same as above but in addition returns coefficients c which are the % byproduct of the 'dgt' method. % % Other flags and parameters work as before. % % % 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. % % K. R. Fitz and S. A. Fulop. A unified theory of time-frequency % reassignment. CoRR, abs/0903.3080, 2009. % % D. J. Nelson. Instantaneous higher order phase derivatives. Digital % Signal Processing, 12(2-3):416--428, 2002. [1]http ] % % F. Auger, E. Chassande-Mottin, and P. Flandrin. On phase-magnitude % relationships in the short-time fourier transform. Signal Processing % Letters, IEEE, 19(5):267--270, May 2012. % % Z. Průša. STFT and DGT phase conventions and phase derivatives % interpretation. Technical report, Acoustics Research Institute, % Austrian Academy of Sciences, 2015. % % References % % 1. http://dx.doi.org/10.1006/dspr.2002.0456 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/gabor/gabphasederiv.html} %@seealso{resgram, gabreassign, dgt, pderiv, gabphasegrad} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, 2008; Zdenek Průša, 2015 % REMARK: There is no problem with phase conventions with the second % derivatives. complainif_notenoughargs(nargin,2,upper(mfilename)); definput.flags.type = {'t','f','tt','ff','tf','ft'}; definput.flags.method = {'dgt','phase','abs','cross'}; definput.import = {'gabphasederivconv'}; typewascell = 0; if ischar(type) types = {type}; elseif iscell(type) %error('Multiple derivatives at once were not implemented yet.'); types = type; typewascell = 1; else error('%s: First argument must be either char or a cell array.',... upper(mfilename)); end types = lower(types); for ii=1:numel(types) type = types{ii}; if ~ischar(type) || ~any(strcmpi(type, definput.flags.type)) error(['%s: First argument must contain the type of the derivative: %s'],... upper(mfilename),... strjoin(cellfun(@(el) sprintf('"%s"',el),... definput.flags.type,'UniformOutput',0),', ')); end end if ~ischar(method) || ~any(strcmpi(method, definput.flags.method)) error(['%s: Second argument must be the method name: %s '], ... upper(mfilename),... strjoin(cellfun(@(el) sprintf('"%s"',el),... definput.flags.method,'UniformOutput',0),', ')); end; diphaseconv = arg_gabphasederivconv; foundFlags = cellfun(@(el)ischar(el) && any(strcmpi(el,diphaseconv.flags.phaseconv)),... varargin); flags1 = ltfatarghelper({},definput,{types{1},method,varargin{foundFlags}}); definput = []; % Definput is used again later varargin(foundFlags) = []; % Remove the phaseconv flags switch flags1.method case {'phase','abs'} if nargout>1 error('%s: Too many output arguments. ', upper(mfilename)); end end % Change ft to tf as they are equal if any(strcmpi('ft',types)) types(strcmpi('ft',types)) = {'tf'}; end % Get only unique flags [~,tmpidx] = unique(types,'first'); dflagsUnique = types(sort(tmpidx)); % Find duplicates dflagsDupl = cellfun(@(tEl) strcmpi(tEl,types),dflagsUnique,'UniformOutput',0); % Sort the unique flags according to character count [~,dflagsOrder]=sort(cellfun(@length,dflagsUnique)); % Sort dflagsUnique = dflagsUnique(dflagsOrder); % Allocate the output cell array phased2 = cell(1,numel(dflagsUnique)); switch flags1.method case {'dgt','cross'} complainif_notenoughargs(numel(varargin),4,mfilename); [f,gg,a,M]=deal(varargin{1:4}); definput.keyvals.L=[]; definput.keyvals.minlvl=eps; definput.keyvals.lt=[0 1]; [~,kv,L,minlvl]=ltfatarghelper({'L','minlvl'},definput,varargin(5:end)); % Change f to correct shape. [f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0); % Even though this check is also in dgt, we must do it here too if isempty(L) L = dgtlength(Ls,a,M,kv.lt); else 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 % Extend or crop f to correct length f=postpad(f,L); N = L/a; b = L/M; end switch flags1.method case 'dgt' % --------------------------- DGT method ------------------------ % % Naming conventions used here: % c - dgt coefficients using window g % c_s - second power of c with small values set to minlvl*max(c_s) % c_h - dgt coefficietns computed using time-weighted window hg % c_d - dgt coefficients computed using time-derived window dg % c_h2 - dgt coefficients computed using twice time-weighted window hg2 % c_d2 - dgt coefficients computed using second derivative of window g: hg2 % c_hd - dgt coefficients computed using time-weighted derivative of window g: hdg % c_dh - dgt coefficients computed using derivative of time-weighted window g: dhg % % Call dgt once to check all the parameters % This computes frequency invariant phase. [c,~,g] = dgt(f,gg,a,M,L,'lt',kv.lt); % Compute spectrogram and remove small values because we need to % divide by c_s. % This will also set the derivative to zeros in the regions % containing only small coefficients. c_s = abs(c).^2; c_s = max(c_s,minlvl*max(c_s(:))); % We also need info for info.gauss [~,info]=gabwin(gg,a,M,L,kv.lt,'callfun',upper(mfilename)); % These could be shared dg = []; c_d = []; hg = []; c_h = []; for typedId=1:numel(dflagsUnique) typed = dflagsUnique{typedId}; if info.gauss % TODO: Save computations for 2nd derivatives end switch typed case 't' if info.gauss && ~isempty(c_h) phased = -imag(c_h.*conj(c)./c_s)/info.tfr; else % fir2long is here to avoid possible boundary effects % as the time support of the Inf derivative is not FIR dg = pderiv(fir2long(g,L),[],Inf)/(2*pi); c_d = comp_dgt(f,flipwin(dg),a,M,kv.lt,0,0,0); phased = imag(c_d.*conj(c)./c_s); end switch flags1.phaseconv case {'freqinv','relative'} % Do nothing case 'timeinv' phased = bsxfun(@plus,phased,fftindex(M)*b); case 'symphase' phased = bsxfun(@plus,phased,fftindex(M)*b/2); end case 'f' if info.gauss && ~isempty(c_d) phased = -real(c_d.*conj(c)./c_s)*info.tfr; else % Compute the time weighted version of the window. % g is already a column vector hg = fftindex(size(g,1)).*g; c_h = comp_dgt(f,flipwin(hg),a,M,kv.lt,0,0,0); phased = real(c_h.*conj(c)./c_s); end switch flags1.phaseconv case 'timeinv' % Do nothing case 'relative' phased = -phased; case 'freqinv' phased = bsxfun(@plus,phased,-fftindex(N).'*a); case 'symphase' phased = bsxfun(@plus,phased,-fftindex(N).'*a/2); end case 'tt' if isempty(dg) dg = pderiv(fir2long(g,L),[],Inf)/(2*pi); c_d = comp_dgt(f,flipwin(dg),a,M,kv.lt,0,0,0); end dg2 = pderiv(dg,[],Inf); c_d2 = comp_dgt(f,flipwin(dg2),a,M,kv.lt,0,0,0); phased = imag(c_d2.*conj(c)./c_s - 2*pi*(c_d.*conj(c)./c_s).^2)/L; % Phase convention does not have any effect case 'ff' if isempty(hg) % Time weighted window hg = fftindex(size(g,1)).*g; c_h = comp_dgt(f,flipwin(hg),a,M,kv.lt,0,0,0); end hg2 = fftindex(size(g,1)).^2.*g; c_h2 = comp_dgt(f,flipwin(hg2),a,M,kv.lt,0,0,0); phased = imag(-c_h2.*conj(c)./c_s + (c_h.*conj(c)./c_s).^2)*2*pi/L; switch flags1.phaseconv case 'relative' phased = -phased; end case {'ft','tf'} if isempty(hg) hg = fftindex(size(g,1)).*g; c_h = comp_dgt(f,flipwin(hg),a,M,kv.lt,0,0,0); end if isempty(dg) dg = pderiv(fir2long(g,L),[],Inf)/(2*pi); c_d = comp_dgt(f,flipwin(dg),a,M,kv.lt,0,0,0); end hdg = (fftindex(size(dg,1))/L).*dg; c_hd = comp_dgt(f,flipwin(hdg),a,M,kv.lt,0,0,0); % This is mixed derivative tf for freq. invariant phased = real(c_hd.*conj(c)./c_s - (1/L)*c_h.*c_d.*(conj(c)./c_s).^2)*2*pi; switch flags1.phaseconv case {'freqinv','relative'} % Do nothing case 'timeinv' phased = phased + 1; case 'symphase' phased = phased + 1/2; end otherwise error('%s: This should never happen.',upper(mfilename)); end phased2{typedId} = phased; end case 'phase' % ---------- Direct numerical derivative of the phase ---------------- complainif_notenoughargs(numel(varargin),2,mfilename); [cphase,a]=deal(varargin{1:2}); complainif_notposint(a,'a',mfilename) if ~isreal(cphase) error(['%s: Input phase must be real valued. Use the "angle" ' ... 'function to compute the argument of complex numbers.'],... upper(mfilename)); end; % --- linear method --- [M,N,W]=size(cphase); L=N*a; b=L/M; tgrad = []; fgrad = []; for typedId=1:numel(dflagsUnique) typed = dflagsUnique{typedId}; % REMARK: Second derivative in one direction does not need phase % unwrapping if isempty(tgrad) && any(strcmpi(typed,{'t','tt','ft','tf'})) % This is the classic phase vocoder algorithm by Flanagan modified to % yield a second order centered difference approximation. % Perform derivative along rows while unwrapping the phase by 2*pi tgrad = pderivunwrap(cphase,2,2*pi); % Normalize %tgrad = tgrad/(2*pi); % Normalize again using time step tgrad = tgrad/(a); end if isempty(fgrad) && any(strcmpi(typed,{'f','ff'})) % Phase-lock the angles. % We have the frequency invariant phase ... TimeInd = (0:(N-1))*a; FreqInd = (0:(M-1))/M; phl = FreqInd'*TimeInd; cphaseLock = cphase+2*pi.*phl; % ... and now the time-invariant phase. % Perform derivative along cols while unwrapping the phase by 2*pi fgrad = pderivunwrap(cphaseLock,1,2*pi); % Convert from radians to relative frequencies %fgrad = fgrad/(2*pi); % Normalize again using frequency step fgrad = fgrad/(b); end % tgrad fgrad here are relative quantites switch typed case 't' phased = tgrad*L/(2*pi); switch flags1.phaseconv case {'freqinv','relative'} % Do nothing case 'timeinv' phased = bsxfun(@plus,phased,fftindex(M)*b); case 'symphase' phased = bsxfun(@plus,phased,fftindex(M)*b/2); end case 'f' phased = fgrad*L/(2*pi); switch flags1.phaseconv case 'timeinv' % Do nothing case 'relative' phased = -phased; case 'freqinv' phased = bsxfun(@plus,phased,-fftindex(N).'*a); case 'symphase' phased = bsxfun(@plus,phased,-fftindex(N).'*a/2); end case 'tt' % Second derivatives should be independent of the phase % convention. % tgrad is already unwrapped along time, we can call pderiv % directly. phased = pderiv(tgrad,2,2)/(2*pi); % Phase convention does not have any effect. case 'ff' % fgrad is already unwrapped along frequency phased = pderiv(fgrad,1,2)/(2*pi); switch flags1.phaseconv case 'relative' phased = -phased; end case {'tf','ft'} % Phase has not yet been unwrapped along frequency phased = pderivunwrap(tgrad,1,2*pi)*M/(2*pi); switch flags1.phaseconv case 'timeinv' phased = phased +1; case {'freqinv','relative'} % Do nothing case 'symphase' phased = phased +1/2; end % Phase has not yet been unwrapped along time % phased = pderivunwrap(fgrad,2,2*pi)*N/(2*pi); otherwise error('%s: This should never happen.',upper(mfilename)); end phased2{typedId} = phased; end case 'abs' % --------------------------- abs method ------------------------ complainif_notenoughargs(numel(varargin),3,mfilename); [s,g,a]=deal(varargin{1:3}); complainif_notposint(a,'a',mfilename) if numel(varargin)>3 difforder=varargin{4}; else difforder=4; end; if ~(all(s(:)>=0)) error('%s: s must be positive or zero.',mfilename); end; [M,N,W]=size(s); L=N*a; [~,info]=gabwin(g,a,M,L,'callfun',upper(mfilename)); if ~info.gauss error(['%s: The window must be a Gaussian window (specified as a string or ' ... 'as a cell array).'],upper(mfilename)); 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; % This is equal to about 95dB of 'normal' dynamic range logs(logs0 l = fftindex(gl)/gl; fshiftop = @(g) g.*exp(1i*2*pi*fshift*l); end if abs(tshift) >0 tshiftop = @(g) circshift(g,tshift); end if timeshiftfirst g = fshiftop(tshiftop(g)); else g = tshiftop(fshiftop(g)); end ltfat/inst/gabor/gabframebounds.m0000664000175000017500000001005213026262303016763 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabframebounds.html} %@seealso{gabrieszbounds, gabwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %% ---------- 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 LM*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; ltfat/inst/gabor/phaselockreal.m0000664000175000017500000000512313026262303016624 0ustar susnaksusnakfunction c = phaselockreal(c,a,M,varargin) %-*- texinfo -*- %@deftypefn {Function} phaselockreal %@verbatim %PHASELOCKREAL Phaselock Gabor coefficients % Usage: c=phaselockreal(c,a,M); % % PHASELOCKREAL(c,a,M) phaselocks the Gabor coefficients c. % The coefficients must have been obtained from a DGTREAL 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. % % Please see help of PHASELOCK for more details. % % % 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.github.io/doc/gabor/phaselockreal.html} %@seealso{dgtreal, phaseunlockreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Christoph Wiesmeyr, Peter L. Soendergaard, Zdenek Prusa % TESTING: test_phaselock % REFERENCE: OK if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; if ~isscalar(a) || ~isnumeric(a) || rem(a,1)~=0 error('a must be integer'); end; if ~isscalar(M) || ~isnumeric(M) || rem(M,1)~=0 error('M must be integer'); end; definput.flags.accuracy={'normal', 'precise'}; flags=ltfatarghelper({},definput,varargin); M2=size(c,1); M2user = floor(M/2) + 1; if M2~=M2user error('%s: Size of s does not comply with M.',upper(mfilename)); end N=size(c,2); if flags.do_normal TimeInd = (0:(N-1))*a; FreqInd = (0:(M2-1)); phase = FreqInd'*TimeInd; phase = mod(phase,M); phase = exp(2*1i*pi*phase/M); % Handle multisignals c=bsxfun(@times,c,phase); elseif flags.do_precise frames = ifftreal(c,M); for n=0:N-1 frames(:,n+1,:) = circshift(frames(:,n+1,:),-n*a); end c = fftreal(frames); end ltfat/inst/gabor/gabfirtight.m0000664000175000017500000001310213026262303016275 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabfirtight.html} %@seealso{gaboptdual, gabdual, gabtight, gabfirdual, gabconvexopt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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'); ltfat/inst/gabor/latticetype2matrix.m0000664000175000017500000000325413026262303017650 0ustar susnaksusnakfunction 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.github.io/doc/gabor/latticetype2matrix.html} %@seealso{matrix2latticetype} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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]; ltfat/inst/gabor/constructphase.m0000664000175000017500000001567413026262303017070 0ustar susnaksusnakfunction [c,newphase,usedmask,tgrad,fgrad]=constructphase(s,g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} constructphase %@verbatim %CONSTRUCTPHASE Construct phase for DGT % Usage: c=constructphase(s,g,a); % c=constructphase(s,g,a,tol); % c=constructphase(c,g,a,tol,mask); % c=constructphase(c,g,a,tol,mask,usephase); % [c,newphase,usedmask,tgrad,fgrad] = constructphase(...); % % Input parameters: % s : Initial coefficients. % g : Analysis Gabor window. % a : Hop factor. % tol : Relative tolerance. % mask : Mask for selecting known phase. % usephase : Explicit known phase. % Output parameters: % c : Coefficients with the constructed phase. % newphase : Just the (unwrapped) phase. % usedmask : Mask for selecting coefficients with the new phase. % tgrad : Relative time phase derivative. % fgrad : Relative frequency phase derivative. % % 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 random values. % By default, tol has the value 1e-10. % % CONSTRUCTPHASE(c,g,a,M,tol,mask) accepts real or complex valued % c and real valued mask of the same size. Values in mask which can % be converted to logical true (anything other than 0) determine % coefficients with known phase which is used in the output. Only the % phase of remaining coefficients (for which mask==0) is computed. % % CONSTRUCTPHASEreal(c,g,a,M,tol,mask,usephase) does the same as before % but uses the known phase values from usephase rather than from c. % % In addition, tol can be a vector containing decreasing values. In % that case, the algorithm is run numel(tol) times, initialized with % the result from the previous step in the 2nd and the further steps. % % Further, the function accepts the following flags: % % 'freqinv' The constructed phase complies with the frequency % invariant phase convention such that it can be directly % used in IDGTREAL. % This is the default. % % 'timeinv' The constructed phase complies with the time-invariant % phase convention. The same flag must be used in the other % functions e.g. IDGTREAL % % This function requires a computational subroutine that is only % available in C. Use LTFATMEX to compile it. % % % References: % Z. Průša, P. Balazs, and P. L. Soendergaard. A Non-iterative Method for % STFT Phase (Re)Construction. IEEE/ACM Transactions on Audio, Speech, % and Language Processing, 2016. In preparation. Preprint will be % available at http://ltfat.github.io/notes/ltfatnote040.pdf. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/gabor/constructphase.html} %@seealso{dgt, gabphasegrad, ltfatmex} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, Zdenek Prusa thismfilename = upper(mfilename); complainif_notposint(a,'a',thismfilename); definput.keyvals.tol=[1e-1 1e-10]; definput.keyvals.mask=[]; definput.keyvals.usephase=[]; definput.flags.phase={'freqinv','timeinv'}; [flags,~,tol,mask,usephase]=ltfatarghelper({'tol','mask','usephase'},definput,varargin); if ~isnumeric(s) error('%s: *s* must be numeric.',thismfilename); end if ~isempty(usephase) && isempty(mask) error('%s: Both mask and usephase must be used at the same time.',... thismfilename); end if isempty(mask) if ~isreal(s) || any(s(:)<0) error('%s: *s* must be real and positive when no mask is used.',... thismfilename); end else if any(size(mask) ~= size(s)) || ~isreal(mask) error(['%s: s and mask must have the same size and mask must',... ' be real.'],thismfilename) end % Sanitize mask (anything other than 0 is true) mask = cast(mask,'double'); mask(mask~=0) = 1; end if ~isempty(usephase) if any(size(mask) ~= size(s)) || ~isreal(usephase) error(['%s: s and usephase must have the same size and usephase must',... ' be real.'],thismfilename) end else usephase = angle(s); end if ~isnumeric(tol) || ~isequal(tol,sort(tol,'descend')) error(['%s: *tol* must be a scalar or a vector sorted in a ',... 'descending manner.'],thismfilename); end abss = abs(s); % Compute phase gradient, check parameteres [tgrad,fgrad] = gabphasegrad('abs',abss,g,a,2); absthr = max(abss(:))*tol; if isempty(mask) usedmask = zeros(size(s)); else usedmask = mask; end if isempty(mask) % Build the phase (calling a MEX file) newphase=comp_heapint(abss,tgrad,fgrad,a,tol(1),flags.do_timeinv); % Set phase of the coefficients below tol to random values bigenoughidx = abss>absthr(1); usedmask(bigenoughidx) = 1; else newphase=comp_maskedheapint(abss,tgrad,fgrad,mask,a,tol(1),... flags.do_timeinv,usephase); % Set phase of small coefficient to random values % but just in the missing part % Find all small coefficients in the unknown phase area missingidx = find(usedmask==0); bigenoughidx = abss(missingidx)>absthr(1); usedmask(missingidx(bigenoughidx)) = 1; end % Do further tol for ii=2:numel(tol) newphase=comp_maskedheapint(abss,tgrad,fgrad,usedmask,a,tol(ii),... flags.do_timeinv,newphase); missingidx = find(usedmask==0); bigenoughidx = abss(missingidx)>absthr(ii); usedmask(missingidx(bigenoughidx)) = 1; end % Convert the mask so it can be used directly for indexing usedmask = logical(usedmask); % Assign random values to coefficients below tolerance zerono = numel(find(~usedmask)); newphase(~usedmask) = rand(zerono,1)*2*pi; % Combine the magnitude and phase c=abss.*exp(1i*newphase); ltfat/inst/gabor/gabopttight.m0000664000175000017500000001336013026262303016325 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabopttight.html} %@seealso{gabfirdual, gabdual, gabtight, gaboptdual, gabconvexopt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/gabor/tconv.m0000664000175000017500000000567613026262303015155 0ustar susnaksusnakfunction 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.github.io/doc/gabor/tconv.html} %@seealso{spreadop, spreadfun, spreadinv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/iwmdct2.m0000664000175000017500000000553713026262303015371 0ustar susnaksusnakfunction [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.github.io/doc/gabor/iwmdct2.html} %@seealso{wmdct2, dgt2, wildual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/matrix2latticetype.m0000664000175000017500000000761313026262303017653 0ustar susnaksusnakfunction [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.github.io/doc/gabor/matrix2latticetype.html} %@seealso{latticetype2matrix} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 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]; ltfat/inst/gabor/gabconvexopt.m0000664000175000017500000005113513026262303016512 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabconvexopt.html} %@seealso{gaboptdual, gabdual, gabtight, gabfirtight, gabopttight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)/tola1 will give better % frequency resolution at the expense of a worse time % resolution. A value of 0. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/dwilt2.m0000664000175000017500000000741513026262303015222 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dwilt2.html} %@seealso{dwilt, idwilt2, dgt2, wildual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/gabprojdual.m0000664000175000017500000000711413026262303016303 0ustar susnaksusnakfunction 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.github.io/doc/gabor/gabprojdual.html} %@seealso{gabdual, gabtight, gabdualnorm, fir2long} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/iwmdct.m0000664000175000017500000000652513026262303015305 0ustar susnaksusnakfunction [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.github.io/doc/gabor/iwmdct.html} %@seealso{wmdct, wilwin, dgt, wildual, wilorth} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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]); ltfat/inst/gabor/gabreassignadjust.m0000664000175000017500000001421513026262303017511 0ustar susnaksusnakfunction sr=gabreassignadjust(s,pderivs,a,varargin) %-*- texinfo -*- %@deftypefn {Function} gabreassignadjust %@verbatim %GABREASSIGNADJUST Adjustable reassignment of a time-frequency distribution % Usage: sr = gabreassignadjust(s,pderivs,a,mu); % % GABREASSIGNADJUST(s,pderivs,a,mu) reassigns the values of the positive % time-frequency distribution s using first and second order phase % derivatives given by pderivs and parameter mu*>0. % The lattice is determined by the time shift a and the number of % channels deduced from the size of s. % % pderivs is a cell array of phase derivatives which can be obtained % as follows: % % pderivs = gabphasederiv({'t','f','tt','ff','tf'},...,'relative'); % % Please see help of GABPHASEDERIV for description of the missing % parameters. % % gabreassign(s,pderivs,a,mu,despeckle) works as above, but some % coeficients are removed prior to the reassignment process. More % precisely a mixed phase derivative pderivs{5} is used to determine % which coefficients m,n belong to sinusoidal components (such that % abs(1+pderivs{5}(m,n)) is close to zero) and to impulsive % components (such that abs(pderivs{5}(m,n)) is close to zero). % Parameter despeckle determines a threshold on the previous quantities % such that coefficients with higher associated values are set to zeros. % % Algorithm % --------- % % The routine uses the adjustable reassignment presented in the % references. % % Examples: % --------- % % The following example demonstrates how to manually create a % reassigned spectrogram.: % % % Compute the phase derivatives % a=4; M=100; % [pderivs, c] = gabphasederiv({'t','f','tt','ff','tf'},'dgt',bat,'gauss',a,M,'relative'); % % % Reassignemt parameter % mu = 0.1; % % Perform the actual reassignment % sr = gabreassignadjust(abs(c).^2,pderivs,a,mu); % % % Display it using plotdgt % plotdgt(sr,a,143000,50); % % % References: % F. Auger, E. Chassande-Mottin, and P. Flandrin. On phase-magnitude % relationships in the short-time fourier transform. Signal Processing % Letters, IEEE, 19(5):267--270, May 2012. % % F. Auger, E. Chassande-Mottin, and P. Flandrin. Making reassignment % adjustable: The Levenberg-Marquardt approach. In Acoustics, Speech and % Signal Processing (ICASSP), 2012 IEEE International Conference on, % pages 3889--3892, March 2012. % % Z. Průša. STFT and DGT phase conventions and phase derivatives % interpretation. Technical report, Acoustics Research Institute, % Austrian Academy of Sciences, 2015. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/gabor/gabreassignadjust.html} %@seealso{gabphasederiv, gabreassign} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, 2008; Zdeněk Průša 2015 thisname = upper(mfilename); complainif_notenoughargs(nargin,3,thisname); complainif_notposint(a,'a',thisname); definput.keyvals.mu=0; definput.keyvals.despeckle=0; [~,~,mu,despeckle] = ltfatarghelper({'mu','despeckle'},definput,varargin); if ~(isscalar(mu) && mu>=0) error('%s: mu must be a real positive number.',thisname); end if ~(isscalar(despeckle) && despeckle>=0) error('%s: despeckle must be a real positive number.',thisname); end [M,N,W] = size(s); if W>1 error(['%s: c must be 2D matrix.'],thisname); end if ~(iscell(pderivs) && numel(pderivs) == 5) error(['%s: pderiv must be a cell array of phase derivatives in ',... 'the following order t,f,tt,ff,tf.'],thisname); end % Basic checks if any(cellfun(@(el) isempty(el) || ~isnumeric(el),{s,pderivs{:}})) error(['%s: s and elements of the cell array pderivs must be ',... 'non-empty and numeric.'],upper(mfilename)); end % Check if argument sizes are consistent sizes = cellfun(@size,pderivs,'UniformOutput',0); if ~isequal(size(s),sizes{:}) error(['%s: s and all elements of the cell array pderivs must ',... 'have the same size.'], upper(mfilename)); end % Check if any argument is not real if any(cellfun(@(el) ~isreal(el),{s,pderivs{:}})) error('%s: s and all elements of the cell array pderivs must be real.',... upper(mfilename)); end if any(s<0) error('%s: s must contain positive numbers only.',... upper(mfilename)); end [tgrad,fgrad,ttgrad,ffgrad,tfgrad] = deal(pderivs{:}); if despeckle~=0 % Removes coefficients which are neither sinusoidal component or % impulse component based on the mixed derivative. % How reassigned time position changes over time thatdt = -tfgrad; % How reassigned frequency position changes along frequency ohatdo = 1+tfgrad; % Only coefficients with any of the previous lower than despeckle is % kept. s(~(abs(ohatdo). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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.gl1 && isnumeric(gorig{2}) && gorig{2}<=2*M... || ischar(gorig) isfir = 1; else isfir = 0; end ltfat/inst/gabor/resgram.m0000664000175000017500000001730113026262303015450 0ustar susnaksusnakfunction 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=RESGRAM(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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/dgtlength.m0000664000175000017500000000734313026262303015775 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dgtlength.html} %@seealso{dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/gabor/idgt2.m0000664000175000017500000001014213026262303015015 0ustar susnaksusnakfunction [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.github.io/doc/gabor/idgt2.html} %@seealso{dgt2, gabdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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]); ltfat/inst/gabor/longpar.m0000664000175000017500000000556713026262303015465 0ustar susnaksusnakfunction [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.github.io/doc/gabor/longpar.html} %@seealso{dgt, dwilt, pgauss, psech, pherm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard, Jordy van Velthoven (TESTING). % TESTING: TEST_DSFT % REFERENCE: REF_DSFT 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; ltfat/inst/gabor/proj_dual.m0000664000175000017500000000627213026262303015774 0ustar susnaksusnakfunction [ 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.github.io/doc/gabor/proj_dual.html} %@seealso{prox_l2, proj_b1} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % % 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 ltfat/inst/gabor/constructphasereal.m0000664000175000017500000001520513026262303017722 0ustar susnaksusnakfunction [c,newphase,usedmask,tgrad,fgrad]=constructphasereal(s,g,a,M,varargin) %-*- texinfo -*- %@deftypefn {Function} constructphasereal %@verbatim %CONSTRUCTPHASEREAL Construct phase for DGTREAL % Usage: c=constructphasereal(s,g,a,M); % c=constructphasereal(s,g,a,M,tol); % c=constructphasereal(c,g,a,M,tol,mask); % c=constructphasereal(c,g,a,M,tol,mask,usephase); % [c,newphase,usedmask,tgrad,fgrad] = constructphasereal(...); % % Input parameters: % s : Initial coefficients. % g : Analysis Gabor window. % a : Hop factor. % M : Number of channels. % tol : Relative tolerance. % mask : Mask for selecting known phase. % usephase : Explicit known phase. % Output parameters: % c : Coefficients with the constructed phase. % newphase : Just the (unwrapped) phase. % usedmask : Mask for selecting coefficients with the new phase. % tgrad : Relative time phase derivative. % fgrad : Relative frequency phase derivative. % % CONSTRUCTPHASEREAL(s,g,a,M) will construct a suitable phase for the % positive valued coefficients s. % % If s contains the absolute values of the Gabor coefficients of a signal % obtained using the window g, time-shift a and number of channels % M, i.e.: % % c=dgtreal(f,g,a,M); % s=abs(c); % % then constuctphasereal(s,g,a,M) 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',...}. % % CONSTRUCTPHASEREAL(s,g,a,M,tol) does as above, but sets the phase of % coefficients less than tol to random values. % By default, tol has the value 1e-10. % % CONSTRUCTPHASEREAL(c,g,a,M,tol,mask) accepts real or complex valued % c and real valued mask of the same size. Values in mask which can % be converted to logical true (anything other than 0) determine % coefficients with known phase which is used in the output. Only the % phase of remaining coefficients (for which mask==0) is computed. % % CONSTRUCTPHASEREAL(c,g,a,M,tol,mask,usephase) does the same as before % but uses the known phase values from usephase rather than from c. % % In addition, tol can be a vector containing decreasing values. In % that case, the algorithm is run numel(tol) times, initialized with % the result from the previous step in the 2nd and the further steps. % % Further, the function accepts the following flags: % % 'freqinv' The constructed phase complies with the frequency % invariant phase convention such that it can be directly % used in IDGTREAL. % This is the default. % % 'timeinv' The constructed phase complies with the time-invariant % phase convention. The same flag must be used in the other % functions e.g. IDGTREAL % % This function requires a computational subroutine that is only % available in C. Use LTFATMEX to compile it. % % % References: % Z. Průša, P. Balazs, and P. L. Soendergaard. A Non-iterative Method for % STFT Phase (Re)Construction. IEEE/ACM Transactions on Audio, Speech, % and Language Processing, 2016. In preparation. Preprint will be % available at http://ltfat.github.io/notes/ltfatnote040.pdf. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/gabor/constructphasereal.html} %@seealso{dgtreal, gabphasegrad, ltfatmex} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, Zdenek Prusa thismfilename = upper(mfilename); complainif_notposint(a,'a',thismfilename); complainif_notposint(M,'M',thismfilename); definput.keyvals.tol=[1e-1,1e-10]; definput.keyvals.mask=[]; definput.keyvals.usephase=[]; definput.flags.phase={'freqinv','timeinv'}; [flags,~,tol,mask,usephase]=ltfatarghelper({'tol','mask','usephase'},definput,varargin); if ~isnumeric(s) error('%s: *s* must be numeric.',thismfilename); end if ~isempty(usephase) && isempty(mask) error('%s: Both mask and usephase must be used at the same time.',... upper(mfilename)); end if isempty(mask) if ~isreal(s) || any(s(:)<0) error('%s: *s* must be real and positive when no mask is used.',... thismfilename); end else if any(size(mask) ~= size(s)) || ~isreal(mask) error(['%s: s and mask must have the same size and mask must',... ' be real.'],thismfilename) end % Sanitize mask (anything other than 0 is true) mask = cast(mask,'double'); mask(mask~=0) = 1; end if ~isempty(usephase) if any(size(mask) ~= size(s)) || ~isreal(usephase) error(['%s: s and usephase must have the same size and usephase must',... ' be real.'],thismfilename) end else usephase = angle(s); end if ~isnumeric(tol) || ~isequal(tol,sort(tol,'descend')) error(['%s: *tol* must be a scalar or a vector sorted in a ',... 'descending manner.'],thismfilename); end [M2,N,W] = size(s); M2true = floor(M/2) + 1; if M2true ~= M2 error('%s: Mismatch between *M* and the size of *s*.',thismfilename); end L=N*a; [~,info]=gabwin(g,a,M,L,'callfun',upper(mfilename)); if ~info.gauss error(['%s: The window must be a Gaussian window (specified ',... 'as a string or as a cell array)'],upper(mfilename)); end % Here we try to avoid calling gabphasegrad as it only works with full % dgts. abss = abs(s); logs=log(abss+realmin); tt=-11; logs(logs. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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]); ltfat/inst/gabor/wilframediag.m0000664000175000017500000000326313026262303016445 0ustar susnaksusnakfunction 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.github.io/doc/gabor/wilframediag.html} %@seealso{dwilt, wmdct, gabframediag} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; d=gabframediag(g,M,2*M,L)/2; ltfat/inst/gabor/phaseplot.m0000664000175000017500000001306013026262303016005 0ustar susnaksusnakfunction varargout=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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)0 varargout={coef}; end; ltfat/inst/gabor/gaboptdual.m0000664000175000017500000001247113026262303016135 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gaboptdual.html} %@seealso{gabfirdual, gabdual, gabtight, gabopttight, gaboptdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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{:}); ltfat/inst/gabor/dwilt.m0000664000175000017500000001372113026262303015135 0ustar susnaksusnakfunction [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.github.io/doc/gabor/dwilt.html} %@seealso{idwilt, wilwin, wil2rect, dgt, wmdct, wilorth} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 L1 will give better % frequency resolution at the expense of a worse time % resolution. A value of 0. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; definput.keyvals.fs=[]; [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)0 varargout={coef}; end; ltfat/inst/gabor/plotwmdct.m0000664000175000017500000000405513026262303016027 0ustar susnaksusnakfunction C=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. % % C=PLOTWMDCT(...) 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. % % 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.github.io/doc/gabor/plotwmdct.html} %@seealso{wmdct, tfplot, sgram, plotdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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]; C = tfplot(coef,M,yr,'argimport',flags,kv); if nargout<1 clear C; end ltfat/inst/gabor/plotdwilt.m0000664000175000017500000000525113026262303016033 0ustar susnaksusnakfunction C=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. % % C=PLOTDWILT(...) 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. % % 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.github.io/doc/gabor/plotdwilt.html} %@seealso{dwilt, tfplot, sgram, wil2rect} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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]; C=tfplot(coef,M,yr,'argimport',flags,kv); if nargout<1 clear C; end ltfat/inst/gabor/Contents.m0000664000175000017500000001176713026262303015617 0ustar susnaksusnak% LTFAT - Gabor analysis % % Peter L. Soendergaard, 2007 - 2016. % % 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 for real-valued signals % 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 % PROJKERN - Projection of Gabor coefficients onto kernel space % 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 % GABPHASEDERIV - Phase derivatives % GABREASSIGN - Reassign positive distribution % GABREASSIGNADJUST - Adjustable t-f reassignment % % Phase reconstruction % CONSTRUCTPHASE - Phase construction from abs. values of DGT % CONSTRUCTPHASEREAL - CONSTRUCTPHASE for DGTREAL % % Phase conversions % PHASELOCK - Phase Lock Gabor coefficients to time. inv. % PHASEUNLOCK - Undo phase locking % PHASELOCKREAL - Same as PHASELOCK for DGTREAL % PHASEUNLOCKREAL - Same as PHASEUNLOCK for IDGTREAL % 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 visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/gabor/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/gabor/idgtreal.m0000664000175000017500000001330013026262303015576 0ustar susnaksusnakfunction [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.github.io/doc/gabor/idgtreal.html} %@seealso{idgt, gabwin, gabdual, dwilt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ~isnumeric(g) && 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; if kv.lt(2)~=1 && flags.do_timeinv error(['%s: Time-invariant phase for quinqux lattice is not ',... 'supported.'],upper(mfilename)); end %% ----- step 3 : Determine the window [g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename)); if L. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/gabrieszbounds.m0000664000175000017500000000503613026262303017033 0ustar susnaksusnakfunction [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.github.io/doc/gabor/gabrieszbounds.html} %@seealso{gabframebounds, gabwin, gabdualnorm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/gabor/projkern.m0000664000175000017500000000475613026262303015654 0ustar susnaksusnakfunction 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.github.io/doc/gabor/projkern.html} %@seealso{dgt, idgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/gabor/gabdualnorm.m0000664000175000017500000001130113026262303016275 0ustar susnaksusnakfunction [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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %% ---------- 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; ltfat/inst/gabor/phaselock.m0000664000175000017500000000567313026262303015772 0ustar susnaksusnakfunction 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.github.io/doc/gabor/phaselock.html} %@seealso{dgt, phaseunlock, symphase} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/tfplot.m0000664000175000017500000001453613026262303015327 0ustar susnaksusnakfunction 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.github.io/doc/gabor/tfplot.html} %@seealso{sgram, plotdgt, plotdgtreal, plotwmdct, plotdwilt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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(coefkv.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; if nargout<1 clear coef; end ltfat/inst/gabor/isgram.m0000664000175000017500000002054313026262303015274 0ustar susnaksusnakfunction [f,relres,iter]=isgram(s,g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} isgram %@verbatim %ISGRAM Spectrogram inversion % Usage: f=isgram(c,g,a); % f=isgram(c,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; % % The BFGS method makes use of the minFunc software. 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.github.io/doc/gabor/isgram.html} %@seealso{isgramreal, frsynabs, dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/gabor/wilbounds.m0000664000175000017500000000527313026262303016023 0ustar susnaksusnakfunction [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.github.io/doc/gabor/wilbounds.html} %@seealso{wilwin, gabframebounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/gabor/gaborinit.m0000664000175000017500000000163513026262303015771 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} gaborinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/gabor/gaborinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/gabor/gabtight.m0000664000175000017500000001460313026262303015603 0ustar susnaksusnakfunction 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.github.io/doc/gabor/gabtight.html} %@seealso{gabdual, gabwin, fir2long, dgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 LM*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; ltfat/inst/gabor/phaseunlockreal.m0000664000175000017500000000511313026262303017166 0ustar susnaksusnakfunction c = phaseunlockreal(c,a,M,varargin) %-*- texinfo -*- %@deftypefn {Function} phaseunlockreal %@verbatim %PHASEUNLOCKREAL Undo phase lock of Gabor coefficients % Usage: c=phaseunlockreal(c,a,M); % % PHASEUNLOCKREAL(c,a,M) removes phase locking from the Gabor coefficients c. % The coefficient must have been obtained from a DGTREAL with parameter a* % and using the 'timeinv' flag. % % Phase locking the coefficients modifies them so as if they were obtained % from a frequency-invariant Gabor system. A filter bank produces phase locked % coefficients. % % % 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.github.io/doc/gabor/phaseunlockreal.html} %@seealso{dgt, phaselockreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter Balazs, Peter L. Soendergaard, Zdenek Prusa % TESTING: OK % REFERENCE: OK if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; if ~isscalar(a) || ~isnumeric(a) || rem(a,1)~=0 error('a must be integer'); end; if ~isscalar(M) || ~isnumeric(M) || rem(M,1)~=0 error('M must be integer'); end; definput.flags.accuracy={'normal', 'precise'}; flags=ltfatarghelper({},definput,varargin); M2=size(c,1); M2user = floor(M/2) + 1; if M2~=M2user error('%s: Size of s does not comply with M.',upper(mfilename)); end N=size(c,2); if flags.do_normal TimeInd = (0:(N-1))*a; FreqInd = (0:(M2-1)); phase = FreqInd'*TimeInd; phase = mod(phase,M); phase = exp(-2*1i*pi*phase/M); % Handle multisignals c=bsxfun(@times,c,phase); elseif flags.do_precise frames = ifftreal(c,M); for n=0:N-1 frames(:,n+1,:) = circshift(frames(:,n+1,:),n*a); end c = fftreal(frames); end ltfat/inst/README0000664000175000017500000000260413026262276013431 0ustar susnaksusnakTo use the toolbox, 'cd' to the LTFAT directory and execute 'ltfatstart'. In Octave you can put this command in your ~/.octaverc file. Directory struture. The toolbox is organized in subdirectories including the following: fourier - Fourier analysis, DCT/DST transforms and filtering. gabor - Gabor, Wilson and WMDCT analysis/synthesis functions. wavelets - Wavelet analysis/synthesis, wavelet filter banks filterbank - General and auditory inspired filterbanks. nonstatgab - Non-stationary Gabor frames. quadratic - Quadratic distributions frames - Frame objects and linear operators associated with frames. sigproc - A collection of simple, signal processing tools. blockproc - Methods for block processing and block-adapted transforms. auditory - Auditory scales and common filters types. demos - Demos showing applications or aspects of LTFAT functions. 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.ltfat/inst/blockproc/0000775000175000017500000000000013026262303014514 5ustar susnaksusnakltfat/inst/blockproc/block.m0000664000175000017500000005475313026262303016002 0ustar susnaksusnakfunction [fs,classid] = block(source,varargin) %-*- texinfo -*- %@deftypefn {Function} block %@verbatim %BLOCK Initialize block stream % Usage: block(source); % % Input parameters: % source : Block stream input. % 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. % % data % input data as columns of a matrix for each input channel % % 'rec' % input is taken from a microphone/auxilary input; % % {'rec','file.wav'} or {'rec','dialog'} or {'rec',data} % does the same as 'rec' but plays a chosen audio data simultaneously. % % 'playrec' % loopbacks the input to the output. In this case, the block size % (in BLOCKREAD) cannot change during the playback. % % BLOCK accepts the following optional key-value pairs % % 'fs',fs % Required sampling rate - Some devices might support only a % limited range of samp. frequencies. Use BLOCKDEVICES to list % supported sampling rates of individual devices. % When the target device does not support the chosen sampling rate, % on-the-fly resampling will be performed in the background. % This option overrides sampling rate read from a wav file. % % The default value is 44100 Hz, min. 4000 Hz, max. 96000 Hz % % 'L',L % Block length - Specifying L fixes the buffer length, which cannot be % changed in the loop. % % The default is 1024. In the online mode the minimum is 32. % % '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 ones should be used. E.g. for two channel device, [1,2] % can be used to specify channels. % % 'recch',recch % If device supports more input channels, 'recch' can be used to % specify which ones should be used. % % 'outfile','file.wav' % Creates a wav file header for on-the-fly storing of block data using % BLOCKWRITE. Existing file will be overwritten. Only 16bit fixed % point precision is supported in the files. % % '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 has a public method updateBar(double). % % Optional flag groups (first is default) % % 'noloop', 'loop' % Plays the input in a loop. % % 'single', 'double' % Data type to be used. In the offline mode (see below) the flag is % ignored and everything is cast do double. % % 'online', 'offline' % Use offline flag for offline blockwise processing of data input or a % wav file without initializing and using the playrec MEX. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/block.html} %@seealso{blockread, blockplay, blockana, blocksyn, demo_blockproc_basicloop, demo_blockproc_slidingsgram} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Zdenek Prusa % The function uses the Playrec tool by Robert Humphrey % http://www.playrec.co.uk/ which in turn relies on % Portaudio lib http://www.portaudio.com/ complainif_notenoughargs(nargin,1,'BLOCK'); 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); failIfNotPositiveInteger(kv.L,'L'); failIfNotPositiveInteger(kv.fs,'fs'); failIfNotPositiveInteger(kv.nbuf,'nbuf'); % Reset all persistent data block_interface('reset'); if ~flags.do_offline % 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 end end % Store option for displaying the loop playback block_interface('setIsLoop',flags.do_loop); else % Check whether any of incompatible params are set failIfInvalidOfflinePar(kv,'devid'); failIfInvalidOfflinePar(kv,'playch'); failIfInvalidOfflinePar(kv,'recch'); failIfInvalidOfflinePar(kv,'nbuf'); failIfInvalidOfflinePar(kv,'loadind',definput.keyvals.loadind); failIfInvalidOfflinePar(flags,'loop',definput.flags.loop{1}); kv.loadind = 'nobar'; % Different behavior for the fmt flag flags.fmt = 'double'; % fs is maybe needed for setting fs for the output wav block_interface('setOffline',1); 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; do_recaudio = 0; oldsource = source; % Handle {'rec',...} format if iscell(source) && strcmpi(source{1},'rec') recChannels = 1; record = 1; source = source{2}; if isempty(kv.nbuf) kv.nbuf = 3; end do_recaudio = 1; end if ischar(source) 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); if isempty(kv.fs) [~, kv.fs] = wavload(source, 'i'); end play = 1; 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 if isempty(kv.fs) [~, kv.fs] = wavload(source, 'i'); end play = 1; else error('%s: "%s" is not valid wav filename.',upper(mfilename),source); end else error('%s: Unrecognized source "%s".',upper(mfilename),source); end elseif(isnumeric(source)) if isempty(kv.fs) && flags.do_online kv.fs = 44100; warning('%s: Sampling rate not specified. Using default value %i Hz.',... upper(mfilename),kv.fs); end play = 1; else error('%s: Unrecognized source.',upper(mfilename)); end if play && ~record playChannels = 2; if isempty(kv.nbuf) kv.nbuf = 3; end end if isempty(kv.fs) kv.fs = 44100; end is_wav = ischar(source) && numel(source)>4 && strcmpi(source(end-3:end),'.wav'); is_numeric = isnumeric(source); if flags.do_offline if ~is_wav && ~is_numeric error(['%s: In the offline mode, only wav file or a data vector can ',... ' be used as a source.'],upper(mfilename)); end if isempty(kv.fs) && ~isempty(kv.outfile) error('%s: Missing fs for the output file.',upper(mfilename)); end end % Store option for displaying the load bar block_interface('setDispLoad',kv.loadind); % Store data type. block_interface('setClassId',flags.fmt); % Store length of the buffer circular queue block_interface('setBufCount',kv.nbuf); % if ~isempty(kv.outfile) && ~strcmpi(kv.outfile(end-3:end),'.wav') error('%s: %s does not contain *.wav suffix.',upper(mfilename),kv.outfile); end % Return parameters classid = flags.fmt; fs = kv.fs; % Set block length if isempty(kv.L) block_interface('setBufLen',-1); else if kv.L<32 && flags.do_online error('%s: Minimum buffer length is 32.',upper(mfilename)) end block_interface('setBufLen',kv.L); end % Store data block_interface('setSource',source); block_interface('setFs',fs); % Handle sources with known input length if is_wav [~,~,~,fid] = wavload(source,'i'); Ls = fid(4); chanNo = fid(5); block_interface('setLs',[Ls,chanNo]); block_interface('setSource',@(pos,endSample)... cast(wavload(source,'',endSample-pos+1,pos-1),... block_interface('getClassId')) ); % block_interface('setSource',@(pos,endSample)... % cast(wavread(source,[pos,endSample]),... % block_interface('getClassId')) ); elseif is_numeric source = comp_sigreshape_pre(source,'BLOCK'); if size(source,2)>8 error('%s: More than 8 channels not allowed.',upper(mfilename)); end block_interface('setLs',size(source)); block_interface('setSource',@(pos,endSample)... cast(source(pos:endSample,:),... block_interface('getClassId'))); end % Modify the source just added to block_interface if do_recaudio block_interface('setSource',{'rec',block_interface('getSource')}); % By default, we only want a single speaker to be active playChannels = 1; end % Not a single playrec call has been done until now if ~flags.do_offline if flags.do_online && kv.fs<4000 || kv.fs>96000 error('%s: Sampling rate must be in range 4-96 kHz ',upper(mfilename)); end % From now on, playrec is called 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 clear playrec; 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 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 the priority device if present if prioriryPlayID~=-1 && priorityRecID~=-1 kv.devid = [prioriryPlayID, priorityRecID]; else kv.devid = [playDevIds(1), recDevIds(1)]; end end try 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 catch failedInit(devs,kv); end if ~do_recaudio if numel(kv.recch) >1 && numel(kv.recch) ~= numel(kv.playch) error('%s: Using more than one input channel.',upper(mfilename)); end 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 try 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 catch failedInit(devs,kv); end block_interface('setPlayChanList',kv.playch); if(playrec('getPlayMaxChannel')1) error('%s: devid should be scalar.',upper(mfilename)); end 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 try 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 catch failedInit(devs,kv); 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'); if play chanString = sprintf('%d,',kv.playch); dev = devs(find(arrayfun(@(dEl) dEl.deviceID==kv.devid(1),devs))); 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)); 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 % Another slight delay to allow printing all messages prior to the playback % starts. pause(0.1); end % Handle output file if ~isempty(kv.outfile) % Use number of recording channes only if mic is an input. if (record && ~play) || (record && play) blockreadChannels = numel(block_interface('getRecChanList')); else Ls = block_interface('getLs'); blockreadChannels = Ls(2); end headerStruct = writewavheader(blockreadChannels,kv.fs,kv.outfile); block_interface('setOutFile',headerStruct); end %%%%%%%%%%%%% % END BLOCK % %%%%%%%%%%%%% function failedInit(devs,kv) % Common function for playrec initialization error messages errmsg = ''; % playFs = devs([devs.deviceID]==kv.devid(1)).supportedSampleRates; % if ~isempty(playFs) && ~any(playFs==kv.fs) % fsstr = sprintf('%d, ',playFs); % fsstr = ['[',fsstr(1:end-2),']' ]; % errmsg = [errmsg, sprintf(['Device %i does not ',... % 'support the required fs. Supported are: %s \n'],... % kv.devid(1),fsstr)]; % end % % if numel(kv.devid)>1 % recFs = devs([devs.deviceID]==kv.devid(2)).supportedSampleRates; % if ~isempty(recFs) && ~any(recFs==kv.fs) % fsstr = sprintf('%d, ',recFs); % fsstr = ['[',fsstr(1:end-2),']' ]; % errmsg = [errmsg, sprintf(['Recording device %i does not ',... % 'support the required fs. Supported are: %s \n'],... % kv.devid(2),fsstr)]; % end % end if isempty(errmsg) err = lasterror; error('%s',err.message); else error(errmsg); end function failIfInvalidOfflinePar(kv,field,defval) % Helper function for checking if field of kv is empty or not % equal to defval. failed = 0; if nargin<3 if ~isempty(kv.(field)) failed = 1; end else if ~isequal(kv.(field),defval) failed = 1; end end if failed error('%s: ''%s'' is not a valid parameter in the offline mode',... upper(mfilename),field); end function failIfNotPositiveInteger(par,name) if ~isempty(par) if ~isscalar(par) || ~isnumeric(par) || rem(par,1)~=0 || par<=0 error('%s: %s should be positive integer.',upper(mfilename),name); end end function headerStruct = writewavheader(Nchan,fs,filename) %WRITEWAVHEADER(NCHAN, FS, FILENAME) % %Creates a new WAV File and writes only the header into it. %No audio data is written here. % %Note that this implementation is hardcoded to 16 Bits/sample. % %input parameters: % NCHAN - 1: Mono, 2: Stereo % FS - Sampling rate in Hz % FILENAME - Name of the WAVE File including the suffix '.wav' % Original copyright: %--------------------------------------------------------------- % Oticon A/S, Bjoern Ohl, March 9, 2012 %--------------------------------------------------------------- % Modified: Zdenek Prusa % predefined elements: bitspersample = 16; % hardcoded in this implementation, as other % quantizations do not seem relevant mainchunk = 'RIFF'; chunktype = 'WAVE'; subchunk = 'fmt '; subchunklen = 16; % 16 for PCM format = 1; % 1 = PCM (linear quantization) datachunk = 'data'; % calculated elements: alignment = Nchan * bitspersample / 8; %dlength = Total_Nsamp*alignment; % total amount of audio data in bytes dlength = 0; flength = dlength + 36; % dlength + 44 bytes (header) - 8 bytes (definition) bytespersecond = fs*alignment; % data rate in bytes/s % write header into file: fid = fopen(filename,'w'); %writing access fwrite(fid, mainchunk); fwrite(fid, flength, 'uint32'); fwrite(fid, chunktype); fwrite(fid, subchunk); fwrite(fid, subchunklen, 'uint32'); fwrite(fid, format, 'uint16'); fwrite(fid, Nchan, 'uint16'); fwrite(fid, fs, 'uint32'); fwrite(fid, bytespersecond, 'uint32'); fwrite(fid, alignment, 'uint16'); fwrite(fid, bitspersample, 'uint16'); fwrite(fid, datachunk); fwrite(fid, dlength, 'uint32'); fclose(fid); % close file headerStruct = struct('filename',filename,'Nchan',Nchan,... 'alignment',alignment); ltfat/inst/blockproc/private/0000775000175000017500000000000013026262303016166 5ustar susnaksusnakltfat/inst/blockproc/private/block_ifwt.m0000664000175000017500000000523313026262303020472 0ustar susnaksusnakfunction 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,w,J,Lb); % % f = BLOCK_IFWT(c,w,J,Lb) returns block of data reconstructed % from coefficients c using the SegDWT algorithm (based on overlap-add % block convolution) with wavelet filters w and J levels. The % reconstructed block contains overlap to the next block(s). % % Do not call this function directly. It is called from BLOCKSYN when % using 'fwt' frame type with 'segola' block transform handling (see % BLOCKFRAMEACCEL). % % Function should be independent of block_interface. % % % References: % Z. Průša. Segmentwise Discrete Wavelet Transform. PhD thesis, Brno % University of Technology, Brno, 2012. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/private/block_ifwt.html} %@seealso{block, block_ifwt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,w.a,J,Ls,'valid'); ltfat/inst/blockproc/private/block_fwt.m0000664000175000017500000000663013026262303020323 0ustar susnaksusnakfunction 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, w, J); % % Input parameters: % f : Input data. % w : Analysis Wavelet Filterbank. % J : Number of filterbank iterations. % % Output parameters: % c : Coefficient vector. % % c = BLOCK_FWT(f,w,J) accepts suitably extended block of data f* % and produces correct coefficients using the SegDWT algorithm (based on % overlap-save block convolution) with wavelet filters defined by w % and J levels. f is expected to be a column vector or a matrix and % the processing is done column-wise. % % Do not call this function directly. The function is called from % BLOCKANA when used with frame type 'fwt' and 'segola' block transform % handling see BLOCKFRAMEACCEL. % % Function should be independent of block_interface. % % % References: % Z. Průša. Segmentwise Discrete Wavelet Transform. PhD thesis, Brno % University of Technology, Brno, 2012. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/private/block_fwt.html} %@seealso{block, block_ifwt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 % This is effectivelly the "negative" right extension described in chapter % 4.1.4 in the reference. 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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, % global, persistent variables 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(sprintf('%s: JVM support not present.',upper(mfilename))); end; end % Check if Java is not only in a headless state % We are not using warning_isjavaheadless directly because it migh not % yet be in the path % ge = javaMethod('getLocalGraphicsEnvironment','java.awt.GraphicsEnvironment'); % if javaMethod('isHeadless',ge) % warning(sprintf(['%s: JRE is available in headless mode only. ',... % 'Block processing GUI will not work. Consider ',... % 'installing full JRE.'],upper(mfilename))); % end else if ltfatstartprint warning(sprintf('%s: Java toolbox not present.',upper(mfilename))); end; end ltfat/inst/blockproc/blockwrite.m0000664000175000017500000000700213026262303017036 0ustar susnaksusnakfunction blockwrite(f) %-*- texinfo -*- %@deftypefn {Function} blockwrite %@verbatim %BLOCKWRITE Append block to an existing file % Usage: blockwrite(f); % % Input parameters: % f : Block stream input. % % Function appends f to a existing file. The file must have been % explicitly defined as the 'outfile' parameter of BLOCK prior % calling this function. If not, the function does nothing. % % The function expect exactly the same format of f as is returned by % BLOCKREAD. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/blockwrite.html} %@seealso{block} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Authors: Bjoern Ohl, Zdenek Prusa complainif_notenoughargs(nargin,1,'BLOCKWRITE'); filestruct = block_interface('getOutFile'); if isempty(filestruct) % Do nothing if the file was not setup in block. return; %error('%s: Output file was not specified in block function.',... % upper(mfilename)); end filename = filestruct.filename; % Reformat f if necessary f = comp_sigreshape_pre(f,'BLOCKPLAY',0); [L, W] = size(f); Wread = filestruct.Nchan; if Wread ~= W error(['%s: %s was initialized to work with %i channels but', ... ' only %i provided. '],upper(mfilename),filename,Wread,W); end if W>2 error('%s: Cannot work with more than 2 channels.',upper(mfilename)); end % prepare data depending on mono/stereo: if W == 2 % stereo f = f.'; f = f(:); end % flength = dlength + 36; % We need to read one field from the header and % update two. fid = fopen(filename,'r+'); fseek(fid,40,-1); dataLenInBytes = fread(fid,1,'uint32'); dataLenInBytes = dataLenInBytes + filestruct.alignment*L; fileLenInBytes = dataLenInBytes + 36; try if fseek(fid,4,-1) ~= 0 error('d'); end if fwrite(fid,fileLenInBytes,'uint32')<=0 error('d'); end if fseek(fid,40,-1)~=0 error('d'); end if fwrite(fid,dataLenInBytes,'uint32') <=0 error('d'); end catch % We have to check whether the header was modified properly. error(['%s: An error has ocurred when modifying header of the ',... ' wav file. The file might be unreadable. Consider',... ' starting over.'],upper(mfilename)); end fclose(fid); % And now we can append the actual data fid = fopen(filename,'a'); %write data into file (amplified by 2^15 to suit int16-range (from -2^15 to +2^15): maxval = 1-(1/2^16); minval = -1; % Allow clipping since it is hard to do some sensible normalization. f(f >= maxval) = maxval; f(f <= minval) = minval; % clipping check: %if (max(tempvec) >= maxval) || (min(tempvec) <= minval) %We have no way how to find out how to properly normalize in blocks %warning('Clipping! Audio data limited to [-1, +1)'); %end fwrite(fid, f*2^15, 'int16'); fclose(fid); %close file ltfat/inst/blockproc/blocksyn.m0000664000175000017500000002253613026262303016526 0ustar susnaksusnakfunction [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. Note 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.github.io/doc/blockproc/blocksyn.html} %@seealso{block, blockana, framedual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,3,'BLOCKSYN'); complainif_notvalidframeobj(F,'BLOCKSYN'); if ~isfield(F,'blockalg') F.blockalg = 'naive'; end if ~isfield(F,'L') error(['%s: The frame object was not accelerated. See ',... 'BLOCKFRAMEACCEL.'],upper(mfilename)); 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') if F.L < Lb error(['%s: The frame object was accelerated with incompatible ',... 'length. The block length is %i but the accelerated ',... 'length is %i.'],upper(mfilename),Lb,F.L); end % 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') if F.L < 2*Lb error(['%s: The frame object was accelerated with incompatible ',... 'length. The block length is %i but the accelerated ',... 'length is %i.'],upper(mfilename),Lb,F.L); end % 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 % Required more samples than stored if 0 error('%s: Required more samples than stored.',upper(mfilename)); else % pad with zeros overlapTmp = zeros(L,chan,block_interface('getClassId')); overlapTmp(end-Lo+1:end,:) = overlap; overlap = overlapTmp; end 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 ltfat/inst/blockproc/ltfatplay.m0000664000175000017500000000524313026262303016676 0ustar susnaksusnakfunction ltfatplay(source,varargin) %-*- texinfo -*- %@deftypefn {Function} ltfatplay %@verbatim %LTFATPLAY Play data samples or a wav file % Usage: ltfatplay('file.wav') % ltfatplay(data,'fs',fs) % ltfatplay(...,'devid',devid) % % % LTFATPLAY('file.wav') plays a wav file using the default sound device. % % LTFATPLAY('file.wav','devid',devid) plays a wav file using the sound % device with id devid. A list of available devices can be obtained by % BLOCKDEVICES. % % LTFATPLAY(data,'fs',fs,...) works entirely similar, but data is % expected to be a vector of length L or a LxW matrix with % columns as individual channels and fs to be a sampling rate to be used. % When no sampling rate is specified, 44.1 kHz is used. % % In addition, individual channels of the output sound device can be % selected by using an additional key-value pair % % 'playch',playch % A vector of channel indexes starting at 1. % % This function has the advantage over sound and soundsc that one can % directly specify output device chosen from BLOCKDEVICES. Similar % behavior can be achieved using audioplayer and audiodevinfo but % only in Matlab. Audioplayer is not yet supported in Octave. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/ltfatplay.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author: Zdenek Prusa % Initialize block stream block(source,varargin{:}); sourceHandle = block_interface('getSource'); % Allow playing data and wav files only if ~isa(sourceHandle,'function_handle') error('%s: Specified source cannot be played.',upper(mfilename)); end % Make the vector safe Ls = block_interface('getLs'); Lssafe = max([256,Ls(1)]); f = postpad(sourceHandle(1,Ls(1)),Lssafe); % If one channel is used, broadcast it to all output channels chanList = block_interface('getPlayChanList'); if size(f,2)==1 f = repmat(f,1,numel(chanList)); end % Finally play it at once playrec('play',f,chanList); ltfat/inst/blockproc/blockframeaccel.m0000664000175000017500000001146113026262303017772 0ustar susnaksusnakfunction 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. This % does not affect the synthesis windowing. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/blockframeaccel.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'BLOCKFRAMEACCEL'); complainif_notvalidframeobj(F,'BLOCKFRAMEACCEL'); 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 {'fwt'} Fo = frameaccel(F,Lb); Fo.a = F.g.a(:); 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),max(Fo.a(:,1)),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 ltfat/inst/blockproc/blockread.m0000664000175000017500000002567313026262303016635 0ustar susnaksusnakfunction [f,valid] = blockread(L) %-*- texinfo -*- %@deftypefn {Function} blockread %@verbatim %BLOCKREAD Read one block from input % Usage: f=blockread(L) % % Input parameters: % L : Number of samples. % Output parameters: % f : Samples. % valid : Input data valid flag. % % f=BLOCKREAD(L) reads next L audio samples according to source % specified in BLOCK. f is a LxW matrix, where columns are % channels in the stream. % % [f,valid]=blockrad(...) does the same and in addition it returns valid* % flag, which is set to 1, except for the last block of the stream (e.g. % at the end of a file). % % 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.github.io/doc/blockproc/blockread.html} %@seealso{block, blockplay} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa persistent Lwav; persistent clearStr; persistent readTime; persistent t1; persistent t2; %global delayLog; %global delayLog2; is_offline = block_interface('getOffline'); 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<32 && ~is_offline error('%s: Minimum buffer length is 32.',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; % This returns the actual sampling rate value Portaudio was % initialized with. We however want the Matlab side sampling rate. % fs= playrec('getSampleRate'); fs= block_interface('getFs'); 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 % "Fix" the buffer length to L passed to the first call to blockread block_interface('setBufLen',L); 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 a single 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 or a data vector % elseif isa(source,'function_handle') % Number of wav samples (is chached, since it is a disk read operation) Lwav = block_interface('getLs'); % Internal data pointer for audio data pos = block_interface('getDatapos') +1; block_interface('setDatapos',pos+L-1); % Determine valid samples endSample = min(pos + L - 1, Lwav(1)); %f = cast(wavread(source,[pos, endSample]),block_interface('getClassId')); f = cast(source(pos,endSample),classid); % 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('setDatapos',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 if ~is_offline % 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 % 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 %%% %% {'rec',...} Recording while playing % elseif iscell(source) recChanList = block_interface('getRecChanList'); playChanList = block_interface('getPlayChanList'); if do_updateBAR || do_updateGUI readTime = toc(t2); end source = source{2}; Lwav = block_interface('getLs'); % Issue reading buffers up to max while block_interface('getEnqBufCount') <= block_interface('getBufCount') % Internal data pointer for audio data pos = block_interface('getDatapos') +1; block_interface('setDatapos',pos+L-1); % Determine valid samples endSample = min(pos + L - 1, Lwav(1)); %f = cast(wavread(source,[pos, endSample]),block_interface('getClassId')); fin = 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(fin,1),:) = fin; fin = ftmp; % Rewind if loop option was set. if block_interface('getIsLoop') block_interface('setDatapos',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 % Broadcast single input channel to all output chanels. if size(fin,2)==1 fin = repmat(fin,1,numel(playChanList)); end % Play and record block_interface('pushPage',playrec('playrec', fin, playChanList, -1,... 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('getPlayrec',pageList(1)),classid); % Delete page playrec('delPage', pageList(1)); % Throw away the page id block_interface('popPage'); end if ~is_offline if pageNo<=1 playrec('resetSkippedSampleCount'); end if do_updateBAR || do_updateGUI t1=tic; end end ltfat/inst/blockproc/blockpanel.m0000664000175000017500000000751513026262303017014 0ustar susnaksusnakfunction p = blockpanel(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.github.io/doc/blockproc/blockpanel.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.keyvals.location = [50,50]; definput.keyvals.params = {}; [~,kv,params]=ltfatarghelper({'params'},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) error('%s: Input should be a nonempty cell array.',upper(mfilename)); end if ~isempty(params) && ~iscell(params{1}) params = {params}; end complainif_isjavaheadless('BLOCKPANEL'); 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{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); ltfat/inst/blockproc/blockana.m0000664000175000017500000002141413026262303016446 0ustar susnaksusnakfunction [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.github.io/doc/blockproc/blockana.html} %@seealso{block, blocksyn, blockplay} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'BLOCKANA'); complainif_notvalidframeobj(F,'BLOCKANA'); if nargin<3 fola = []; end if ~isfield(F,'blockalg') F.blockalg = 'naive'; end % Block length Lb = size(f,1); if ~isfield(F,'L') error(['%s: The frame object was not accelerated. See ',... 'BLOCKFRAMEACCEL.'],upper(mfilename)); 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; do_sliced = strcmp(F.blockalg,'sliced'); do_segola = strcmp(F.blockalg,'segola'); if strcmp(F.blockalg,'naive') if F.L < Lb error(['%s: The frame object was accelerated with incompatible ',... 'length. The block length is %i but the accelerated ',... 'length is %i.'],upper(mfilename),Lb,F.L); end % 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 if F.L < 2*Lb error(['%s: The frame object was accelerated with incompatible ',... 'length. The effective block length is %i but the accelerated ',... 'length is %i.'],upper(mfilename),2*Lb,F.L); end % 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 Lb1 && isempty(fola) % Avoiding case when empty fola means just uninitialized % custom overlap. fola = 0; end % 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,chan); 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 ltfat/inst/blockproc/blockplot.m0000664000175000017500000000667713026262303016703 0ustar susnaksusnakfunction cola=blockplot(p,arg0,arg1,cola) %-*- texinfo -*- %@deftypefn {Function} blockplot %@verbatim %BLOCKPLOT Plot block coefficients % Usage: blockplot(p,c); % blockplot(p,F,c); % blockplot(p,F,c,cola); % % 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. p must be a Java object with a % append method. % % 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. % % BLOCKPLOT(p,c) or BLOCKPLOT(p,[],c) does the same, but expects c % to be already formatted matrix of real numbers. The data dimensions % are not restricted, but it will be shrinked or expanded to fit with % the running plot. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/blockplot.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'BLOCKPLOT'); if ~isempty(arg0) && isstruct(arg0) && isfield(arg0,'frana') F = arg0; c = arg1; complainif_notenoughargs(nargin,3,'BLOCKPLOT'); complainif_notvalidframeobj(F,'BLOCKPLOT'); if size(c,2)>1 error('%s: Only one channel input is supported.',upper(mfilename)); end ctf = framecoef2tfplot(F,c(:,1)); 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 ~isempty(arg0) c = arg0; elseif nargin>2 c = arg1; else error('%s: Not enough input arguments',upper(mfilename)); end 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 ltfat/inst/blockproc/blockframepairaccel.m0000664000175000017500000000636713026262303020657 0ustar susnaksusnakfunction [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.github.io/doc/blockproc/blockframepairaccel.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,3,'BLOCKFRAMEPAIRACCEL'); complainif_notvalidframeobj(Fa,'BLOCKFRAMEPAIRACCEL'); complainif_notvalidframeobj(Fs,'BLOCKFRAMEPAIRACCEL'); 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 ltfat/inst/blockproc/Contents.m0000664000175000017500000000357313026262303016477 0ustar susnaksusnak% LTFAT - Block processing % % Zdenek Prusa, 2013 - 2016. % % 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 % BLOCKWRITE - Appends data to a wav file % % 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 % % Other % LTFATPLAY - Replacement for the sound command allowing selecting an output device % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/blockproc/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/blockproc/blockdevices.m0000664000175000017500000000441113026262303017327 0ustar susnaksusnakfunction 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.github.io/doc/blockproc/blockdevices.html} %@seealso{block} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . clear playrec; 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 ltfat/inst/blockproc/java/0000775000175000017500000000000013026262276015446 5ustar susnaksusnakltfat/inst/blockproc/java/net/0000775000175000017500000000000013026262276016234 5ustar susnaksusnakltfat/inst/blockproc/java/net/sourceforge/0000775000175000017500000000000013026262276020557 5ustar susnaksusnakltfat/inst/blockproc/java/net/sourceforge/ltfat/0000775000175000017500000000000013026262276021671 5ustar susnaksusnakltfat/inst/blockproc/java/net/sourceforge/ltfat/ContFrame.java0000664000175000017500000003243313026262276024417 0ustar susnaksusnak/* * 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 paramComponentsMap = null; private Map sliderBoundsMap = null; private KeyboardFocusManager kfm = null; private KeyEventDispatcher ked = 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 void setVisibleParam(String param, boolean visible ) throws NoSuchFieldException { // Do nothing if paramSliderMap has not been initlialized yet if (paramComponentsMap == null) return; List s = (List) paramComponentsMap.get(param); if (s == null) { throw new NoSuchFieldException("Parameter " + param + " not found."); } for (JComponent c : s) { c.setVisible(visible); } //s.disable(); //s.setVisible(false); } 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(); sliderParamMap = new HashMap(); paramComponentsMap = new HashMap>(); sliderBoundsMap = new HashMap(); initFrameComponents(params); jf.pack(); jf.validate(); jf.setVisible(true); } }); } public void close() { // This is uded to escape the main loop flag = 0; // We have to remove the Ctrl-C blocker if (kfm != null && ked != null) { kfm.removeKeyEventDispatcher(ked); } // Dispose the JFrame, this object lives on if (jf != null) { jf.setVisible(false); jf.dispose(); } } private void onExit() { close(); } 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); if(jf != null) { jf.pack(); } } 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 requestFocus() { runInEDT(new Runnable() { @Override public void run() { if (jf != null) { jf.requestFocus(); } } }); } 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) { close(); } }); // Add a global Ctrc-C keyboard shortcut listener kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); ked = new KeyEventDispatcher() { @Override public boolean dispatchKeyEvent(KeyEvent e) { if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_C && e.getID() == KeyEvent.KEY_PRESSED) { // The Ctrl-C is consumed here. It is not passed further. e.consume(); close(); } return false; } }; kfm.addKeyEventDispatcher(ked); return buildJF; } private void initFrameComponents(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, 10)); 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); ArrayList l = new ArrayList(); l.add(jname); l.add(jval); l.add(jvalTxt); paramComponentsMap.put(name, l); sliderBoundsMap.put(jval, new SliderBounds(minVal, maxVal)); } loadTxt = new JLabel("0%"); loadTxt.setPreferredSize(new Dimension(50, 10)); 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; } } } ltfat/inst/blockproc/java/net/sourceforge/ltfat/thirdparty/0000775000175000017500000000000013026262276024063 5ustar susnaksusnakltfat/inst/blockproc/java/net/sourceforge/ltfat/thirdparty/JRangeSlider.java0000664000175000017500000007543613026262276027256 0ustar susnaksusnakpackage 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; /** *

Implements a Swing-based Range slider, which allows the user to enter a * range (minimum and maximum) value.

* * @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 does not 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 ltfat/inst/blockproc/java/net/sourceforge/ltfat/Utils.java0000664000175000017500000001201013026262276023626 0ustar susnaksusnak/* * 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;yymax){ 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;yymax){ in[yy][xx]=max; } if(in[yy][xx]max){ in[yy]=max; } if(in[yy]max){ in[yy]=max; } if(in[yy]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(); } } } ltfat/inst/blockproc/java/Makefile0000664000175000017500000000070713026262276017112 0ustar susnaksusnak# 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 ltfat/inst/blockproc/blockdone.m0000664000175000017500000000347313026262303016641 0ustar susnaksusnakfunction 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.github.io/doc/blockproc/blockdone.html} %@seealso{block} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % TO DO: Process additional zeros to compensate for the delay block_interface('clearAll'); if playrec('isInitialised') playrec('reset'); end clear playrec; 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 ltfat/inst/blockproc/blockpanelget.m0000664000175000017500000000504313026262303017506 0ustar susnaksusnakfunction [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.github.io/doc/blockproc/blockpanelget.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . nout = nargout(); complainif_notenoughargs(nargin,1,'BLOCKPANELGET'); 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 ltfat/inst/blockproc/blockfigure.m0000664000175000017500000000602613026262303017172 0ustar susnaksusnakfunction 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.github.io/doc/blockproc/blockfigure.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.keyvals.cm=[]; definput.keyvals.location=[50,120]; [flags,kv]=ltfatarghelper({},definput,varargin); complainif_isjavaheadless('BLOCKFIGURE'); 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 = {ltfat_inferno()}; 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); ltfat/inst/blockproc/blockplay.m0000664000175000017500000000334013026262303016652 0ustar susnaksusnakfunction 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. % In case no audio output is expected (in the rec only mode), % the function does nothing. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/blockproc/blockplay.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'BLOCKPLAY'); source = block_interface('getSource'); if ( iscell(source) && strcmp(source{1},'rec')) || ... strcmp(source,'rec') % Do nothing in rec only mode. return; % error('%s: Blocks cannot be played in the rec only mode.',upper(mfilename)); end % Reformat f if necessary f = comp_sigreshape_pre(f,'BLOCKPLAY',0); block_interface('setToPlay',f); ltfat/inst/demos/0000775000175000017500000000000013026262303013645 5ustar susnaksusnakltfat/inst/demos/demo_blockproc_paramequalizer.m0000664000175000017500000001663513026262303022122 0ustar susnaksusnakfunction 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 and Sons Ltd, 2 % edition, 2008. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_blockproc_paramequalizer.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % 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 try fs = block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p); err = lasterror; error(err.message); end % Buffer length (30 ms) bufLen = floor(30e-3*fs); % 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 + 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 ltfat/inst/demos/demo_blockproc_slidingerblets.m0000664000175000017500000000475613026262303022113 0ustar susnaksusnakfunction 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.github.io/doc/demos/demo_blockproc_slidingerblets.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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(); % Setup blocktream try fs=block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p,fobj); err = lasterror; error(err.message); end % Buffer length (30 ms) bufLen = floor(30e-3*fs); zpad = floor(bufLen/2); % Number of filters M = 200; F = frame('erbletfb',fs,2*bufLen+2*zpad,'fractionaluniform','M',M); Fa = blockframeaccel(F,bufLen,'sliced','zpad',zpad); 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(bufLen); 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); ltfat/inst/demos/demo_wavelets.m0000664000175000017500000000546113026262303016667 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_wavelets %@verbatim %DEMO_WAVELETS Wavelet filter banks % % This demo exemplifies the use of the wavelet filter bank trees. All % representations use "least asymmetric" Daubechies wavelet orthonormal % filters 'sym8' (8-regular, length 16). % % Figure 1: DWT representation % % The filter bank tree consists of 11 levels of iterated 2-band basic % wavelet filter bank, where only the low-pass output is further % decomposed. This results in 12 bands with octave resolution. % % Figure 2: 8-band DWT representation % % The filter bank tree (effectively) consists of 3 levels of iterated % 8-band basic wavelet filter bank resulting in 22 bands. Only the % low-pass output is decomposed at each level. % % Figure 3: Full Wavelet filter bank tree representation % % The filter bank tree depth is 8 and it is fully decomposed meaning % both outputs (low-pass and high-pass) of the basic filter bank is % plot further. This results in 256 bands linearly covering the % frequency axis. % % Figure 4: Full Wavelet filter bank tree representation % % The same case as before, but symmetric nearly orthogonal basic % filter bank is used. % % Figure 5: Full Dual-tree Wavelet filter bank representation % % This is a 2 times redundant representation using Q-shift dual-tree % wavelet filters. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_wavelets.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Read the test signal and crop it to the range of interest [f,fs]=gspi; f=f(10001:100000); dr=50; figure(1); [c1,info]=fwt(f,'sym8',11); plotwavelets(c1,info,fs,'dynrange',dr); figure(2); [c2,info]=wfbt(f,{'sym8',3,'quadband'}); plotwavelets(c2,info,fs,'dynrange',dr); figure(3); [c3,info]=wfbt(f,{'sym8',8,'full'}); plotwavelets(c3,info,fs,'dynrange',dr); figure(4); [c4,info]=wfbt(f,{'symorth3',8,'full'}); plotwavelets(c4,info,fs,'dynrange',dr); figure(5); [c5,info]=dtwfbreal(f,{'qshift5',8,'full','first','symorth3'}); plotwavelets(c5,info,fs,'dynrange',dr); ltfat/inst/demos/demosinit.m0000664000175000017500000000163613026262303016024 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} demosinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demosinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/demos/demo_nsdgt.m0000664000175000017500000000565713026262303016163 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_nsdgt %@verbatim %DEMO_NSDGT Non-stationary Gabor transform demo % % This script sets up a non-stationary 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 (colour-coded) image of the nsdgt coefficient % modulus. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_nsdgt.html} %@seealso{nsdgt, insdgt, nsgabdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,M,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 so it is periodic. f=sin(2*pi*(289/Ls)*(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); ltfat/inst/demos/demo_frsynabs.m0000664000175000017500000000435313026262303016663 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_frsynabs %@verbatim %DEMO_FRSYNABS Construction 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. % % The BFGS method makes use of the minFunc software. To use the BFGS method, % please install the minFunc software from: % http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_frsynabs.html} %@seealso{isgramreal, isgram} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/demos/demo_blockproc_slidingcqt.m0000664000175000017500000000641113026262303021230 0ustar susnaksusnakfunction 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.github.io/doc/demos/demo_blockproc_slidingcqt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % Setup blocktream try fs=block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p,fobj); err = lasterror; error(err.message); end % Buffer length (30 ms) bufLen = floor(30e-3*fs); zpad = floor(bufLen/2); % Prepare CQT filters in range floor(fs/220),floor(fs/2.2) Hz, % 48 bins per octave % 320 + 2 filters in total (for fs = 44100 Hz). % And a frame object representing the filterbank F = frame('cqtfb',fs,floor(fs/220),floor(fs/2.2),48,2*bufLen+2*zpad,'fractionaluniform'); % 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(bufLen); 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); ltfat/inst/demos/demo_filterbanks.m0000664000175000017500000001415113026262303017335 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_filterbanks %@verbatim %DEMO_FILTERBANKS CQT, ERBLET and AUDLET filterbanks % % This demo shows CQT (Constant Quality Transform), ERBLET (Equivalent % Rectangular Bandwidth -let transform), and AUDLET (Auditory -let) % representations acting as filterbanks with high and low redundancies. % Note that ERBLET and AUDLET are similar concepts. The main difference % is that ERBlet uses only the perceptual ERB scale while AUDlet allows % for various perceptual scales like Bark or Mel scales. In short, % ERBFILTERS is a wrapper of AUDFILTERS for the ERB scale. % Filterbanks are build such that the painless condition is always satisfied. % Real input signal and filters covering only the positive frequency range % are used. The redundancy is calculated as a ratio of the number of (complex) % coefficients and the input length times two to account for the storage % requirements of complex numbers. % % The high redundancy representation uses 'uniform' subsampling i.e. % all channels are subsampled with the same subsampling factor which % is the lowest from the filters according to the painless condition % rounded towards zero. % % The low redundancy representation uses 'fractional' subsampling % which results in the least redundant representation still % satisfying the painless condition. Actual time positions of atoms % can be non-integer, hence the word fractional. % % Figure 1: ERBLET representations % % The high-redundany plot (top) consists of 400 channels (~9 filters % per ERB) and low-redundany plot (bottom) consists of 44 channels % (1 filter per ERB). % % Figure 2: CQT representations % % Both representations consist of 280 channels (32 channels per octave, % frequency range 50Hz-20kHz). The high-redundany represention is on % the top and the low-redundancy repr. is on the bottom. % % Figure 3: AUDLET representations % % The first representation consists of 72 channels BARKlet FB (3 filters % per Bark in the frequency range 100Hz-16kHz using fractional subsampling. % The second representation consists of 40 channels MELlet FB using % uniform subsampling and triangular windows. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_filterbanks.html} %@seealso{audfilters, erbfilters, cqtfilters} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Read the test signal and crop it to the range of interest [f,fs]=gspi; f=f(10001:100000); dr=50; figure(1); subplot(2,1,1); % Create the ERB filterbank using 400 filters linearly spaced in the % ERB scale and using uniform subsampling. [g,a,fc]=erbfilters(fs,numel(f),'M',400,'uniform'); % Compute the filterbank response c1=filterbank(f,g,a); % Compute redundancy erb1_redundancy = 2*sum(1./a); % Plot the representation plotfilterbank(c1,a,fc,fs,dr,'audtick'); title('ERBLET representations') subplot(2,1,2); % Create the ERB filterbank using 44 filters linearly spaced in the % ERB scale and using fractional subsampling. [g,a,fc]=erbfilters(fs,numel(f),'fractional'); % Compute the filterbank response c2=filterbank(f,g,a); % Compute redundancy erb2_redundancy = 2*sum(a(:,2)./a(:,1)); % Plot the representation plotfilterbank(c2,a,fc,fs,dr,'audtick'); fprintf('ERBLET high redundancy %.2f, low redundany %.2f.\n',... erb1_redundancy,erb2_redundancy); figure(2); subplot(2,1,1); % Create the CQT filterbank using 32 channels per octave in frequency % range 50Hz-20kHz using uniform subsampling. [g,a,fc] = cqtfilters(fs,50,20000,32,numel(f),'uniform'); % Compute the filterbank response c3=filterbank(f,g,a); % Compute redundancy cqt1_redundancy = 2*sum(1./a); % Plot the representation plotfilterbank(c3,a,fc,fs,'dynrange',dr); title('CQT representations') subplot(2,1,2); % Create the CQT filterbank using 32 channels per octave in frequency % range 50Hz-20kHz using fractional subsampling. [g,a,fc] = cqtfilters(fs,50,20000,32,numel(f),'fractional'); % Compute the filterbank response c4=filterbank(f,g,a); % Compute redundancy cqt2_redundancy = 2*sum(a(:,2)./a(:,1)); % Plot the representation plotfilterbank(c4,a,fc,fs,'dynrange',dr); fprintf('CQT high redundancy %.2f, low redundany %.2f.\n',... cqt1_redundancy,cqt2_redundancy); % Finally two settings of AUDFILTERS are illustrated, namely an analysis on % the Bark scale (top) and one on the Mel scale using triangular windows (bottom). figure(3); subplot(2,1,1); % Create a Barklet FB with 3 filters per Bark in the % frequency range 100Hz-16kHz using fractional subsampling. [g,a,fc]=audfilters(fs,numel(f),100,16000,'bark','fractional','spacing',1/3); % Compute the filterbank response c5=filterbank(f,{'realdual',g},a); % Compute redundancy bark_redundancy = 2*sum(a(:,2)./a(:,1)); % Plot the representation plotfilterbank(c5,a,fc,fs,dr,'audtick'); title('AUDLET representations: Bark scale (top) and Mel scale (bottom)') fprintf('BARKLET redundancy %.2f\n',bark_redundancy); subplot(2,1,2); % Create a MELlet FB with 40 filters and a triangular window using % uniform subsampling. [g,a,fc]=audfilters(fs,numel(f),'mel','uniform','M',40,'tria'); % Compute the filterbank response c6=filterbank(f,{'realdual',g},a); % Compute redundancy mel_redundancy = 2*sum(a.^-1); % Plot the representation plotfilterbank(c6,a,fc,fs,dr,'audtick'); title('MELlet representation') fprintf('MELLET redundancy %.2f\n',mel_redundancy); ltfat/inst/demos/demo_blockproc_dgtequalizer.m0000664000175000017500000000606513026262303021574 0ustar susnaksusnakfunction 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.github.io/doc/demos/demo_blockproc_dgtequalizer.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); % Setup blocktream try fs=block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p,fobj); err = lasterror; error(err.message); end % Buffer length (30 ms) bufLen = floor(30e-3*fs); % 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(bufLen); 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); ltfat/inst/demos/demo_gabmixdual.m0000664000175000017500000000676713026262303017164 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_gabmixdual.html} %@seealso{gabmixdual, gabdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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'); ltfat/inst/demos/demo_firwin.m0000664000175000017500000000240013026262303016321 0ustar susnaksusnakclf; 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.github.io/doc/demos/demo_firwin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/demos/demo_audiocompression.m0000664000175000017500000000541613026262303020420 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_audiocompression.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/demos/demo_blockproc_denoising.m0000664000175000017500000000533213026262303021047 0ustar susnaksusnakfunction 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.github.io/doc/demos/demo_blockproc_denoising.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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} }); % Number of frequency channels M = 1000; % Setup blocktream try fs=block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p); err = lasterror; error(err.message); end % Buffer length (30 ms) bufLen = floor(30e-3*fs); % Window length in ms winLenms = 20; %floor(fs*winLenms/1e3) [F,Fdual] = framepair('dgtreal',{'hann',floor(fs*winLenms/1e3)},'dual',40,M); % Or using fwt %[F,Fdual] = framepair('fwt','ana:symorth3','dual',7); [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(bufLen); % 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); ltfat/inst/demos/demo_blockproc_basicloop.m0000664000175000017500000000400313026262303021035 0ustar susnaksusnakfunction 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.github.io/doc/demos/demo_blockproc_basicloop.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if demo_blockproc_header(mfilename,nargin) return; end % Basic Control pannel (Java object) p = blockpanel({ {'GdB','Gain',-20,20,0,21},... }); % Setup blocktream try fs = block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p); err = lasterror; error(err.message); end % Set buffer length to 30 ms L = floor(30e-3*fs); 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(L); % The following does nothing in the rec only mode. blockplay(f*gain); % The following does nothing if 'outfile' was not specified blockwrite(f); end blockdone(p); ltfat/inst/demos/demo_wfbt.m0000664000175000017500000000711513026262303015775 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_wfbt %@verbatim %DEMO_WFBT Auditory filterbanks built using filterbank tree structures % % This demo shows two specific constructions of wavelet filterbank trees % using several M-band filterbanks with possibly different M (making the % thee non-homogenous) in order to approximate auditory frequency bands % and a musical scale respectively. Both wavelet trees produce perfectly % reconstructable non-redundant representations. % % The constructions are the following: % % 1) Auditory filterbank, approximately dividing the frequency band % into intervals reminisent of the bask scale. % % 2) Musical filterbank, approximately dividing the freq. band into % intervals reminicent of the well-tempered musical scale. % % Shapes of the trees were taken from fig. 8 and fig. 9 from the refernece. % Sampling frequency of the test signal is 48kHz as used in the article. % % Figure 1: Frequency responses of the auditory filterbank. % % Both axes are in logarithmic scale. % % Figure 2: TF plot of the test signal using the auditory filterbank. % % Figure 3: Frequency responses of the musical filterbank. % % Both axes are in logarithmic scale. % % Figure 4: TF plot of the test signal using the musical filterbank. % % References: % F. Kurth and M. Clausen. Filter bank tree and M-band wavelet packet % algorithms in audio signal processing. Signal Processing, IEEE % Transactions on, 47(2):549--554, Feb 1999. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_wfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Load a test signal and resample it to 48 kHz since such sampling % rate is assumed in the reference. f = resample(greasy,3,1); fs = 48000; % Bark-like filterbank tree % Creating tree depicted in Figure 8 in the reference. w = wfbtinit({'cmband3',1}); w = wfbtput(1,0,'cmband6',w); w = wfbtput(1,1,'cmband3',w); w = wfbtput(2,0:1,'cmband5',w); w = wfbtput(2,2:3,'cmband2',w); % Convert to filterbank [g,a] = wfbt2filterbank(w); % Plot frequency responses figure(1); filterbankfreqz(g,a,2*2048,'plot','fs',fs,'dynrange',30,'posfreq','flog'); % Do the transform [c,info] = wfbt(f,w); disp('The reconstruction should be close to zero:') norm(f-iwfbt(c,info)) figure(2); plotwavelets(c,info,fs,'dynrange',60); % Well-tempered musical scale filterbank tree % Creating tree depicted in Figure 9 in the reference. w2 = wfbtinit({'cmband4',1}); w2 = wfbtput(1,0:1,'cmband6',w2); w2 = wfbtput(2,0:1,'cmband4',w2); w2 = wfbtput(3,1:4,'cmband4',w2); % Convert to filterbank [g2,a2] = wfbt2filterbank(w2); figure(3); filterbankfreqz(g2,a2,2*2048,'plot','fs',fs,'dynrange',30,'posfreq','flog'); [c2,info2] = wfbt(f,w2); disp('The reconstruction should be close to zero:') norm(f-iwfbt(c2,info2)) figure(4); plotwavelets(c2,info2,fs,'dynrange',60); ltfat/inst/demos/demo_pgauss.m0000664000175000017500000000661313026262303016337 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_pgauss.html} %@seealso{pgauss} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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'); ltfat/inst/demos/demo_filterbanksynchrosqueeze.m0000664000175000017500000001037513026262303022166 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_filterbanksynchrosqueeze %@verbatim %DEMO_FILTERBANKSYNCHROSQUEEZE Filterbank synchrosqueezing and inversion % % The demo shows that the synchrosqueezed filterbank representation can be % directly used to reconstruct the original signal. % Since we do not work with a filterbank which forms a tight frame % (its FILTERBANKRESPONSE is not constant) the direct reconstruction % (mere summing all the channels) does not work well. We can fix that by % filtering (equalizing) the result by the inverse of the overall analysis % filterbank frequency response. % % Figure 1: ERBlet spectrogram (top) and synchrosqueezed ERBlet spectrogram (bottom) % % The signal used is the first second from GSPI. Only the energy of % the coefficients is show. Both representations are in fact complex and % invertible. % % Figure 2: Errors of the direct and the equalized reconstructions % % There is still a small DC offset of the signal obtained by the direct % summation. % % References: % N. Holighaus, Z. Průša, and P. L. Soendergaard. Reassignment and % synchrosqueezing for general time-frequency filter banks, subsampling % and processing. Signal Processing, 125:1--8, 2016. [1]http ] % % References % % 1. http://www.sciencedirect.com/science/article/pii/S0165168416000141 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_filterbanksynchrosqueeze.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Get one second of gspi Ls = 44100; [f,fs] = gspi; f = f(1:Ls); % Create an UNIFORM filterbank [g,a,fc] = erbfilters(fs,Ls,'uniform','M',400); % We will not do no subsampling. % This is the main requirement for synchrosqueezing to work. a = 1; % Compute the time phase derivative and the coefficients [tgrad,~,~,c] = filterbankphasegrad(f,g,a); % Do the synchrosqueezing cs = filterbanksynchrosqueeze(c,tgrad,cent_freqs(fs,fc)); % Plot spectrograms figure(1);clf; subplot(2,1,1); plotfilterbank(c,a,fc,fs,60); subplot(2,1,2); plotfilterbank(cs,a,fc,fs,60); % Reformat the coefficients to matrices cmat = cell2mat(c.'); csmat = cell2mat(cs.'); % Compute the overall analysis filterbank response. Frespall = sum(filterbankfreqz(g,a,Ls),2); % The fiterbank is defined only for positive frequencies, we % sum the response with its involution Frespfull = Frespall + involute(Frespall); % The filterbank is not tight, so the direct reconstruction % will not give a good reconstruction. % We do that anyway for comparison. % % Just scale so that the response is around 1 C = mean(abs(Frespfull)); Frespfull = Frespfull/C; % Direct reconstruction from the original coefficients fhat1 = 2*real(sum(cmat,2))/C; % Direct reconstruction from the synchrosqueezed coefficents fhat1s = 2*real(sum(csmat,2))/C; % Reconstruction errors err1 = norm(f-fhat1)/norm(f); err1s = norm(f-fhat1s)/norm(f); % We "equalize" the reconstruction by inverse of Frespfull fhat2 = real(ifft(fft(fhat1)./Frespfull)); fhat2s = real(ifft(fft(fhat1s)./Frespfull)); % Compute errors err2 = norm(f-fhat2)/norm(f); err2s = norm(f-fhat2s)/norm(f); % Plot errors for comparison figure(2);clf; title('Error of the reconstruction'); plot([f-fhat1s, f-fhat2s]); legend({'notequalized','equalized'}); fprintf(['Direct reconstruction MSE:\n From the coefficients: %e\n',... ' From the synchrosqueezed coefficients: %e\n'],err1,err1s); fprintf(['Equalized reconstruction MSE:\n From the coefficients: %e\n',... ' From the synchrosqueezed coefficients: %e\n'],err2,err2s); ltfat/inst/demos/demo_audscales.m0000664000175000017500000000357013026262303017000 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_audscales.html} %@seealso{freqtoaud, audtofreq, audspace, audspacebw} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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)'); ltfat/inst/demos/demo_dgt.m0000664000175000017500000001261613026262303015613 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_dgt.html} %@seealso{sgram, dgt, dgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % -------- 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.'); ltfat/inst/demos/demo_framemul.m0000664000175000017500000001030213026262303016633 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_framemul.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/demos/demo_pbspline.m0000664000175000017500000000744113026262303016651 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_pbspline.html} %@seealso{pbspline, middlepad} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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.'); ltfat/inst/demos/demo_audiodenoise.m0000664000175000017500000000521613026262303017503 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_audiodenoise.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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'); ltfat/inst/demos/Contents.m0000664000175000017500000000630613026262303015625 0ustar susnaksusnak% LTFAT - Demos % % Peter L. Soendergaard, 2007 - 2016. % % This page documents the demos. % % Basic demos % DEMO_DGT - DGT and comparison to SGRAM % DEMO_GABFIR - FIR windows in Gabor systems. % DEMO_WAVELETS - Wavelet representations using FWT and WFBT. % % 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. % DEMO_BPFRAMEMUL - A Gabor multiplier as a time-varying bandpass filter. % DEMO_FRSYNABS - Synthetic spectrogram iterative reconstruction. % DEMO_FILTERBANKSYNCHROSQUEEZE - Reconstruction from synchrosqueezed representation. % % 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_PHASERET - Spectrogram phase retrieval and phase difference % DEMO_NEXTFASTFFT - Next fast FFT size. % DEMO_FILTERBANKS - Non-stationary Gabor systems defined in frequency domain % % Auditory scales and filters % DEMO_AUDSCALES - Different auditory scales. % DEMO_AUDITORYFILTERBANK - Erb-spaced auditory filter bank. % DEMO_WFBT - Auditory filter banks created using WFBT. % % 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_DGTEQUALIZER - Variable Gabor Multiplier as equalizer. % DEMO_BLOCKPROC_EFFECTS - Real-time vocoder effects. % % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/demos/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/demos/demo_phaseret.m0000664000175000017500000000433513026262303016647 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} demo_phaseret %@verbatim %DEMO_PHASERET Phase retrieval and phase difference % % This demo demonstrates iterative reconstruction of a spectrogram and % the phase difference. % % Figure 1: Original spectrogram % % This figure shows the target spectrogram of an excerpt of the gspi % signal % % Figure 2: Phase difference % % This figure shows a difference between the original phase and the % reconstructed using 100 iterations of a Fast Griffin-Lim algorithm. % Note: The figure in the LTFAT 2.0 paper differs slightly because it % is genarated using 1000 iterations. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_phaseret.html} %@seealso{frsynabs, plotframe} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Here the number of iterations is set to 100 to speedup the execution maxit = 100; [f,fs]=gspi; f=f(10001:100000); g='gauss'; a=100; M=1000; F = frame('dgtreal',g,a,M); c = frana(F,f); % Spectrogram values s=abs(c).^2; % Original phase theta=angle(c); % Do the reconstruction using the magnitude only r = frsynabs(F,sqrt(s),'fgriflim','maxit',maxit); % Re-analyse using the original frame c_r = frana(F,r); % Obtain phase of the re-analysis s_r = abs(c_r).^2; theta_r=angle(c_r); d1=abs(theta-theta_r); d2=2*pi-d1; anglediff=min(d1,d2); % Plot the original spectrogram figure(1); plotframe(F,c,fs,'dynrange',50); % Plot the phase difference figure(2); anglediff(abs(c)<10^(-50/20)) = 0; plotframe(F,anglediff,fs,'lin'); ltfat/inst/demos/demo_audioshrink.m0000664000175000017500000000650213026262303017352 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_audioshrink.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)"'); ltfat/inst/demos/demo_imagecompression.m0000664000175000017500000000565413026262303020405 0ustar susnaksusnak%-*- 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 DB6 with J=5 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.github.io/doc/demos/demo_imagecompression.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %% 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='db6'; % Synthesis filters ws='db6'; % 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'); ltfat/inst/demos/demo_phaseplot.m0000664000175000017500000001040413026262303017025 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_phaseplot.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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'); ltfat/inst/demos/demo_nextfastfft.m0000664000175000017500000000441013026262303017362 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_nextfastfft.html} %@seealso{nextfastfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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) ltfat/inst/demos/demo_gabmulappr.m0000664000175000017500000001026113026262303017161 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_gabmulappr.html} %@seealso{gabmulappr} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 F = frametight(frame('dgt','gauss',a,M)); Gs1=framemul(s1(:),F,F,framenative2coef(F,sym)); Ge1=framemul(e1(:),F,F,framenative2coef(F,sym)); % 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); ltfat/inst/demos/demo_blockproc_slidingsgram.m0000664000175000017500000000467313026262303021562 0ustar susnaksusnakfunction 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.github.io/doc/demos/demo_blockproc_slidingsgram.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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(); % Setup blockstream try fs=block(source,varargin{:},'loadind',p); catch % Close the windows if initialization fails blockdone(p,fobj); err = lasterror; error(err.message); end % 30 ms bufLen = floor(30e-3*fs); % Using dgtreal with 20ms hann window, hop factor 80, 1000 channels. % Redundancy factor 12.5 winLenms = 40; 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(bufLen); 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); ltfat/inst/demos/demo_ofdm.m0000664000175000017500000001141113026262303015752 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_ofdm.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/demos/demo_blockproc_effects.m0000664000175000017500000002064013026262303020506 0ustar susnaksusnakfunction demo_blockproc_effects(source,varargin) %-*- texinfo -*- %@deftypefn {Function} demo_blockproc_effects %@verbatim %DEMO_BLOCKPROC_EFFECTS Various vocoder effects using DGT % Usage: demo_blockproc_effects('gspi.wav') % % For additional help call DEMO_BLOCKPROC_EFFECTS without arguments. % This demo works correctly only with the sampling rate equal to 44100 Hz. % % This script demonstrates several real-time vocoder effects. Namely: % % 1) Robotization effect: Achieved by doing DGT reconstruction using % absolute values of coefficients only. % % 2) Whisperization effect: Achieved by randomizing phase of DGT % coefficients. % % 3) Pitch shifting effect: Achieved by stretching/compressing % coefficients along frequency axis. % % 4) Audio morphing: Input is morphed with a background sound such % that the phase of DGT coefficients is substituted by phase % of DGT coefficients of the background signal. % File beat.wav (at 44,1kHz) (any sound will do) is expected to % be in the search path, oherwise the effect will be disabled. % % This demo was created for the Lange Nacht der Forschung 4.4.2014 event. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_blockproc_effects.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Zdenek Prusa, Nicki Holighaus if demo_blockproc_header(mfilename,nargin) return; end fobj = blockfigure(); % Common block setup bufLen = 1024; % Morphing params Fmorph = frametight(frame('dgtreal',{'hann',512},128,512,'timeinv')); Fmorph = blockframeaccel(Fmorph, bufLen,'segola'); haveWav = 0; try [ff, fsbeat] = wavload('beat.wav'); ff = ff(:,1); %ff = 0.8*resample(ff,4,1); ffblocks = reshape(postpad(ff,ceil(size(ff,1)/bufLen)*bufLen),bufLen,[]); cidx = 1; haveWav = 1; catch warning('beat.wav not found. morphing effect is disabled.'); end if haveWav && fsbeat~=44100 error('%s: beat.wav must be sampled at 44.1 kHz.',upper(mfilename)); end % Plain analysis params Fana = frame('dgtreal',{'hann',882},300,3000); Fana = blockframeaccel(Fana, bufLen,'segola'); % Robotization params Mrob = 2^12; Frob = frametight(frame('dgtreal',{'hann',Mrob},Mrob/8,Mrob,'timeinv')); Frob = blockframeaccel(Frob, bufLen,'segola'); % Whisperization params Mwhis = 512; Fwhis = frametight(frame('dgtreal',{'hann',512},128,Mwhis)); Fwhis = blockframeaccel(Fwhis, bufLen,'segola'); % Pitch shift % Window length in ms M = 1024; a = 512; [F] = frametight(frame('dgtreal',{'hann',1024},a,M,'timeinv')); Fa = blockframeaccel(F, bufLen,'segola'); Fs = Fa; Mhalf = floor(M/2) + 1; scale = (0:Mhalf-1)/Mhalf; scale = scale(:); shiftRange = 12; scaleTable = round(scale*2.^(-(1:shiftRange)/12)*Mhalf)+1; scaleTable2 = round(scale*2.^((1:shiftRange)/12)*Mhalf)+1; scaleTable2(scaleTable2>Mhalf) = Mhalf; phaseCorr = exp(abs(bsxfun(@minus,scaleTable,(1:size(scaleTable,1))'))./M*2*pi*1i*a); phaseCorr2 = exp(abs(bsxfun(@minus,scaleTable2,(1:size(scaleTable2,1))'))./M*2*pi*1i*a); fola = []; phasecorrVect = ones(Mhalf,1,'single'); if haveWav % Basic Control pannel (Java object) parg = { {'GdB','Gain',-20,20,0,21},... {'Eff','Effect',0,4,0,5},... {'Shi','Shift',-shiftRange,shiftRange,0,2*shiftRange+1} }; else parg = { {'GdB','Gain',-20,20,0,21},... {'Eff','Effect',0,3,0,4},... {'Shi','Shift',-shiftRange,shiftRange,0,2*shiftRange+1} }; end p = blockpanel(parg); % Setup blocktream try fs=block(source,varargin{:},'loadind',p,'L',bufLen); catch % Close the windows if initialization fails blockdone(p,fobj); err = lasterror; error(err.message); end if fs~=44100 error('%s: This demo only works with fs=44100 Hz.',upper(mfilename)); end p.setVisibleParam('Shi',0); oldEffect = 0; flag = 1; ffola = []; %Loop until end of the stream (flag) and until panel is opened while flag && p.flag gain = blockpanelget(p,'GdB'); gain = 10.^(gain/20); effect = blockpanelget(p,'Eff'); shift = fix(blockpanelget(p,'Shi')); effectChanged = 0; if oldEffect ~= effect effectChanged = 1; end oldEffect = effect; % Read block of data [f,flag] = blockread(); % Apply gain f=f*gain; if effect ==0 % Just plot spectrogram if effectChanged % Flush overlaps used in blockana and blocksyn p.setVisibleParam('Shi',0); % Now we can merrily continue end % Obtain DGT coefficients c = blockana(Fana, f); blockplot(fobj,Fana,c(:,1)); fhat = f; elseif effect == 1 % Robotization if effectChanged % Flush overlaps used in blockana and blocksyn p.setVisibleParam('Shi',0); % Now we can merrily continue end % Obtain DGT coefficients c = blockana(Frob, f); % Do the actual coefficient shift cc = Frob.coef2native(c,size(c)); if(strcmpi(source,'playrec')) % Hum removal (aka low-pass filter) cc(1:2,:,:) = 0; end c = Frob.native2coef(cc); c = abs(c); % Plot the transposed coefficients blockplot(fobj,Frob,c(:,1)); % Reconstruct from the modified coefficients fhat = blocksyn(Frob, c, size(f,1)); elseif effect == 2 % Whisperization if effectChanged p.setVisibleParam('Shi',0); % Now we can merrily continue end c = blockana(Fwhis, f); % Do the actual coefficient shift cc = Fwhis.coef2native(c,size(c)); if(strcmpi(source,'playrec')) % Hum removal (aka low-pass filter) cc(1:2,:,:) = 0; end c = Fwhis.native2coef(cc); c = abs(c).*exp(i*2*pi*randn(size(c))); % Plot the transposed coefficients blockplot(fobj,Fwhis,c(:,1)); % Reconstruct from the modified coefficients fhat = blocksyn(Fwhis, c, size(f,1)); elseif effect == 3 if effectChanged p.setVisibleParam('Shi',1); % Now we can merrily continue end % Obtain DGT coefficients c = blockana(Fa, f); % Do the actual coefficient shift cc = Fa.coef2native(c,size(c)); cTmp = zeros(size(cc),class(c)); if shift<0 slices = size(cc,2); for s = 1:slices phasecorrVect = phasecorrVect.*phaseCorr(:,-shift); cTmp(scaleTable(:,-shift),s,:) =... bsxfun(@times,cc(1:numel(scaleTable(:,-shift)),s,:),phasecorrVect); end elseif shift>0 slices = size(cc,2); for s = 1:slices phasecorrVect = phasecorrVect.*phaseCorr2(:,shift); cTmp(scaleTable2(:,shift),s,:) =... bsxfun(@times,cc(1:numel(scaleTable2(:,shift)),s,:),phasecorrVect); end %cc = [zeros(shift,size(cc,2),size(cc,3))]; else cTmp = cc; end c = Fa.native2coef(cTmp); % Reconstruct from the modified coefficients fhat = blocksyn(Fs, c, size(f,1)); [c2,fola] = blockana(Fa,fhat,fola); % Plot the transposed coefficients blockplot(fobj,Fa,c2(:,1)); elseif effect == 4 if effectChanged % Flush overlaps used in blockana and blocksyn p.setVisibleParam('Shi',0); % Now we can merrily continue end % Audio morphing effect [cff,ffola] = blockana(Fmorph, ffblocks(:,cidx), ffola); cidx = mod(cidx,size(ffblocks,2)) + 1; % Obtain DGT coefficients c = blockana(Fmorph, f); c = bsxfun(@times,abs(c),exp(1i*(angle(cff) ))); % Plot the transposed coefficients blockplot(fobj,Fmorph,c(:,1)); % Reconstruct from the modified coefficients fhat = blocksyn(Fmorph, c, size(f,1)); end % Enqueue to be played blockplay(fhat); blockwrite(fhat); end % Clear and close all blockdone(p,fobj); ltfat/inst/demos/demo_bpframemul.m0000664000175000017500000001455513026262303017173 0ustar susnaksusnakfunction demo_bpframemul %-*- texinfo -*- %@deftypefn {Function} demo_bpframemul %@verbatim %DEMO_BPFRAMEMUL Frame multiplier acting as a time-varying bandpass filter % % This demo demonstrates creation and effect of a Gabor multiplier. The % multiplier performs a time-varying bandpass filtering. The band-pass % filter with center frequency changing over time is explicitly created % but it is treated as a "black box" system. The symbol is identified by % "probing" the system with a white noise and dividing DGT of the output % by DGT of the input element-wise. The symbol is smoothed out by a 5x5 % median filter. % % Figure 1: The symbol of the multiplier. % % This figure shows a symbol used in the Gabor multiplier. % % Figure 2: Spectroram obtained by re-analysis of the test signal after applying the multiplier % % This figure shows a spectrogram of the test signal after applying % the estimated Gabor multiplier. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/demos/demo_bpframemul.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Sampling rate fs = 44100; % Input signal f = gspi; % Input length L = numel(gspi); % Initial center frequency of the band-pass filter fc = 5000; % Modulation parameter for the center frequency of the band-pass filter fvar = 4800; % Gabor system parameters win = {'tight','hann',882}; a = 200; M = 1000; % The bandpass filter chnges it's center frequency every 2*a samples Lch = ceil(L/(2*a)); L = Lch*2*a; % Center frequencies l = 0:Lch-1; l = l(:); fcm = fc+fvar*sin(2*pi*l/Lch*10); % Parameters of the bandpass filter G = 40; Q = 4; Ha = zeros(Lch,3); Hb = zeros(Lch,3); % Design a IIR peaking filters ... for l=1:Lch [Ha(l,:),Hb(l,:)]=parpeak(fcm(l),Q,G,fs); end % ...and make them band-pass filters. Ha = Ha/10^(G/20); % Create a white noise and divide it into input into blocks ff = randn(L,1); fblocks = reshape(ff,numel(ff)/Lch,Lch); % Do a blockwise filtering of the white noise y = blockfilter(fblocks,Ha,Hb); % Obtain DGT of the output ... cy = dgtreal(y(:),win,a,M); % And the input cx = dgtreal(fblocks(:),win,a,M); % Create a symbol by a plain division of DGT of the output and the input. % (This would be a deconvolution if Fourier multiplier was used) symbol = cy./cx; % Smooth out the extremes using a 2D 5x5 median filter symbol = cmedfilt2(symbol,[5,5]); % Plot the symbol figure(1); plotdgtreal(symbol,a,M,44100,'dynrange',50); % Apply the symbol to a test signal f = postpad(f,L); c = dgtreal(f,win,a,M); c = c.*symbol; fhat = idgtreal(c,win,a,M,L); % Plot spectrogram of the resulting signal figure(2); c = dgtreal(fhat,win,a,M); plotdgtreal(c,a,M,44100,'dynrange',50); % Filter the input signal by the time-varying band-pass filter directly y = blockfilter(reshape(f,numel(f)/Lch,Lch),Ha,Hb); % Export the signals (since we are in a function) assignin('base','forig', f(:)); assignin('base','fmul', fhat(:)); assignin('base','fdir', y(:)); disp('The original signal can be played by typing: sound(forig,44100);'); disp(['The signal obtained by a direct filtering cen be played by ',... '(this is what is approximated by the multiplier): sound(fdir,44100);']); disp(['The signal obtained by applying the Gabor multiplier: sound(fmul,44100);']); function y = blockfilter(fb,Ha,Hb) %BLOCKFILTER Block filtering y = zeros(size(fb)); Lch = size(fb,2); Z = zeros(2,1); for l=1:Lch [y(:,l),Z] = filter(Ha(l,:),Hb(l,:),fb(:,l),Z); end function fo = cmedfilt2(f,d) % CMEDFILT2 Complex 2D median filter if any(rem(d,2)~=1) error('%s: Median filer window should have odd dimensions.',... upper(mfilename)); end dims = size(f); if dims(1) < d(1) error('%s: Median filer height is bigger than the image height.',... upper(mfilename)); end if dims(2) < d(2) error('%s: Median filer width is bigger than the image width.',... upper(mfilename)); end fo = f; whalf = floor(d(2)/2); hhalf = floor(d(1)/2); % Safely inside of the image % The border values are taken from the input for ii=(1+hhalf):(dims(1)-hhalf) for jj=(1+whalf):(dims(2)-whalf) neigh = sort(reshape(f(ii-hhalf:ii+hhalf,jj-whalf:jj+whalf),[],1)); fo(ii,jj) = neigh(ceil(end/2)); end end % Top rows for ii=1:hhalf for jj=(1+whalf):(dims(2)-whalf) neigh = sort(reshape(f(1:ii+hhalf,jj-whalf:jj+whalf),[],1)); fo(ii,jj) = neigh(ceil(end/2)); end end % Top bottom rows for ii=1:hhalf for jj=(1+whalf):(dims(2)-whalf) neigh = sort(reshape(f(end+1-(ii+hhalf):end,jj-whalf:jj+whalf),[],1)); fo(end+1-ii,jj) = neigh(ceil(end/2)); end end % The leftmost and rightmost collumns are not processed... 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 Zolzer: Digital Audio Signal % Processing, 2nd Edition, ISBN: 978-0-470-99785-7 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 + 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 ltfat/inst/demos/demo_auditoryfilterbank.m0000664000175000017500000000725113026262303020736 0ustar susnaksusnak%-*- 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.github.io/doc/demos/demo_auditoryfilterbank.html} %@seealso{freqtoaud, audfiltbw, gammatonefir, ufilterbank, filterbankrealdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/mulaclab/0000775000175000017500000000000013026262303014316 5ustar susnaksusnakltfat/inst/mulaclab/octave_poly2mask.m0000664000175000017500000001727113026262303017766 0ustar susnaksusnak%-*- texinfo -*- %@deftypefn {Function} octave_poly2mask %@verbatim % Copyright (C) 2004 Josep Mones i Teixidor % % This program is free software; you can redistribute it and/or modify it under % the terms of the GNU General Public License as published by the Free Software % Foundation; either version 3 of the License, or (at your option) any later % version. % % This program is distributed in the hope that it will be useful, but WITHOUT % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or % FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more % details. % % You should have received a copy of the GNU General Public License along with % this program; if not, see . %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/mulaclab/octave_poly2mask.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % -*- texinfo -*- % @deftypefn {Function File} {@var{BW} = } poly2mask (@var{x},@var{y},@var{m},@var{n}) % Convert a polygon to a region mask. % % BW=poly2mask(x,y,m,n) converts a polygon, specified by a list of % vertices in @var{x} and @var{y} and returns in a @var{m}-by-@var{n} % logical mask @var{BW} the filled polygon. Region inside the polygon % is set to 1, values outside the shape are set to 0. % % @var{x} and @var{y} should always represent a closed polygon, first % and last points should be coincident. If they are not poly2mask will % close it for you. If @var{x} or @var{y} are fractional they are % nearest integer. % % If all the polygon or part of it falls outside the masking area % (1:m,1:n), it is discarded or clipped. % % This function uses scan-line polygon filling algorithm as described % in http://www.cs.rit.edu/~icss571/filling/ with some minor % modifications: capability of clipping and scan order, which can % affect the results of the algorithm (algorithm is described not to % reach ymax, xmax border when filling to avoid enlarging shapes). In % this function we scan the image backwards (we begin at ymax and end % at ymin), and we don't reach ymin, xmin, which we believe should be % compatible with MATLAB. % @end deftypefn % TODO: check how to create a logical BW without any conversion function BW = octave_poly2mask (x, y, m, n) if (nargin ~= 4) print_usage (); end % check x and y x = round (x (:).'); y = round (y (:).'); if (length (x) < 3) error ('poly2mask: polygon must have at least 3 vertices.'); end if (length (x) ~= length (y)) error ('poly2mask: length of x doesn''t match length of y.'); end % create output matrix BW = false (m, n); % close polygon if needed if ((x (1) ~= x (length (x))) || (y (1) ~= y (length (y)))) x = horzcat (x, x (1)); y = horzcat (y, y (1)); end % build global edge table ex = [x(1:length (x) - 1); x(1, 2:length (x))]; % x values for each edge ey = [y(1:length (y) - 1); y(1, 2:length (y))]; % y values for each edge idx = (ey(1, :) ~= ey(2, :)); % eliminate horizontal edges ex = ex (:, idx); ey = ey (:, idx); eminy = min (ey); % minimum y for each edge emaxy = max (ey); % maximum y for each edge t = (ey == [eminy; eminy]); % values associated to miny exvec = ex(:); exminy = exvec(t); % x values associated to min y exmaxy = exvec(~t); % x values associated to max y emaxy = emaxy.'; % we want them vertical now... eminy = eminy.'; m_inv = (exmaxy - exminy)./(emaxy - eminy); % calculate inverse slope ge = [emaxy, eminy, exmaxy, m_inv]; % build global edge table ge = sortrows (ge, [1, 3]); % sort on eminy and exminy % we add an extra dummy edge at the end just to avoid checking % while indexing it ge = [-Inf, -Inf, -Inf, -Inf; ge]; % initial parity is even (0) parity = 0; % init scan line set to bottom line sl = ge (size (ge, 1), 1); % init active edge table % we use a loop because the table is sorted and edge list could be % huge ae = []; gei = size (ge, 1); while (sl == ge (gei, 1)) ae = [ge(gei, 2:4); ae]; gei = gei - 1; end % calc minimum y to draw miny = min (y); if (miny < 1) miny = 1; end while (sl >= miny) % check vert clipping if (sl <= m) % draw current scan line % we have to round because 1/m is fractional ie = round (reshape (ae (:, 2), 2, size (ae, 1)/2)); % this discards left border of image (this differs from version at % http://www.cs.rit.edu/~icss571/filling/ which discards right % border) but keeps an exception when the point is a vertex. ie (1, :) = ie (1, :) + (ie (1, :) ~= ie (2, :)); % we'll clip too, just in case m,n is not big enough ie (1, (ie (1, :) < 1)) = 1; ie (2, (ie (2, :) > n)) = n; % we eliminate segments outside window ie = ie (:, (ie (1, :) <= n)); ie = ie (:, (ie (2, :) >= 1)); for i = 1:size(ie,2) BW (sl, ie (1, i):ie (2, i)) = true; end end % decrement scan line sl = sl - 1; % eliminate edges that eymax==sl % this discards ymin border of image (this differs from version at % http://www.cs.rit.edu/~icss571/filling/ which discards ymax). ae = ae ((ae (:, 1) ~= sl), :); % update x (x1=x0-1/m) ae(:, 2) = ae(:, 2) - ae(:, 3); % update ae with new values while (sl == ge (gei, 1)) ae = vertcat (ae, ge (gei, 2:4)); gei = gei - 1; end % order the edges in ae by x value if (size(ae,1) > 0) ae = sortrows (ae, 2); end end end % This should create a filled octagon %!demo %! s = [0:pi/4:2*pi]; %! x = cos (s) * 90 + 101; %! y = sin (s) * 90 + 101; %! bw = poly2mask(x, y, 200, 200); %! imshow (bw); % This should create a 5-vertex star %!demo %! s = [0:2*pi/5:pi*4]; %! s = s ([1, 3, 5, 2, 4, 6]); %! x = cos (s) * 90 + 101; %! y = sin (s) * 90 + 101; %! bw = poly2mask (x, y, 200, 200); %! imshow (bw); %!# Convex polygons %!shared xs, ys, Rs, xt, yt, Rt %! xs=[3,3,10,10]; %! ys=[4,12,12,4]; %! Rs=zeros(16,14); %! Rs(5:12,4:10)=1; %! Rs=logical(Rs); %! xt=[1,4,7]; %! yt=[1,4,1]; %! Rt=[0,0,0,0,0,0,0; %! 0,0,1,1,1,1,0; %! 0,0,0,1,1,0,0; %! 0,0,0,1,0,0,0; %! 0,0,0,0,0,0,0]; %! Rt=logical(Rt); %!assert(poly2mask(xs,ys,16,14),Rs); # rectangle %!assert(poly2mask(xs,ys,8,7),Rs(1:8,1:7)); # clipped %!assert(poly2mask(xs-7,ys-8,8,7),Rs(9:16,8:14)); # more clipping %!assert(poly2mask(xt,yt,5,7),Rt); # triangle %!assert(poly2mask(xt,yt,3,3),Rt(1:3,1:3)); # clipped %!# Concave polygons %!test %! x=[3,3,5,5,8,8,10,10]; %! y=[4,12,12,8,8,11,11,4]; %! R=zeros(16,14); %! R(5:12,4:5)=1; %! R(5:8,6:8)=1; %! R(5:11,9:10)=1; %! R=logical(R); %! assert(poly2mask(x,y,16,14), R); %!# Complex polygons %!test %! x=[1,5,1,5]; %! y=[1,1,4,4]; %! R=[0,0,0,0,0,0; %! 0,0,1,1,0,0; %! 0,0,1,1,0,0; %! 0,1,1,1,1,0; %! 0,0,0,0,0,0]; %! R=logical(R); %! assert(poly2mask(x,y,5,6), R); ltfat/inst/mulaclab/mulaclabinit.m0000664000175000017500000000166113026262303017144 0ustar susnaksusnakstatus = 2; %-*- texinfo -*- %@deftypefn {Function} mulaclabinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/mulaclab/mulaclabinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . status = 2; ltfat/inst/mulaclab/icons/0000775000175000017500000000000013026262276015442 5ustar susnaksusnakltfat/inst/mulaclab/icons/play.png0000664000175000017500000000111713026262276017115 0ustar susnaksusnakPNG  IHDRh6sRGBbKGD pHYs B(xtIME ,4K(IDAT(}RPݧJCD:OH Db"!xU(3"ad?*Ηsݟ5:쵲gdc.qG}G˲ eljbe2O!d>[VmNh\5 cjH$ q\Te^1h4t:LN8R !DݴVo8wJr%X.rc8uvkX\VZk*J$iBxl~l6a 2|߯T*cEQh4<[,PשzO~, c,2B|>,iZ6{ZUUUU~{$I IENDB`ltfat/inst/mulaclab/icons/colormap.png0000664000175000017500000000033513026262276017765 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  tIME oIDAT(cܼy3/nWƂ,:{SSDv憮A@ @!4 " oI D7iPzGjT4l޼y׮]5{GRIENDB`ltfat/inst/mulaclab/icons/stop.png0000664000175000017500000000100513026262276017131 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs B(xtIME )}[IDAT(}R;@12c2"O:9!A d$@{" rx#}4U݅,˂j&yvk۶\e0J+! dn( -N뺳lZZT*(4N1Ʀi"ba,Gbvv8n; 7xlt]0kZ{{xLFKeEB/|>|Ozm;MBclF\=RJzʼn4hĽlbਵN轋3!"D9ZEC8 ""R1>Bkȿn6YJSz66viZ)|6c^ax3a{!IENDB`ltfat/inst/mulaclab/icons/pan.png0000664000175000017500000000035113026262276016725 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  tIME d:{IDAT(ϕRI0 (k@zpdr9E1pgidrf0mJRͤF ul۵Fkg[#;ճZ5-Aݨ{{Rt_IENDB`ltfat/inst/mulaclab/icons/freehand.png0000664000175000017500000000123513026262276017725 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  tIME #mW</IDAT(}kpO_$Y۬e0Ej-@?L >xa`GD*U"tZvs[mm$>`?ϟ$ PU(\lyq<3UӵFn×꾮v>M͂$$uU?;{K$zfw=|/FE;rǟڊ"%YnN_ٝXtM<qe5Mk[<hO!OxY-6fVUUdE܍LF3j f ڪzNK$'HJ8X[F^f 8[,wT+?nL&ڬHD#$)kG96', )s0KS -߹06iwM&^IENDB`ltfat/inst/mulaclab/icons/resizebutton.png0000664000175000017500000000036413026262276020710 0ustar susnaksusnakPNG  IHDR s+sRGBbKGD pHYs  tIME*Q[tEXtCommentCreated with GIMPWOIDAT(ύ1 |ACC"ecf5DލI@IOrtWx!)@Ͻ׿r'cΒSIENDB`ltfat/inst/mulaclab/icons/zoomin.png0000664000175000017500000000116113026262276017462 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  ~tIME  lIDAT(ύkpƟI1tѭ)uN܏֕0cN;I^?xAAVvD=6cl2JN6oSu2|//,(Jr=%S@ o|i= sp|f1|x<I"|KUKqGGb<YYLOD25`LTzfzb Qo62IENDB`ltfat/inst/mulaclab/icons/magicwand.png0000664000175000017500000000110013026262276020072 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs B(xtIME  `CIDAT(υ[kawfs0ZWEP FßSDjR!E`AM&lo/`ߛgfV)Y 0Ҕ0.jXZAJY6!wsXkVCQat8m]'+Egƹ~|6 "ţ$B*Oϐ;D"&Dn|Y@ndF(Iጌ ! g(˔Ys_gB">Yu|i` %Pd/r)q;3vԂ/ҔD$GӝFӉ ~}urꓧ8P} BIB~}ygA?0q"LJ7n-t#h+^yAAQmck5lQe<`hݭ;{Е FIENDB`ltfat/inst/mulaclab/icons/union.png0000664000175000017500000000035013026262276017276 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  tIME +9zIDAT(R!0 ۦyAQ_22mge`cmG7Qe?y$壵vW'ԙPc[߰` Y^Sp fv1̩H! l_đ9*pSIENDB`ltfat/inst/mulaclab/icons/showsymbol.png0000664000175000017500000000036313026262276020360 0ustar susnaksusnakPNG  IHDRasRGB pHYs  tIME"WW$IDAT8哱 0 ֓' ;a5A<һ L V_0u~@.@s/zP$R/>={!j\\5/zo^V\|4D###@)D p_V CIENDB`ltfat/inst/mulaclab/icons/subbandsel.png0000664000175000017500000000030713026262276020272 0ustar susnaksusnakPNG  IHDRh6 pHYs B(xtIME#T۷DfIDAT(QA  [_H A!r[!Ֆz*:7y~Te2#$3O{wyfAKRDB #V^E2]Z -j$1IENDB`ltfat/inst/mulaclab/icons/difference.png0000664000175000017500000000030013026262276020233 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  tIME $QRIDAT(cܼy3)D05@/_T˗˗/Ԡ߼yjuuula <<<$x)I7IENDB`ltfat/inst/mulaclab/icons/zoomout.png0000664000175000017500000000114213026262276017662 0ustar susnaksusnakPNG  IHDRh6sRGB pHYs  ~tIME ) IDAT(ύOka7v%RR#b#Bk[=C#hdC5X UĢr0M*λ"5i8<3 , q~[&Sf1vee+9~ltQZ=,]I0QK{Nl}ntk2㴯*e QA B(9p\s6 @QaFqLinhwv|( 9<Ⓤ(EjTKɞE\|$Dh09zOdj{yC8#"">vd 5^wTioH 9_N_޼| e!+ֆ ߢ"W^z=p\.tvd(MLNs\{cP)q5;j˫s\P,@vdX:5crnFye5nl~j33ӅCt2ОP,M}d ȁѷ힀)IENDB`ltfat/inst/mulaclab/icons/apply.png0000664000175000017500000000144313026262276017277 0ustar susnaksusnakPNG  IHDRh6sRGBbKGD pHYs  tIME5ONIDAT(mOO`߾-mS(PYp`bg&w澃#y03.n0qPVL;=_I,ɀN(u1Lv㸉')N!Qʲ\.JM4b,{{3sx8 \.zѧ@ qMNzqh6P(ͦJ+r 8Af 0 i_TfETya,vg<aby,k00vftnl vM}w6MUUvy bz333HDUU\zb^cq|OIr4hȕX,0(9v,V\.(Cu (Ygn6pGW}IENDB`ltfat/inst/mulaclab/icons/loop.png0000664000175000017500000000106713026262276017125 0ustar susnaksusnakPNG  IHDRh6sRGBbKGD pHYs B(xtIME +ԁDIDAT(uR=@FG Y1 i4DcaX p tw XhruVj#:py!<{bsΜCeu]E1|8~8m/2PJ鴪Rt:u]WBzR;ϷmJ&xl14 !ZNS8r4HjTxE\.z{`}4m4)xߞP@Ac&_Տ$PJa2#]<(0 >{sR*IRc,rDt}!feYqt:=+L&JBP,sbjHa^3!Fx 0, pa{k} is an interior boundary of a polygon % with at least one hole. % hb : (Optional) logical array with hole flags for polygons in pb. % op : type of algebraic operation: % 'notb' : difference - points in polygon pa and not in polygon pb % 'and' : intersection - points in polygon pa and in polygon pb % 'xor' : exclusive or - points either in polygon pa or in polygon pb % 'or' : union - points in polygons pa or pb % ug : (Optional) conversion factor from user coordinates to % integer grid coordinates. Default is 10^6. % pc : cell array with the result(s) of the boolean set operation % of polygons pa and pb (can be more than one polygon) % hc : logical array with hole flags for each of the output % polygons. If hc(k) > 0, pc{k} is an interior boundary of a % polygon with at least one hole. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/mulaclab/polyboolclipper.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DISCLAIMER % This software was developed at the National Institute of Standards and % Technology by employees of the United States Federal Government in the % course of their official duties. Pursuant to title 17 Section 105 of % the United States Code this software is not subject to copyright % protection and is in the public domain. This software is an % experimental system. NIST assumes no responsibility whatsoever for its % use by other parties, and makes no guarantees, expressed or implied, % about its quality, reliability, or any other characteristic. % % Ulf Griesmann, June 2013 % ulf.griesmann@nist.gov, ulfgri@gmail.com % This function is based on the Clipper Library for C++ by Angus Johnson % http://www.angusj.com/delphi/clipper.php % The Clipper software is free software under the Boost software license. % Ulf Griesmann, NIST, August 2014 % check arguments if nargin < 3 error('polyboolclipper : expecting at least 3 arguments.'); end if nargin < 4, ha = []; end if nargin < 5, hb = []; end if nargin < 6, ug = []; end if isempty(ha), ha = logical(zeros(1,length(pa))); end if isempty(hb), hb = logical(zeros(1,length(pb))); end if isempty(ug), ug = 1e6; end if ~islogical(ha) || ~islogical(hb) error('polyboolclipper : hole flags must be logical arrays.'); end % prepare arguments if ~iscell(pa), pa = {pa}; end if ~iscell(pb), pb = {pb}; end % call polygon clipper [pc, hc] = polyboolmex(pa, pb, op, ha, hb, ug); end ltfat/inst/ltfatstop.m0000664000175000017500000000644013026262303014740 0ustar susnaksusnakfunction ltfatstop(varargin) %-*- 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.github.io/doc/ltfatstop.html} %@seealso{ltfatstart} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard, Zdenek Prusa %% PKG_DEL: ltfatstop('notbasepath') do_removebp = ~any(strcmpi('notbasepath',varargin)); dirlist = {}; jarsubpath = ['blockproc', filesep(), 'java', filesep(), 'blockproc.jar']; % Old versions of Matlab does not have "mfilename('fullpath')" pkg_folder = which(mfilename); % Kill the function name from the path. -3 for .m and / pkg_folder=pkg_folder(1:end-numel(mfilename)-3); d= dir(pkg_folder); % Take only valid directories d= {d(arrayfun(@(dEl) dEl.isdir && ~strcmp(dEl.name(1),'.'),d))}; basedir = {filesep()}; while ~isempty(d) for ii=1:numel(d{1}) name = d{1}(ii).name; dtmp = dir([pkg_folder basedir{1},name]); dtmp = dtmp(arrayfun(@(dEl) dEl.isdir && ~strcmp(dEl.name(1),'.'),dtmp)); if ~isempty(dtmp) d{end+1} = dtmp; basedir{end+1} = [basedir{1},name,filesep]; end if exist([pkg_folder,basedir{1},name,filesep(),lower(name),'init.m'],'file') dirtmp = [pkg_folder,basedir{1},name]; pathCell = regexp(path, pathsep, 'split'); if ispc % Windows is not case-sensitive onPath = any(strcmpi(dirtmp, pathCell)); else onPath = any(strcmp(dirtmp, pathCell)); end % Add to the list only if it is already in path if onPath dirlist{end+1} = [basedir{1},name]; end end end basedir(1) = []; d(1) = []; end % Remove directories from the path cellfun(@(dEl) rmpath([pkg_folder,dEl]),dirlist); % Remove the root dir pathCell = regexp(path, pathsep, 'split'); if ispc % Windows is not case-sensitive onPath = any(strcmpi(pkg_folder, pathCell)); else onPath = any(strcmp(pkg_folder, pathCell)); end % This can actually remove user hardcoded path to LTFAT's root. if onPath && do_removebp rmpath(pkg_folder); end % Clean the classpath if ~isempty(which('javaclasspath')) try jp = javaclasspath(); if any(strcmp([pkg_folder filesep() jarsubpath],jp)) javarmpath([pkg_folder, filesep(), jarsubpath]); end catch % Do nothing. At this point, user is most probably aware that % there is something wrong with the JAVA support. end end ltfat/inst/ltfatmex.m0000664000175000017500000004242413026262303014546 0ustar susnaksusnakfunction 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. % Please see INSTALL-Matlab or INSTALL-Octave for the requirements. % % 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. % % 'pbc' Perform action on the PolyBoolClipper 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. % % Other: % % 'verbose' Print action details. % % 'debug' Build a debug version. This will disable compiler % optimizations and include debug symbols. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/ltfatmex.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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','pbc','playrec','java','blockproc'}; % This has to be also defined definput.flags.comptarget={'release','debug'}; definput.flags.command={'compile','clean','test'}; definput.flags.verbosity={'noverbose','verbose'}; s = which('ltfatarghelper'); if strcmpi(mexext,s(end-numel(mexext)+1:end)) % We must avoid calling corrupt ltfatarghelper.mexext % The following must not fail try ltfatarghelper({},struct(),{}); catch if any(strcmpi('verbose',varargin)) fprintf('Removing corrupt ltfatarghelper.%s',mexext); end delete(s); % Now there is just a ltfatarghelper.m end end [flags,kv]=ltfatarghelper({},definput,varargin); % 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 PolyBoolClipper.mex do_pbc = flags.do_pbc || flags.do_auto; % 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 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,'libltfat',filesep,'ltfatcompat']); callmake(make_exe,makefilename,'target','clean',flags.verbosity); %[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,flags.verbosity); %[status,result]=system([make_exe, ' -f ',makefilename,' clean',... % ' EXT=',ext]); end; if do_pbc % Use the correct makefile makefilename_pbc = makefilename; if isoctave if ~strcmpi(makefilename(end-2:end),ext) makefilename_pbc = [makefilename,ext]; end end disp('========= Cleaning PolyBoolClipper ===================='); cd([bp,'thirdparty',filesep,'polyboolclipper']); clear mex; callmake(make_exe,makefilename_pbc,'target','clean','ext',mexext,flags.verbosity); %[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,flags.verbosity); end; if do_java disp('========= Cleaning JAVA ================'); cd([bp,'blockproc',filesep,'java']); %[status,result]=system([make_exe,' clean']); callmake(make_exe,[],'target','clean',flags.verbosity); end; cd(curdir); end; % -------------- Handle compiling -------------------------------- if flags.do_compile if do_lib disp('========= Compiling libltfat =============='); cd([bp,'libltfat',filesep,'ltfatcompat']); 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,flags.verbosity,... 'comptarget',flags.comptarget); 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,... flags.verbosity,... 'comptarget',flags.comptarget); if(~status) disp('Done.'); else error('Failed to build %s interfaces: %s \n',upper(extname),result); end end; if do_pbc makefilename_pbc = makefilename; if isoctave if ~strcmpi(makefilename(end-2:end),ext) makefilename_pbc = [makefilename,ext]; end end disp('========= Compiling PolyBoolClipper ==================='); % Compile PolyBoolClipper mex file for use with mulaclab cd([bp,'thirdparty',filesep,'polyboolclipper']); clear mex; [status,result] = callmake(make_exe,makefilename_pbc,'matlabroot','arch',... 'ext',ext,flags.verbosity); if(~status) disp('Done.'); else error('Failed to build PlyBoolClipper:\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 installation 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 installation.\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,'extra','HAVE_PORTAUDIO',... flags.verbosity); 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,'Makefile',flags.verbosity); 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 install 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 installation.\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.comptarget=[]; definput.keyvals.portaudio=[]; definput.keyvals.extra=[]; definput.flags.verbosity={'noverbose','verbose'}; [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.comptarget) && ~strcmpi(kv.comptarget,'release') systemCommand = [systemCommand, ' COMPTARGET=',kv.comptarget]; end if ~isempty(kv.extra) systemCommand = [systemCommand, ' ',kv.extra,'=1']; end if ~isempty(kv.target) systemCommand = [systemCommand,' ',kv.target]; end if flags.do_verbose fprintf('Calling:\n %s\n\n',systemCommand); end [status,result]=system(systemCommand); if flags.do_verbose && ~isoctave disp(result); end ltfat/inst/ltfathelp.m0000664000175000017500000000607413026262303014706 0ustar susnaksusnakfunction 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.github.io/doc/ltfathelp.html} %@seealso{ltfatstart} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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@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; ltfat/inst/ltfatbasepath.m0000664000175000017500000000225713026262303015544 0ustar susnaksusnakfunction 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.github.io/doc/ltfatbasepath.html} %@seealso{ltfatstart} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . f=mfilename('fullpath'); bp = f(1:end-13); ltfat/inst/ChangeLog0000664000175000017500000004363213026262276014331 0ustar susnaksusnakVersion 2.2.0 24/12 2016 * New Gabor window generating functions: ptpfun, ptpfundual, pebfun, pebfundual * New filterbank functions: filterbankscale, ifilterbankiter * New window and filter generating functions: freqwin, freqfilter * New functions for changing DGT phase convention: phaselockreal, phaseunlockreal * Included new colormaps: ltfat_inferno, ltfat_magma, ltfat_plasma, ltfat_viridis, ltfat_nicecolormap * erbfilters and audfilters can now generate Gammatone and other filters * Removed deprication warnings in test_all_ltfat * Mulaclab no longer requires the Image processing toolbox to be installed (for the basic functionality). * Mulaclab now works on GNU Octave (thanks to Florent Jaillet). Version 2.1.2 x/3 2016 * Improved functions for DGT and DGTREAL phase reconstruction: constructphase, constructphasereal * The backend library is now in separate repository: https://github.com/ltfat/libltfat and it is included as a subtree in subdirectory libltfat/ (replacing src/) Version 2.1.1 x/10 2015 * New function for computing higher order phase derivatives: gabphasederiv * New function doing the adjustable reassignment: gabreassignadjust * New function for the Gabor transform phase reconstruction: constructphase, constructphasereal * New filterbank-generating function: audfilters * New generic quadratic TF distribution function: quadtfdist * New functions for reading and writing wav files (since wavread and wavwrite were removed in Matlab 2015b): wavload, wavsave (taken from VOICEBOX http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html) * Added 'nojava' flag to ltfatstart to optionally disable adding the blockproc JAVA classes to the classpath. * Updated the lBFGS method in frsynabs according to the new paper. * Fixed bug in gabphasegrad which prevented it from being used with any window other than Gaussian. * Fixed bug in comp_ifilterbank_fftbl for non-painless filterbanks. Version 2.1.0 6/5 2015 * New filterbank-generating function: warpedfilters * New filterbank spectrogram reassignment function: filterbankreassign * ltfatarghelper is now also implemented as a MEX file. * The block function can now handle synchronized simultaneous playback and recording. E.g. {'rec','file.wav'} plays a wav file while recording. This is different from the option 'playrec', which works the "other way" i.e. it records and play the recorded. * Function framebounds(...,'iter') now uses pcg to represent the inverse of the frame operator when calculating the lowest eigenvalue using eigs. * Added implementation of some quadratic time-frequency representations: Rihaczek, Wigner-Ville * Fixed #112 (Sourceforge): Octave package now compiles on Windows (mxe version) thanks to John Donoghue. * Related to #111 (Sourceforge): Wavelet filters were hand-centered around the origin. * comp_filterbank, comp_ifilterbank and ltfatarghelper can be compiled as MEX files on Octave. Version 2.0.1 8/10 2014 (released only at Octave-Forge) * Included test suite. Version 2.0.0 7/10 2014 * Fixed bug in filterbankdual and filterbankrealdual for the uniform case. Also the routines are now much faster. * Added possibility to force treatment of a filterbank as a painless filterbank using 'forcepainless' flag in filterbank(real)dual routines. * Fixed bug in comp_ifilterbank MEX causing crashes for mixed type filterbanks. * Added implementation of dual-tree wavelet transform, general dual-tree wavelet filterbanks and *M*-band transforms. * New dual-tree wavelet filters: wfiltdt_qshift, wfiltdt_oddeven, wfiltdt_optsym, wfiltdt_dden * New regular DWT filters: wfilt_symorth, wfilt_symtight * wfilt_ functions now return filters in a format compatible with LTFAT filter format (struct with .h and .offset fields). * Closed #100 FEATURE: Add on-the-fly sample rate conversion to the blockproc framework. It effectivelly allows recording and playback at arbitrary sampling rates. * Added support for cross-compilation (src/Makefile_crossmingw): Producing Windows binaries on an Unix system using MXE (http://mxe.cc/). Works only with MEX files for Matlab. * Blockproc. framework now supports any sampling rate from interval 4-96kHz trough on-the-fly resampling in the background. * Fixed compilation issue with gcc 4.7. Version 1.4.5 7/5 2014 * Phase locking in DGT ('timeinv' flag) moved to the C backend. It was too slow in Octave. * Added franabp - solving a basis pursuit problem argmin ||c||_1 s.t. Fc = f for an arbitrary frame F. * The lambda parameter in franabp and franalasso can now be a vector. => thresh acceps such lambda too. * New demos to accompany the LTFAT 2.0 paper: demo_filterbanks, demo_wavelets, demo_wfbt, demo_bpframemul, demo_phaseret * New blockproc demo: demo_blockproc_effects * blockproc framework can be now used offline without a single call to the playrec MEX. * Closed #49: blockwrite method. Allows blockwise storage of audio data to a wav file. * All wavelet routines were correctly included in the frames framework. Correct computation of canonical dual and tight frames for undecimated wavelet filterbanks. * New wrapper frame types in the frames framework: erbletfb, cqtfb * Removed demo_blockproc_pitchshift. It is now part of demo_blockproc_effects. * Removed some esoteric wavelet filters. 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 ltfat/inst/auditory/0000775000175000017500000000000013026262303014376 5ustar susnaksusnakltfat/inst/auditory/audfiltbw.m0000664000175000017500000000644713026262303016550 0ustar susnaksusnakfunction bw = audfiltbw(fc,varargin) %-*- texinfo -*- %@deftypefn {Function} audfiltbw %@verbatim %AUDFILTBW Bandwidth of auditory filter % Usage: bw = audfiltbw(fc) % % AUDFILTBW(fc) returns the critical bandwidth of the auditory filter % at center frequency fc defined in equivalent rectangular bandwidth. % The function uses the relation: % % bw = 24.7 + fc/9.265 % % as estimated in Glasberg and Moore (1990). This function is also used % when the original ERB scale ('erb83') is chosen. % % AUDFILTBW(fc,'bark') returns the critical bandwidth at fc according % to the Bark scale using the relation: % % bw = 25 + 75 ( 1+1.4*10^{-6} fc^2 )^0.69 % % as estimated by Zwicker and Terhardt (1980). % % For the scales 'mel', 'mel1000', 'log10' and 'semitone', no critical % bandwidth function is usually given. Following the example of the % equivalent rectangular bandwidth (associated with the ERB scale), we % use the derivative of the inverse of the scale function F_{Scale}, % evaluated at F_{Scale}(fc), i.e. % % bw = (F_{scale}^{-1})'(F_{scale}(fc)) % % % References: % E. Zwicker and E. Terhardt. Analytical expressions for criticalband % rate and critical bandwidth as a function of frequency. The Journal of % the Acoustical Society of America, 68(5):1523--1525, 1980. [1]http ] % % B. R. Glasberg and B. Moore. Derivation of auditory filter shapes from % notched-noise data. Hearing Research, 47(1-2):103, 1990. % % References % % 1. http://scitation.aip.org/content/asa/journal/jasa/68/5/10.1121/1.385079 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/auditory/audfiltbw.html} %@seealso{freqtoerb, erbspace, freqtoaud, audtofreq} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard % ------ Checking of input parameters --------- % error(nargchk(1,1,nargin)); if nargin<1 error('%s: Too few input parameters.',upper(mfilename)); end; if ~isnumeric(fc) || any(fc(:)<0) error('AUDFILTBW: fc must be non-negative.'); end; definput.flags.audscale={'erb','erb83','bark','mel','mel1000','log10','semitone'}; [flags,kv]=ltfatarghelper({},definput,varargin); % ------ Computation -------------------------- % FIXME: What is the upper frequency for which the estimation is valid? if flags.do_erb || flags.do_erb83 bw = 24.7 + fc/9.265; end if flags.do_bark bw = 25 + 75*(1 + 1.4E-6*fc.^2).^0.69; end if flags.do_mel bw = log(17/7)*(700+fc)/1000; end if flags.do_mel1000 bw = log(2)*(1+fc/1000); end; if flags.do_log10 || flags.do_semitone bw = fc; end ltfat/inst/auditory/audtofreq.m0000664000175000017500000000454313026262303016554 0ustar susnaksusnakfunction 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.github.io/doc/auditory/audtofreq.html} %@seealso{freqtoaud, audspace, audfiltbw} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; freq = sign(aud).*14675.*(1-exp(0.0895255*abs(aud)))./(exp(0.0895255*abs(aud)) - 47.0353); end; if flags.do_freq freq=aud; end; if flags.do_log10 || flags.do_semitone freq = 10^(aud); end ltfat/inst/auditory/erbspace.m0000664000175000017500000000237613026262303016350 0ustar susnaksusnakfunction [y,bw] = erbspace(fmin,fmax,n) %-*- texinfo -*- %@deftypefn {Function} erbspace %@verbatim %ERBSPACE Equidistantly spaced points on erbscale % Usage: y=erbspace(fmin,fmax,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.github.io/doc/auditory/erbspace.html} %@seealso{audspace, freqtoaud} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard [y,bw] = audspace(fmin,fmax,n,'erb'); ltfat/inst/auditory/rangecompress.m0000664000175000017500000000473213026262303017432 0ustar susnaksusnakfunction [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.github.io/doc/auditory/rangecompress.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/auditory/rangeexpand.m0000664000175000017500000000413613026262303017054 0ustar susnaksusnakfunction 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.github.io/doc/auditory/rangeexpand.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/auditory/freqtoerb.m0000664000175000017500000000236113026262303016547 0ustar susnaksusnakfunction 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.github.io/doc/auditory/freqtoerb.html} %@seealso{freqtoaud, demo_audscales} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard erb = freqtoaud(freq,'erb'); ltfat/inst/auditory/semiaudplot.m0000664000175000017500000000520513026262303017104 0ustar susnaksusnakfunction 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.github.io/doc/auditory/semiaudplot.html} %@seealso{freqtoaud} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/auditory/erbspacebw.m0000664000175000017500000000256113026262303016675 0ustar susnaksusnakfunction [y,n] = erbspacebw(fmin,fmax,varargin) %-*- texinfo -*- %@deftypefn {Function} erbspacebw %@verbatim %ERBSPACEBW Erbscale points specified by bandwidth % Usage: y=erbspacebw(fmin,fmax,bw,hitme); % y=erbspacebw(fmin,fmax,bw); % y=erbspacebw(fmin,fmax); % % 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.github.io/doc/auditory/erbspacebw.html} %@seealso{audspacebw, freqtoaud} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard [y,n] = audspacebw(fmin,fmax,varargin{:},'erb'); ltfat/inst/auditory/erbtofreq.m0000664000175000017500000000272513026262303016553 0ustar susnaksusnakfunction 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.github.io/doc/auditory/erbtofreq.html} %@seealso{audtofreq, freqtoaud} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard freq = audtofreq(erb,'erb'); ltfat/inst/auditory/gammatonefir.m0000664000175000017500000001266013026262303017232 0ustar susnaksusnakfunction 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 : max. filter length. % 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 with length at most n, 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. The actual length of the inpulse response % depends on fc (the filter is longer for low center frequencies), % fs and betamul but it is never bigger than n. % % 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^(4-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.github.io/doc/auditory/gammatonefir.html} %@seealso{erbspace, audspace, audfiltbw, demo_auditoryfilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/auditory/auditoryinit.m0000664000175000017500000000164613026262303017307 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} auditoryinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/auditory/auditoryinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/auditory/Contents.m0000664000175000017500000000346013026262303016354 0ustar susnaksusnak% LTFAT - Simple auditory processing % % Peter L. Soendergaard, 2011 - 2016 % % 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 visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/auditory/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/auditory/audspace.m0000664000175000017500000000503513026262303016344 0ustar susnaksusnakfunction [y,bw] = audspace(fmin,fmax,n,varargin) %-*- texinfo -*- %@deftypefn {Function} audspace %@verbatim %AUDSPACE Equidistantly spaced points on auditory scale % Usage: y=audspace(fmin,fmax,n,scale); % % AUDSPACE(fmin,fmax,n,scale) computes a vector of length n* % containing values equidistantly scaled on the selected auditory scale % between the frequencies fmin and fmax. 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.github.io/doc/auditory/audspace.html} %@seealso{freqtoaud, audspacebw, audfiltbw} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard %% ------ Checking of input parameters --------- if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; % Default parameters. if ~isnumeric(fmin) || ~isscalar(fmin) error('%s: fmin must be a scalar.',upper(mfilename)); end; if ~isnumeric(fmax) || ~isscalar(fmax) error('%s: fmax 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 fmin>fmax error('%s: fmin must be less than or equal to fmax.',upper(mfilename)); end; definput.import={'freqtoaud'}; [flags,kv]=ltfatarghelper({},definput,varargin); %% ------ Computation -------------------------- audlimits = freqtoaud([fmin,fmax],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)=fmin; y(end)=fmax; ltfat/inst/auditory/audspacebw.m0000664000175000017500000000705513026262303016701 0ustar susnaksusnakfunction [y,n] = audspacebw(fmin,fmax,varargin) %-*- texinfo -*- %@deftypefn {Function} audspacebw %@verbatim %AUDSPACEBW Auditory scale points specified by bandwidth % Usage: y=audspacebw(fmin,fmax,bw,hitme); % y=audspacebw(fmin,fmax,bw); % y=audspacebw(fmin,fmax); % [y,n]=audspacebw(...); % % AUDSPACEBW(fmin,fmax,bw,scale) computes a vector containing values % equistantly scaled between frequencies fmin and fmax 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 fmin and fmax. % % See the help on FREQTOAUD to get a list of the supported values of the % scale parameter. % % AUDSPACEBW(fmin,fmax,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.github.io/doc/auditory/audspacebw.html} %@seealso{freqtoaud, audspace, audfiltbw} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard % ------ Checking of input parameters --------- if nargin<2 error('%s: Too few input parameters.',upper(mfilename)); end; if ~isnumeric(fmin) || ~isscalar(fmin) || fmin<0 error('%s: fmin must be a non-negative scalar.',upper(mfilename)); end; if ~isnumeric(fmax) || ~isscalar(fmax) || fmax<0 error('%s: fmax must be a non-negative scalar.',upper(mfilename)); end; if fmin>fmax error('%s: fmin must be less than or equal to fmax.',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([fmin,fmax],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 fmin and fmax. 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([fmin,fmax,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); ltfat/inst/auditory/freqtoaud.m0000664000175000017500000001231713026262303016552 0ustar susnaksusnakfunction 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.github.io/doc/auditory/freqtoaud.html} %@seealso{freqtoaud, audspace, audfiltbw} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 = 11.17*sign(freq).*(log((abs(freq)+312)./(abs(freq)+14675)) ... - log(312/14675)); end; if flags.do_freq aud = freq; end; if flags.do_log10 || flags.do_semitone aud = log10(freq); end ltfat/inst/mulaclab.m0000664000175000017500000043553513026262303014513 0ustar susnaksusnakfunction [] = mulaclab(file, varargin) %-*- texinfo -*- %@deftypefn {Function} mulaclab %@verbatim %MULACLAB Graphical interface for audio processing using frame multipliers % Usage: mulaclab; % mulaclab(filename); % mulaclab(signal, fs); % % Input parameters: % filename : File name of the signal to process. % signal : Signal to process, which must be a vector. % fs : Sampling frequency of the signal. % % When starting MULACLAB without any input parameter, the user is asked to % choose the processed signal, named original signal in the interface. % % Possible signals are .wav files and .mat files containing decompositions % preliminarily saved using the MULACLAB interface. The interface only % handles monochannel signals. So for multichannel .wav files, the first % channel is used as the original signal. % % Optionnaly, the file name of the original signal can be directly passed as % an input parameter. The original signal can also be directly passed as a % vector along its sampling frequency. % % After choosing the original signal, the user is presented with the main % interface. This interface is divided in two areas: % % The right part of the figure contains the visualizations, which % represent the spectrograms of the original and modified signals. % % The 'Original signal' visualization is used to display the original % signal spectrogram and to graphically define the symbol of the frame % multiplier that will be applied on this signal. % % The 'Overview of original signal' visualization also represents the % original signal spectrogram and can be used for fast zooming and moving % of the other visualizations. Zooming and moving is controlled by mouse % interaction with the white rectangle displayed on this visualization. % % The 'Modified signal' visualization is used to display the spectrogram % of the modified signal after application of the multiplier. % % It is possible to hide the 'Overview of original signal' and 'Modified % signal' visulizations using the 'Visualization' menu. % % The left part of the figure contains panels with tools for user % interaction. % % The 'Audioplayer' panel contains the controls for audio playback of the % original and modified signal. % % The 'Visualization' panel contains tools used to adapt the display % of the visualizations. % % The 'Selection' panel contains tools and information concerning the % multilayered selection used to graphically specify the symbol of the % multiplier. % % Known MATLAB limitations: % % When using MATLAB on Linux with multiple screens, there might be a % MATLAB bug preventing the display of the multiplier symbol. This can be % solved by docking the figure. % % When using a MATLAB version prior to 7.3 (R2006b), the rectangle % displayed on the 'Overview of original signal' visualization is not % automatically updated when using the zoom and pan tools of the 'Zoom' % panel. It can be manually updated by re-clicking on the currently % selected tool or by changing the current tool. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/mulaclab.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %AUTHOR: Florent Jaillet % Known bugs: % - There might be a bug with noise level when using selection layers of type % hole filling with noise. % Something really strange is hapenning, for a given selection we will have a % level which is too low, when everything works nicely with a slightly % modified version of the selection. % - when using undo it seems that parameters of the type of layer are not % updated % % Acronym used in the comments: % PI: possible improvement, used to specify things that could be done to % improve the current version of mulaclab. In particular, it can be % efficiency improvements or suitable functionnality addition. % % Some PI : % - add possibility to see an individual atom of the frame (and the dual) % (with right clic menu?) % - possibility to have a nice view (3D?) of the symbol % - possibility to choose the channel and a time selection of wave files % - switch between original and modified when audio playing without stopping % playback % - add editable keyboard shortcuts for almost everything % - add something to show that a processing is currently running % (progressbar? change of mouse pointer?) % - give possibility to use a Gaussian window % - update information of contextual menu for layers to know what are the % currently selected properties % - add possibility to modify afterward the polygons % List of functions used from the image toolbox : % bwselect: used for the magic wand. % In Octave, uses bwfill which is written in c++ % imdilate: used to convert layers of type fill and fillNoise. % In Octave, uses imerode which is written in c++ % _____________________ Description of shared data ________________________ % % Mulaclab was initially developped only for MATLAB as Octave was at that time % missing the needed features to build advanced GUIs. % % In this original version, nested functions were used to share data among GUI % callbacks and a set of variables where defined at the top level of the % mulaclab function to share the data between the GUI components. % % With its version 4.0.0, Octave gained most of the GUI features needed by % mulaclab, so mulaclab was then adapted to work on both MATLAB and Octave. % % But Octave 4.0.0 doesn't support the use of nested functions in GUI callbacks. % So the new version of mulaclab now uses global variables to share data % among GUI callbacks (even if it's not an elegant solution, but we do with the % limitations that we face...) . % % Here is a list of these global variables with their description: % NOTE: This list has not been fully updated with the evolution of the mulaclab % code. So it misses the description of some shared variables introduced later % in the developement and might be incomplete and inaccurate in some places. % % sig: (struct) data describing the processed signal % % - sig.ori: (vector) samples of the original signal % % - sig.mod: (vector) samples of the modified signal % % - sig.sampFreq: (scalar) sampling frequency of the original and modified % signals % % - sig.real: (bool) boolean to know if the signal is real (true) % or complex (false) % % frame: (struct) data describing the frame % % - frame.type: (string) type of the frame (currently only Gabor frames are % implemented, other frames could be added, like wavelet frames, % nonstationnary Gabor frames, nonuniform filterbanks, general frames) % % - frame.def: (struct) data defining the frame (fields depend of the % frame type) % % For Gabor frames, frame.def fields are: % - frame.def.winType: (string) type of window as defined in the firwin % function of LTFAT, see parameter 'name' in the help of firwin % function for details % % - frame.def.winLen: (scalar) window length in number of samples % % - frame.def.hop: (scalar) hop size (ie Gabor frame time shift) in % number of samples (parameter 'a' of LTFAT dgt function) % % - frame.def.nbFreq: (scalar) number of frequency bins (parameter 'M' % of LTFAT dgt function) % % coeff: (struct) coefficients obtained by decomposition of the signal % on the frame % % - coeff.ori: (matrix, dimension 1: frequency, dimension 2:time) % coefficients for the original signal sig.ori % % - coeff.mod: (matrix, dimension 1: frequency, dimension 2:time) % coefficients for the modified signal sig.mod % % - coeff.oriC: (matrix, dimension 1: frequency, dimension 2:time) % plotted spectrogram as image in DB % % - coeff.info: (struct) % additonal data necesary for the reconstruction % % sel: (struct) data describing the graphical selection % The graphical selection contains several layers, each layer containing % several polygons defining a region of the time-frequency that must be % modified. These polygons can be drawn freely by the user using the two % available tools (freehand selection and magic wand). % sel contains data defining these polygons and layers, and data % specifying how they should be plotted % % - sel.mode: (string) specifies how the next polygon drawn by the user % must be combined with the polygons already defined in the currently % edited layer % possible modes are 'union', 'intersection', 'difference' % % - sel.curLay: index of the currently edited layer % % - sel.lay: (struct) data describing the layers, it's a vector of struct, % and sel.lay(ind) contains data for layer number ind % % - sel.lay.convType: (string) conversion type of the layer, it specifies % how the values of the symbol must be computed for the current layer, % possible types are: % % 'constGain': apply a constant gain on the whole time-frequency region % corresponding to the polygons of the layer % % 'smoothBorder': also apply a gain on the region corresponding to the % polygons of the layer, but the gain values are smoothed at the border % to go linearly from 1 outside the polygons to the gain value % specified for the layer inside the polygons % % 'fill': try to fill the region corresponding to the polygons of the % layer according to the neighborhood level, this is done by % replacing the absolute value of the coefficient inside the polygons % by the interpolated values using the level of the coefficient in a % specified neigborhood outside the polygons % the phase of the coefficients are left unchanged % % 'fillNoise': same as 'fill', but the coefficients inside the polygons % of the layers are replaced by coefficients obtained from a noise and % multiplied by the interpolated absolute values % % - sel.lay.param: (struct) parameters for the conversion of the layer, % it's a struct array, sel.lay(indLay).param(indParam) defines the % parameter number indParam of the layer number indLay % the number of parameters and their nature depends of the convType % parameter of the layer according to the following: % % * if convType is 'constGain': only one parameter named 'Gain' is % defined and it contain the value of the constant gain applied to % region corresponding to the polygons of the layer % % * if convType is 'smoothBorder': two parameters named 'Gain' and % 'Border' are defined % 'Gain' contain the value of the gain applied inside region % corresponding to the polygons of the layer away from the border % 'Border' specify the distance from the border (in number of % coeffiicents) in which the gain value is linearly interpolated % between 1 and the value given by 'Gain' % % * if convType is 'fill' or 'fillNoise' : two parameters 'Height' and % 'Width' are defined % these parameters specifiy the size of the ellipse used to define % the size of the neighborhood used the estimate the level around the % polygons % 'Height' is the radius (in number of coefficients) of the ellipse % along frequency (y axis), and 'Width' is the radius (in number of % coefficients) of the ellipse along time (x axis) % % - sel.lay.param.name: (string) name of the parameter, as displayed % in the GUI under the layer list % % - sel.lay.param.val: (scalar) the value of the parameter % % - sel.lay.lineWidth: (scalar) width of the lines representing the % polygons of the layer % % - sel.lay.color: (colorspec) color of the lines representing the % polygons of the layer % % - sel.lay.marker: (string) marker type of the lines representing the % polygons of the layer % % - sel.lay.markerSize: (scalar) marker size of the lines representing % the polygons of the layer % % - sel.lay.lineStyle: (string) line style of the lines representing the % polygons of the layer % % - sel.lay.poly: (struct) data defining the polygons of the layer, it's % a struct array, sel.lay(indLay).poly(indPoly) defines the % polygon number indPoly of the layer number indLay % % - sel.lay.poly.x: (row vector) x-coordinates (ie time-coordinates) % of the polygon points % % - sel.lay.poly.y: (row vector) y-coordinates (ie % frequency-coordinates) of the polygon points % % - sel.lay.poly.hole: (bool) specifies if the polygon is a hole % % - sel.lay.poly.id: (graphics object handle) handle to the line % representing the polygon % % - sel.lay.label: (string) layer label as displayed in the layer list in % the GUI % % % visu: (struct) data defining parameters of the visualizations % visu is a struct array, visu(ind) contains data for the visualization % number ind. % The visualizations are the representations plotted on the right part of % the GUI. They are plotted in the order specified by visu from top to % bottom, that is to say that visu(1) is plotted on top, visu(2) is plotted % under visu(1) and so on. % PI: Currently only three visualizations are available: the spectrogram % of the original signal (used as the support for graphical definition of % the multiplier), the spectrogram of the modified signal to observe the % effect of the multiplier, and an overview spectrogram of the original % signal for fast navigation in the time-frequency plane. % But it should be easy to add some new visualizations if needed. To add a % new visualization, adding an element to vector visu with appropriate % parameters and implementing the associated updating function should be % enough. If the possibility to show and hide the new visualization is % also needed, some handling of it in the menu is also required. % % - visu.label: (string) the title appearing on top of the visualization % % - visu.height: (scalar) number specifying the height of the % visualization. It is a number between 0 and 1 specifying the ratio of % the figure height that should be used for each visualisation. To cover % the whole figure, values should be chosen so that they sum up to 1 when % considering all the visible visualizations % % - visu.position: (vector) the position vector of the uipanels containing % the visualizations. It is automatically computed by function resize % using the values of visu.height. % % - visu.updateFcn: (function handle) the handle of the function that must % be used to update the plot of the visualization % % - visu.dynamic: (scalar) colorscale dynamic of the visualization % (positive number in dB) % % - visu.visible: (bool) boolean specifying if the visualization is % visible and must be plotted (true) or not (false) % % - visu.linkX: (bool) boolean specifying if the visualization x axe (time % axe) must be linked with the one of the other visualizations % % - visu.linkY: (bool) boolean specifying if the visualization y axe % (frequency axe) must be linked with the one of the other visualizations % % - visu.linkCLim: (bool) boolean specifying if the visualization % colorscale limits must be linked with the one of the other varargin % visualizations % % - visu.uipanelId: (graphics object handle) handle of the uipanel % containing the visualization % % - visu.axesId: (graphics object handle) handle of the axes of the % visualization % % gui: (struct) graphical user interface data % gui contains data used to define properties of certain graphics object % (in particular their position) and data used to dynamically handle the % inferface (in particular many graphics object handles) % % - gui.mainFigPos: (4x1 vector) position of the main figure using the % usual matlab position definition of the form [left bottom width height] % % - gui.fontSize: (scalar) font size (in points) for the elements appearing % in the panels on the left part of the interface % % - gui.textHeight: (scalar) height (in number of pixels) for text % uicontrol appearing in the panels on the left part of the interface % % - gui.textWidth: (scalar) width (in number of pixels) for text % uicontrol appearing in the panels on the left part of the interface % % - gui.editWidth: (scalar) width (in number of pixels) for edit % uicontrol appearing in the panels on the left part of the interface % % - gui.buttonBackgroundColor: (colorspec) background color used for % uicontrol appearing in the panels on the left part of the interface % % - gui.buttonWidth: (scalar) width (in number of pixels) for button % uicontrol appearing in the panels on the left part of the interface % % - gui.buttonHeight: (scalar) height (in number of pixels) for button % uicontrol appearing in the panels on the left part of the interface % % - gui.horiDist: (scalar) horizontal distance (in number of pixels) % between two elements appearing in the panels on the left part of the % interface % % - gui.vertDist: (scalar) vertical distance (in number of pixels) % between two elements appearing in the panels on the left part of the % interface % % - gui.margin: (1x2 vector) distance from the border of the panel (in % number of pixels) of the element closest to the border of the panel. % First element is horizontal distance, second element is vertical % distance. % % - gui.marginSub: (1x2 vector) same as gui.margin but for elements % appearing in sub-panels % % - gui.panelWidth: (scalar) width (in number of pixels) of the panels % appearing on the left part of the interface % % - gui.panelHeight: (vector) height (in number of pixels) of the panels % appearing on the left part of the interface. These values must be % adapted by hand if other parameters such as gui.buttonHeight are % changed % % - gui.panelTitle: (cell array of strings) title of the panels appearing % on the left part of the interface % % - gui.visuResizeButtonWidth: (scalar) width (in number of pixels) of % the draggable resize buttons appearing between two visualizations on % the right part of the interface % % - gui.visuResizeButtonHeight: (scalar) height (in number of pixels) of % the draggable resize buttons appearing between two visualizations on % the right part of the interface % % - gui.curTool: (string) currently used graphical tool, can be one of the % possible names stored in gui.tool.name, which are: % 'free' for freehand selection % 'level' for level selection (ie magic wand) % 'zoomIn' for zoom in mode % 'zoomOut' for zoom out mode % 'pan' for pan mode % % - gui.tool: (struct) struct array containing tool data % gui.tool(ind) contains data for tool number ind % % - gui.tool.buttonId: (graphics object handle) handle of the tool button % % - gui.tool.name: (string) name of the tool, used to identify the % current tool in gui.curTool % % - gui.tool.function (function handle) handle of the function that must % be executed to initialize the tool when clicking the corresponding % button % % - gui.tool.param: (struct) struct array containing the tool parameters % the content of this element depends on the tool and is empty for all % the tools except for the levele selection (magick wand), for which % one parameter named 'Tolerance' is defined % % - gui.tool.param.name: (string) the name of the parameter, as % displayed under the tools subpanel % % - gui.tool.param.val: (string) the value of the parameter represented % as a string (so a conversion is needed if the parameter is a % number) % % - gui.symbOpacity: (scalar) opacity value used for plotting of symbol % (any value between 0:transparent and 1:opaque) % % - gui.showSymb: (bool) boolean specifying if the symbol should be plotted % (true) or not (false) % % - gui.symbImageId: (graphics object handle) handle of the image used to % plot the symbol (the symbol is plotted as a transparent image on top % of the image of the spectrogram) % % - gui.player: (struct) structure containing the handles associated with % the gui of the audioplayer % % - gui.player.buttongroupId: (graphics object handle) handle of the % buttongroup used for the selection of the signal played (original or % modified) % % - gui.player.buttonOriId: (graphics object handle) handle of the radio % button for the selection of original signal % % - gui.player.buttonModId: (graphics object handle) handle of the radio % button for the selection of modified signal % % - gui.ResizeVisuButtonId: (graphics object handle vector) vector % containing the handles of the draggable resize buttons appearing % between two visualizations on the right part of the interface % % - gui.mainFigId: (graphics object handle) handle of the main figure of % the interface % % - gui.undoMenuId: (graphics object handle) handle of the 'Undo' menu % element % % - gui.redoMenuId: (graphics object handle) handle of the 'Redo' menu % element % % - gui.visuMenu: (struct) structure containing menu handles used to show % and hide visualizations % % - gui.visuMenu.showModId: (graphics object handle) handle of the % 'Show modified signal' menu element % % - gui.visuMenu.showOverviewId: (graphics object handle) handle of the % 'Show overview of original signal' menu element % % - gui.exploreRect: (struct) handle of the graphical objects used to % represent the rectangular selection on the overview of original signal % visualization % % - gui.exploreRect.patchId: (graphics object handle) handle of the patch % used to draw the movable selection rectangle % % - gui.exploreRect.lineId: (graphics object handle) handle of the line % used to draw the movable points at the corners of the rectangle % % - gui.panelId: : (graphics object handle vector) vector containg the % handles of the uipanels drawn on the left part of the interface % % - gui.editDynamicId: (graphics object handle) handle of the edit % uicontrol used to specify the colorscale dynamic % % - gui.layListId: (graphics object handle) handle of the listbox % uicontrol used to show the slection layers list % % - gui.layPanelId: (graphics object handle) uipanel handle of the 'Layers' % subpanel % % - gui.toolPanelId: (graphics object handle) uipanel handle of the 'Tools' % subpanel % % link: (struct) data for linking of axes of the different visualization % % - link.CLim: (linkprop object) link object used to link the colorscale % limits (through the CLim property) of the visualizations having their % parameter visu.linkCLim set to true % % - link.XLim: (linkprop object) link object used to link the time axe % (through the XLim property) of the visualizations having their % parameter visu.linkXLim set to true % % - link.YLim: (linkprop object) link object used to link the frequency axe % (through the YLim property) of the visualizations having their % parameter visu.linkYLim set to true % % player: (struct) data used for audio playing % % - player.ori: (audioplayer object) audioplayer used to play the original % signal % % - player.mod: (audioplayer object) audioplayer used to play the modified % signal % % - player.selected: (string) indicate the currently selected audio signal % can be 'ori' for the original signal, or 'mod' for the modified signal % % - player.loop: (bool) indicate if the audio signal must be looped (true) % or not (false) when playing % % - player.position: (scalar) sample position at which the audio playing % will start at next pressing of start % % - player.forceStop: (bool) indicate to the stop function of the % audioplayer that the player must be stopped (needed to be able to stop % when looping) % % - player.positionPlotId: (graphics object handle vector) contains handles % to the moving vertical white lines that are displayed on the % visualizations to show the current position when playing % % default: default data for some variables % PI: This could be used more systematically to define the default value % of all the parameters of the interface. It could then be used to % configure the application by loading variable default from a file during % initialization, and we could also give the possibility to the user % to modify these default values % % - default.dynamic: (scalar) default value for colorscale dynamic % (positive number in dB) % % - default.opacity: (scalar) default value for opacity used for plotting % of symbol (any value between 0:transparent and 1:opaque) % % - default.sel: (struct) default sel variable (see the description of sel) % % - default.frame: (struct) default frame variable (see the description of % frame) % % undoData: (cell) data for undo functionnality % Each cell of undoData contain a copy of the sel variable as it was at a % preceding state % % redoData: (cell) data for redo functionnality % Each cell of redoData contain a copy of the sel variable as it was at a % preceding state % % ___________________ End of description of shared data ___________________ % % __________________________ Beginning of code ____________________________ % % define the variables that will be used to share data between % interface components. They are defined at the top level of the function % so that they are usable by all the functions used by the interface (as % these are nested functions). global coeff default export frame gui link player redoData sel sig symbol global undoData visu visucommon forceSingleInstanceOfMulaclab(); coeff = struct; default = struct; export = struct; frame = struct; gui = struct; link = struct; player = struct; redoData = {}; sel = struct; sig = struct; symbol = struct; undoData = {}; visu = struct; visucommon = struct; % possible values for default.backendClipPoly: 'clipper' or 'polygonclip' or % 'binmasks' default.backendClipPoly = 'clipper'; % initialize the interface if(nargin<1) file = []; end initialize(file, varargin{:}); end % end of main function, from here everything is handled with the callbacks % using the following functions function forceSingleInstanceOfMulaclab() % as we use global variables to share data between callbacks, we need to % insure that only one instance of the mulaclab gui is running mulaclabFigId = findall(0, 'name', 'MulAcLab'); % depending on the version of MATLAB, the figure number can either be % known through its handle or through the property Number try figNumber = num2str(mulaclabFigId); catch figNumber = num2str(get(mulaclabFigId, 'Number')); end if ~isempty(mulaclabFigId) error(['Only one single instance of the MulAcLab gui can be run at a '... 'time and MulAcLab is already running in figure ', figNumber]); end end % __________________________ INITIALIZATION _______________________________ function initialize(file, varargin) global coeff default export frame gui link player redoData sel sig symbol global undoData visu visucommon % check that we have all the toolboxes and functions that we need checkToolbox; loadFile = 0; if nargin==0 || isempty(file) % get an original signal or decomposition to have something to show [fileName, pathName] = uigetfile({'*.wav;*.mat',... 'Supported formats'},... 'Open original signal or decomposition'); if fileName == 0 % the user pressed cancel, we stop here return; end loadFile = 1; elseif(ischar(file)) fileName = file; pathName = ''; loadFile = 1; end if loadFile [~, ~, ext] = fileparts(fileName); switch lower(ext) case '.wav' % read the orginal signal in a wave file [sig.ori, sig.sampFreq] =... wavload([pathName, fileName]); sig.real = true; case '.mat' % read the original signal decomposition in a mat file data = load([pathName, fileName]); if isfield(data, 'frame') && isfield(data, 'savedSig') frame = data.frame; sig = data.savedSig; else errordlg([fileName ' is not a valid signal decomposition file']); return; end end elseif(nargin>=1) definput.keyvals.Fs=[]; [flags,kv,Fs]=ltfatarghelper({'Fs'},definput,varargin); if(isempty(Fs)) error('%s: Second parameter: sampling frequency is missing. ',... upper(mfilename)); end if(numel(find(size(file)>1))>1) error('%s: Input has to be one channel signal.',upper(mfilename)); end % normalize and change to column vector tmpMax = max(abs(file(:))); if tmpMax ~= 0 sig.ori=file(:)/tmpMax; else sig.ori=file(:); end sig.real=isreal(file); sig.sampFreq = Fs; else errordlg(sprintf('%s: Unrecognized input parameters.',upper(mfilename))); return; end if size(sig.ori, 2) > 1 % multichannel wave, we keep only the first channel sig.ori = sig.ori(:, 1); end sig.mod = sig.ori; % initialize the different parameters of the application initializeParameter(); % initialize the frame definition and the coefficients frame = default.frame; % create main window gui.mainFigId = figure(... 'Name', 'MulAcLab',... 'Position', gui.mainFigPos,... 'Toolbar', 'none',... 'Colormap', jet(256),... 'ResizeFcn', @resize,... 'MenuBar', 'none',... 'WindowStyle', 'normal',... 'Visible', 'off'); % create menu of main window menuFileId = uimenu(gui.mainFigId, 'Label','File'); uimenu(menuFileId,... 'Label','Open original signal',... 'Callback',@openOriSig); uimenu(menuFileId,... 'Label','Import original signal decomposition',... 'Callback',@openOriDecompo); uimenu(menuFileId,... 'Label','Import selection',... 'Callback',@importSel); uimenu(menuFileId,... 'Label','Import symbol',... 'Callback',@importSymbol); uimenu(menuFileId,... 'Label','Save modified signal',... 'Callback',@saveModSig,... 'Separator', 'on'); uimenu(menuFileId,... 'Label','Save original signal decomposition',... 'Callback',@saveOriDecompo); uimenu(menuFileId,... 'Label','Save modified signal decomposition',... 'Callback',@saveModDecompo); uimenu(menuFileId,... 'Label','Export selection as ...',... 'Callback',@exportSel); uimenu(menuFileId,... 'Label','Export symbol as ...',... 'Callback',@exportSymbol); menuEditId = uimenu(gui.mainFigId,... 'Label','Edit'); gui.undoMenuId = uimenu(menuEditId,... 'Label','Undo',... 'Accelerator', 'z',... 'enable', 'off',... 'Callback',@undo); gui.redoMenuId = uimenu(menuEditId,... 'Label','Redo',... 'Accelerator', 'y',... 'enable', 'off',... 'Callback',@redo); menuFrameId = uimenu(gui.mainFigId,... 'Label','Frame'); menuFrameTypeId = uimenu(menuFrameId,... 'Label','Choose frame type'); for ind=1:length(gui.supportedFrames) uimenu(menuFrameTypeId,... 'Label',gui.supportedFrames{ind}.type,... 'Callback',@changeFrameType,... 'UserData',ind); end uimenu(menuFrameId,... 'Label','Edit frame parameters',... 'Callback',@changeFrameDef); uimenu(menuFrameId,... 'Label','Load frame parameters',... 'Callback',@loadFrameParam,... 'Separator', 'on'); uimenu(menuFrameId,... 'Label','Save frame parameters',... 'Callback',@saveFrameParam); menuVisuId = uimenu(gui.mainFigId,... 'Label','Visualization'); % PI: the folowing checked on or off should be set automatically % during initialization gui.visuMenu.showModId = uimenu(menuVisuId,... 'Label','Show modified signal',... 'Checked', 'off',... 'Callback',@toggleModVisu); gui.visuMenu.showOverviewId = uimenu(menuVisuId,... 'Label','Show overview of original signal',... 'Checked', 'off',... 'Callback',@toggleOverviewVisu); % create gui panels currentY = 1; for indPanel = 1:length(gui.panelHeight) gui.panelId(indPanel) = uipanel(gui.mainFigId, ... 'Title', gui.panelTitle{indPanel},... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels', ... 'Position', [1 currentY gui.panelWidth gui.panelHeight(indPanel)]); currentY = currentY + gui.panelHeight(indPanel); end % create audioplayers panel drawAudioplayer(gui.panelId(1)); % create visualization tools panel drawVisualizationTool(gui.panelId(2)); % create selection tools panel drawSelectionTool(gui.panelId(3)); resetMulaclab(); toggleOverviewVisu(); % Do not show te overview window resetSel(); resetSymbol(); % end of initialization, show the interface to the user set(gui.mainFigId, 'Visible', 'on'); end function [] = initializeParameter() global default gui visu export % Dictionary of structures field names string expansions gui.mulaclabDict = struct('winType','Window type',... 'nbFreq','Number of frequency bins',... 'hop','Hop size',... 'winLen','Window length',... 'wavelet','Wavelet type',... 'J','Decomposition depth'); % Cellaray of supported frames gui.supportedFramesIdx = 1; gui.supportedFrames = ... {... struct('type','Gabreal','def',... struct('winType','hann','winLen',1024,'hop',256,... 'nbFreq',2048)),... struct('type','erblet','def',... struct('M',300,'downsampling','fractionaluniform')),... ... struct('type','cqt','def',... struct('fmin',50,'fmax',20000,'bins',32,'downsampling','uniform')),... ... struct('type','Gabor','def',... struct('winType','hann','winLen',1024,'hop',256,... 'nbFreq',2048)),... ... struct('type','DWT','def',... struct('wavelet','sym10','J',8)),... ... struct('type','UDWT','def',... struct('wavelet','sym10','J',8)),... ... struct('type','WFBT','def',... struct('wavelet','sym10','J',7)),... ... struct('type','UWFBT','def',... struct('wavelet','sym10','J',4)),... }; % set default values % default colorscale dynamic in dB default.dynamic = 60; % default opacity parameter for symbol plotting (from 0:transparent to % 1:opaque) default.opacity = 0.5; % default selection default.sel.mode = 'union'; default.sel.curLay = 1; default.sel.lay.convType = 'constGain'; default.sel.lay.param(1).name = 'Gain'; default.sel.lay.param(1).val = 0; default.sel.lay.lineWidth = 2; default.sel.lay.color = 'w'; default.sel.lay.marker = 'none'; default.sel.lay.markerSize = 2; default.sel.lay.lineStyle = '-'; default.sel.lay.poly = []; default.sel.lay.label = 'Layer'; default.frame = gui.supportedFrames{gui.supportedFramesIdx}; default.symbol.data.name = 'Selection'; default.symbol.data.val = []; default.symbol.data.invert = false; default.symbol.curSymb = 1; default.zerotodb = -100; % define parameters for the gui (graphical user interface) set(0,'Units','Pixels'); screenSize = get(0,'ScreenSize'); screenSize = screenSize(3:4); if screenSize(1) > 1920 screenSize(1) = 1920; end if screenSize(2) > 1080 screenSize(2) = 1080; end ratio = 0.8; gui.mainFigPos = round([screenSize*0.5*(1-ratio), round(screenSize*ratio)]); gui.fontSize = 9; gui.textHeight = gui.fontSize + 7; gui.textWidth = 57; gui.editWidth = 28; gui.buttonBackgroundColor = [0.7 0.7 0.7]; % chosen to fit icons color if isoctave() gui.buttonWidth = 40; else gui.buttonWidth = 27; end gui.buttonHeight = 22; gui.horiDist = 3; gui.vertDist = 2; gui.margin = [6, 6]; gui.marginSub= [3, 3]; nbButtton = 3; % number of buttons on one line gui.panelWidth = 2*gui.margin(2) + (nbButtton-1) * gui.horiDist +... nbButtton*gui.buttonWidth; gui.panelHeight(1) = 96; gui.panelTitle{1} = 'Audioplayer'; gui.panelHeight(2) = 228; gui.panelTitle{2} = 'Visualization'; gui.panelHeight(3) = 268; gui.panelTitle{3} = 'Selection'; gui.visuResizeButtonWidth = 15; gui.visuResizeButtonHeight = 15; gui.curTool = 'freehand'; gui.tool = struct; gui.symbOpacity = 0.5; gui.showSymb = false; gui.symbImageId = []; gui.player.buttongroupId = []; gui.iconpath=[ltfatbasepath,'mulaclab',filesep,'icons',filesep]; % define parameters for the visualizations % NOTE: height of visu at initilisation must be choosen so that the sum % of visible visu is 1 % Main visualization: spectrogram of the original signal visu(1).label = 'originalMain'; visu(1).height = 0.67; visu(1).position = [0, 0, 1, 1]; % we can initialise this with wathever value % as it will be corrrected during resize visu(1).updateFcn = @updateVisuOriSpec; visu(1).dynamic = default.dynamic; visu(1).visible = true; % Important: the orginalMain visu must always stay % visible visu(1).linkX = true; visu(1).linkY = true; visu(1).linkCLim = true; visu(1).uipanelId = []; visu(1).axesId = []; % Visualization of the spectrogram of the modified signal visu(2).label = 'modified'; visu(2).height = 0.; visu(2).position = [0, 0, 1, 1]; visu(2).updateFcn = @updateVisuModSpec; visu(2).dynamic = default.dynamic; % useless if linkCLim is true visu(2).visible = false; visu(2).linkX = true; visu(2).linkY = true; visu(2).linkCLim = true; visu(2).uipanelId = []; visu(2).axesId = []; % Visualization for the overview of the original spectrogram with fast % scrolling visu(3).label = 'originalOverview'; visu(3).height = 0.33; visu(3).position = [0, 0, 1, 1]; visu(3).updateFcn = @updateVisuOriOverview; visu(3).dynamic = default.dynamic; % useless if linkCLim is true visu(3).visible = true; visu(3).linkX = false; visu(3).linkY = false; visu(3).linkCLim = true; visu(3).uipanelId = []; visu(3).axesId = []; gui.ResizeVisuButtonId = NaN(length(visu), 1); % set export parameters export.xLim = 800; export.limitXaxesRes = false; export.symbol = {}; end function checkToolbox() global default gui if isoctave() if getOctaveVersion() < 4.0 error(['This function requires Octave version 4.0.0 or higher.']); end end % Check that the function for polygon clipping is available checkPolygonClipping(); % Check that the Image Processing Toolbox is available if isoctave() imageInfo = ver('image'); if isempty(imageInfo) || isempty(imageInfo.Version) warning(do_string_escapes(... ['For improved features in mulaclab, you can install the Image '... 'package\nfrom Octave-forge using the following command:\n'... ' pkg install -forge image'])); gui.hasImagePackage = false; else % load the image package in case it is not already loaded pkg('load', 'image'); gui.hasImagePackage = true; end else if isempty(ver('images')) gui.hasImagePackage = false; else gui.hasImagePackage = true; end end end function checkPolygonClipping() global default gui usePolygonClip = false; useBinMasks = false; if strcmp(default.backendClipPoly, 'clipper') temp1 = {[1; 1]}; temp2 = temp1; try [tempPol, tempHoles] = polyboolclipper(temp1, temp2, 'or'); gui.backendClipPoly = 'clipper'; return; catch useBinMasks = true; end end if strcmp(default.backendClipPoly, 'polygonclip') || usePolygonClip temp1.x = [1]; temp1.y = [1]; temp1.hole = false; temp2 = temp1; try temp = PolygonClip(temp1, temp2); gui.backendClipPoly = 'polygonclip'; return; catch useBinMasks = true; end end if strcmp(default.backendClipPoly, 'binmasks') || useBinMasks if useBinMasks warning(sprintf(... ['No compiled function for polygon clipping was found, switching to'... '\nbinary masks for polygon clipping.\n'... 'Please compile using the "ltfatmex" command for a more efficient '... 'solution.'])); end gui.backendClipPoly = 'binmasks'; end end % ___________________ COMPUTATIONAL FUNCTIONS _____________________________ function coef = calculateCoeff(f) global frame coeff switch lower(frame.type) case 'gabreal' win = firwin(frame.def.winType,frame.def.winLen); coef= dgtreal(f, win, frame.def.hop, frame.def.nbFreq); case 'gabor' win = firwin(frame.def.winType,frame.def.winLen); coef = dgt(f, win, frame.def.hop, frame.def.nbFreq); case {'erblet','cqt'} coef = filterbank(f,frame.precomp.g,frame.precomp.a); case 'dwt' [coef, coeff.info] = fwt(f,frame.def.wavelet,frame.def.J); case 'wfbt' [coef, coeff.info] = wfbt(f,{frame.def.wavelet,frame.def.J,'full'}); case 'uwfbt' [coef, coeff.info] = uwfbt(f,{frame.def.wavelet,frame.def.J,'full'}); case 'udwt' [coef, coeff.info] = ufwt(f,frame.def.wavelet,frame.def.J); otherwise error('%s: Unrecognized frame type',upper(mfilename)); end end function fhat = recFromCoeff(coef) global coeff frame sig switch lower(frame.type) case 'gabreal' win = gabdual(firwin(frame.def.winType,frame.def.winLen),... frame.def.hop, frame.def.nbFreq); fhat = idgtreal(coef, win, frame.def.hop,frame.def.nbFreq,... length(sig.ori)); case 'gabor' win = gabdual(firwin(frame.def.winType,frame.def.winLen),... frame.def.hop, frame.def.nbFreq); fhat = idgt(coef, win, frame.def.hop,length(sig.ori)); case {'erblet','cqt'} fhat = 2*real(ifilterbank(coef,frame.precomp.gdual,frame.precomp.a,... length(sig.ori))); case 'dwt' fhat = ifwt(coef,coeff.info); case 'wfbt' fhat = iwfbt(coef,{frame.def.wavelet,frame.def.J,'full'},length(sig.ori)); case 'uwfbt' fhat = iuwfbt(coef,{frame.def.wavelet,frame.def.J,'full'}); case 'udwt' fhat = iufwt(coef,coeff.info); otherwise error('%s: Unrecognized frame type',upper(mfilename)); end fhat = real(fhat); end function C = plotCoeff(coef,axesId,key,value) global coeff frame sig export switch lower(frame.type) case 'gabreal' C = plotdgtreal(coef,frame.def.hop,frame.def.nbFreq,sig.sampFreq,key,... value); case 'gabor' C = plotdgt(coef,frame.def.hop,sig.sampFreq,key,value); case {'erblet','cqt'} C = plotfilterbank(coef,frame.precomp.a,frame.precomp.fc,sig.sampFreq,... key,value); case {'dwt','udwt','wfbt','uwfbt','ufwt'} C = plotwavelets(coef,coeff.info,sig.sampFreq,key,value); otherwise error('%s: Unrecognized frame type',upper(mfilename)); end if export.limitXaxesRes C=interp1(linspace(0,1,size(C,2)),C.',linspace(0,1,export.xLim),'nearest'); C=C.'; end end function mult = convSymbToCoefFormat(symb) global frame export coeff switch lower(frame.type) % Classical gabor coeff format case {'gabreal','gabor'} if strcmp(lower(frame.type), 'gabor') % we need to invert the circshift that was done in plotdgt to move zero % frequency to the center and Nyquist frequency to the top M = size(symb, 1); if rem(M, 2) == 0 symb = circshift(symb, -(M/2-1)); else symb = circshift(symb, -(M-1)/2); end end if export.limitXaxesRes L = size(coeff.ori,2); Lplot = size(symb,2); mult=interp1(linspace(0,1,Lplot),symb.',linspace(0,1,L),'nearest'); mult = mult.'; else mult = symb; end % Cell array containing column vectors format case {'wfbt','erblet','cqt'} M = numel(coeff.ori); Lplot = size(symb,2); Lc = cellfun(@(cEl) size(cEl,1),coeff.ori); mult = cell(size(coeff.ori)); for m=1:M mult{m} = interp1(linspace(0,1,Lplot),symb(m,:),linspace(0,1,Lc(m)),... 'nearest').'; end % FWT specific coefficient format case 'dwt' Lc = coeff.info.Lc; Lcstart = cumsum([1;Lc(1:end-1)]); Lcend = cumsum(Lc); mult = zeros(sum(Lc),1); M = numel(Lc); Lplot = size(symb,2); for m=1:M mult(Lcstart(m):Lcend(m)) = interp1(1:Lplot,symb(m,:),... linspace(1,Lplot,Lc(m)),'nearest').'; end % ufilterbak and all wavelet functions beginning with u case {'udwt','uwfbt'} M = size(coeff.ori,2); L = size(coeff.ori,1); Lplot = size(symb,2); mult = zeros(size(coeff.ori)); for m=1:M mult(:,m) = interp1(1:Lplot,symb(m,:),linspace(1,Lplot,L),'nearest').'; end otherwise error('%s: Unrecognized frame type',upper(mfilename)); end end function symb = convCoefFormatToSymb(mult) global frame export coeff switch lower(frame.type) % Classical gabor coeff format case {'gabreal','gabor'} if export.limitXaxesRes L = size(coeff.ori,2); Lmult = size(mult,2); symb=interp1(linspace(0,1,Lmult),mult.',linspace(0,1,L),'nearest'); symb = symb.'; else symb=mult; end % Cell array containing column vectors format case {'wfbt','erblet','cqt'} M = numel(coeff.ori); Lsymb = size(coeff.oriC,2); Lc = cellfun(@(cEl) size(cEl,1),mult); symb = zeros(size(coeff.oriC)); for m=1:M symb(m,:) = interp1(linspace(0,1,Lc(m)),mult{m},linspace(0,1,Lsymb),... 'nearest'); end % FWT specific coefficient format case 'dwt' Lc = coeff.info.Lc; Lcstart = cumsum([1;Lc(1:end-1)]); Lcend = cumsum(Lc); symb = zeros(size(coeff.oriC)); %mult = zeros(sum(Lc),1); M = numel(Lc); Lplot = size(symb,2); for m=1:M symb(m,:) = interp1(linspace(1,Lplot,Lc(m)),mult(Lcstart(m):Lcend(m)),... 1:Lplot,'nearest'); end % ufilterbak and all wavelet functions beginning with u case {'udwt','uwfbt'} L = size(coeff.oriC,2); M = size(coeff.ori,2); Lmult = size(mult,1); symb = zeros(size(coeff.oriC)); for m=1:M symb(m,:) = interp1(1:Lmult,mult(:,m),linspace(1,Lmult,L),'nearest'); end otherwise error('%s: Unrecognized frame type',upper(mfilename)); end end function precomputeStuff() global frame sig if isfield(frame,'precomp') && isfield(frame.precomp,'L') ... && frame.precomp.L == length(sig.ori) % Already done, do nothing. return; end frame.precomp = struct(); frame.precomp.L = length(sig.ori); switch lower(frame.type) case 'erblet' [frame.precomp.g,frame.precomp.a,frame.precomp.fc] = erbfilters(... sig.sampFreq,length(sig.ori),'M',frame.def.M,frame.def.downsampling); frame.precomp.gdual = filterbankrealdual(frame.precomp.g,... frame.precomp.a,length(sig.ori)); case 'cqt' [frame.precomp.g,frame.precomp.a,frame.precomp.fc] = cqtfilters(... sig.sampFreq,frame.def.fmin,frame.def.fmax,frame.def.bins,... length(sig.ori),frame.def.downsampling); frame.precomp.gdual = filterbankrealdual(frame.precomp.g,... frame.precomp.a,filterbanklength(length(sig.ori),frame.precomp.a)); end end function applyMultiplier(c,mult) global coeff sig visu if(isnumeric(c)&&isnumeric(mult)) coeff.mod = c.*mult; elseif(iscell(c)&&iscell(mult)) coeff.mod = cellfun(@(x,y) x.*y,c,mult,'UniformOutput',false); else error('%s: Unrecognized frame type',upper(mfilename)); end sig.mod = recFromCoeff(coeff.mod); updatePlayerMod; coeff.mod = calculateCoeff(sig.mod); modInd = find(strcmp('modified', {visu.label}), 1); if ~visu(modInd).visible toggleModVisu; end updateVisu; end function applySel(objId, eventData) % convert the selection to get the symbol of the multiplier and apply % the multiplier global symbol coeff if isempty(symbol.data(symbol.curSymb).val) mult = convSymbToCoefFormat(convSelToSymb()); else mult = convSymbToCoefFormat(symbol.data(symbol.curSymb).val); end applyMultiplier(coeff.ori, mult); end function symb = convSelToSymb() global coeff sel symb = ones(size(coeff.oriC)); for indLay = 1:length(sel.lay) if ~isempty(sel.lay(indLay).poly) mask = convPolyToMask(sel.lay(indLay).poly); symbCurr = convMaskToSymb(mask, indLay); symb = symb.*symbCurr; else warning(['Selection layer ' num2str(indLay), ' is currently empty']); end end end function mask = convPolyToMask(poly) global coeff mask = zeros(size(coeff.oriC)); % PI: type of data for the mask might be optimized (bool, uint8?) % PI: could be optimized by doing the conversion in smaller boxes % around each polygon (not on the whole time-frequency plane) for ind = 1:length(poly) xvals = convAxesToIndX(poly(ind).x)-0.5; yvals = convAxesToIndY(poly(ind).y)-0.5; tmpmask = octave_poly2mask(xvals,yvals,size(mask,1), size(mask,2)); if poly(ind).hole mask = mask - tmpmask; else mask = mask + tmpmask; end end end function symb = convMaskToSymb(mask, indLay) global sel sig coeff % NOTE: a case should be added here when creating new selection type switch sel.lay(indLay).convType case 'constGain' gain = sel.lay(indLay).param(1).val; symb = ones(size(mask)); symb = symb + (gain-1)*mask; case 'smoothBorder' gain = sel.lay(indLay).param(1).val; threshold = sel.lay(indLay).param(2).val; % bwdist returns single symb = double(bwdist(~mask)); symb(symb > threshold) = threshold; symb = symb * (gain-1)/threshold + 1; case 'fill' % simple filling test, just interpolating in 3D the modulus % estimation of the level in the neighbourhood of the selection timeRadius = sel.lay(indLay).param(1).val; freqRadius = sel.lay(indLay).param(2).val; % find the points that are just next to the selection neighbour = imdilate(mask, strel('square',3)) - mask; % for these points, compute mean level in a specified neighbourhood % (but not taking into account the values of the transform inside % the selection) % create the matrix defining the neighbourhood mat = computeEllipse(freqRadius, timeRadius); % NOTE: this could be a more general filter if we want % PI: in the following applications of filter2, we need only the filtered % values for the points in neighbour, so this could be computed more % efficiently if needed temp1 = filter2(mat, 10.^(coeff.oriC/20) .* (1-mask)); temp2 = filter2(mat, 1-mask); [ind1Neigh, ind2Neigh] = find(neighbour); valNeigh = sqrt(temp1(sub2ind(size(temp1), ind1Neigh,... ind2Neigh))./temp2(sub2ind(size(temp2), ind1Neigh, ind2Neigh))); [ind1Mask, ind2Mask] = find(mask); try valInterp = griddata(ind1Neigh, ind2Neigh, valNeigh,... ind1Mask, ind2Mask, 'linear'); catch % sometime griddata fail, and adding this option seem to solve % the problem, but it is not clear why valInterp = griddata(ind1Neigh, ind2Neigh, valNeigh,... ind1Mask, ind2Mask, 'linear', {'QJ'}); end symb = ones(size(mask)); % PI: there could be divisions by zero in the following, this % should be cleanly handled symb(sub2ind(size(symb), ind1Mask, ind2Mask)) = valInterp ./... abs(coeff.oriC(sub2ind(size(coeff.oriC), ind1Mask, ind2Mask))); case 'fillNoise' % other hole filling test, using coefficients taken from a noise % estimation of the level in the neighbourhood of the selection timeRadius = sel.lay(indLay).param(1).val; freqRadius = sel.lay(indLay).param(2).val; % find the points that are just next to the selection neighbour = imdilate(mask, strel('square',3)) - mask; % for these points, compute mean level in a specified neighbourhood % (but not taking into account the values of the transform inside % the selection) % create the matrix defining the neighbourhood mat = computeEllipse(freqRadius, timeRadius); % NOTE: this could be a more general filter if we want % PI: in the following applications of filter2, we need only the filtered % values for the points in neighbour, so this could be computed more % efficiently if needed temp1 = filter2(mat, 10.^(coeff.oriC/20).* (1-mask)); temp2 = filter2(mat, 1-mask); [ind1Neigh, ind2Neigh] = find(neighbour); valNeigh = sqrt(temp1(sub2ind(size(temp1), ind1Neigh,... ind2Neigh))./temp2(sub2ind(size(temp2), ind1Neigh, ind2Neigh))); [ind1Mask, ind2Mask] = find(mask); try valInterp = griddata(ind1Neigh, ind2Neigh, valNeigh, ... ind1Mask, ind2Mask, 'linear'); catch % sometime griddata fail, and adding this option seem to solve % the problem, but it is not clear why valInterp = griddata(ind1Neigh, ind2Neigh, valNeigh,... ind1Mask, ind2Mask, 'linear', {'QJ'}); end symb = ones(size(mask)); % compute the transform of a noise noise = rand(numel(sig.ori), 1) - 0.5; coeffNoise = calculateCoeff(noise); % PI: here all the interpolations and mean are done directly on the % absolute value of the coefficients, it could be more meaningfull % to work with the sqaure of the modulus due to its possible % intepretation a energy ditribution coeffNoiseSymb = convCoefFormatToSymb(coeffNoise); meanLevelNoise = sum(abs(coeffNoiseSymb(sub2ind(size(coeffNoiseSymb), ... ind1Mask, ind2Mask-min(ind2Mask)+1)))) / length(ind1Mask); % PI: there could be divisions by zero in the following, this % should be cleanly handled symb(sub2ind(size(symb), ind1Mask, ind2Mask)) = valInterp .*... coeffNoiseSymb(sub2ind(size(coeffNoiseSymb), ind1Mask,... ind2Mask-min(ind2Mask)+1)) ./... (coeffNoiseSymb(sub2ind(size(coeffNoiseSymb), ind1Mask, ind2Mask)) *... meanLevelNoise); end % of switch end function xData = convIndToAxesX(ind) % convert scale from image index to scale used by axes along X axe global sig coeff visucommon xData = (ind-1) * visucommon.timeStep; end function ind = convAxesToIndX(xData) % convert scale from scale used by axes to image index along X axe % NOTE: there is no round (on purpose), it must be added if when we really % want an integer index global visucommon ind = xData / visucommon.timeStep + 1; end function yData = convIndToAxesY(ind) % convert scale from image index to scale used by axes along Y axe global visucommon coeff Ylim = visucommon.oriYlim; yData = (ind-0.5) * ((Ylim(2)-Ylim(1)) / size(coeff.oriC,1)) + Ylim(1); end function ind = convAxesToIndY(yData) % convert scale from scale used by axes to image index along Y axe % NOTE: there is no round (on purpose), it must be added if when we really % want an integer index global visucommon coeff Ylim = visucommon.oriYlim; ind = (yData-Ylim(1)) * (size(coeff.oriC,1) / (Ylim(2)-Ylim(1))) + 0.5; end function ellipse = computeEllipse(dim1Radius, dim2Radius) ellipse = zeros(2*dim1Radius+1, 2*dim2Radius+1); ellipse(dim1Radius+1, :) = 1; ellipse(:, dim2Radius+1) = 1; for ind1 = 1:dim1Radius-1 for ind2 = 1:dim2Radius-1 if ((ind1/dim1Radius)^2 + (ind2/dim2Radius)^2) <= 1 ellipse(dim1Radius+1+ind1, dim2Radius+1+ind2) = 1; ellipse(dim1Radius+1-ind1, dim2Radius+1+ind2) = 1; ellipse(dim1Radius+1+ind1, dim2Radius+1-ind2) = 1; ellipse(dim1Radius+1-ind1, dim2Radius+1-ind2) = 1; end end end end % _____________________ GENERAL FUNCTIONS FOR UI __________________________ function matlabVersion = getMatlabVersion() matlabInfo = ver('Matlab'); matlabVersion = convertVersion(matlabInfo.Version); end function octaveVersion = getOctaveVersion() octaveInfo = ver('Octave'); octaveVersion = convertVersion(octaveInfo.Version); end function versionNum = convertVersion(versionString) % the version number is sometime of the form X.X.X, so it cannot be % easily converted into a number, so we need to modify it so that it % is more usable for comparison temp = find(versionString == '.'); temp = temp(2:end); for ind = 1:size(temp, 2) % we remove the extra points '.' in the string versionString = versionString([1:temp(ind)-1, temp(ind)+1:end]); end versionNum = str2num(versionString); end function resetMulaclab() global coeff gui sig visu visucommon initializePlayer(); precomputeStuff(); coeff.ori = calculateCoeff(sig.ori); sig.mod = sig.ori; coeff.mod = coeff.ori; resetSel(); undoData = {}; modInd = find(strcmp('modified', {visu.label}), 1); if visu(modInd).visible toggleModVisu(); end updateVisu(true); % update visualization with reset of axes limits oriInd = find(strcmp('originalMain', {visu.label}), 1); visucommon.oriXlim = get(visu(oriInd).axesId,'Xlim'); visucommon.oriYlim = get(visu(oriInd).axesId,'Ylim'); % activate the current tool changeTool([], [], gui.curTool); end function openOriSig(objId, eventData) global sig [fileName, pathName] = uigetfile('*.wav',... 'Open original signal'); if fileName == 0 % user pressed cancel, stop here return; end [newSig, sampFreq] = wavload([pathName, fileName]); if size(newSig, 2) > 1 % multichannel wave, we keep only the first channel newSig = newSig(:, 1); end sig.sampFreq = sampFreq; sig.ori = newSig; sig.mod = newSig; sig.real = true; resetMulaclab(); end function saveModSig(objId, eventData) global sig [fileName, pathName] = uiputfile('*.wav', 'Save modified signal'); if fileName == 0 % user pressed cancel, stop here return; end wavsave(sig.mod, sig.sampFreq,[pathName, fileName]); end function openOriDecompo(objId, eventData) global frame sig [fileName, pathName] = uigetfile('*.mat', 'Load frame parameters'); if fileName == 0 % user pressed cancel, stop here return; end data = load([pathName, fileName]); if ~(isfield(data, 'frame') && isfield(data, 'savedSig')) errordlg([fileName ' is not a valid signal decomposition file']); return; end frame = data.frame; sig = data.savedSig; sig.mod = sig.ori; resetMulaclab(); end function saveOriDecompo(objId, eventData) global sig frame [fileName, pathName] = uiputfile('*.mat', 'Export selection'); if fileName == 0 % user pressed cancel, stop here return; end savedSig = sig; rmfield(savedSig, 'mod'); save([pathName, fileName], 'frame', 'savedSig'); end function saveModDecompo(objId, eventData) global sig frame [fileName, pathName] = uiputfile('*.mat', 'Export selection'); if fileName == 0 % user pressed cancel, stop here return; end savedSig = sig; savedSig.ori = savedSig.mod; rmfield(savedSig, 'mod'); save([pathName, fileName], 'frame', 'savedSig'); end function exportSel(objId, eventData) global sel [fileName, pathName] = uiputfile('*.mat', 'Export selection'); if fileName == 0 % user pressed cancel, stop here return; end save([pathName, fileName], 'sel'); end function exportSymbol(objId, eventData) global gui coeff visu [fileName, pathName] = uiputfile('*.png', 'Export symbol as...'); if fileName == 0 % user pressed cancel, stop here return; end cm = get(gui.mainFigId,'Colormap'); oriInd = find(strcmp('originalMain', {visu.label}), 1); Clim = get(visu(oriInd).axesId,'CLim'); oriIdx = round((flipud(coeff.oriC)-Clim(1))/(Clim(2)-Clim(1))*255)+1; oriExt = zeros([size(coeff.oriC),3]); oriExt(:,:,1) = reshape(cm(oriIdx,1),size(coeff.oriC)); oriExt(:,:,2) = reshape(cm(oriIdx,2),size(coeff.oriC)); oriExt(:,:,3) = reshape(cm(oriIdx,3),size(coeff.oriC)); absSymb = flipud(abs(convSelToSymb())); if isoctave() % Octave doesn't yet support the bitdepth parameter in imwrite imwrite(oriExt,[pathName, fileName],'png','Alpha',absSymb); else imwrite(oriExt,[pathName, fileName],'png','Alpha',absSymb,'bitdepth',16); end end function importSel(objId, eventData) global sel gui [fileName, pathName] = uigetfile('*.mat', 'Import selection'); if fileName == 0 % user pressed cancel, stop here return; end data = load([pathName, fileName]); if ~isfield(data, 'sel') errordlg([fileName ' is not a valid signal selection file']); return; end % as the saved selection might have been created using a longer signal, % or a signal with a higher sampling frequency, it could be wider that % the part of the time-frequency plane corresponding to the signal. % We need to force the selection to stay in the right region fullPoly = fullSigPoly; for ind = 1:length(data.sel.lay) % intersection of the polygon with a polygon covering the whole % signal data.sel.lay(ind).poly = clipPoly(data.sel.lay(ind).poly,... fullPoly, 1); end delSel; sel.lay(end+1:end+length(data.sel.lay)) = data.sel.lay; updateLayerList; set(gui.layListId, 'Value', 1); changeSelLay; drawAllSel; end function importSymbol(objId, eventData) global coeff default gui symbol [fileName, pathName] = uigetfile('*.png', 'Import symbol'); if fileName == 0 % user pressed cancel, stop here return; end [imag, ~, alpha] = imread([ pathName,fileName]); if(size(imag,3)>1) if isempty(alpha) errordlg(sprintf('%s does not contain alpha channel.',fileName)); return; end mask = double(alpha)/double(max(alpha(:))); else mask = double(imag)/double(max(imag(:))); end if any(size(coeff.oriC)~=size(mask)) errordlg([fileName ' is not a valid symbol image. The dimensions are different.']); return; end %limit mmss = 10^(default.zerotodb/20); mask(abs(mask) 0) widthVisu = 0.5; end curY = 1; for ind = 1:length(visu) if visu(ind).visible curY = curY - visu(ind).height; visu(ind).position = [xVisu curY widthVisu visu(ind).height]; set(visu(ind).uipanelId, 'Position', visu(ind).position); if ishandle(gui.ResizeVisuButtonId(ind)) set(gui.ResizeVisuButtonId(ind), 'Position',... [figPos(3)-gui.visuResizeButtonWidth,... round(curY*figPos(4)-gui.visuResizeButtonHeight/2),... gui.visuResizeButtonWidth, ... gui.visuResizeButtonHeight]); end end end end function updateUndoData() global undoData redoData gui sel undoData{end+1} = sel; set(gui.undoMenuId, 'Enable', 'on'); redoData = {}; set(gui.redoMenuId, 'Enable', 'off'); end function undo(objId, eventData) % PI: Currently the implementation of undo/redo is very rudimentary. % Only undo/redo of actions modifying the polygons of the selection sel % are taken into account. For example, zoom actions, or change of layer % parameters (type of conversion, color of line, ...) are not taken % into account. A more general handling could be implemented. % The memory consumption for undo could also be improved. Currently for % each action modifying the polygons, the whole old variable sel is % stored in a cell of undoData. It's generally contains more % information than stricly needed to undo as only one layer is modified % at a time. If improved efficiency is needed, it could be taken into % account to save minimally needed information. The number of undo % levels is currently unlimited, this could be also changed if needed global undoData redoData sel gui if ~isempty(undoData) delSel; redoData{end+1} = sel; set(gui.redoMenuId, 'Enable', 'on'); sel = undoData{end}; undoData = undoData(1:end-1); if isempty(undoData) set(gui.undoMenuId, 'Enable', 'off'); end drawAllSel; set(gui.layListId, 'Value', sel.curLay); updateLayerList; end end function redo(objId, eventData) % PI: see the PI for undo function global undoData redoData sel gui if ~isempty(redoData) delSel; undoData{end+1} = sel; set(gui.undoMenuId, 'Enable', 'on'); sel = redoData{end}; redoData = redoData(1:end-1); if isempty(redoData) set(gui.redoMenuId, 'Enable', 'off'); end drawAllSel; set(gui.layListId, 'Value', sel.curLay); updateLayerList; end end function setButtonAppearance(buttonId, string, iconName) global gui % Octave doesn't yet support the use of CData to display icons on buttons % (see http://savannah.gnu.org/bugs/?44332) so we only display a string in % Octave and we display an icon in MATLAB if isoctave() set(buttonId, 'String', string); else icon = imread([gui.iconpath, iconName]); set(buttonId, 'CData', icon); end end % ______________________ VISUALIZATION FUNCTIONS __________________________ function updateVisu(resetVisu, changeCLim) global gui visu link if nargin == 0 resetVisu = false; changeCLim = false; end delete(gui.symbImageId); gui.symbImageId = []; % keep the properties of the axes if we're not resetting the % visualization axesProp = struct; if ~resetVisu for ind = 1:length(visu) if ~isempty(visu(ind).axesId) axesProp(ind).xLim = get(visu(ind).axesId, 'XLim'); axesProp(ind).yLim = get(visu(ind).axesId, 'YLim'); axesProp(ind).cLim = get(visu(ind).axesId, 'CLim'); end end end % update the visualization of the signal linkXId = []; linkYId = []; linkCLimId=[]; for ind = 1:length(visu) delete(visu(ind).uipanelId); visu(ind).uipanelId = []; visu(ind).axesId = []; if visu(ind).visible visu(ind).uipanelId = uipanel(gui.mainFigId, ... 'Units', 'normalized', ... 'Position', visu(ind).position); if visu(ind).linkX linkXId = [linkXId ind]; end if visu(ind).linkY linkYId = [linkYId ind]; end if visu(ind).linkCLim linkCLimId = [linkCLimId ind]; end end end oriInd = find(strcmp('originalMain', {visu.label}), 1); updateOneVisu(oriInd); oriInd = find(strcmp('originalMain', {visu.label}), 1); if isoctave() % Octave and MATLAB have slighlty diffrent call signatures for addlistener addlistener(visu(oriInd).axesId, 'XLim', @updateExploreRect); addlistener(visu(oriInd).axesId, 'YLim', @updateExploreRect); else addlistener(visu(oriInd).axesId, 'XLim', 'PostSet', @updateExploreRect); addlistener(visu(oriInd).axesId, 'YLim', 'PostSet', @updateExploreRect); end if length(linkCLimId) > 1 link.CLim = get(visu(oriInd).axesId,'CLim'); end range = 1:length(visu); range(oriInd) = []; for ind = range updateOneVisu(ind); end if length(linkXId) > 1 link.XLim = linkprop([visu(linkXId).axesId],'XLim'); end if length(linkYId) > 1 link.YLim = linkprop([visu(linkXId).axesId],'YLim'); end if ~resetVisu % we go in reverse order to update axes limits so that % all the linked axes come back to the limits of the original % spectrogram, even if some new linked axes are added for ind = length(visu):-1:1 if visu(ind).visible try set(visu(ind).axesId, 'XLim', axesProp(ind).xLim); end try set(visu(ind).axesId, 'YLim', axesProp(ind).yLim); end if ~changeCLim try set(visu(ind).axesId, 'CLim', axesProp(ind).cLim); end end end end end drawAllSel; overviewInd = find(strcmp('originalOverview', {visu.label}), 1); if ~isempty(overviewInd) if visu(overviewInd).visible exploreOverview(visu(overviewInd).axesId); end end if ~resetVisu % restore the current tool changeTool([], [], gui.curTool); end drawResizeVisuButton; resize; end function updateOneVisu(ind) global visu sig player gui if visu(ind).visible visu(ind).axesId = visu(ind).updateFcn(visu(ind)); % plot for the visualisation of play position during playback lim = axis(visu(ind).axesId); xPos = (player.position-1) / sig.sampFreq; hold(visu(ind).axesId, 'on'); player.positionPlotId(ind) = plot(visu(ind).axesId, [xPos xPos],... lim(3:4), 'w'); % PI: give the possibility to change the color set(player.positionPlotId(ind), 'Visible', 'off', 'LineWidth', 2); hold(visu(ind).axesId, 'off'); % the following insures the possibility to zoom out % completely even if we are already zoomed in axes(visu(ind).axesId); zoom(gui.mainFigId, 'reset'); end end function [axesId,C,timeStep] = updateVisuCommon(coef,lim,visuData) global link axesId = axes('Parent',visuData.uipanelId); if(lim) C = plotCoeff(coef,axesId,'clim',link.CLim); else C = plotCoeff(coef,axesId,'dynrange',visuData.dynamic); end colorbar off; xLim = get(axesId,'XLim'); timeStep = (xLim(2)-xLim(1)) / (size(C,2)); end function [axesId] = updateVisuOriSpec(visuData) global coeff visucommon [axesId, coeff.oriC, timeStep] = updateVisuCommon(coeff.ori,false,visuData); title('Original signal'); visucommon.timeStep = timeStep; end function [axesId] = updateVisuModSpec(visuData) global coeff [axesId, coeff.modC] = updateVisuCommon(coeff.mod,visuData.linkCLim,visuData); title('Modified signal'); end function [axesId] = updateVisuOriOverview(visuData) global coeff axesId = updateVisuCommon(coeff.ori,visuData.linkCLim,visuData); title('Overview of original signal'); end function drawResizeVisuButton() global gui visu for ind = 1:length(gui.ResizeVisuButtonId) if ishandle(gui.ResizeVisuButtonId(ind)) delete(gui.ResizeVisuButtonId(ind)); end end nbVisibleVisu = length(find([visu.visible])); nbButton = 0; gui.ResizeVisuButtonId = NaN(length(visu), 1); if nbVisibleVisu > 1 for ind = 1:length(visu) if visu(ind).visible gui.ResizeVisuButtonId(ind) = uicontrol(... 'Parent', gui.mainFigId,... 'Style', 'pushbutton',... 'TooltipString', 'Resize visualization',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Enable', 'off',... 'buttonDownFcn', {@resizeVisu, ind}); setButtonAppearance(gui.ResizeVisuButtonId(ind), 'x',... 'resizebutton.png'); nbButton = nbButton + 1; if nbButton == nbVisibleVisu-1 break; end end end end end function resizeVisu(objId, eventData, indVisu) global gui visu % In Octave, the button up event is generally lost, so we put the same % action on the right button down if strcmp(get(gui.mainFigId,'SelectionType'),'alt') if isequal(get(gui.mainFigId, 'WindowButtonMotionFcn'),... @resizeVisuButtonMotionFcn) resizeVisuButtonUpFcn(objId, eventData); end return; end initPos = get(gui.mainFigId, 'CurrentPoint'); buttonMotionFcn = get(gui.mainFigId, 'WindowButtonMotionFcn'); if (~isequal(buttonMotionFcn, @resizeVisuButtonMotionFcn)) backupButtonMotionFcn = buttonMotionFcn; else backupButtonMotionFcn = gui.resizeVisu.backupButtonMotionFcn; end buttonUpFcn = get(gui.mainFigId, 'WindowButtonUpFcn'); if (~isequal(buttonUpFcn, @resizeVisuButtonUpFcn)) backupButtonUpFcn = buttonUpFcn; else backupButtonUpFcn = gui.resizeVisu.backupButtonUpFcn; end figPos = get(gui.mainFigId, 'Position'); buttonPos = get(gui.ResizeVisuButtonId(indVisu), 'Position'); % find the index of the visible visualization next to the one with % index indVisu indNextVisu = 0; for ind = indVisu+1:length(visu) if visu(ind).visible indNextVisu = ind; break; end end initHeight = [visu(indVisu).height, visu(indNextVisu).height]; % As the zoom and pan mode of matlab doesn't allow to change the % WindowButtonUpFcn, I temporarly change the tool curTool = gui.curTool; changeTool(objId, eventData, 'freehand'); set(gui.mainFigId,... 'WindowButtonUpFcn', @resizeVisuButtonUpFcn); set(gui.mainFigId,... 'WindowButtonMotionFcn', @resizeVisuButtonMotionFcn); gui.resizeVisu.initPos = initPos; gui.resizeVisu.backupButtonMotionFcn = backupButtonMotionFcn; gui.resizeVisu.backupButtonUpFcn = backupButtonUpFcn; gui.resizeVisu.figPos = figPos; gui.resizeVisu.buttonPos = buttonPos; gui.resizeVisu.indNextVisu = indNextVisu; gui.resizeVisu.initHeight = initHeight; gui.resizeVisu.curTool = curTool; gui.resizeVisu.indVisu = indVisu; end function resizeVisuButtonMotionFcn(objId, eventData) global gui visu initPos = gui.resizeVisu.initPos; backupButtonMotionFcn = gui.resizeVisu.backupButtonMotionFcn; backupButtonUpFcn = gui.resizeVisu.backupButtonUpFcn; figPos = gui.resizeVisu.figPos; buttonPos = gui.resizeVisu.buttonPos; indNextVisu = gui.resizeVisu.indNextVisu; initHeight = gui.resizeVisu.initHeight; curTool = gui.resizeVisu.curTool; indVisu = gui.resizeVisu.indVisu; pos = get(gui.mainFigId, 'CurrentPoint'); shift = (pos(2) - initPos(2)) / figPos(4); if (initHeight(1) - shift) > 0.01 && (initHeight(2) + shift) > 0.01 visu(indVisu).height = initHeight(1) - shift; visu(indNextVisu).height = initHeight(2) + shift; end resize; end function resizeVisuButtonUpFcn(objId, eventData) global gui initPos = gui.resizeVisu.initPos; backupButtonMotionFcn = gui.resizeVisu.backupButtonMotionFcn; backupButtonUpFcn = gui.resizeVisu.backupButtonUpFcn; figPos = gui.resizeVisu.figPos; buttonPos = gui.resizeVisu.buttonPos; indNextVisu = gui.resizeVisu.indNextVisu; initHeight = gui.resizeVisu.initHeight; curTool = gui.resizeVisu.curTool; indVisu = gui.resizeVisu.indVisu; set(gui.mainFigId, 'WindowButtonMotionFcn', backupButtonMotionFcn); set(gui.mainFigId, 'WindowButtonUpFcn', backupButtonUpFcn); % restore the tool changeTool(objId, eventData, curTool); end function toggleModVisu(objId, eventData) global visu gui oriInd = find(strcmp('originalMain', {visu.label}), 1); modInd = find(strcmp('modified', {visu.label}), 1); overInd = find(strcmp('originalOverview', {visu.label}), 1); if visu(modInd).visible visu(modInd).visible = false; set(gui.visuMenu.showModId, 'Checked', 'off'); visu(oriInd).height = visu(oriInd).height + visu(modInd).height; else flagBuggyCase = false; if visu(overInd).visible % In Octave we get a crash if we show the modified visu while the % overview is already shown, so we need to temporary hide the overview flagBuggyCase = true; end if flagBuggyCase oriHeight = visu(oriInd).height; overHeight = visu(overInd).height; toggleOverviewVisu; end visu(modInd).visible = true; set(gui.visuMenu.showModId, 'Checked', 'on'); visu(modInd).height = visu(oriInd).height / 2; visu(oriInd).height = visu(oriInd).height / 2; if flagBuggyCase toggleOverviewVisu; visu(modInd).height = oriHeight / 2; visu(oriInd).height = oriHeight / 2; visu(overInd).height = overHeight; end end updateVisu; resize; end function toggleOverviewVisu(objId, eventData) global visu gui oriInd = find(strcmp('originalMain', {visu.label}), 1); overviewInd = find(strcmp('originalOverview', {visu.label}), 1); if visu(overviewInd).visible visu(overviewInd).visible = false; set(gui.visuMenu.showOverviewId, 'Checked', 'off'); visu(oriInd).height = visu(oriInd).height + visu(overviewInd).height; else visu(overviewInd).visible = true; set(gui.visuMenu.showOverviewId, 'Checked', 'on'); visu(overviewInd).height = visu(oriInd).height * 1/3; visu(oriInd).height = visu(oriInd).height * 2/3; end updateVisu; resize; end % ______________________ AUDIOPLAYER FUNCTIONS ____________________________ function initializePlayer() global player sig player.ori = audioplayer(sig.ori, sig.sampFreq); player.mod = audioplayer(sig.mod, sig.sampFreq); player.selected = 'ori'; player.loop = false; player.position = 1; player.forceStop = false; end function drawAudioplayer(uipanelId) global gui subPanelHeight = 2*gui.textHeight + 2*gui.marginSub(2) +... gui.vertDist+gui.fontSize+2; % Octave does not provide uibuttongroup so we need to handle the radiobuttons % by hand gui.player.buttongroupId = uipanel(... 'Parent', uipanelId,... 'Title', 'Signal',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, 1, gui.panelWidth-4, subPanelHeight]); gui.player.buttonOriId = uicontrol(... 'Parent', gui.player.buttongroupId,... 'Style', 'radiobutton',... 'FontSize', gui.fontSize, ... 'String', ' Original',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Tag', 'ori',... 'Value', true,... 'CallBack', @switchAudioplayer,... 'Position', [gui.marginSub(1),... gui.textHeight+gui.marginSub(2)+gui.vertDist,... gui.panelWidth-4-2*gui.marginSub(2),... gui.textHeight]); gui.player.buttonModId = uicontrol(... 'Parent', gui.player.buttongroupId,... 'Style', 'radiobutton',... 'FontSize', gui.fontSize, ... 'String', ' Modified',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Tag', 'mod',... 'Value', false,... 'CallBack', @switchAudioplayer,... 'Position', [gui.marginSub,... gui.panelWidth-4-2*gui.marginSub(2),... gui.textHeight]); yPos = subPanelHeight; buttonPlayPauseId = uicontrol(... 'Parent', uipanelId,... 'Style', 'pushbutton',... 'TooltipString', 'Play/pause audio',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(1, 1, gui.margin + [0, yPos]),... 'CallBack',@playPauseAudioplayer); setButtonAppearance(buttonPlayPauseId, 'play', 'play.png'); buttonStopId = uicontrol(... 'Parent', uipanelId,... 'Style', 'pushbutton',... 'TooltipString', 'Stop audio',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(2, 1, gui.margin + [0, yPos]),... 'CallBack',@stopAudioplayer); setButtonAppearance(buttonStopId, 'stop', 'stop.png'); buttonLoopId = uicontrol(... 'Parent', uipanelId, ... 'Style', 'togglebutton',... 'TooltipString', 'Loop audio',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(3, 1, gui.margin + [0, yPos]),... 'CallBack',@loopAudioplayer,... 'Min', false,... 'Max', true,... 'Value', false); setButtonAppearance(buttonLoopId, 'loop', 'loop.png'); end function switchAudioplayer(objId, eventData) global player gui stopAudioplayer; if player.selected == 'ori' set(gui.player.buttonOriId, 'Value', false); set(gui.player.buttonModId, 'Value', true); player.selected = 'mod'; else set(gui.player.buttonOriId, 'Value', true); set(gui.player.buttonModId, 'Value', false); player.selected = 'ori'; end end function playPauseAudioplayer(objId, eventData) global player visu sig switch player.selected case 'ori' currPlayer = player.ori; case 'mod' currPlayer = player.mod; end if isplaying(currPlayer) player.forceStop = true; pause(currPlayer); player.position = get(currPlayer, 'CurrentSample'); else for ind = 1:length(player.positionPlotId) if visu(ind).visible set(player.positionPlotId(ind), 'Visible', 'on'); end end player.forceStop = false; if get(currPlayer, 'CurrentSample') == 0 ||... get(currPlayer, 'CurrentSample') == get(currPlayer, 'TotalSamples') play(currPlayer); else resume(currPlayer); end while isplaying(currPlayer) pos = (get(currPlayer, 'CurrentSample')-1) / sig.sampFreq; for ind = 1:length(player.positionPlotId) if visu(ind).visible set(player.positionPlotId(ind), 'XData', [pos pos]); end end pause(1/15); end if player.loop && ~player.forceStop pause(0.1); % Needed to avoid java error playPauseAudioplayer(); end for ind = 1:length(player.positionPlotId) if visu(ind).visible set(player.positionPlotId(ind), 'Visible', 'off'); end end end end function stopAudioplayer(objId, eventData) global player player.forceStop = true; stop(player.ori); stop(player.mod); player.position = 1; end function playerStopFcnOri(objId, eventData) global player visu for ind = 1:length(player.positionPlotId) if visu(ind).visible set(player.positionPlotId(ind), 'Visible', 'off'); end end player.position = get(player.ori, 'CurrentSample'); if player.loop && ~player.forceStop pause(0.1); % needed to avoid java error play(player.ori, player.position); end end function playerStopFcnMod(objId, eventData) global player visu for ind = 1:length(player.positionPlotId) if visu(ind).visible set(player.positionPlotId(ind), 'Visible', 'off'); end end player.position = get(player.mod, 'CurrentSample'); if player.loop && ~player.forceStop pause(0.1); % needed to avoid java error play(player.mod, player.position); end end function loopAudioplayer(objId, eventData) global player player.loop = get(objId, 'Value'); end function updatePlayPosition(objId, eventData) global player sig visu pos = (get(objId, 'CurrentSample')-1) / sig.sampFreq; for ind = 1:length(player.positionPlotId) if visu(ind).visible set(player.positionPlotId(ind), 'XData', [pos pos]); end end end function updatePlayerMod() global player sig player.mod = audioplayer(sig.mod, sig.sampFreq); end % ____________________ SELECTION TOOLS FUNCTIONS __________________________ function drawSelectionTool(uipanelId) global gui subSize = subpanelSize(1); processingToolPanelId = uipanel(... 'Parent', uipanelId,... 'Title', 'Apply',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, 1, subSize]); % draw processing tools subpanel drawProcessingTool(processingToolPanelId); heightLayerPanel = 115; layerPanelId = uipanel(... 'Parent', uipanelId,... 'Title', 'Layers',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, 1+subSize(2), subSize(1), heightLayerPanel]); % draw layer panel drawLayerPanel(layerPanelId); % Octave does not provide uibuttongroup so we need to handle the % tooglebuttons by hand buttongroupId = uipanel(... 'Parent', uipanelId,... 'Title', 'Mode',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, subSize(2)+heightLayerPanel+1, subSize]); gui.buttonUnionId = uicontrol(... 'Parent',buttongroupId,... 'Style', 'togglebutton',... 'TooltipString', 'Union',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Tag', 'union',... 'Position', buttonPos(1, 1, gui.marginSub),... 'Value', true,... 'Callback', @switchSelMode); setButtonAppearance(gui.buttonUnionId, 'u', 'union.png'); gui.buttonInterId = uicontrol(... 'Parent',buttongroupId,... 'Style', 'togglebutton',... 'TooltipString', 'Intersection',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Tag', 'intersection',... 'Position', buttonPos(2, 1, gui.marginSub),... 'Value', false,... 'Callback', @switchSelMode); setButtonAppearance(gui.buttonInterId, 'n', 'intersection.png'); gui.buttonDiffId = uicontrol(... 'Parent',buttongroupId,... 'Style', 'togglebutton',... 'TooltipString', 'Set difference',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Tag', 'difference',... 'Position', buttonPos(3, 1, gui.marginSub), ... 'Value', false,... 'Callback', @switchSelMode); setButtonAppearance(gui.buttonDiffId, '-', 'difference.png'); % reserved space to draw parameters of the tools gui.toolPanelId = uipanel(... 'Parent', uipanelId,... 'Title', 'Tools',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize,... 'Units', 'pixels',... 'Position', [1, 2*subSize(2)+heightLayerPanel+1, subSize(1),... 2*gui.marginSub(2) + gui.vertDist + gui.textHeight + ... gui.buttonHeight + gui.fontSize+2]); buttonFreehandId = uicontrol(... 'Parent', gui.toolPanelId,... 'HandleVisibility', 'off',... 'Style', 'togglebutton',... 'TooltipString', 'Free-hand selection',... 'Min', false,... 'Max', true,... 'Value', false,... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(1, 1,... gui.marginSub+[0,... gui.marginSub(2)+gui.textHeight]),... 'CallBack', {@changeTool, 'freehand'}); setButtonAppearance(buttonFreehandId, 'free', 'freehand.png'); gui.tool(end+1).buttonId = buttonFreehandId; gui.tool(end).name = 'freehand'; gui.tool(end).function = @selecFreehand; buttonLevelId = uicontrol(... 'Parent', gui.toolPanelId,... 'HandleVisibility', 'off',... 'Style', 'togglebutton',... 'TooltipString', 'Magic wand (Level selection)',... 'Min', false,... 'Max', true,... 'Value', false,... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(2, 1,... gui.marginSub+[0,... gui.marginSub(2)+gui.textHeight]),... 'CallBack', {@changeTool, 'level'}); setButtonAppearance(buttonLevelId, 'wand', 'magicwand.png'); gui.tool(end+1).buttonId = buttonLevelId; gui.tool(end).name = 'level'; gui.tool(end).function = @selecLevel; gui.tool(end).param.name = 'Tolerance'; gui.tool(end).param.val = '10'; % value of the tolerance in dB buttonSubbandId = uicontrol(... 'Parent', gui.toolPanelId,... 'HandleVisibility', 'off',... 'Style', 'togglebutton',... 'TooltipString', 'Subband selection',... 'Min', false,... 'Max', true,... 'Value', false,... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(3, 1,... gui.marginSub+[0,... gui.marginSub(2)+gui.textHeight]),... 'CallBack', {@changeTool, 'subband'}); setButtonAppearance(buttonSubbandId, 'sub', 'subbandsel.png'); gui.tool(end+1).buttonId = buttonSubbandId; gui.tool(end).name = 'subband'; gui.tool(end).function = @selecSubband; end function changeTool(objId, eventData, toolName) global gui zoom(gui.mainFigId, 'off'); pan(gui.mainFigId, 'off'); for ind = 1:length(gui.tool) set(gui.tool(ind).buttonId, 'Value', false); end toolNameList = {gui.tool.name}; % cell array listing the tool names curInd = find(strcmp(toolName, toolNameList)); set(gui.tool(curInd).buttonId, 'Value', true); gui.curTool = gui.tool(curInd).name; gui.tool(curInd).function(curInd); drawToolParam(curInd); end function drawToolParam(toolInd) global gui child = findobj(gui.toolPanelId); child = setdiff(child, gui.toolPanelId); delete(child); for ind = 1:length(gui.tool(toolInd).param) uicontrol(... 'Parent', gui.toolPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'text',... 'String', gui.tool(toolInd).param(ind).name,... 'Position', [gui.marginSub(1),... gui.marginSub(2)+(ind-1)*(gui.textHeight+gui.vertDist),... gui.textWidth, gui.textHeight]) ; uicontrol(... 'Parent', gui.toolPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'edit',... 'BackgroundColor', gui.buttonBackgroundColor,... 'String', gui.tool(toolInd).param(ind).val,... 'Position', [gui.marginSub(1)+gui.textWidth,... gui.marginSub(2)+(ind-1)*(gui.textHeight+gui.vertDist),... gui.editWidth, gui.textHeight],... 'Callback', {@changeToolParam, toolInd, ind}); end end function changeToolParam(objId, eventData, toolInd, paramInd) global gui gui.tool(toolInd).param(paramInd).val = get(objId, 'String'); end function selecFreehand(toolInd) % NOTE: toolInd is not used but needed as a parameter is always passed to % this function global gui visu oriInd = find(strcmp('originalMain', {visu.label}), 1); axesId = visu(oriInd).axesId; imageId = findobj(axesId, 'Type', 'Image'); set(imageId, 'ButtonDownFcn', @selecFreeHandButtonDown); gui.selecFreehand.poly.x = []; gui.selecFreehand.poly.y = []; gui.selecFreehand.init = true; % boolean to know if we are drawing the first % point or not gui.selecFreehand.lineId = []; end function selecFreeHandButtonDown(objId, eventData) global gui visu sel poly = gui.selecFreehand.poly; oriInd = find(strcmp('originalMain', {visu.label}), 1); axesId = visu(oriInd).axesId; switch get(gui.mainFigId,'SelectionType') case 'normal' if gui.selecFreehand.init point = get(axesId,'CurrentPoint'); poly.x = [point(1,1)]; poly.y = [point(1,2)]; poly.hole = false; gui.selecFreehand.lineId = line(... 'XData', poly.x,... 'YData', poly.y,... 'LineWidth', sel.lay(sel.curLay).lineWidth,... 'Color', sel.lay(sel.curLay).color,... 'Marker', sel.lay(sel.curLay).marker,... 'MarkerSize', sel.lay(sel.curLay).markerSize,... 'LineStyle', sel.lay(sel.curLay).lineStyle); gui.selecFreehand.init = false; set(gui.mainFigId,'WindowButtonDownFcn',@selecFreeHandButtonDown); set(gui.mainFigId,'WindowButtonMotionFcn',@selecFreeHandMotion); else point = get(axesId,'CurrentPoint'); poly.x = [poly.x; point(1,1)]; poly.y = [poly.y; point(1,2)]; set(gui.selecFreehand.lineId, 'XData',poly.x , 'YData', poly.y); drawnow; end case 'alt' if ~gui.selecFreehand.init set(gui.mainFigId,'WindowButtonMotionFcn',''); set(gui.mainFigId,'WindowButtonDownFcn',''); set(gui.mainFigId,'WindowButtonUpFcn',''); gui.selecFreehand.init = true; delete(gui.selecFreehand.lineId); combineSel(poly); drawCurSel; end end gui.selecFreehand.poly = poly; end function selecFreeHandMotion(objId, eventData) global gui visu poly = gui.selecFreehand.poly; oriInd = find(strcmp('originalMain', {visu.label}), 1); axesId = visu(oriInd).axesId; point = get(axesId,'CurrentPoint'); xData = [poly.x; point(1,1)]; yData = [poly.y; point(1,2)]; set(gui.selecFreehand.lineId, 'XData', xData, 'YData', yData); drawnow; end function selecLevel(toolInd) global visu oriInd = find(strcmp('originalMain', {visu.label}), 1); imageId = findobj(visu(oriInd).axesId, 'Type', 'Image'); set(imageId, 'ButtonDownFcn', {@selecLevelButtonDown, toolInd}); end function selecLevelButtonDown(objId, eventData, toolInd) global visu coeff gui oriInd = find(strcmp('originalMain', {visu.label}), 1); point = get(visu(oriInd).axesId,'CurrentPoint'); indTime = round(convAxesToIndX(point(1,1))); indFreq = round(convAxesToIndY(point(1,2))); refLevel = coeff.oriC(indFreq, indTime); levelTol = str2num(gui.tool(toolInd).param.val); if isempty(levelTol) || levelTol < 0 errordlg(['Tolerance parameter for magic wand is invalid, '... 'it must be a positive number in dB']); return; end lowLevel = refLevel - levelTol; highLevel = refLevel + levelTol; mask = (coeff.oriC >= lowLevel) & (coeff.oriC <= highLevel); mask = selectRoi(mask, indTime, indFreq); poly = convMaskToPoly(mask); combineSel(poly); drawCurSel; end function maskRoi = selectRoi(mask, indTime, indFreq) global gui if gui.hasImagePackage maskRoi = bwselect(mask, indTime, indFreq, 4); else % PI: The following implementation of the flood fill algorithm is not very % efficient and could be improved (for example using a scan-line approach) maskRoi = zeros(size(mask)); queueRow = indFreq; queueCol = indTime; while ~isempty(queueRow) row = queueRow(1); col = queueCol(1); queueRow = queueRow(2:end); queueCol = queueCol(2:end); if ~maskRoi(row, col) && mask(row, col) maskRoi(row, col) = 1; if col+1 < size(mask, 1) queueRow(end+1) = row; queueCol(end+1) = col+1; end if col-1 >= 1 queueRow(end+1) = row; queueCol(end+1) = col-1; end if row+1 < size(mask, 2) queueRow(end+1) = row+1; queueCol(end+1) = col; end if row-1 >= 1 queueRow(end+1) = row-1; queueCol(end+1) = col; end end end end end function selecSubband(toolInd) global visu gui oriInd = find(strcmp('originalMain', {visu.label}), 1); axesId = visu(oriInd).axesId; imageId = findobj(axesId, 'Type', 'Image'); set(imageId, 'ButtonDownFcn', @selecSubbandButtonDown); gui.selecSubband.selection = []; set(gui.mainFigId,'WindowButtonMotionFcn',''); set(gui.mainFigId,'WindowButtonUpFcn',''); end function selecSubbandButtonDown(objId, eventData) global visu gui coeff sel oriInd = find(strcmp('originalMain', {visu.label}), 1); point = get(visu(oriInd).axesId,'CurrentPoint'); gui.selecSubband.selection = [point(1, 2), point(1, 2)]; hold(visu(oriInd).axesId, 'on'); xVal = convIndToAxesX([0.5, size(coeff.oriC, 2)+0.5]); yVal = gui.selecSubband.selection; gui.selecSubband.lineId(1) = line(... 'XData', [xVal(1), xVal(2), xVal(2), xVal(1), xVal(1)],... 'YData', [yVal(1), yVal(1), yVal(2), yVal(2), yVal(1)],... 'LineWidth', sel.lay(sel.curLay).lineWidth,... 'Color', sel.lay(sel.curLay).color,... 'Marker', sel.lay(sel.curLay).marker,... 'MarkerSize', sel.lay(sel.curLay).markerSize,... 'LineStyle', sel.lay(sel.curLay).lineStyle); hold(visu(oriInd).axesId, 'off'); set(gui.mainFigId, 'WindowButtonMotionFcn', @selecSubbandMotionDown); set(gui.mainFigId,'WindowButtonUpFcn', @selecSubbandButtonUp); end function selecSubbandMotionDown(objId, eventData) global visu gui oriInd = find(strcmp('originalMain', {visu.label}), 1); point = get(visu(oriInd).axesId,'CurrentPoint'); gui.selecSubband.selection(2) = point(1,2); set(gui.selecSubband.lineId, 'YData',... [gui.selecSubband.selection(1), gui.selecSubband.selection(1),... gui.selecSubband.selection(2), gui.selecSubband.selection(2),... gui.selecSubband.selection(1)]); end function selecSubbandButtonUp(objId, eventData) global gui set(gui.mainFigId,'WindowButtonMotionFcn',''); set(gui.mainFigId,'WindowButtonUpFcn',''); poly.x = get(gui.selecSubband.lineId, 'XData').'; poly.y = get(gui.selecSubband.lineId, 'YData').'; poly.hole = false; delete(gui.selecSubband.lineId); combineSel(poly); drawCurSel; end function [poly] = convMaskToPoly(mask) poly = mask2poly(mask); for ind = 1:length(poly) poly(ind).x = convIndToAxesX(poly(ind).x); poly(ind).y = convIndToAxesY(poly(ind).y); end end function [poly] = mask2poly(mask) % Convert region mask to region of interest (ROI) polygon % PI: The polygon outputed by this function should be simplified (the portions % having multiple points aligned should be replaced by a single line segment) maskRef = mask; mask = zeros(size(mask, 1)+2, size(mask, 2)+2); mask(2:end-1,2:end-1) = maskRef; [ind1, ind2] = find(mask); % position of segments on the edge for first dimension seg1 = sparse(size(mask,1)+1, size(mask,2)); % position of segments on the edge for second dimension seg2 = sparse(size(mask,1), size(mask,2)+1) ; for n = 1:length(ind1) if ~mask(ind1(n)-1, ind2(n)) seg1(ind1(n), ind2(n)) = 1; end if ~mask(ind1(n)+1, ind2(n)) seg1(ind1(n)+1, ind2(n)) = 1; end if ~mask(ind1(n), ind2(n)-1) seg2(ind1(n), ind2(n)) = 1; end if ~mask(ind1(n), ind2(n)+1) seg2(ind1(n), ind2(n)+1) = 1; end end ind = 0; while nnz(seg1)>1 curve = chainSeg; if ~isempty(curve) ind = ind+1; poly(ind).x = curve(:,2); poly(ind).y = curve(:,1); for xVal = poly(ind).x(1) + [0.5, -0.5] for yVal = poly(ind).y(1) + [0.5, -0.5] if inpolygon (xVal, yVal, poly(ind).x, poly(ind).y) poly(ind).hole = ~logical(maskRef(yVal, xVal)); break end end end end end function curve = chainSeg() % chaining of segments % choose one start segment [ind1, ind2] = find(seg1); ind1 = ind1(1); ind2 = ind2(1); curve = [ind1, ind2; ind1, ind2+1]; seg1(ind1, ind2) = 0; % pos is a variable to remember in which direction we are % progressing % [1 1] if we're going in a growing index number % [-1 0] otherwise pos = [1, 1]; % precise if the last added segment comes from seg1 or seg2 last1 = true; while true if last1 % the last segment was from dimension 1 if seg1(ind1, ind2+pos(1)) ind2 = ind2+pos(1); seg1(ind1, ind2) = 0; curve = [curve; ind1, ind2+pos(2)]; elseif seg2(ind1-1, ind2+pos(2)) ind1 = ind1-1; ind2 = ind2+pos(2); pos = [-1, 0]; seg2(ind1, ind2) = 0; curve = [curve; ind1, ind2]; last1 = false; elseif seg2(ind1, ind2+pos(2)) ind2 = ind2+pos(2); pos = [1, 1]; seg2(ind1, ind2) = 0; curve = [curve; ind1+1, ind2]; last1 = false; else break; end else % the last segment was from dimension 2 if seg2(ind1+pos(1), ind2) ind1 = ind1+pos(1); seg2(ind1, ind2) = 0; curve = [curve; ind1+pos(2), ind2]; elseif seg1(ind1+pos(2), ind2-1) ind1 = ind1+pos(2); ind2 = ind2-1; pos = [-1, 0]; seg1(ind1, ind2) = 0; curve = [curve; ind1, ind2]; last1 = true; elseif seg1(ind1+pos(2), ind2) ind1 = ind1+pos(2); pos = [1, 1]; seg1(ind1, ind2) = 0; curve = [curve; ind1, ind2+1]; last1 = true; else break; end end end curve = curve-1.5; if size(curve, 1)==2 % the first segment couldn't be linked to some other segment, % there is no polygon curve = []; end end end function [outPol] = clipPoly(refPol, clipPol, typeFlag) % typeFlag defines the polygon clipping operation with: % 0 - Substraction % 1 - Intersection % 2 - Xor % 3 - Union global gui switch gui.backendClipPoly case 'clipper' [refPolCell, refHoles] = convertPolIn(refPol); [clipPolCell, clipHoles] = convertPolIn(clipPol); operation = convertTypeFlagToOperation(typeFlag); [outPolCell, outHoles] = polyboolclipper(refPolCell, clipPolCell,... operation, refHoles, clipHoles); outPol = convertPolOut(outPolCell, outHoles); case 'polygonclip' outPol = PolygonClip(refPol, clipPol, typeFlag); case 'binmasks' refMask = convPolyToMask(refPol); clipMask = convPolyToMask(clipPol); switch typeFlag case 0 % substraction mask = refMask - clipMask; case 1 % intersection mask = and(refMask, clipMask); case 2 % xor mask = xor(refMask, clipMask); case 3 % union mask = or(refMask, clipMask); end outPol = convMaskToPoly(mask); end end function [operation] = convertTypeFlagToOperation(type) operation_match = {'notb', 'and', 'xor', 'or'}; operation = operation_match{type+1}; end function [polCell, holes] = convertPolIn(pol) polCell = {}; holes = false(length(pol), 1); for ind = 1:length(pol) polCell{end+1} = [pol(ind).x, pol(ind).y]; holes(ind) = logical(pol(ind).hole); end end function [pol] = convertPolOut(polCell, holes) if isempty(polCell) pol = []; else for ind = 1:length(polCell) pol(ind).x = polCell{ind}(:, 1); pol(ind).y = polCell{ind}(:, 2); pol(ind).hole = holes(ind); end end end function combineSel(poly) global sel if ~isempty(sel.lay(sel.curLay).poly) % there is already a selection that should be combined with the new one switch sel.mode case 'union' newPoly = clipPoly(sel.lay(sel.curLay).poly, poly, 3); case 'intersection' newPoly = clipPoly(sel.lay(sel.curLay).poly, poly, 1); case 'difference' newPoly = clipPoly(sel.lay(sel.curLay).poly, poly, 0); end % we must remove the selection plot before replacing the selection data delCurPoly; sel.lay(sel.curLay).poly = newPoly; else % the selection was empty if strcmp(sel.mode, 'union') updateUndoData; sel.lay(sel.curLay).poly = poly; end end end function delCurPoly() global sel updateUndoData; if ~isempty(sel.lay(sel.curLay).poly) for ind = 1:length(sel.lay(sel.curLay).poly) delete(sel.lay(sel.curLay).poly(ind).id); end sel.lay(sel.curLay).poly = []; end end function delAllPoly() global sel updateUndoData; for indLay = 1:length(sel.lay) if ~isempty(sel.lay(indLay).poly) for ind = 1:length(sel.lay(indLay).poly) delete(sel.lay(indLay).poly(ind).id); end sel.lay(indLay).poly = []; end end end function delSel() % delete graphical selection (but keep the polygons) global sel for indLay = 1:length(sel.lay) if ~isempty(sel.lay(indLay).poly) for ind = 1:length(sel.lay(indLay).poly) delete(sel.lay(indLay).poly(ind).id); end end end end function resetSel() % erase sel and put it to default value global sel gui default sel = default.sel; if isfield(gui, 'layListId') if ishandle(gui.layListId) set(gui.layListId, 'Value', sel.curLay); drawLayParam(sel.curLay); updateLayerList; end end end function drawCurSel() global visu sel handleSymb; oriInd = find(strcmp('originalMain', {visu.label}), 1); hold(visu(oriInd).axesId, 'on'); if ~isempty(sel.lay(sel.curLay).poly) for ind = 1:length(sel.lay(sel.curLay).poly) sel.lay(sel.curLay).poly(ind).id = line(... 'XData', [sel.lay(sel.curLay).poly(ind).x;... sel.lay(sel.curLay).poly(ind).x(1)],... 'YData', [sel.lay(sel.curLay).poly(ind).y;... sel.lay(sel.curLay).poly(ind).y(1)],... 'LineWidth', sel.lay(sel.curLay).lineWidth,... 'Color', sel.lay(sel.curLay).color,... 'Marker', sel.lay(sel.curLay).marker,... 'MarkerSize', sel.lay(sel.curLay).markerSize,... 'LineStyle', sel.lay(sel.curLay).lineStyle,... 'Parent', visu(oriInd).axesId); end end hold(visu(oriInd).axesId, 'off'); end function drawAllSel() global visu sel handleSymb; oriInd = find(strcmp('originalMain', {visu.label}), 1); hold(visu(oriInd).axesId, 'on'); for indLay = 1:length(sel.lay) if ~isempty(sel.lay(indLay).poly) for ind = 1:length(sel.lay(indLay).poly) sel.lay(indLay).poly(ind).id = line(... 'XData', [sel.lay(indLay).poly(ind).x;... sel.lay(indLay).poly(ind).x(1)],... 'YData', [sel.lay(indLay).poly(ind).y;... sel.lay(indLay).poly(ind).y(1)],... 'LineWidth', sel.lay(indLay).lineWidth,... 'Color', sel.lay(indLay).color,... 'Marker', sel.lay(indLay).marker,... 'MarkerSize', sel.lay(indLay).markerSize,... 'LineStyle', sel.lay(indLay).lineStyle,... 'Parent', visu(oriInd).axesId); end end end hold(visu(oriInd).axesId, 'off'); end function handleSymb() global gui delete(gui.symbImageId); gui.symbImageId = []; if gui.showSymb showSymb(); end end function showSymb() global coeff gui symbol visu % plot symbol of the multiplier oriInd = find(strcmp('originalMain', {visu.label}), 1); axesId = visu(oriInd).axesId; hold(axesId, 'on'); symb = symbol.data(symbol.curSymb).val; if(isempty(symb)) absSymb = abs(convSelToSymb()); else absSymb = abs(symb); end if(symbol.data(symbol.curSymb).invert) absSymb = max([1,max(absSymb(:))])-absSymb; end % Symbol is represented using transparency, with two different % colors for absolute values of the symbol in [0,1] and for values > 1. % Transparency is total for absolute value of 1, and opacity % grows when going away from 1 % PI: these colors should be set as variables that the user can set color1 = [0 0 0]; % black color2 = [1 1 1]; % white % PI: A dB scale could be used for transparency nbTime = size(coeff.oriC, 2); % construct the image with white for value > 1 and black in other parts tempIm = repmat(reshape(color1, [1 1 3]), [nbPlottedFreq() nbTime 1]); [ind1, ind2] = find(absSymb(1:nbPlottedFreq(), :) > 1); if ~isempty(ind1) for ind3 = 1:size(tempIm, 3) ind = sub2ind(size(tempIm), ind1, ind2, ind3 + zeros(size(ind1))); tempIm(ind) = color2(ind3); end end % construct transparency data % initialisation using formula valid for values in [0, 1] tempAlpha = (1 - absSymb(1:nbPlottedFreq(), :)); % correction for values > 1 ind = sub2ind(size(tempAlpha), ind1, ind2); tempAlpha(ind) = 1 - 1./absSymb(ind); gui.symbImageId = image(... convIndToAxesX([1, nbTime]),... convIndToAxesY([1, nbPlottedFreq]),... tempIm,... 'alphaData',gui.symbOpacity * tempAlpha,... 'Parent', axesId); hold(axesId, 'off'); % restore the current tool changeTool([], [], gui.curTool); end function switchSelMode(objId,eventData) global sel gui sel.mode = get(objId,'Tag'); modesIds = [gui.buttonUnionId,gui.buttonInterId,gui.buttonDiffId]; modesIds = setdiff(modesIds, objId); for modeId = modesIds set(modeId, 'Value', false); end set(objId, 'Value', true); end function drawProcessingTool(uipanelId) % creation of apply button global gui applyId = uicontrol(... 'Parent', uipanelId,... 'Style', 'pushbutton',... 'TooltipString', 'Apply multiplier',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(2, 1, gui.marginSub),... 'CallBack',@applySel); setButtonAppearance(applyId, 'x', 'apply.png'); end % __________________________ LAYERS FUNCTIONS _____________________________ function drawLayerPanel(uipanelId) global gui layUicontextmenu = uicontextmenu; uimenu(layUicontextmenu,... 'Label', 'Line color',... 'Callback', @changeSelLayColor); layStyleMenuId = uimenu(layUicontextmenu,... 'Label', 'Line style'); uimenu(layStyleMenuId,... 'Label', 'Solid',... 'Callback', {@changeSelLayStyle, '-'}); uimenu(layStyleMenuId,... 'Label', 'Dashed',... 'Callback', {@changeSelLayStyle, '--'}); uimenu(layStyleMenuId,... 'Label', 'Dot',... 'Callback', {@changeSelLayStyle, ':'}); uimenu(layStyleMenuId,... 'Label', 'Dash-dot',... 'Callback', {@changeSelLayStyle, '-.'}); uimenu(layStyleMenuId,... 'Label', 'None',... 'Callback', {@changeSelLayStyle, 'none'}); layWidthMenuId = uimenu(layUicontextmenu,... 'Label', 'Line width'); uimenu(layWidthMenuId,... 'Label', '1.0',... 'Callback', {@changeSelLayWidth, 1}); uimenu(layWidthMenuId,... 'Label', '2.0',... 'Callback', {@changeSelLayWidth, 2}); uimenu(layWidthMenuId,... 'Label', '3.0',... 'Callback', {@changeSelLayWidth, 3}); uimenu(layWidthMenuId,... 'Label', '4.0',... 'Callback', {@changeSelLayWidth, 4}); uimenu(layWidthMenuId,... 'Label', '5.0',... 'Callback', {@changeSelLayWidth, 5}); uimenu(layWidthMenuId,... 'Label', '6.0',... 'Callback', {@changeSelLayWidth, 6}); uimenu(layWidthMenuId,... 'Label', '7.0',... 'Callback', {@changeSelLayWidth, 7}); uimenu(layWidthMenuId,... 'Label', '8.0',... 'Callback', {@changeSelLayWidth, 8}); uimenu(layWidthMenuId,... 'Label', '9.0',... 'Callback', {@changeSelLayWidth, 9}); uimenu(layWidthMenuId,... 'Label', '10.0',... 'Callback', {@changeSelLayWidth, 10}); layMarkerMenuId = uimenu(layUicontextmenu,... 'Label', 'Marker'); uimenu(layMarkerMenuId,... 'Label', 'None',... 'Callback', {@changeSelLayMarker, 'none'}); uimenu(layMarkerMenuId,... 'Label', '+',... 'Callback', {@changeSelLayMarker, '+'}); uimenu(layMarkerMenuId,... 'Label', 'o',... 'Callback', {@changeSelLayMarker, 'o'}); uimenu(layMarkerMenuId,... 'Label', '*',... 'Callback', {@changeSelLayMarker, '*'}); uimenu(layMarkerMenuId,... 'Label', '.',... 'Callback', {@changeSelLayMarker, '.'}); uimenu(layMarkerMenuId,... 'Label', 'x',... 'Callback', {@changeSelLayMarker, 'x'}); uimenu(layMarkerMenuId,... 'Label', 'Square',... 'Callback', {@changeSelLayMarker, 'square'}); uimenu(layMarkerMenuId,... 'Label', 'Diamond',... 'Callback', {@changeSelLayMarker, 'diamond'}); uimenu(layMarkerMenuId,... 'Label', '^',... 'Callback', {@changeSelLayMarker, '^'}); uimenu(layMarkerMenuId,... 'Label', 'v',... 'Callback', {@changeSelLayMarker, 'v'}); uimenu(layMarkerMenuId,... 'Label', '>',... 'Callback', {@changeSelLayMarker, '>'}); uimenu(layMarkerMenuId,... 'Label', '<',... 'Callback', {@changeSelLayMarker, '<'}); uimenu(layMarkerMenuId,... 'Label', 'Pentagram',... 'Callback', {@changeSelLayMarker, 'pentagram'}); uimenu(layMarkerMenuId,... 'Label', 'Hexagram',... 'Callback', {@changeSelLayMarker, 'hexagram'}); layMarkerSizeMenuId = uimenu(layUicontextmenu,... 'Label', 'Marker Size'); uimenu(layMarkerSizeMenuId,... 'Label', '2.0',... 'Callback', {@changeSelLayMarkerSize, 2}); uimenu(layMarkerSizeMenuId,... 'Label', '3.0',... 'Callback', {@changeSelLayMarkerSize, 3}); uimenu(layMarkerSizeMenuId,... 'Label', '4.0',... 'Callback', {@changeSelLayMarkerSize, 4}); uimenu(layMarkerSizeMenuId,... 'Label', '5.0',... 'Callback', {@changeSelLayMarkerSize, 5}); uimenu(layMarkerSizeMenuId,... 'Label', '6.0',... 'Callback', {@changeSelLayMarkerSize, 6}); uimenu(layMarkerSizeMenuId,... 'Label', '7.0',... 'Callback', {@changeSelLayMarkerSize, 7}); uimenu(layMarkerSizeMenuId,... 'Label', '8.0',... 'Callback', {@changeSelLayMarkerSize, 8}); uimenu(layMarkerSizeMenuId,... 'Label', '9.0',... 'Callback', {@changeSelLayMarkerSize, 9}); uimenu(layMarkerSizeMenuId,... 'Label', '10.0',... 'Callback', {@changeSelLayMarkerSize, 10}); uimenu(layUicontextmenu,... 'Label', 'Edit label',... 'Callback', @changeSelLayLabel); layTypeMenuId = uimenu(layUicontextmenu,... 'Label', 'Layer type'); uimenu(layTypeMenuId,... 'Label', 'Constant gain',... 'Callback', {@changeSelLayConvType, 'constGain'}); uimenu(layTypeMenuId,... 'Label', 'Gain with smoothed border',... 'Callback', {@changeSelLayConvType, 'smoothBorder'}); if gui.hasImagePackage uimenu(layTypeMenuId,... 'Label', 'Hole filling',... 'Callback', {@changeSelLayConvType, 'fill'}); uimenu(layTypeMenuId,... 'Label', 'Hole filling with noise phase',... 'Callback', {@changeSelLayConvType, 'fillNoise'}); end uimenu(layUicontextmenu,... 'Label', 'Invert layer',... 'Callback', @invertSelLay); uimenu(layUicontextmenu,... 'Label', 'Duplicate layer',... 'Callback', @duplicateSelLay); uimenu(layUicontextmenu,... 'Label', 'Clear layer',... 'Callback', @clearSelLay); uimenu(layUicontextmenu,... 'Label', 'Delete layer',... 'Callback', @delSelLay); uimenu(layUicontextmenu,... 'Label', 'Add new layer',... 'Callback', @addSelLay); gui.layListId = uicontrol(... 'Parent', uipanelId,... 'HandleVisibility', 'off',... 'Style', 'listbox',... 'Fontsize', gui.fontSize,... 'String', '',... 'UIContextMenu', layUicontextmenu,... 'BackgroundColor', [1 1 1],... 'Position', [gui.marginSub(1),... gui.marginSub(2)+2*gui.textHeight+2*gui.vertDist+1,... gui.panelWidth-2*gui.margin(1)-1, 60],... 'CallBack',@changeSelLay); gui.layPanelId = uipanelId; updateLayerList; changeSelLay; end function updateLayerList() global gui sel layCell = {}; if isfield(sel,'lay') for ind = 1:length(sel.lay) layCell{end+1} = sel.lay(ind).label; end set(gui.layListId, 'String', layCell); end end function changeSelLayColor(objId, eventData) global sel try sel.lay(sel.curLay).color = uisetcolor; delSel; drawAllSel; catch % uisetcolor is not available in Octave, so we provide a simple gui chooseLineColor(); end end function chooseLineColor() global gui; mainFigPosition = get(gui.mainFigId, 'Position'); position = [mainFigPosition(1)+mainFigPosition(3)/2,... mainFigPosition(2)+mainFigPosition(4)/2, 250, 100]; gui.chooseLineColor.figId = figure(... 'Name', 'Line color',... 'Position', position,... 'Menubar', 'none',... 'windowstyle', 'modal'); % Note: the 'modal' windowstyle seems ignored in Octave % So we need to make the main window unclicable by hand % and the only solution seem to be hinding the main window, as the % following is not enough (the buttons are still clickable): % set(gui.mainFigId, 'HitTest', 'off'); set(gui.mainFigId, 'Visible', 'off'); uimenu(gui.chooseLineColor.figId); % Removing the default menu buttonOkId = uicontrol(... 'Parent', gui.chooseLineColor.figId,... 'Style', 'pushbutton',... 'String', 'OK',... 'Callback', @chooseLineColorOk,... 'Position', [50, 10, 50, 30]); buttonCancelId = uicontrol(... 'Parent', gui.chooseLineColor.figId,... 'Style', 'pushbutton',... 'String', 'Cancel',... 'Callback', @chooseLineColorCancel,... 'Position', [150, 10, 50, 30]); gui.chooseLineColor.colors = {'w', 'k', 'r', 'g', 'b', 'y', 'm', 'c'}; colorLabels = {'white', 'black', 'red', 'green', 'blue', 'yelow',... 'magenta', 'cyan'}; defaultValue = 1; gui.chooseLineColor.popupmenuId = uicontrol(... 'Parent', gui.chooseLineColor.figId,... 'Style', 'popupmenu',... 'String', colorLabels,... 'Value', defaultValue,... 'Position', [25, 50, 200, 30]); end function chooseLineColorOk(objId, eventData) global gui sel; set(gui.mainFigId, 'Visible', 'on'); % Needed for Octave figure(gui.mainFigId); ind = get(gui.chooseLineColor.popupmenuId, 'Value'); close(gui.chooseLineColor.figId); sel.lay(sel.curLay).color = gui.chooseLineColor.colors{ind}; delSel; drawAllSel; end function chooseLineColorCancel(objId, eventData) global gui; set(gui.mainFigId, 'Visible', 'on'); % Needed for Octave figure(gui.mainFigId); close(gui.chooseLineColor.figId); end function changeSelLayStyle(objId, eventData, lineStyle) global sel sel.lay(sel.curLay).lineStyle = lineStyle; delSel; drawAllSel; end function changeSelLayWidth(objId, eventData, lineWidth) global sel sel.lay(sel.curLay).lineWidth = lineWidth; delSel; drawAllSel; end function changeSelLayMarker(objId, eventData, marker) global sel sel.lay(sel.curLay).marker = marker; delSel; drawAllSel; end function changeSelLayMarkerSize(objId, eventData, markerSize) global sel sel.lay(sel.curLay).markerSize = markerSize; delSel; drawAllSel; end function changeSelLayLabel(objId, eventData) global sel newLabel = inputdlg('New label for the current selection layer',... 'Change layer label'); sel.lay(sel.curLay).label = newLabel{1}; updateLayerList; end function changeSelLayConvType(objId, eventData, convType) global sel delSel; sel.lay(sel.curLay).convType = convType; sel.lay(sel.curLay).param = []; switch convType case 'constGain' sel.lay(sel.curLay).param(1).name = 'Gain'; sel.lay(sel.curLay).param(1).val = 0; case 'smoothBorder' sel.lay(sel.curLay).param(1).name = 'Gain'; sel.lay(sel.curLay).param(1).val = 0; sel.lay(sel.curLay).param(2).name = 'Border'; sel.lay(sel.curLay).param(2).val = 10; case 'fill' sel.lay(sel.curLay).param(1).name = 'Width'; sel.lay(sel.curLay).param(1).val = 2; sel.lay(sel.curLay).param(2).name = 'Height'; sel.lay(sel.curLay).param(2).val = 3; case 'fillNoise' sel.lay(sel.curLay).param(1).name = 'Width'; sel.lay(sel.curLay).param(1).val = 2; sel.lay(sel.curLay).param(2).name = 'Height '; sel.lay(sel.curLay).param(2).val = 3; end changeSelLay; drawAllSel; end function invertSelLay(objId, eventData) global sel if isempty(sel.lay(sel.curLay).poly) sel.lay(sel.curLay).poly = fullSigPoly; else % compute difference between a polygon around the whole signal and % the current selection to inverse current selection newPoly = clipPoly(fullSigPoly, sel.lay(sel.curLay).poly, 0); delCurPoly; sel.lay(sel.curLay).poly = newPoly; end drawCurSel; end function poly = fullSigPoly() % compute a polygon corresponding to the whole signal global coeff tempX = convIndToAxesX([0.5, size(coeff.oriC, 2)+0.5]); tempY = convIndToAxesY([0.5, size(coeff.oriC, 1)+0.5]); poly.x = [tempX(1); tempX(2); tempX(2); tempX(1)]; poly.y = [tempY(1); tempY(1); tempY(2); tempY(2)]; poly.hole = false; end function duplicateSelLay(objId, eventData) global sel sel.lay(end+1) = sel.lay(sel.curLay); sel.lay(end).label = [sel.lay(end).label ' copy']; if isfield(sel.lay(end).poly(1), 'id') for ind = 1:length(sel.lay(end).poly) sel.lay(end).poly(ind).id = []; end end updateLayerList; end function clearSelLay(objId, eventData) global sel delSel; updateUndoData; sel.lay(sel.curLay).poly = []; drawAllSel; end function delSelLay(objId, eventData) % check that we leave at least one layer global gui sel if length(sel.lay) == 1 warndlg('The selection must contain at least one layer'); return; end delSel; updateUndoData; sel.lay = sel.lay([1:sel.curLay-1 sel.curLay+1:end]); updateLayerList; set(gui.layListId, 'Value', 1); changeSelLay; drawAllSel; end function addSelLay(objId, eventData) global sel default sel.lay(end+1) = default.sel.lay; sel.lay(end).label = 'New layer'; updateLayerList; end function changeSelLay(objId, eventData) global sel gui sel.curLay = get(gui.layListId, 'Value'); drawLayParam(sel.curLay); end function drawLayParam(layInd) global sel gui if ~isfield(sel,'lay') return; end child = findobj(gui.layPanelId); child = setdiff(child, gui.layPanelId); delete(child); for ind = 1:length(sel.lay(layInd).param) uicontrol(... 'Parent', gui.layPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'text',... 'String', sel.lay(layInd).param(ind).name,... 'Position', [gui.marginSub(1),... gui.marginSub(2)+(ind-1)*(gui.textHeight+gui.vertDist),... gui.textWidth, gui.textHeight]) ; uicontrol(... 'Parent', gui.layPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'edit',... 'String', num2str(sel.lay(layInd).param(ind).val),... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', [gui.marginSub(1)+gui.textWidth,... gui.marginSub(2)+(ind-1)*(gui.textHeight+gui.vertDist),... gui.editWidth, gui.textHeight],... 'Callback', {@changeLayParam, layInd, ind}); end end function changeLayParam(objId, eventData, layInd, paramInd) global sel handleSymb; temp = str2num(get(objId, 'String')); if isempty(temp) errordlg([sel.lay(layInd).param(paramInd).name... ' parameter is invalid']); set(objId, 'String', num2str(sel.lay(layInd).param(paramInd).val)); return; end sel.lay(layInd).param(paramInd).val = temp; end function changeOpacity(objId, eventData) global gui temp = str2num(get(objId, 'String')); if isempty(temp) || temp < 0 || temp > 1 errordlg(['Opacity parameter is invalid, it must be a number '... 'between 0 (transparent) and 1 (opaque)']); set(objId, 'String', num2str(gui.symbOpacity)); return; end gui.symbOpacity = temp; handleSymb(); end % __________________ VISUALIZATION TOOLS FUNCTIONS ________________________ function drawVisualizationTool(uipanelId) global gui default subPanelHeight = gui.margin(2) + gui.buttonHeight +... gui.textHeight + gui.fontSize + 4; visPanelPos = get(uipanelId,'Position'); symbolPanelHeight = 2*subPanelHeight; currPos = 0; symbolPanelId = uipanel(... 'Parent', uipanelId,... 'Title', 'Symbol',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, currPos+1, gui.panelWidth-4 , symbolPanelHeight]); currPos = currPos + symbolPanelHeight; gui.symbListId = uicontrol(... 'Parent', uipanelId,... 'HandleVisibility', 'off',... 'Style', 'listbox',... 'Fontsize', gui.fontSize,... 'String', '',... 'BackgroundColor', [1 1 1],... 'Position', [gui.marginSub(1),... gui.marginSub(2)+2*gui.textHeight+2*gui.vertDist+6,... gui.panelWidth-2*gui.margin(1)-1, 50],... 'CallBack',@changeSelSymb); symbId = uicontrol(... 'Parent', symbolPanelId,... 'Style', 'togglebutton',... 'TooltipString', 'Show multiplier symbol',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(2, 1, gui.marginSub),... 'Value', false,... 'CallBack',@clicSymb); setButtonAppearance(symbId, 'show', 'showsymbol.png'); opacityTextId = uicontrol(... 'Parent', symbolPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'Text',... 'FontSize', gui.fontSize, ... 'String', 'Opacity',... 'Position', [gui.marginSub(1),... gui.marginSub(2)+gui.buttonHeight,... gui.textWidth,... gui.textHeight],... 'CallBack',@changeOpacity); opacityId = uicontrol(... 'Parent', symbolPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'edit',... 'String', num2str(default.opacity),... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', [gui.marginSub(1)+gui.textWidth,... gui.marginSub(2)+gui.buttonHeight, gui.editWidth, gui.textHeight],... 'CallBack',@changeOpacity); if isoctave() % Octave doen't support transprency with images, so we cannot display % the symbol over the spectrogram, so we remove the associated controls set(symbId, 'Visible', 'off'); set(opacityTextId, 'Visible', 'off'); set(opacityId, 'Visible', 'off'); end colormapPanelId = uipanel(... 'Parent', uipanelId,... 'Title', 'Colormap',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, currPos+1, gui.panelWidth-4 , subPanelHeight]); currPos = currPos + subPanelHeight; buttonColormapId = uicontrol(... 'Parent', colormapPanelId,... 'Style', 'pushbutton',... 'TooltipString', 'Edit colormap',... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(2, 1, gui.marginSub),... 'CallBack',@editColormap); setButtonAppearance(buttonColormapId, 'map', 'colormap.png'); uicontrol(... 'Parent', colormapPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'Text',... 'FontSize', gui.fontSize, ... 'String', 'Dynamic',... 'Position', [gui.marginSub(1), gui.marginSub(2)+gui.buttonHeight,... gui.textWidth, gui.textHeight],... 'CallBack',@changeOpacity); gui.editDynamicId = uicontrol(... 'Parent', colormapPanelId,... 'FontSize', gui.fontSize, ... 'Style', 'edit',... 'BackgroundColor', gui.buttonBackgroundColor,... 'String', num2str(default.dynamic),... 'Position', [gui.marginSub(1)+gui.textWidth,... gui.marginSub(2)+gui.buttonHeight,... gui.editWidth,... gui.textHeight],... 'CallBack',@changeDynamic); zoomPanelId = uipanel(... 'Parent', uipanelId,... 'Title', 'Zoom',... 'TitlePosition', 'centertop',... 'FontSize', gui.fontSize, ... 'Units', 'pixels',... 'Position', [1, currPos+1, subpanelSize(1)]); buttonZoomInId = uicontrol(... 'Parent', zoomPanelId,... 'Style', 'togglebutton',... 'TooltipString', 'Zoom in',... 'Min', false,... 'Max', true,... 'Value', false,... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(1, 1, gui.marginSub),... 'CallBack', {@changeTool, 'zoomIn'}); setButtonAppearance(buttonZoomInId, 'in', 'zoomin.png'); gui.tool(end).buttonId = buttonZoomInId; gui.tool(end).name= 'zoomIn'; gui.tool(end).function = @switchZoomIn; buttonZoomOutId = uicontrol(... 'Parent', zoomPanelId,... 'Style', 'togglebutton',... 'TooltipString', 'Zoom out',... 'Min', false,... 'Max', true,... 'Value', false,... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(2, 1, gui.marginSub),... 'CallBack', {@changeTool, 'zoomOut'}); setButtonAppearance(buttonZoomOutId, 'out', 'zoomout.png'); gui.tool(end+1).buttonId = buttonZoomOutId; gui.tool(end).name = 'zoomOut'; gui.tool(end).function = @switchZoomOut; buttonPanId = uicontrol(... 'Parent', zoomPanelId,... 'Style', 'togglebutton',... 'TooltipString', 'Pan',... 'Min', false,... 'Max', true,... 'Value', false,... 'BackgroundColor', gui.buttonBackgroundColor,... 'Position', buttonPos(3, 1, gui.marginSub),... 'CallBack', {@changeTool, 'pan'}); setButtonAppearance(buttonPanId, 'pan', 'pan.png'); gui.tool(end+1).buttonId = buttonPanId; gui.tool(end).name = 'pan'; gui.tool(end).function = @switchPan; end function clicSymb(objId, eventData) global gui button_state = get(objId,'Value'); if button_state == get(objId,'Max') delSel; gui.showSymb = true; drawAllSel; elseif button_state == get(objId,'Min') delSel; gui.showSymb = false; drawAllSel; end end function switchZoomIn(toolInd) % NOTE: toolInd is not used but needed as a parameter is always passed to % this function global gui if isoctave() zoom(gui.mainFigId, 'on'); else if getMatlabVersion() >= 7.3 zoomId = zoom(gui.mainFigId); set(zoomId,... 'Direction', 'in',... 'Enable', 'on'); else zoom(gui.mainFigId, 'on'); % NOTE: this is undocumented in version 7.2 but it works, something more % general would be better zoom(gui.mainFigId, 'Direction', 'in'); end end end function switchZoomOut(toolInd) % NOTE: toolInd is not used but needed as a parameter is always passed to % this function global gui visu visucommon if isoctave() oriInd = find(strcmp('originalMain', {visu.label}), 1); axesId = visu(oriInd).axesId; imageId = findobj(axesId, 'Type', 'Image'); set(imageId, 'ButtonDownFcn', ''); zoom(gui.mainFigId, 'out'); % setting zoom(gui.mainFigId, 'out') does not reliably fully zoom out in % some cases, so we also force the full zoom out by hand axis(visu(oriInd).axesId, [visucommon.oriXlim, visucommon.oriYlim]); else if getMatlabVersion() >= 7.3 zoomId = zoom(gui.mainFigId); set(zoomId,... 'Direction', 'out',... 'Enable', 'on'); else zoom(gui.mainFigId, 'on'); % NOTE: this is undocumented in version 7.2 but it works, something more % general would be better zoom(gui.mainFigId, 'Direction', 'out'); end end end function switchPan(toolInd) % NOTE: toolInd is not used but needed as a parameter is always passed to % this function global gui if isoctave() pan(gui.mainFigId, 'on'); else if getMatlabVersion() >= 7.3 panId = pan(gui.mainFigId); set(panId,... 'Enable', 'on'); else pan(gui.mainFigId, 'on'); end end end function [res] = updateExploreRect(objId, eventData) global visu oriInd = find(strcmp('originalMain', {visu.label}), 1); exploreSetRect(get(visu(oriInd).axesId, 'XLim'),... get(visu(oriInd).axesId, 'YLim')); end function editColormap(objId, eventData) global gui try colormapeditor(gui.mainFigId); catch % the colormapeditor is not available in Octave so we implement a simple gui % to choose the colormap chooseColormap; end end function chooseColormap() global gui; mainFigPosition = get(gui.mainFigId, 'Position'); position = [mainFigPosition(1)+mainFigPosition(3)/2,... mainFigPosition(2)+mainFigPosition(4)/2, 250, 130]; gui.chooseColormap.figId = figure(... 'Name', 'Colormap',... 'Position', position,... 'Menubar', 'none',... 'windowstyle', 'modal'); % Note: the 'modal' windowstyle seems ignored in Octave % So we need to make the main window unclicable by hand % and the only solution seem to be hinding the main window, as the % following is not enough (the buttons are still clickable): % set(gui.mainFigId, 'HitTest', 'off'); set(gui.mainFigId, 'Visible', 'off'); uimenu(gui.chooseColormap.figId); % Removing the default menu buttonOkId = uicontrol(... 'Parent', gui.chooseColormap.figId,... 'Style', 'pushbutton',... 'String', 'OK',... 'Callback', @chooseColormapOk,... 'Position', [50, 10, 50, 30]); buttonCancelId = uicontrol(... 'Parent', gui.chooseColormap.figId,... 'Style', 'pushbutton',... 'String', 'Cancel',... 'Callback', @chooseColormapCancel,... 'Position', [150, 10, 50, 30]); gui.chooseColormap.checkboxId = uicontrol(... 'Parent', gui.chooseColormap.figId,... 'Style', 'checkbox',... 'String', 'Invert colormap',... 'Value', false,... 'Position', [25, 50, 200, 30]); maps = colormap('list'); defaultValue = find(strcmp('jet', maps)); gui.chooseColormap.popupmenuId = uicontrol(... 'Parent', gui.chooseColormap.figId,... 'Style', 'popupmenu',... 'String', maps,... 'Value', defaultValue,... 'Position', [25, 90, 200, 30]); end function chooseColormapOk(objId, eventData) global gui; set(gui.mainFigId, 'Visible', 'on'); % Needed for Octave figure(gui.mainFigId); invertColormap = get(gui.chooseColormap.checkboxId, 'Value'); maps = get(gui.chooseColormap.popupmenuId, 'String'); mapName = maps{get(gui.chooseColormap.popupmenuId, 'Value')}; map = colormap(mapName); if invertColormap map = map(end:-1:1, :); end colormap(map); close(gui.chooseColormap.figId); end function chooseColormapCancel(objId, eventData) global gui; set(gui.mainFigId, 'Visible', 'on'); % Needed for Octave figure(gui.mainFigId); close(gui.chooseColormap.figId); end function changeDynamic(objId, eventData) global visu gui oriInd = find(strcmp('originalMain', {visu.label}), 1); temp = str2num(get(gui.editDynamicId, 'String')); if isempty(temp) || temp < 0 errordlg(['Dynamic parameter is invalid, it must be a positive '... 'number in dB']); set(gui.editDynamicId, 'String', num2str(visu(oriInd).dynamic)); return; end visu(oriInd).dynamic = temp; updateVisu(false, true); end function exploreOverview(axesId) global visu gui oriInd = find(strcmp('originalMain', {visu.label}), 1); axLim = axis(visu(oriInd).axesId); xLim = axLim(1:2); yLim = axLim(3:4); indXData = [1, 2, 2, 1]; indYData = [1, 1, 2, 2]; gui.exploreRect.patchId = patch(... 'Parent', axesId,... 'XData', xLim(indXData),... 'YData', yLim(indYData),... 'FaceColor', 'none',... 'LineWidth', 2,... 'EdgeColor', 'w',... % PI: put the color and width as variables 'ButtonDownFcn', @explorePatchButtonDown); gui.exploreRect.lineId = line(... 'Parent', axesId,... 'XData', xLim(indXData),... 'YData', yLim(indYData),... 'LineStyle', 'None',... 'LineWidth', 2,... 'Color', 'w',... % PI: put the color and width as variables 'Marker', 'o',... 'MarkerSize', 7,... 'ButtonDownFcn', @exploreLineButtonDown); patchId = gui.exploreRect.patchId; lineId = gui.exploreRect.lineId; figId = gui.mainFigId; initPoint = []; indX = []; indY = []; exploreAxesXLim = []; exploreAxesYLim = []; gui.exploreOverview.axesId = axesId; gui.exploreOverview.indX = indX; gui.exploreOverview.indY = indY; gui.exploreOverview.xLim = xLim; gui.exploreOverview.yLim = yLim; gui.exploreOverview.initPoint = initPoint; gui.exploreOverview.exploreAxesXLim = exploreAxesXLim; gui.exploreOverview.exploreAxesYLim = exploreAxesYLim; end function exploreLineButtonDown(objId, eventData) global gui axesId = gui.exploreOverview.axesId; lineId = gui.exploreRect.lineId; figId = gui.mainFigId; % the coordinate that should be modified depends on the selected corner point = get(axesId,'CurrentPoint'); xData = get(lineId, 'XData'); yData = get(lineId, 'YData'); xLim = xData(1:2); yLim = yData(2:3); [mi, indX] = min(abs(xLim - point(1,1))); [mi, indY] = min(abs(yLim - point(1,2))); gui.exploreOverview.indX = indX; gui.exploreOverview.indY = indY; gui.exploreOverview.xLim = xLim; gui.exploreOverview.yLim = yLim; set(figId,'WindowButtonMotionFcn',@exploreMotionLine); set(figId,'WindowButtonUpFcn',@exploreButtonUp); end function exploreMotionLine(objId, eventData) global gui visu indXData = [1, 2, 2, 1]; indYData = [1, 1, 2, 2]; patchId = gui.exploreRect.patchId; lineId = gui.exploreRect.lineId; axesId = gui.exploreOverview.axesId; indX = gui.exploreOverview.indX; indY = gui.exploreOverview.indY; xLim = gui.exploreOverview.xLim; yLim = gui.exploreOverview.yLim; point = get(axesId,'CurrentPoint'); xLim(indX) = point(1,1); yLim(indY) = point(1,2); % reorder the values xLimSort = sort(xLim); yLimSort = sort(yLim); set(patchId,... 'XData', xLimSort(indXData),... 'YData', yLimSort(indYData)); set(lineId,... 'XData', xLimSort(indXData),... 'YData', yLimSort(indYData)); oriInd = find(strcmp('originalMain', {visu.label}), 1); axis(visu(oriInd).axesId, [xLimSort, yLimSort]); gui.exploreOverview.indX = indX; gui.exploreOverview.indY = indY; gui.exploreOverview.xLim = xLim; gui.exploreOverview.yLim = yLim; end function explorePatchButtonDown(objId, eventData) global gui axesId = gui.exploreOverview.axesId; patchId = gui.exploreRect.patchId; figId = gui.mainFigId; initPoint = get(axesId,'CurrentPoint'); exploreAxesXLim = get(axesId, 'XLim'); exploreAxesYLim = get(axesId, 'YLim'); xData = get(patchId, 'XData'); yData = get(patchId, 'YData'); xLim = xData(1:2); yLim = yData(2:3); set(figId,'WindowButtonMotionFcn',@exploreMotionPatch); set(figId,'WindowButtonUpFcn',@exploreButtonUp); gui.exploreOverview.xLim = xLim; gui.exploreOverview.yLim = yLim; gui.exploreOverview.initPoint = initPoint; gui.exploreOverview.xLim = xLim; gui.exploreOverview.yLim = yLim; gui.exploreOverview.exploreAxesXLim = exploreAxesXLim; gui.exploreOverview.exploreAxesYLim = exploreAxesYLim; end function exploreMotionPatch(objId, eventData) global gui visu axesId = gui.exploreOverview.axesId; xLim = gui.exploreOverview.xLim; yLim = gui.exploreOverview.yLim; initPoint = gui.exploreOverview.initPoint; exploreAxesXLim = gui.exploreOverview.exploreAxesXLim; exploreAxesYLim = gui.exploreOverview.exploreAxesYLim; patchId = gui.exploreRect.patchId; lineId = gui.exploreRect.lineId; indXData = [1, 2, 2, 1]; indYData = [1, 1, 2, 2]; point = get(axesId,'CurrentPoint'); newXLim = xLim + (point(1,1)-initPoint(1,1)); newYLim = yLim + (point(1,2)-initPoint(1,2)); if ~(newXLim(2) < exploreAxesXLim(1) ||... newXLim(1) > exploreAxesXLim(2) ||... newYLim(2) < exploreAxesYLim(1) ||... newYLim(1) > exploreAxesYLim(2)) set(patchId,... 'XData', newXLim(indXData),... 'YData', newYLim(indYData)); set(lineId,... 'XData', newXLim(indXData),... 'YData', newYLim(indYData)); oriInd = find(strcmp('originalMain', {visu.label}), 1); axis(visu(oriInd).axesId, [newXLim(1), newXLim(2), newYLim(1), newYLim(2)]); end end function exploreButtonUp(objId, eventData) global gui visu figId = gui.mainFigId; patchId = gui.exploreRect.patchId; set(figId,'WindowButtonMotionFcn',''); set(figId,'WindowButtonUpFcn',''); xData = get(patchId, 'XData'); yData = get(patchId, 'YData'); oriInd = find(strcmp('originalMain', {visu.label}), 1); axis(visu(oriInd).axesId, [xData(1), xData(2), yData(2), yData(3)]); end function exploreSetRect(xLim, yLim) global gui indXData = [1, 2, 2, 1]; indYData = [1, 1, 2, 2]; if ishandle(gui.exploreRect.patchId) set(gui.exploreRect.patchId,... 'XData', xLim(indXData),... 'YData', yLim(indYData)); end if ishandle(gui.exploreRect.lineId) set(gui.exploreRect.lineId,... 'XData', xLim(indXData),... 'YData', yLim(indYData)); end end function changeSelSymb(objId, eventData) global symbol gui symbol.curSymb = get(gui.symbListId, 'Value'); handleSymb(); end function resetSymbol() % erase sel and put it to default value global symbol default gui symbol = default.symbol; if isfield(gui, 'symbListId') if ishandle(gui.symbListId) set(gui.symbListId, 'Value', symbol.curSymb); drawSymbolParam(symbol.curSymb); updateSymbolList; end end end function updateSymbolList() global symbol gui symCell = {}; if isfield(symbol,'data') for ind = 1:length(symbol.data) symCell{end+1} = symbol.data(ind).name; end set(gui.symbListId, 'String', symCell); end end function drawSymbolParam(symbInd) % nothing to do yet end function addSymbolListItem(symb) global symbol symbol.data(end+1).val = symb; symbol.data(end).name = 'Imported'; updateSymbolList(); end ltfat/inst/Contents.m0000664000175000017500000000314513026262303014514 0ustar susnaksusnak% LTFAT - Base routines % % Peter L. Soendergaard, 2009 - 2016. % % 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 visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/isoctave.m0000664000175000017500000000240513026262303014532 0ustar susnaksusnakfunction 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.github.io/doc/isoctave.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: NA % REFERENCE: NA persistent inout; if isempty(inout), inout = exist('OCTAVE_VERSION','builtin') ~= 0; end; t = inout; ltfat/inst/ltfatgetdefaults.m0000664000175000017500000000255513026262303016265 0ustar susnaksusnakfunction 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.github.io/doc/ltfatgetdefaults.html} %@seealso{ltfatsetdefaults, ltfatstart} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/0000775000175000017500000000000013026262303013474 5ustar susnaksusnakltfat/inst/comp/comp_framelength_tensor.m0000664000175000017500000000220013026262303020550 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_framelength_tensor.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . error(['For the tensor product frame, call framelength for the ', ... 'individual subframes']); ltfat/inst/comp/arg_firwin.m0000664000175000017500000000251513026262303016004 0ustar susnaksusnakfunction definput=arg_firwin(definput) truncgaussflags = {'truncgauss'}; definput.flags.wintype=[{... 'hanning','hann','sine','cosine', 'sqrthann','hamming', 'square',... 'rect', 'tria','bartlett', 'triangular','sqrttria','blackman',... 'blackman2', 'nuttall','nuttall10','nuttall01','nuttall20',... 'nuttall11','nuttall03', 'nuttall12','nuttall21', 'nuttall30',... 'ogg', 'itersine', 'nuttall02'}, truncgaussflags ]; %-*- texinfo -*- %@deftypefn {Function} arg_firwin %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_firwin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_idgt.m0000664000175000017500000000525313026262303015624 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_idgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. M=size(coef,1); N=size(coef,2); W=size(coef,3); L=N*a; if lt(2)==1 f = comp_isepdgt(coef,g,L,a,M,phasetype); else if (algns==1) || (algns==0 && lt(2)<=2) % FIXME : Calls non-comp function if phasetype==1 coef=phaseunlock(coef,a,'lt',lt); end; % ----- 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; ltfat/inst/comp/comp_iwfbt.m0000664000175000017500000000552013026262303016005 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_iwfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); gCell = cellfun(@(gEl) 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(:)); offset = cellfun(@(gEl) 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; ltfat/inst/comp/assert_sigreshape_pre.m0000664000175000017500000000533613026262303020242 0ustar susnaksusnakfunction [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.github.io/doc/comp/assert_sigreshape_pre.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_gfeigs.m0000664000175000017500000000337613026262303016145 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_gfeigs.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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(:)); ltfat/inst/comp/comp_ifilterbank_td.m0000664000175000017500000000444113026262303017654 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ifilterbank_td.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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 ltfat/inst/comp/comp_idgt_long.m0000664000175000017500000000422413026262303016640 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_idgt_long.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/arg_fwt.m0000664000175000017500000000206213026262303015303 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_fwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.flags.ext = {'per','zero','even','odd'}; ltfat/inst/comp/comp_fourierwindow.m0000664000175000017500000001177213026262303017603 0ustar susnaksusnakfunction [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,L,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.github.io/doc/comp/comp_fourierwindow.html} %@seealso{gabwin, wilwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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) % The DGT window format to struct with .h field format if size(g,2)>1 if size(g,1)>1 error('%s: g must be a vector',callfun); 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); % And continue processing this since it becomes a FIR filter. end if isstruct(g) if isfield(g,'h') && isnumeric(g.h) && isvector(g.h) info.wasreal=isreal(g.h); info.gl=length(g.h); info.isfir=1; % g.h was a row vector if size(g.h,2)>1 g.h = g.h(:); end % In case a filter lacks .offset, set it to zero if ~isfield(g,'offset') g.offset= 0; end elseif isfield(g,'H') && ... ( isnumeric(g.H) && isvector(g.H) || isa(g.H,'function_handle') ) info.wasreal=isfield(g,'realonly') && g.realonly; info.gl=[]; % g.H was a row vector if size(g.H,2)>1 g.H = g.H(:); end % In case a filter lacks .foff, make a low-pass filter of it. if ~isfield(g,'foff') g.foff= @(L) 0; end if isa(g.H,'function_handle') if ~isa(g.foff,'function_handle') error('%s: g.foff should be a function handle.',... callfun); end elseif isnumeric(g.H) if ~isfield(g,'L') error('%s: .H is numeric, but g.L was not defined.',... callfun); end end else error(['%s: The struct. defining a filter must contain ',... 'either .h (numeric vector) or .H (numeric vector, ',... 'anonymous fcn) fields.'],callfun); end; else % We can probably never get here % Information to be determined post creation. info.wasreal = isreal(g); info.gl = length(g); if (~isempty(L) && (info.gl. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; % Sanity checks % All numers in a must be integers if ~isnumeric(a) || any(a(:)<=0) error('%s: All subsampling factors must be positive.',upper(mfilename)); end % Avoid a being scalar if M>1 if isscalar(a) a = a*ones(M,1); end % One filter expect a to be a single value or a 2 element row vector if M==1 && (size(a,1)~=1 || ~any(size(a,2)==[1,2])) error('%s: One channel, but more subsampling factors.',upper(mfilename)); end % .. and sanitize if it is a column vector if M==1 && size(a,2)==1 a = [a,1]; end % Two filters can have [a1,a2],[a1;a2], [a1,a1;a2,a2] if M==2 && ~any(size(a)==2) error('%s: Bad format of a.',upper(mfilename)); end % .. and sanitize if M==2 && isvector(a) a = [a(:),ones(numel(a),1)]; end % In another configuration, there is no confusion % e.g. for M = 3, a can be: % a = [a1,a2,a3] % a = [a1;a2;a3] % a = [a1,a1;a2,a2;a3,a3]; % Make column vector if M>2 && isvector(a) a = a(:); end if isvector(a) && M~=1 && size(a,2)<2 if numel(a)~=M error(['%s: The number of entries in "a" must match the number of ' ... 'filters.'],upper(mfilename)); end if all(a==a(1)) info.isuniform=1; end; a=[a,ones(M,1)]; else if size(a,2)>2 error(['%s: Bad format of a.'],upper(mfilename)); end % 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; ltfat/inst/comp/comp_frsyn_fusion.m0000664000175000017500000000227013026262303017415 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_frsyn_fusion.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_painlessfilterbank.m0000664000175000017500000000372313026262303020555 0ustar susnaksusnakfunction gout = comp_painlessfilterbank(g,a,L,type,do_real) %-*- texinfo -*- %@deftypefn {Function} comp_painlessfilterbank %@verbatim %COMP_PAINLESSFILTERBANK % % Function computes filterbank dual or tight frame for the painless case. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_painlessfilterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . M = numel(g); F = comp_filterbankresponse(g,a,L,do_real); % inf here ensures FIR filters will stay FIR g = comp_filterbank_pre(g,a,L,inf); if strcmpi(type,'tight') F = sqrt(F); elseif strcmpi(type,'dual') % Do nothing else %Fail error('%s: Internal error. Unrecognized frame type.',upper(mfilename)); end gout=cell(1,M); for m=1:M thisgd=struct(); if isfield(g{m},'H') 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; thisgd.L = L; elseif isfield(g{m},'h') H=comp_transferfunction(g{m},L)./F; thisgd = ifft(H); end gout{m}=thisgd; end; % Convert appropriate filters to structs with .h fields. gId = cellfun(@(gEl) isfield(gEl,'h'),g); if any(gId) gout(gId) = filterbankwin(gout(gId),a(gId)); end ltfat/inst/comp/arg_ltfattranslate.m0000664000175000017500000000223313026262303017533 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_ltfattranslate.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_dgtreal_ola.m0000664000175000017500000000437013026262303017151 0ustar susnaksusnakfunction coef=comp_dgtreal_ola(f,g,a,M,Lb,phasetype) %-*- 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.github.io/doc/comp/comp_dgtreal_ola.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [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=comp_sepdgtreal(postpad(f(ii*Lb+1:(ii+1)*Lb,:),Lext),gpad,a,M,phasetype); % 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; ltfat/inst/comp/comp_idgtreal_fb.m0000664000175000017500000000723713026262303017143 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_idgtreal_fb.html} %@seealso{idgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_idwiltiv.m0000664000175000017500000000345213026262303016527 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_idwiltiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,:); ltfat/inst/comp/comp_idgtreal_long.m0000664000175000017500000000436013026262303017505 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_idgtreal_long.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/complainif_toomanyargs.m0000664000175000017500000000213413026262303020416 0ustar susnaksusnakfunction complainif_toomanyargs(fnargin,limit,callfun) if nargin<3 callfun = mfilename; end if fnargin>limit error('%s: Too many input arguments.',upper(callfun)); end %-*- texinfo -*- %@deftypefn {Function} complainif_toomanyargs %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/complainif_toomanyargs.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_wpfbtscale.m0000664000175000017500000000377213026262303017033 0ustar susnaksusnakfunction wt = comp_wpfbtscale(wt,interscaling) %-*- texinfo -*- %@deftypefn {Function} comp_wpfbtscale %@verbatim %COMP_WPFBTSCALE Scale filters in the filterbank tree %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_wpfbtscale.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Here we handle scaling of intermediate outputs in the tree if ~strcmpi(interscaling,'intnoscale') if strcmp('intscale',interscaling) interscalingfac = 1/2; elseif strcmp('intsqrt',interscaling) interscalingfac = 1/sqrt(2); end wtPath = nodeBForder(0,wt); rangeLoc = nodesLocOutRange(wtPath,wt); wtNodes = wt.nodes(wtPath); for ii=1:numel(wtPath) range = 1:numel(wtNodes{ii}.h); % Remove the outputs which are terminal range(rangeLoc{ii}) = []; wtNodes{ii}.h(range) = ... cellfun(@(hEl) setfield(hEl,'h',hEl.h*interscalingfac),... wtNodes{ii}.h(range),... 'UniformOutput',0); wtNodes{ii}.g(range) = ... cellfun(@(hEl) setfield(hEl,'h',hEl.h*interscalingfac),... wtNodes{ii}.g(range),... 'UniformOutput',0); end % Write the scaled ones back wt.nodes(wtPath) = wtNodes; end ltfat/inst/comp/comp_dgt.m0000664000175000017500000000467313026262303015460 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_dgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: OK % REFERENCE: OK L=size(f,1); if lt(2)==1 c=comp_sepdgt(f,g,a,M,phasetype); 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; % FIXME : Calls non-comp function if phasetype==1 c=phaselock(c,a,'lt',lt); end; end; ltfat/inst/comp/comp_fwt.m0000664000175000017500000000603413026262303015473 0ustar susnaksusnakfunction c = comp_fwt(f,h,a,J,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.github.io/doc/comp/comp_fwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); hCell = cellfun(@(hEl) 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); offset = cellfun(@(hEl) 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; ltfat/inst/comp/comp_filterbankphasegrad.m0000664000175000017500000000274513026262303020700 0ustar susnaksusnakfunction [tgrad,fgrad,s] = comp_filterbankphasegrad(c,ch,cd,L,minlvl) %-*- texinfo -*- %@deftypefn {Function} comp_filterbankphasegrad %@verbatim % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_filterbankphasegrad.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Compute spectrogram and % remove small values because we need to divide by cs temp = cell2mat(c); minlvl = minlvl*max(abs(temp(:)).^2); s = cellfun(@(x) max(abs(x).^2,minlvl),c,'UniformOutput',false); % Compute instantaneous frequency tgrad=cellfun(@(x,y,z) real(x.*conj(y)./z)/L*2,cd,c,s,'UniformOutput',false); % Limit tgrad = cellfun(@(fEl) fEl.*(abs(fEl)<=2) ,tgrad,'UniformOutput',0); % Compute group delay fgrad=cellfun(@(x,y,z) imag(x.*conj(y)./z),ch,c,s,'UniformOutput',false); ltfat/inst/comp/comp_inonsepdgt_shear.m0000664000175000017500000000726113026262303020232 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_inonsepdgt_shear.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/comp/comp_ifilterbank_fft.m0000664000175000017500000000236413026262303020026 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ifilterbank_fft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . W = size(c{1},2); M = numel(G); L = numel(G{1}); F = zeros(L,W,assert_classname(c{1},G{1})); 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 ltfat/inst/comp/block_interface.m0000664000175000017500000001133213026262303016764 0ustar susnaksusnakfunction 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.github.io/doc/comp/block_interface.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<1 error('%s: Too few input parameters.',upper(mfilename)); end % Persistent data persistent pos; persistent datapos; % Second data pointer 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 Fs; persistent loop; % DEFAULTS persistent bufLen; persistent outFile; persistent offline; command = varargin{1}; switch command case {'reset','clearAll'} pos = 0; datapos = 0; sourceName = []; maxBufCount = 3; pageList = []; playChanList = []; recChanList = []; pageNo = 0; skipCounter = 0; classid = 'double'; anaOverlap = []; synOverlap = []; toPlayBlock = []; dispLoad = 1; loop = 0; Ls = -1; bufLen = 1024; outFile = []; offline = 0; Fs = 0; %% SETTERS %%% case 'setLs' Ls = varargin{2}; case 'setFs' Fs = varargin{2}; case 'setOutFile' outFile = varargin{2}; case 'setOffline' offline = varargin{2}; case 'setPos' pos = varargin{2}; case 'setDatapos' datapos = 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 'getFs' varargout{1}=Fs; case 'getOutFile' varargout{1}=outFile; case 'getOffline' varargout{1}=offline; case 'getPos' varargout{1}=pos; case 'getDatapos' varargout{1}=datapos; 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 'flushBuffers' anaOverlap = []; synOverlap = []; 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 ltfat/inst/comp/comp_sepdgtreal.m0000664000175000017500000000327013026262303017024 0ustar susnaksusnakfunction [coef]=comp_sepdgtreal(f,g,a,M,phasetype) %-*- 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.github.io/doc/comp/comp_sepdgtreal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % See help on DGT. % AUTHOR : Peter L. Soendergaard. L=size(f,1); Lwindow=size(g,1); if Lwindow. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_dwilt.m0000664000175000017500000000454413026262303016022 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_dwilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,0); 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; ltfat/inst/comp/arg_fwtext.m0000664000175000017500000000207313026262303016026 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_fwtext.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.flags.ext = {'per','zero','even','odd'}; ltfat/inst/comp/comp_gabmixdual_fac.m0000664000175000017500000000367413026262303017630 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_gabmixdual_fac.html} %@seealso{gabmixdual, comp_fac, compute_ifac} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/compinit.m0000664000175000017500000000163213026262303015476 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} compinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/compinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_dwiltiv.m0000664000175000017500000000315213026262303016353 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_dwiltiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_idgt_fac.m0000664000175000017500000000712213026262303016432 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_idgt_fac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_edgt6.m0000664000175000017500000000214413026262303015702 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_edgt6.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/arg_freqtoaud.m0000664000175000017500000000204413026262303016475 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_freqtoaud.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_isepdgtreal.m0000664000175000017500000000363513026262303017202 0ustar susnaksusnakfunction [f]=comp_isepdgtreal(coef,g,L,a,M,phasetype) %-*- 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.github.io/doc/comp/comp_isepdgtreal.html} %@seealso{idgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: OK % REFERENCE: OK Lwindow=size(g,1); if phasetype==1 % Change from time-invariant phase convention to a % frequency-invariant one b=L/M; M2=floor(M/2)+1; N=size(coef,2); %M2short=ceil(M/2); TimeInd = (0:(N-1))/N; FreqInd = (0:(M2-1))*b; phase = FreqInd'*TimeInd; phase = exp(-2*1i*pi*phase); % Handle multisignals coef = bsxfun(@times,coef,phase); end; if L==Lwindow % Do full-window algorithm. % 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; ltfat/inst/comp/comp_filterbank_td.m0000664000175000017500000000531313026262303017502 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_filterbank_td.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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 ltfat/inst/comp/comp_iedgt6.m0000664000175000017500000000240713026262303016055 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_iedgt6.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,:); ltfat/inst/comp/comp_nonsepdgtreal_quinqux.m0000664000175000017500000000346013026262303021332 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_nonsepdgtreal_quinqux.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_filterbankreassign.m0000664000175000017500000001021713026262303020546 0ustar susnaksusnakfunction [sr,repos] = comp_filterbankreassign(s,tgrad,fgrad,a,cfreq) Lc = cellfun(@numel,s); M = numel(s); oneover2 = 1/2; sr = cell(M,1); cfreq2 = zeros(M,1); for mm = 1:M sr{mm} = zeros(Lc(mm),1); cfreq2(mm) = cfreq(mm) - floor(cfreq(mm)*oneover2)*2; end if nargout>1 chan_pos = [0;cumsum(Lc)]; repos = cell(sum(cellfun(@numel,sr)),1); end %-*- texinfo -*- %@deftypefn {Function} comp_filterbankreassign %@verbatim %% Compute reassigned frequencies and times %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_filterbankreassign.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . for mm = M:-1:1 tgradIdx = zeros(Lc(mm),1); fgradIdx = zeros(Lc(mm),1); cfreqm = cfreq2(mm); for jj = 1:Lc(mm) tgradmjj = tgrad{mm}(jj) + cfreqm; oldtgrad = 10; tgradIdx(jj) = 0; if tgrad{mm}(jj) > 0 pos = mm; for ii = mm:M pos = ii; tmptgrad = cfreq2(ii) - tgradmjj; if tmptgrad >= 0 if abs(tmptgrad) < abs(oldtgrad) tgradIdx(jj) = pos; else tgradIdx(jj) = pos-1; end break; end oldtgrad = tmptgrad; end if pos == M && tmptgrad < 0 for ii = 1:mm pos = ii; tmptgrad = cfreq2(ii) - tgradmjj + 2; if tmptgrad >= 0 if abs(tmptgrad) < abs(oldtgrad) tgradIdx(jj) = pos; else tgradIdx(jj) = pos-1; end break; end oldtgrad = tmptgrad; end end if tgradIdx(jj) < 1 tgradIdx(jj) = M; end else pos = mm; for ii = mm:-1:1 pos = ii; tmptgrad = cfreq2(ii) - tgradmjj; if tmptgrad <= 0 if abs(tmptgrad) < abs(oldtgrad) tgradIdx(jj) = pos; else tgradIdx(jj) = pos+1; end break; end oldtgrad = tmptgrad; end if pos == 1 && tmptgrad > 0 for ii = M:-1:mm pos = ii; tmptgrad = cfreq2(ii) - tgradmjj - 2; if tmptgrad <= 0 if abs(tmptgrad) < abs(oldtgrad) tgradIdx(jj) = pos; else tgradIdx(jj) = pos+1; end break; end oldtgrad = tmptgrad; end end if tgradIdx(jj) >= M+1 tgradIdx(jj) = 1; end end end for jj = 1:Lc(mm) tmpIdx = tgradIdx(jj); fgradIdx(jj) = mod(round((fgrad{mm}(jj) + a(mm)*(jj-1))./a(tmpIdx)),Lc(tmpIdx))+1; end for jj=1:Lc(mm) sr{tgradIdx(jj)}(fgradIdx(jj)) = sr{tgradIdx(jj)}(fgradIdx(jj))+s{mm}(jj); end if nargout>1 for jj=1:Lc(mm) repos{chan_pos(tgradIdx(jj))+fgradIdx(jj)}(end+1,1) = chan_pos(mm)+jj; end end end ltfat/inst/comp/assert_L.m0000664000175000017500000000530513026262303015431 0ustar susnaksusnakfunction [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.github.io/doc/comp/assert_L.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_dgtreal_long.m0000664000175000017500000000440413026262303017333 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_dgtreal_long.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_igdgt.m0000664000175000017500000000410513026262303015766 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_igdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_sepdgt.m0000664000175000017500000000262413026262303016162 0ustar susnaksusnakfunction [coef]=comp_sepdgt(f,g,a,M,phasetype) %-*- 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.github.io/doc/comp/comp_sepdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. L=size(f,1); Lwindow=size(g,1); if Lwindow. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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) ltfat/inst/comp/comp_nonsepdgt_shear.m0000664000175000017500000001026313026262303020055 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_nonsepdgt_shear.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/arg_plotfilterbank.m0000664000175000017500000000217713026262303017532 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_plotfilterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_idwiltii.m0000664000175000017500000000365113026262303016513 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_idwiltii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_ufilterbank_td.m0000664000175000017500000000503313026262303017666 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ufilterbank_td.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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; ltfat/inst/comp/comp_gabreassign.m0000664000175000017500000000420713026262303017160 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_gabreassign.html} %@seealso{gabreassign} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_dwiltiii.m0000664000175000017500000000414413026262303016511 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_dwiltiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,0); 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 ltfat/inst/comp/comp_ufilterbank_fft.m0000664000175000017500000000270113026262303020035 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ufilterbank_fft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_ifftreal.m0000664000175000017500000000226713026262303016473 0ustar susnaksusnakfunction f=comp_ifftreal(c,N) %-*- texinfo -*- %@deftypefn {Function} comp_ifftreal %@verbatim %COMP_IFFTREAL Compute an IFFTREAL %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_ifftreal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)); ltfat/inst/comp/comp_dgt_ola.m0000664000175000017500000000436413026262303016310 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_dgt_ola.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [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; ltfat/inst/comp/arg_pfilt.m0000664000175000017500000000173613026262303015630 0ustar susnaksusnakfunction definput=arg_pfilt(definput) definput.keyvals.crossover=120; %-*- texinfo -*- %@deftypefn {Function} arg_pfilt %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_pfilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_idwiltiii.m0000664000175000017500000000377013026262303016666 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_idwiltiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,0); 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; ltfat/inst/comp/comp_dst.m0000664000175000017500000000504313026262303015464 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_dst.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [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; ltfat/inst/comp/comp_gabtight_long.m0000664000175000017500000000312313026262303017477 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_gabtight_long.html} %@seealso{gabtight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_warpedfreqresponse.m0000664000175000017500000000673213026262303020617 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_warpedfreqresponse.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.import={'normalize'}; definput.flags.symmetry = {'nonsymmetric','symmetric'}; [flags,kv]=ltfatarghelper({},definput,varargin); fcwasnegative = fc < 0; if fcwasnegative && flags.do_symmetric fc = -fc; end fcscale = freqtoscale(fc); if ~flags.do_symmetric % 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)).'; else bins_lo = freqtoscale(fs*(0:L-1)/L).'; end % 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-fcscale)/bw; bins_hi=(bins_hi-fcscale)/bw; pos_lo=comp_warpedfoff(fc,bw,fs,L,freqtoscale,scaletofreq,flags.do_symmetric); % 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(fcscale+.5*bw)/fs*L); if pos_hi>L/2 % Filter is high pass and spilling into the negative frequencies pos_hi=floor(scaletofreq(fcscale+.5*bw-nyquest2)/fs*L); end; win_lo=firwin(wintype,bins_lo); win_hi=firwin(wintype,bins_hi); H=win_lo+win_hi; H(isnan(H)) = 0; 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); if fcwasnegative && flags.do_symmetric H = H(end:-1:1); end ltfat/inst/comp/comp_dgtreal.m0000664000175000017500000000276413026262303016323 0ustar susnaksusnakfunction 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/2+1*N array of coefficients. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_dgtreal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. if lt(2)==1 c = comp_sepdgtreal(f,g,a,M,phasetype); else % Quinqux lattice c = comp_nonsepdgtreal_quinqux(f,g,a,M); end; ltfat/inst/comp/comp_ifwt.m0000664000175000017500000000673213026262303015651 0ustar susnaksusnakfunction f = comp_ifwt(c,g,a,J,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.github.io/doc/comp/comp_ifwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); gCell = cellfun(@(gEl) 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); offset = cellfun(@(gEl) 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 ltfat/inst/comp/arg_uwfbtcommon.m0000664000175000017500000000204013026262303017037 0ustar susnaksusnakfunction definput = arg_uwfbtcommon(definput) %-*- texinfo -*- %@deftypefn {Function} arg_uwfbtcommon %@verbatim % Filter scaling %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_uwfbtcommon.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.flags.scaling={'sqrt','scale','noscale','scaling_notset'}; ltfat/inst/comp/comp_iufwt.m0000664000175000017500000000441413026262303016031 0ustar susnaksusnakfunction f = comp_iufwt(c,g,a,J,scaling) %-*- 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.github.io/doc/comp/comp_iufwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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(:)); % Optionally scale the filters g = comp_filterbankscale(g(:),a(:),scaling); %Change format to a matrix gMat = cell2mat(cellfun(@(gEl) gEl.h(:),g(:)','UniformOutput',0)); % 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; ltfat/inst/comp/comp_transferfunction.m0000664000175000017500000000320713026262303020264 0ustar susnaksusnakfunction H=comp_transferfunction(g,L) %-*- texinfo -*- %@deftypefn {Function} comp_transferfunction %@verbatim %COMP_TRANSFERFUNCTION Compute the transfer function % % COMP_TRANSFERFUNCTION(g,L) computes length L transfer function % (frequency response) of a single filter g. This function can only % handle filters in a proper internal format i.e. already processed by % FILTERBANKWIN. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_transferfunction.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Setting crossover to 0 ensures FIR filters to be transformed to % full-length Frequency-domain defined filters with g.H and g.foff fields. g = comp_filterbank_pre({g},1,L,0); % Band-limited filters have to be made full-length H = circshift(postpad(g{1}.H(:),L),g{1}.foff); % Realonly has to be treated separatelly for band-limited filters if isfield(g,'realonly') && g.realonly H=(H+involute(H))/2; end; ltfat/inst/comp/comp_hermite.m0000664000175000017500000000345213026262303016331 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_hermite.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/comp/comp_wpfbt.m0000664000175000017500000000665213026262303016023 0ustar susnaksusnakfunction c=comp_wpfbt(f,wtNodes,rangeLoc,ext,interscaling) %-*- 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.github.io/doc/comp/comp_wpfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Do non-expansve transform if ext=='per' doPer = strcmp(ext,'per'); % Pre-allocated output c = cell(sum(cellfun(@(wtEl) numel(wtEl.h),wtNodes)),1); interscalingfac = 1; if strcmp('intscale',interscaling) interscalingfac = 1/2; elseif strcmp('intsqrt',interscaling) interscalingfac = 1/sqrt(2); end % OLD code doing the scaling directly on filters in the tree % if do_scale % for ii=1:numel(wtNodes) % range = 1:numel(wtNodes{ii}.h); % range(rangeLoc{ii}) = []; % wtNodes{ii}.h(range) = cellfun(@(hEl) setfield(hEl,'h',hEl.h/sqrt(2)),wtNodes{ii}.h(range),... % 'UniformOutput',0); % end % end ca = f; cOutRunIdx = 1; cInRunIdxs = []; % 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); hCell = cellfun(@(hEl) 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); offset = cellfun(@(hEl) 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,outRange]; cOutRunIdx = cOutRunIdx + filtNo; % Prepare input for the next iteration % Scaling introduced in order to preserve energy % (parseval tight frame) if ~isempty(cInRunIdxs) c{cInRunIdxs(1)} = c{cInRunIdxs(1)}*interscalingfac; ca = c{cInRunIdxs(1)}; cInRunIdxs(1) = []; end end ltfat/inst/comp/comp_idgt_fb.m0000664000175000017500000000720213026262303016267 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_idgt_fb.html} %@seealso{idgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_warpedfoff.m0000664000175000017500000000241313026262303017013 0ustar susnaksusnakfunction foff=comp_warpedfoff(fc,bw,fs,L,freqtoscale,scaletofreq,do_symmetric) %-*- texinfo -*- %@deftypefn {Function} comp_warpedfoff %@verbatim %COMP_WARPEDFOFF foff for warped filters %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_warpedfoff.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . fcwasnegative = fc < 0; if fcwasnegative && do_symmetric fc = -fc; fcscale = freqtoscale(fc); foff = -floor(scaletofreq(fcscale+.5*bw)/fs*L)+1; else fcscale = freqtoscale(fc); foff = floor(scaletofreq(fcscale-.5*bw)/fs*L)+1; end ltfat/inst/comp/comp_iwfac.m0000664000175000017500000000433313026262303015764 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_iwfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_phasegradfilters.m0000664000175000017500000000630413026262303020222 0ustar susnaksusnakfunction [gh,gd,g]=comp_phasegradfilters(g,a,L) %-*- texinfo -*- %@deftypefn {Function} comp_phasegradfilters %@verbatim % Number of filters %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_phasegradfilters.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . M = numel(g); % Precompute filters for length L if not done already g = comp_filterbank_pre(g,a,L,100); % Divide filters to time domain and frequency domain groups mFreqBl = 1:M; mTime = mFreqBl(cellfun(@(gEl) isfield(gEl,'h'),g(:))>0); mFreqBl(mTime) = []; mFreqL = mFreqBl(cellfun(@(gEl) isfield(gEl,'H') && numel(gEl.H) == L,g)>0); mFreqBl(mFreqL) = []; % For FIR/full-length frequency response filters, compute center frequency if numel(mFreqBl) < M cfreq = zeros(M,1); tempind = [mTime,mFreqL]; cfreq(tempind) = round(L/2*cent_freqs(g(tempind),L)); end; % Determine impulse response or transfer function length Lg = L*ones(M,1); Lg(mTime) = cellfun(@(gEl) length(gEl.h),g(mTime)); Lg(mFreqBl) = cellfun(@(gEl) length(gEl.H),g(mFreqBl)); gh = g; gd = g; fftind = fftindex(L,0); % Set Nyquist frequency to 0! %% ------ algorithm starts -------------------- % Construct time/frequency weighted versions of filters % defined on the time side for mId = mTime % Compute time weighted version. tempind = (g{mId}.offset:Lg(mId)+g{mId}.offset-1).'; gh{mId}.h = tempind.*g{mId}.h; % Compute frequency weighted version. gH = comp_transferfunction(g{mId},L); gd{mId}.H = circshift(fftind,cfreq(mId)).*gH; gd{mId}=rmfield(gd{mId},'h'); gd{mId}=rmfield(gd{mId},'offset'); gd{mId}.foff = 0; end; % Construct time/frequency weighted versions of bandlimited filters % defined on the frequency side for mId = mFreqBl % Compute frequency weighted version. tempind = [L-floor(Lg(mId)/2)+1:L, ... 1:ceil(Lg(mId)/2)]; gd{mId}.H = fftind(tempind).*g{mId}.H; % Compute time weighted version. % The code below is a quick and dirty version of % longg = fftshift(g{mId}.H); % gd2{mId}.H = fftshift(pderiv(longg,[],Inf)/(2*pi)); n=fftindex(Lg(mId),0); gh{mId}.H = L/Lg(mId)*real(fftshift( ... ifft(1i.*n.*fft(fftshift(g{mId}.H))))); end; % Construct time/frequency weighted versions of full-length filters % defined on the frequency side for mId = mFreqL % Compute frequency weighted version. gd{mId}.H = circshift(fftind,cfreq(mId)).*g{mId}.H; % Compute time weighted version. gh{mId}.H = real(ifft(1i.*fftind.*fft(g{mId}.H))); end; ltfat/inst/comp/comp_iuwpfbt.m0000664000175000017500000000535513026262303016360 0ustar susnaksusnakfunction f=comp_iuwpfbt(c,wtNodes,nodesUps,pOutIdxs,chOutIdxs,scaling,interscaling) %-*- 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.github.io/doc/comp/comp_iuwpfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . interscalingfac = 1; if strcmp('intscale',interscaling) interscalingfac = 1/2; elseif strcmp('intsqrt',interscaling) interscalingfac = 1/sqrt(2); end % For each node in tree in the BF order... for jj=1:length(wtNodes) % Node filters subs. factors a = wtNodes{jj}.a; % Optionally scale the filters g = comp_filterbankscale(wtNodes{jj}.g(:),a(:),scaling); % Node filters to a matrix gMat = cell2mat(cellfun(@(gEl) gEl.h(:),g','UniformOutput',0)); % 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),:) = interscalingfac*(c(:,pOutIdxs(jj),:)+reshape(ctmp,size(ctmp,1),1,size(ctmp,2))); else % We are at the root. f = ctmp; end end ltfat/inst/comp/assert_groworder.m0000664000175000017500000000317113026262303017247 0ustar susnaksusnakfunction 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.github.io/doc/comp/assert_groworder.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_hermite_all.m0000664000175000017500000000360413026262303017160 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_hermite_all.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/comp/comp_dtwfb.m0000664000175000017500000000254213026262303016001 0ustar susnaksusnakfunction c = comp_dtwfb(f,nodes,dualnodes,rangeLoc,rangeOut,ext,do_complex) %-*- texinfo -*- %@deftypefn {Function} comp_dtwfb %@verbatim % First tree %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_dtwfb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . c1 = comp_wfbt(f,nodes,rangeLoc,rangeOut,ext); % Second tree c2 = comp_wfbt(f,dualnodes,rangeLoc,rangeOut,ext); % Combine outputs of trees c = cellfun(@(crEl,ciEl) (crEl+1i*ciEl)/2,c1,c2,'UniformOutput',0); if do_complex % Non-real specific cneg = cellfun(@(crEl,ciEl) (crEl-1i*ciEl)/2,c1,c2,... 'UniformOutput',0); c = [c;cneg(end:-1:1)]; end ltfat/inst/comp/arg_freqwin.m0000664000175000017500000000200513026262303016153 0ustar susnaksusnakfunction definput=arg_freqwin(definput) definput.flags.wintype={ 'gammatone', 'gauss' ,'butterworth'}; %-*- texinfo -*- %@deftypefn {Function} arg_freqwin %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_freqwin.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_pgauss.m0000664000175000017500000000357613026262303016205 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_pgauss.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/arg_normalize.m0000664000175000017500000000246113026262303016506 0ustar susnaksusnakfunction definput=arg_normalize(definput) %-*- texinfo -*- %@deftypefn {Function} arg_normalize %@verbatim % Both 'null' and 'empty' do no scaling when normalize is called % directly. % When used in different functions, % 'empty' can be set as default by definput.importdefaults={'empty'}; % to detect whether any of the other flags were set. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_normalize.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.flags.norm={'2','1','inf','area','energy','peak',... 's0','rms','null','wav','norm_notset'}; ltfat/inst/comp/demo_blockproc_header.m0000664000175000017500000000403313026262303020144 0ustar susnaksusnakfunction 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.github.io/doc/comp/demo_blockproc_header.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_dwiltii.m0000664000175000017500000000327213026262303016341 0ustar susnaksusnakfunction [coef]=comp_dwiltii(coef2,a) %-*- texinfo -*- %@deftypefn {Function} comp_dwiltii %@verbatim %COMP_DWILT Compute Discrete Wilson transform. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_dwiltii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_constructphasereal.m0000664000175000017500000000427713026262303020613 0ustar susnaksusnakfunction [newphase, usedmask] = comp_constructphasereal(s,tgrad,fgrad,a,M,tol,do_timeinv,mask,usephase) absthr = max(s(:))*tol; if isempty(mask) usedmask = zeros(size(s)); else usedmask = mask; end %-*- texinfo -*- %@deftypefn {Function} comp_constructphasereal %@verbatim % Build the phase %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_constructphasereal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isempty(mask) % s is real and positive newphase=comp_heapintreal(s,tgrad,fgrad,a,M,tol(1),do_timeinv); % Find all small coefficients and set the mask bigenoughidx = s>absthr(1); usedmask(bigenoughidx) = 1; else newphase=comp_maskedheapintreal(s,tgrad,fgrad,mask,a,M,tol(1),... do_timeinv,usephase); % Find all small coefficients in the unknown phase area missingidx = find(usedmask==0); bigenoughidx = s(missingidx)>absthr(1); usedmask(missingidx(bigenoughidx)) = 1; end % Do further tol for ii=2:numel(tol) newphase=comp_maskedheapintreal(s,tgrad,fgrad,usedmask,a,M,tol(ii),... do_timeinv,newphase); missingidx = find(usedmask==0); bigenoughidx = s(missingidx)>absthr(ii); usedmask(missingidx(bigenoughidx)) = 1; end % Convert the mask so it can be used directly for indexing usedmask = logical(usedmask); % Assign random values to coefficients below tolerance zerono = numel(find(~usedmask)); newphase(~usedmask) = rand(zerono,1)*2*pi; ltfat/inst/comp/arg_fwt2.m0000664000175000017500000000174613026262303015375 0ustar susnaksusnakfunction definput = arg_fwt2(definput) definput.flags.type2d = {'standard','tensor'}; %-*- texinfo -*- %@deftypefn {Function} arg_fwt2 %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_fwt2.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/nonsepgabpars_from_window.m0000664000175000017500000000351613026262303021133 0ustar susnaksusnakfunction [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.github.io/doc/comp/nonsepgabpars_from_window.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_chirpzt.m0000664000175000017500000000407413026262303016360 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_chirpzt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_gga.m0000664000175000017500000000440413026262303015430 0ustar susnaksusnakfunction c = comp_gga(f,indvec) %-*- texinfo -*- %@deftypefn {Function} comp_gga %@verbatim %COMP_GGA Generalized Goertzel Algorithm % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_gga.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %% Initialization 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 ltfat/inst/comp/comp_zerofilt.m0000664000175000017500000000322413026262303016527 0ustar susnaksusnakfunction H = comp_zerofilt(wintype,fs,chan_min,freqtoscale,scaletofreq,bwmul,bins,Ls) %-*- texinfo -*- %@deftypefn {Function} comp_zerofilt %@verbatim %COMP_ZEROFILT low-pass filter for warped filter banks %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_zerofilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . kk = chan_min; while scaletofreq(kk+bwmul) > fs/Ls kk = kk-1/bins; end Minfilt = kk; Maxpos = floor(Ls/fs*scaletofreq(chan_min-1/bins+bwmul)); samples = freqtoscale((0:Maxpos)*fs/Ls); if samples(1) == -Inf samples(1) = samples(2); end FILTS = zeros(round(bins*(chan_min-Minfilt)),numel(samples)); for kk = 1:size(FILTS,1) FILTS(kk,:) = firwin(wintype,(samples-(chan_min-kk/bins))/(2*bwmul)); end H = zeros(2*numel(samples)-1,1); H(numel(samples):end) = sqrt(sum(abs(FILTS.^2),1)); H(1:numel(samples)-1) = H(end:-1:numel(samples)+1); ltfat/inst/comp/comp_ups.m0000664000175000017500000000772113026262303015506 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ups.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_gabdual_long.m0000664000175000017500000000273613026262303017316 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_gabdual_long.html} %@seealso{gabdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/gabpars_from_windowsignal.m0000664000175000017500000000470113026262303021103 0ustar susnaksusnakfunction [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.github.io/doc/comp/gabpars_from_windowsignal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_iuwfbt.m0000664000175000017500000000566213026262303016201 0ustar susnaksusnakfunction f=comp_iuwfbt(c,wtNodes,nodesUps,rangeLoc,rangeOut,scaling) %-*- 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.github.io/doc/comp/comp_iuwfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; % Optionally scale the filters g = comp_filterbankscale(wtNodes{jj}.g(:),a(:),scaling); % Node filters to a matrix gMat = cell2mat(cellfun(@(gEl) gEl.h(:),g','UniformOutput',0)); % 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,class(c)); 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; ltfat/inst/comp/arg_gabphasederivconv.m0000664000175000017500000000204713026262303020200 0ustar susnaksusnakfunction definput=arg_gabphasederivconv(definput) definput.flags.phaseconv = {'freqinv','timeinv','symphase','relative'}; %-*- texinfo -*- %@deftypefn {Function} arg_gabphasederivconv %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_gabphasederivconv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_filterbank_fftbl.m0000664000175000017500000000437013026262303020172 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_filterbank_fftbl.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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(N-round(N)<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 = -L+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 ltfat/inst/comp/comp_idgtreal_fac.m0000664000175000017500000000717013026262303017301 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_idgtreal_fac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_dct.m0000664000175000017500000000460413026262303015446 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_dct.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [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; ltfat/inst/comp/arg_plotfwt.m0000664000175000017500000000234013026262303016201 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_plotfwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_quadtfdist.m0000664000175000017500000000254513026262303017046 0ustar susnaksusnakfunction p = comp_quadtfdist(f, q);; %-*- texinfo -*- %@deftypefn {Function} comp_quadtfdist %@verbatim % Comp_QUADTFDIST Compute quadratic time-frequency distribution % Usage p = comp_quadtfdist(f, q);; % % Input parameters: % f : Input vector % q : Kernel % % Output parameters: % p : Quadratic time-frequency distribution % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_quadtfdist.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven if isreal(f) z = comp_fftanalytic(f); else z = f; end; R = comp_instcorrmat(z,z); c = ifft2(fft2(R).*fft2(q)); p = fft(c); ltfat/inst/comp/comp_fftreal.m0000664000175000017500000000214213026262303016312 0ustar susnaksusnakfunction f=comp_fftreal(f) %-*- texinfo -*- %@deftypefn {Function} comp_fftreal %@verbatim %COMP_FFTREAL Compute an FFTREAL %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_fftreal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,:); ltfat/inst/comp/complainif_notnonnegint.m0000664000175000017500000000225313026262303020575 0ustar susnaksusnakfunction complainif_notnonnegint(var,varname,callfun) if nargin<3 callfun = mfilename; end if isempty(var) || ~isscalar(var) || ~isnumeric(var) || var<0 || rem(var,1)~=0 error('%s: %s should be a positive integer.',upper(callfun),varname); end %-*- texinfo -*- %@deftypefn {Function} complainif_notnonnegint %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/complainif_notnonnegint.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_cellcoef2tf.m0000664000175000017500000000346613026262303017071 0ustar susnaksusnakfunction coef = comp_cellcoef2tf(coef,maxLen) %-*- texinfo -*- %@deftypefn {Function} comp_cellcoef2tf %@verbatim %COMP_CELLCOEF2TF Cell to a tf-layout % Usage: coef = comp_cellcoef2tf(coef,maxLen) % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_cellcoef2tf.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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'; ltfat/inst/comp/comp_filterbank_fft.m0000664000175000017500000000232113026262303017646 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_filterbank_fft.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/comp/arg_groupthresh.m0000664000175000017500000000177213026262303017064 0ustar susnaksusnakfunction definput=arg_groupthresh(definput) definput.flags.grouptype={'group','elite'}; %-*- texinfo -*- %@deftypefn {Function} arg_groupthresh %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_groupthresh.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_inonsepdgtreal_quinqux.m0000664000175000017500000000471613026262303021510 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_inonsepdgtreal_quinqux.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/assert_squarelat.m0000664000175000017500000000364113026262303017240 0ustar susnaksusnakfunction 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.github.io/doc/comp/assert_squarelat.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_fftanalytic.m0000664000175000017500000000245613026262303017203 0ustar susnaksusnakfunction z = comp_fftanalytic(s) %-*- texinfo -*- %@deftypefn {Function} comp_fftanalytic %@verbatim %COMP_FFTANALYTIC Compute analytic representation % % Usage: z = comp_fftanalytic(s); % % COMP_FFTANALYTIC(s) computes the analytic representation of s. % The analytic representation is computed through the FFT of f. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_fftanalytic.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven Ls = size(s,1); H = floor(Ls/2); z = fft(s); z(2:Ls-H,:) = 2*z(2:Ls-H,:); z(H+2:Ls,:) = 0; z = ifft(z); ltfat/inst/comp/assert_classname.m0000664000175000017500000000327213026262303017205 0ustar susnaksusnakfunction 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.github.io/doc/comp/assert_classname.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/comp/comp_irdgt.m0000664000175000017500000000270113026262303016001 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_irdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_pchirp.m0000664000175000017500000000263613026262303016164 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_pchirp.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_filterbankscale.m0000664000175000017500000000267513026262303020033 0ustar susnaksusnakfunction g = comp_filterbankscale(g,a,scaling) if strcmp(scaling,'scale') g = cellfun(@(gEl,aEl) setfield(gEl,'h',gEl.h./aEl),g(:),... num2cell(a(:)),... 'UniformOutput',0); elseif strcmp(scaling,'noscale') % Do nothing elseif strcmp(scaling,'sqrt') g = cellfun(@(gEl,aEl) setfield(gEl,'h',gEl.h./sqrt(aEl)),g(:),... num2cell(a(:)),... 'UniformOutput',0); else error('%s: Unrecognized scaling flag.',upper(mfilename) ); end %-*- texinfo -*- %@deftypefn {Function} comp_filterbankscale %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_filterbankscale.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_fwtpack2cell.m0000664000175000017500000000436213026262303017256 0ustar susnaksusnakfunction ccell=comp_fwtpack2cell(F,c) %-*- texinfo -*- %@deftypefn {Function} comp_fwtpack2cell %@verbatim %COMP_FWTPACK2CELL Change FWT coef. format from pack to cell % Usage: ccell=comp_fwtpack2cell(F,c) % % Input parameters: % F : FWT frame object % c : Coefficients in pack format % Output parameters: % ccell : Coefficients in cell format % % COMP_FWTPACK2CELL(F,c) exctracts individual FWT subbands from % coefficients in packed format c as elements of a cell array. F must % be of type 'fwt' e.g. obtained by F=frame('fwt',...) and c must % be a Lc xW matrix, obtained by FRANA or BLOCKANA. % % The inverse operation is mere c=cell2mat(ccel) % % THE FUNCTION DOES NOT CHECK THE INPUT PARAMETERS IN ANY WAY! % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_fwtpack2cell.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . w = F.g; filtNo = numel(w.g); J = F.J; subbNo = (filtNo-1)*J+1; Lc = zeros(subbNo,1); runPtr = 0; levelLen = size(c,1)/F.red; 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 Lc(1)=levelLen; ccell = mat2cell(c,Lc); % The following does not work for a not being all equal. % % filtNo = numel(F.g.g); % a = F.g.a(1); % J = F.J; % % subbNo = (filtNo-1)*J+1; % Lc = zeros(subbNo,1); % % Lc(1:filtNo) = size(c,1)/(1+(filtNo-1)*(a^(J)-1)/(a-1)); % % Lc(filtNo+1:end) = kron(Lc(1).*a.^(1:J-1),ones(1,filtNo-1)); % % ccell = mat2cell(c,Lc); ltfat/inst/comp/arg_fwtcommon.m0000664000175000017500000000200513026262303016511 0ustar susnaksusnakfunction definput = arg_fwtcommon(definput) %-*- texinfo -*- %@deftypefn {Function} arg_fwtcommon %@verbatim %definput.flags.ansy = {'syn','ana'}; %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_fwtcommon.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.keyvals.a = []; ltfat/inst/comp/comp_nonsepwin2multi.m0000664000175000017500000000234313026262303020047 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_nonsepwin2multi.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_idwilt.m0000664000175000017500000000430613026262303016167 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_idwilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,0); % 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; ltfat/inst/comp/arg_filterbankdual.m0000664000175000017500000000204213026262303017470 0ustar susnaksusnakfunction definput = arg_filterbankdual(definput) definput.flags.painless = {'none','forcepainless'}; definput.keyvals.L = []; %-*- texinfo -*- %@deftypefn {Function} arg_filterbankdual %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/arg_filterbankdual.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_irdgtii.m0000664000175000017500000000271513026262303016330 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_irdgtii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_idgtreal.m0000664000175000017500000000303113026262303016460 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_idgtreal.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: TEST_DGT % REFERENCE: OK N=size(coef,2); L=N*a; if lt(2)==1 f = comp_isepdgtreal(coef,g,L,a,M,phasetype); else % Quinqux lattice f=comp_inonsepdgtreal_quinqux(coef,g,a,M); end; ltfat/inst/comp/complainif_notenoughargs.m0000664000175000017500000000214413026262303020737 0ustar susnaksusnakfunction complainif_notenoughargs(fnargin,limit,callfun) if nargin<3 callfun = mfilename; end if fnargin. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_ifilterbank.m0000664000175000017500000001043513026262303017165 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ifilterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_downs.m0000664000175000017500000000622613026262303016030 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_downs.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_atrousfilterbank_td.m0000664000175000017500000000435513026262303020745 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_atrousfilterbank_td.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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; ltfat/inst/comp/arg_tfplot.m0000664000175000017500000000247613026262303016024 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_tfplot.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_nyquistfilt.m0000664000175000017500000000314613026262303017267 0ustar susnaksusnakfunction H = comp_nyquistfilt(wintype,fs,chan_max,freqtoscale,scaletofreq,bwmul,bins,Ls) %-*- texinfo -*- %@deftypefn {Function} comp_nyquistfilt %@verbatim %COMP_NYQUISTFILT high-pass filter for warped filter banks %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_nyquistfilt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . kk = chan_max; while scaletofreq(kk-bwmul) < fs/2; kk = kk+1/bins; end Maxfilt = kk; Minpos = ceil(Ls/fs*scaletofreq(chan_max+1/bins-bwmul)); samples = freqtoscale((Minpos-1:floor(Ls/2))*fs/Ls); FILTS = zeros(round(bins*(Maxfilt-chan_max)),numel(samples)); for kk = 1:size(FILTS,1) FILTS(kk,:) = firwin(wintype,(samples-(chan_max+kk/bins))/(2*bwmul)); end H = zeros(2*numel(samples)-1,1); H(1:numel(samples)) = sqrt(sum(abs(FILTS.^2),1)); H(numel(samples)+1:end) = H(numel(samples)-1:-1:1); ltfat/inst/comp/comp_framelength_fusion.m0000664000175000017500000000273513026262303020556 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_framelength_fusion.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/comp/comp_instcorrmat.m0000664000175000017500000000321313026262303017234 0ustar susnaksusnakfunction R = comp_instcorrmat(f, g); %-*- texinfo -*- %@deftypefn {Function} comp_instcorrmat %@verbatim %COMP_INSTCORRMAT Compute instantaneous correlation matrix % Usage R = comp_instcorrmat(f, g); % % Input parameters: % f,g : Input vectors of the same length. % % Output parameters: % R : Instantaneous correlation matrix. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_instcorrmat.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven if ~all(size(f)==size(g)) error('%s: f and g must have the same size.', upper(mfilename)); end Ls = size(f, 1); if ~all(mod(Ls,2) == 0) f = postpad(f, Ls+1); g = postpad(g, Ls+1); end R = zeros(Ls,Ls,assert_classname(f,g)); for l = 0 : Ls-1; m = -min([Ls-l, l, round(Ls/2)-1]) : min([Ls-l, l, round(Ls/2)-1]); R(mod(Ls+m,Ls)+1, l+1) = f(mod(l+m, Ls)+1).*conj(g(mod(l-m, Ls)+1)); end R = R(1:Ls, 1:Ls); ltfat/inst/comp/comp_window.m0000664000175000017500000001330313026262303016177 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_window.html} %@seealso{gabwin, wilwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 isrect if firinfo.issqpu && test_isfirtight(g,a,M) info.istight=1; end; 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,firinfo]=firwin(winname,g{2},'energy',g{3:end}); info.isfir=1; if isrect if firinfo.issqpu && test_isfirtight(g,a,M) info.istight=1; end; end 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; if isempty(L) info.isfir = 1; 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.gl1 && isnumeric(gorig{2}) && gorig{2}<=M... || ischar(gorig) || isnumeric(gorig) && numel(gorig)<=M isfir = 1; else isfir = 0; end function istight=test_isfirtight(g,a,M) % Tests whether the Gabor system given by *a*, *M* and the FIR window % *g* forms a tight frame by computing *a* elements of the diagonal of % the frame operator. if numel(g) > M % There is still a small probability that the system is tight % or at least tight numerically. We have no cheap way how to % figure it out. istight = 0; return; end Lsmallest = lcm(a,M); Nsmallest = Lsmallest/a; glong = fir2long(g,Lsmallest).^2; gdiag = sum(reshape(glong,a,Nsmallest),2); istight = all(abs(gdiag(1)-gdiag)<1e-14); ltfat/inst/comp/comp_wfbt.m0000664000175000017500000000524213026262303015635 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_wfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); hCell = cellfun(@(hEl) 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); offset = cellfun(@(hEl) 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 ltfat/inst/comp/comp_uwfbt.m0000664000175000017500000000552713026262303016030 0ustar susnaksusnakfunction c=comp_uwfbt(f,wtNodes,nodesUps,rangeLoc,rangeOut,scaling) %-*- 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.github.io/doc/comp/comp_uwfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; % Optionally scale the filters h = comp_filterbankscale(wtNodes{jj}.h(:),a(:),scaling); % Node filters to a matrix % hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),h','UniformOutput',0)); hMat = cell2mat(cellfun(@(hEl) hEl.h(:),h','UniformOutput',0)); % Node filters initial skips % hOffset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNodes{jj}.h); hOffset = cellfun(@(hEl) 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 ltfat/inst/comp/arg_thresh.m0000664000175000017500000000203513026262303016000 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_thresh.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/assert_sigreshape_post.m0000664000175000017500000000215613026262303020436 0ustar susnaksusnakfunction 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.github.io/doc/comp/assert_sigreshape_post.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . f=reshape(f,permutedsize); if dim>1 % Undo the permutation. f=ipermute(f,order); end; ltfat/inst/comp/comp_idtwfb.m0000664000175000017500000000276513026262303016161 0ustar susnaksusnakfunction f = comp_idtwfb(c,nodes,dualnodes,Lc,rangeLoc,rangeOut,ext,do_complex) if do_complex % Split the coefficients c1 = cellfun(@(cEl1,cEl2) (cEl1 + cEl2)/2, c(1:end/2),c(end:-1:end/2+1),... 'UniformOutput',0); c2 = cellfun(@(cEl1,cEl2) (-1i*cEl1 + 1i*cEl2)/2, c(1:end/2),c(end:-1:end/2+1),... 'UniformOutput',0); else c1 = cellfun(@real,c,'UniformOutput',0); c2 = cellfun(@imag,c,'UniformOutput',0); end f1 = comp_iwfbt(c1,nodes,Lc,rangeLoc,rangeOut,ext); f = f1 + comp_iwfbt(c2,dualnodes,Lc,rangeLoc,rangeOut,ext); if ~do_complex f = real(f); end %-*- texinfo -*- %@deftypefn {Function} comp_idtwfb %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_idtwfb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_frsyn_tensor.m0000664000175000017500000000221713026262303017425 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_frsyn_tensor.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_iufilterbank_td.m0000664000175000017500000000421713026262303020042 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_iufilterbank_td.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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 ltfat/inst/comp/comp_ufwt.m0000664000175000017500000000513613026262303015662 0ustar susnaksusnakfunction c = comp_ufwt(f,h,a,J,scaling) %-*- 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.github.io/doc/comp/comp_ufwt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); % Optionally scale the filters h = comp_filterbankscale(h(:),a(:),scaling); %Change format to a matrix %hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),h(:)','UniformOutput',0)); hMat = cell2mat(cellfun(@(hEl) hEl.h(:),h(:)','UniformOutput',0)); %Delays %hOffset = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,h(:)); hOffset = cellfun(@(hEl) 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; ltfat/inst/comp/comp_uwpfbt.m0000664000175000017500000000612113026262303016177 0ustar susnaksusnakfunction c=comp_uwpfbt(f,wtNodes,rangeLoc,nodesUps,scaling,interscaling) %-*- 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.github.io/doc/comp/comp_uwpfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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]; interscalingfac = 1; if strcmp('intscale',interscaling) interscalingfac = 1/2; elseif strcmp('intsqrt',interscaling) interscalingfac = 1/sqrt(2); end % For each node in tree in the BF order... for jj=1:numel(wtNodes) % Node filters subs. factors a = wtNodes{jj}.a; % Optionally scale the filters h = comp_filterbankscale(wtNodes{jj}.h(:),a(:),scaling); % Node filters to a matrix % hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),h','UniformOutput',0)); hMat = cell2mat(cellfun(@(hEl) hEl.h(:),h','UniformOutput',0)); % Node filters initial skips % hOffet = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNodes{jj}.h); hOffet = cellfun(@(hEl) 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),:)*interscalingfac; ca = c(:,cInRunIdxs(1),:); end end ltfat/inst/comp/comp_filterbankresponse.m0000664000175000017500000000305413026262303020572 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_filterbankresponse.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_isepdgt.m0000664000175000017500000000334713026262303016336 0ustar susnaksusnakfunction [f]=comp_isepdgt(coef,g,L,a,M,phasetype) %-*- 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.github.io/doc/comp/comp_isepdgt.html} %@seealso{idgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: OK % REFERENCE: OK Lwindow=size(g,1); % FIXME : Calls non-comp function if phasetype==1 coef=phaseunlock(coef,a); end; 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; ltfat/inst/comp/comp_dgt_fb.m0000664000175000017500000000600513026262303016116 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_dgt_fb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/arg_wfbtcommon.m0000664000175000017500000000215513026262303016661 0ustar susnaksusnakfunction 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.github.io/doc/comp/arg_wfbtcommon.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . definput.flags.forder = {'freq','nat'}; ltfat/inst/comp/comp_wfac.m0000664000175000017500000000474513026262303015622 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_wfac.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_sigreshape_pre.m0000664000175000017500000000331213026262303017667 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_sigreshape_pre.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: OK % REFERENCE: OK if ~isnumeric(f) || isempty(f) error('%s: The input must be non-empty numeric.',upper(callfun)); end 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; ltfat/inst/comp/vect2cell.m0000664000175000017500000000235213026262303015537 0ustar susnaksusnakfunction c = vect2cell(x,idx) %-*- texinfo -*- %@deftypefn {Function} vect2cell %@verbatim %VECT2CELL Vector to cell % % Works exactly like mat2cell(x,idx,size(x,2)) % but it is faster. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/vect2cell.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if sum(idx)~=size(x,1) error('%s: Sizes do not comply.',upper(mfilename)); end idxEnd = cumsum(idx(:)); idxStart = [1;1+idxEnd(1:end-1)]; c = arrayfun(@(idS,idE) x(idS:idE,:),idxStart,idxEnd,'UniformOutput',0); ltfat/inst/comp/comp_sigreshape_post.m0000664000175000017500000000232513026262303020071 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_sigreshape_post.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_inonsepdgt.m0000664000175000017500000001027013026262303017042 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_inonsepdgt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_iwpfbt.m0000664000175000017500000000551313026262303016167 0ustar susnaksusnakfunction f=comp_iwpfbt(c,wtNodes,pOutIdxs,chOutIdxs,Ls,ext,interscaling) %-*- 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.github.io/doc/comp/comp_iwpfbt.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Do non-expansve transform if ext=='per' doPer = strcmp(ext,'per'); interscalingfac = 1; if strcmp('intscale',interscaling) interscalingfac = 1/2; elseif strcmp('intsqrt',interscaling) interscalingfac = 1/sqrt(2); end % 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); gCell = cellfun(@(gEl)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); offset = cellfun(@(gEl) 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; c{pOutIdxs(jj)} = interscalingfac*c{pOutIdxs(jj)}; else % We are at the root. f = comp_ifilterbank_td(c(chOutIdxs{jj}),gCell,a,Ls,offset,ext); end end ltfat/inst/comp/comp_filterbank.m0000664000175000017500000000517113026262303017015 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_filterbank.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [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 ltfat/inst/comp/comp_iatrousfilterbank_td.m0000664000175000017500000000415113026262303021110 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_iatrousfilterbank_td.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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 = -(1-filtLen-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(conj(flipud(g(:,m))),cext); f = f + ftmp(1+skipOut(m):L+skipOut(m),:); end ltfat/inst/comp/comp_nonsepdgt_multi.m0000664000175000017500000000345613026262303020113 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_nonsepdgt_multi.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/complainif_notvalidframeobj.m0000664000175000017500000000223113026262303021377 0ustar susnaksusnakfunction complainif_notvalidframeobj(F,callfun) if nargin<2 callfun = mfilename; end if ~isstruct(F) || ~isfield(F,'frana') error('%s: Argument F must be a frame definition structure.',... upper(callfun)); end; %-*- texinfo -*- %@deftypefn {Function} complainif_notvalidframeobj %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/complainif_notvalidframeobj.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/comp/comp_irdgtiii.m0000664000175000017500000000264113026262303016477 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_irdgtiii.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/comp_dgt_walnut.m0000664000175000017500000001031513026262303017040 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_dgt_walnut.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_dgtreal_fb.m0000664000175000017500000000615413026262303016767 0ustar susnaksusnakfunction [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.github.io/doc/comp/comp_dgtreal_fb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/comp/complainif_isjavaheadless.m0000664000175000017500000000314113026262303021040 0ustar susnaksusnakfunction complainif_isjavaheadless(callfun) %-*- texinfo -*- %@deftypefn {Function} complainif_isjavaheadless %@verbatim % COMPLAINIF_ISJAVAHEADLESS % % Prints warning if the available JRE ius in headless mode. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/complainif_isjavaheadless.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<1 callfun=mfilename; end try ge = javaMethod('getLocalGraphicsEnvironment','java.awt.GraphicsEnvironment'); catch % No java support at all. Either we are running matlab -nojvm % or octave(<3.8.0) without octave-java package. % Both cases shoud have already been caught somewhere. return; end if javaMethod('isHeadless',ge) error(['%s: JRE is available in headless mode only. ',... 'Block processing GUI will not work. Consider ',... 'installing full JRE.'],upper(callfun)); end ltfat/inst/comp/gabpars_from_window.m0000664000175000017500000000451313026262303017706 0ustar susnaksusnakfunction [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.github.io/doc/comp/gabpars_from_window.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/comp/comp_filterbank_pre.m0000664000175000017500000001271713026262303017667 0ustar susnaksusnakfunction 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. The function can work only % with g and a in proper formats i.e. processed by % FILTERBANKWINDOW. % % This function expects all numeric g{ii}.H to be instantiated with a % proper L. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/comp/comp_filterbank_pre.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 m = mTime % 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,class(g{m}.h));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,class(g{m}.h))]; 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') tmpg = circshift(postpad(g{m}.h,L),g{m}.offset); g{m}=rmfield(g{m},'h'); g{m}=rmfield(g{m},'offset'); if isfield(g{m},'fc') l=(0:L-1).'/L; tmpg = tmpg.*exp(2*pi*1i*round(g{m}.fc*L/2)*l); g{m}=rmfield(g{m},'fc'); end; g{m}.H = fft(tmpg); % The following parameters have to be set to zeros, because they % have already been incorporated in the freq. resp. calculation. g{m}.foff = 0; % Store the length used g{m}.L = L; elseif isfield(g{m},'H') if isnumeric(g{m}.H) if isfield(g{m},'L') if g{m}.L~=L % middlepad in the time domain. This will break %g.H = fft(middlepad(ifft(circshift(postpad(g.H(:),g.L),g.foff)),L)); %g.foff = 0; %g.L = L; error(['%s: g.H was already instantialized with L=%i, but ',... 'it is now used with L=%i.'],upper(mfilename),g{m}.L,L); end else % We do not know which L was g.H created with, there is no way % how to handle this properly. error('%s: g.H is already a numeric vector, but g.L was not specified.',... upper(mfilename)); end elseif isa(g{m}.H,'function_handle') g{m}.H=g{m}.H(L); if numel(g)>1 && isempty(g{m}.H) fprintf('%s: Warning: Filter %4d has zero bandwidth.\n',upper(mfilename),m); end if numel(g{m}.H) > L error('%s: Filter bandwidth is bigger than L.\n',upper(mfilename)); end % Store the length used g{m}.L = L; else error('%s: SENTINEL: Wrong format of g{ii}.H ',upper(mfilename)); end if isfield(g{m},'foff') if isa(g{m}.foff,'function_handle') g{m}.foff=g{m}.foff(L); elseif isscalar(g{m}.foff) % Nothing else error('%s: SENTINEL: Wrong format of g{ii}.foff ',upper(mfilename)); end else g.foff = 0; end 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, but only for non-fractional subsampling % % Just find out whether we are working with fract. subsampling. [~,info]=comp_filterbank_a(a,M,struct); if numel(g{m}.H)==L && ~info.isfractional 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; ltfat/inst/comp/comp_extBoundary.m0000664000175000017500000001222313026262303017174 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_extBoundary.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_ifilterbank_fftbl.m0000664000175000017500000000465013026262303020344 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_ifilterbank_fftbl.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . M = numel(c); W = size(c{1},2); if size(a,2)>1 afrac=a(:,1)./a(:,2); else afrac = a(:,1); end N = cellfun(@(cEl) size(cEl,1),c); if 0 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 = round(afrac(1).*size(c{1},1)); end F = zeros(L,W,assert_classname(c{1},G{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 % Un-circshift Ctmp = circshift(fft(c{m}(:,w)),-foff(m)); % Periodize and cut to the bandwidth of G{m} periods = ceil(numel(G{m})/N(m)); Ctmp = postpad(repmat(Ctmp,periods,1),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 = -L+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 ltfat/inst/comp/comp_frana_fusion.m0000664000175000017500000000225513026262303017346 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_frana_fusion.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/comp/comp_col2diag.m0000664000175000017500000000274513026262303016364 0ustar susnaksusnakfunction 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.github.io/doc/comp/comp_col2diag.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/nonstatgab/0000775000175000017500000000000013026262303014676 5ustar susnaksusnakltfat/inst/nonstatgab/nsgabdual.m0000664000175000017500000001003213026262303017010 0ustar susnaksusnakfunction 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.github.io/doc/nonstatgab/nsgabdual.html} %@seealso{nsgabtight, nsdgt, insdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/nonstatgab/nsdgt.m0000664000175000017500000001406413026262303016200 0ustar susnaksusnakfunction [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 non-stationary 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 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. % % 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.github.io/doc/nonstatgab/nsdgt.html} %@seealso{insdgt, nsgabdual, nsgabtight, phaselock, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/nonstatgab/plotnsdgt.m0000664000175000017500000000704713026262303017102 0ustar susnaksusnakfunction coef = plotnsdgt(coef,a,varargin) %-*- texinfo -*- %@deftypefn {Function} plotnsdgt %@verbatim %PLOTNSDGT Plot 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.github.io/doc/nonstatgab/plotnsdgt.html} %@seealso{tfplot, nsdgt, unsdgt, nsdgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 cwork=circshift(cwork,kv.yres/2-1); else cwork=circshift(cwork,(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); if nargout<1 clear coef; end ltfat/inst/nonstatgab/nonstatgabinit.m0000664000175000017500000000165413026262303020106 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} nonstatgabinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/nonstatgab/nonstatgabinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/nonstatgab/nsgabtight.m0000664000175000017500000001000213026262303017177 0ustar susnaksusnakfunction 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.github.io/doc/nonstatgab/nsgabtight.html} %@seealso{nsgabtight, nsdgt, insdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/nonstatgab/insdgt.m0000664000175000017500000000634413026262303016353 0ustar susnaksusnakfunction f=insdgt(c,g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} insdgt %@verbatim %INSDGT Inverse non-stationary 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.github.io/doc/nonstatgab/insdgt.html} %@seealso{nsdgt, nsgabdual, nsgabtight, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/nonstatgab/Contents.m0000664000175000017500000000343713026262303016660 0ustar susnaksusnak% LTFAT - Non-stationary Gabor systems % % Florent Jaillet and Peter L. Soendergaard, 2011 - 2016 % % 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 - Diagonal 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 visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/nonstatgab/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/nonstatgab/nsgabwin.m0000664000175000017500000000775613026262303016703 0ustar susnaksusnakfunction [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.github.io/doc/nonstatgab/nsgabwin.html} %@seealso{filterbank, filterbankdual, filterbankrealdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/nonstatgab/nsdgtreal.m0000664000175000017500000001547413026262303017052 0ustar susnaksusnakfunction [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 non-stationary 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 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. % % 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.github.io/doc/nonstatgab/nsdgtreal.html} %@seealso{nsdgt, insdgtreal, nsgabdual, nsgabtight, phaselock, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/nonstatgab/plotnsdgtreal.m0000664000175000017500000000657113026262303017747 0ustar susnaksusnakfunction coef = plotnsdgtreal(coef,a,varargin) %-*- texinfo -*- %@deftypefn {Function} plotnsdgtreal %@verbatim %PLOTNSDGTREAL Plot 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 useful 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.github.io/doc/nonstatgab/plotnsdgtreal.html} %@seealso{tfplot, nsdgt, nsdgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); if nargout<1 clear coef; end ltfat/inst/nonstatgab/nsdgtlength.m0000664000175000017500000000345313026262303017402 0ustar susnaksusnakfunction 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.github.io/doc/nonstatgab/nsdgtlength.html} %@seealso{nsdgt, nsdgtlengthcoef} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/nonstatgab/unsdgt.m0000664000175000017500000001231313026262303016360 0ustar susnaksusnakfunction [c,Ls] = unsdgt(f,g,a,M) %-*- texinfo -*- %@deftypefn {Function} unsdgt %@verbatim %UNSDGT Uniform Non-stationary 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 non-stationary 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 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. 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 consecutive % 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.github.io/doc/nonstatgab/unsdgt.html} %@seealso{insdgt, nsgabdual, nsgabtight, phaselock, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/nonstatgab/nsgabframebounds.m0000664000175000017500000000503613026262303020400 0ustar susnaksusnakfunction [AF,BF]=nsgabframebounds(g,a,M) %-*- texinfo -*- %@deftypefn {Function} nsgabframebounds %@verbatim %NSGABFRAMEBOUNDS Frame bounds of non-stationary 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 non-stationary 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.github.io/doc/nonstatgab/nsgabframebounds.html} %@seealso{nsgabtight, nsdgt, insdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/nonstatgab/unsdgtreal.m0000664000175000017500000001353113026262303017227 0ustar susnaksusnakfunction [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 non-stationary 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 % consecutive 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.github.io/doc/nonstatgab/unsdgtreal.html} %@seealso{nsdgt, insdgtreal, nsgabdual, nsgabtight, phaselock, demo_nsdgt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 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+ Depends: octave (>= 3.8.0) BuildRequires: fftw3 [Debian] libfftw3-3, lapack [Debian] liblapack3, blas [Debian] libblas3, portaudio [Debian] portaudio19-dev Java Runtime [Debian] default-jre Url: http://ltfat.github.io/ ltfat/inst/wavelets/0000775000175000017500000000000013026262304014371 5ustar susnaksusnakltfat/inst/wavelets/wfiltdt_optsym.m0000664000175000017500000000366713026262303017652 0ustar susnaksusnakfunction [h,g,a,info] = wfiltdt_optsym(N) %-*- texinfo -*- %@deftypefn {Function} wfiltdt_optsym %@verbatim %WFILTDT_OPTSYM Optimizatized Symmetric Self-Hilbertian Filters % % Usage: [h,g,a] = wfiltdt_optsym(N); % % [h,g,a]=WFILTDT_OPTSYM(N) with N in {1,2,3} returns filters % suitable for dual-tree complex wavelet transform with optimized % symmetry. % % Examples: % --------- % : % wfiltdtinfo('optsym3'); % % References: % B. Dumitrescu, I. Bayram, and I. W. Selesnick. Optimization of % symmetric self-hilbertian filters for the dual-tree complex wavelet % transform. IEEE Signal Process. Lett., 15:146--149, 2008. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfiltdt_optsym.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa [h(:,1),g(:,1),a,info] = wfilt_optsyma(N); [h(:,2),g(:,2)] = wfilt_optsymb(N); % Default first and leaf filters % They are chosen to be orthonormal near-symmetric here in order not to % break the orthonormality of the overal representation. [info.defaultfirst, info.defaultfirstinfo] = fwtinit('symorth1'); [info.defaultleaf, info.defaultleafinfo] = ... deal(info.defaultfirst,info.defaultfirstinfo); ltfat/inst/wavelets/fwt2.m0000664000175000017500000001022213026262303015425 0ustar susnaksusnakfunction 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 filter bank definition. % J : Number of filter bank 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 filter bank defined by w. % Please see FWT for description of w and J. % % FWT2 supports just the non-expansive boundary condition 'per' and % critically subsampled filter banks 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' % Standard behaviour of the JPEG 2000 standard. % This is the default. % % 'tensor' % This corresponds to doing a full 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,'db8',4); % imagesc(dynlimit(20*log10(abs(c)),70)); % axis('image'); colormap(gray); % % The second example uses the tensor product layout: % % c = fwt2(cameraman,'db8',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.github.io/doc/wavelets/fwt2.html} %@seealso{ifwt2, fwtinit, demo_imagecompression} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; complainif_notposint(J,'J'); [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 filter banks 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(min(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 ltfat/inst/wavelets/wfilt_coif.m0000664000175000017500000001134413026262303016676 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_coif(K) %-*- texinfo -*- %@deftypefn {Function} wfilt_coif %@verbatim %WFILT_COIF Coiflets % % Usage: [h,g,a] = wfilt_coif(K); % % [h,g,a]=WFILT_COIF(K) with K in {1,2,3,4,5} returns a Coiflet % filters of order 2K the number of vanishing moments of both the % scaling and the wavelet functions. % % Values are taken from table 8.1 from the reference. REMARK: There is % a typo in 2nd element for K==1. % % Examples: % --------- % : % wfiltinfo('coif2'); % % : % wfiltinfo('coif5'); % % References: % I. Daubechies. Ten Lectures on Wavelets. Society for Industrial and % Applied Mathematics, Philadelphia, PA, USA, 1992. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_coif.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 1; a = [2;2]; switch(K) case 1 hlp = [ -0.011070271529 -0.051429728471 0.272140543058 0.602859456942 0.238929728471 -0.051429728471 ]; d = [-3,-3]; case 2 hlp = [ -0.000509505399 -0.001289203356 0.003967883613 0.016744410163 -0.042026480461 -0.054085607092 0.294867193696 0.574682393857 0.273021046535 -0.047639590310 -0.029320137980 0.011587596739 ]; d = [-7,-5]; case 3 hlp = [ -0.000024465734 -0.000050192775 0.000329665174 0.000790205101 -0.001820458916 -0.006369601011 0.011229240962 0.024434094321 -0.058196250762 -0.050770140755 0.302983571773 0.561285256870 0.286503335274 -0.043220763560 -0.046507764479 0.016583560479 0.005503126709 -0.002682418671 ]; d= [-11,-7]; case 4 hlp = [ -0.000001262175 -0.000002304942 0.000022082857 0.000044080354 -0.000183829769 -0.000416500571 0.000895594529 0.002652665946 -0.004001012886 -0.010756318517 0.017735837438 0.027813640153 -0.068038127051 -0.047112738865 0.307157326198 0.553126452562 0.293667390895 -0.039652648517 -0.057464234429 0.018867235378 0.011362459244 -0.005194524026 -0.001152224852 0.000630961046 ]; d= [-15,-9]; case 5 hlp = [ -0.0000000673 -0.0000001184 0.0000014593 0.0000026408 -0.0000150720 -0.0000292321 0.0000993776 0.0002137298 -0.0004512270 -0.0011758222 0.0017206547 0.0047830014 -0.0064800900 -0.0139736879 0.0231107770 0.0291958795 -0.0746522389 -0.0438660508 0.3097068490 0.5475054294 0.2980923235 -0.0368000736 -0.0649972628 0.0199178043 0.0165520664 -0.0071637819 -0.0029411108 0.0015402457 0.0002535612 -0.0001499638 ]; d= [-19,-11]; otherwise error('%s: No such COIFLET filters.',upper(mfilename)); end hlp = hlp*sqrt(2); harr = [hlp, (-1).^(0:size(hlp,1)-1).'.*flipud(hlp)]; h=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h=cellfun(@(hEl,dEl) struct('h',hEl(:),'offset',dEl),h,num2cell(d),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/uwpfbt.m0000664000175000017500000001203213026262303016053 0ustar susnaksusnakfunction [c,info]=uwpfbt(f,wt,varargin) %-*- texinfo -*- %@deftypefn {Function} uwpfbt %@verbatim %UWPFBT Undecimated Wavelet Packet FilterBank Tree % Usage: c=uwpfbt(f,wt); % [c,info]=uwpfbt(...); % % 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. % % [c,info]=UWPFBT(f,wt) additionally 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. % % Scaling of intermediate outputs: % -------------------------------- % % The following flags control scaling of intermediate outputs and % therefore the energy relations between coefficient subbands. An % intermediate output is an output of a node which is further used as an % input to a descendant node. % % 'intsqrt' % Each intermediate output is scaled by 1/sqrt(2). % If the filterbank in each node is orthonormal, the overall % undecimated transform is a tight frame. % This is the default. % % 'intnoscale' % No scaling of intermediate results is used. This is % necessaty for the WPBEST function to correctly work with % the cost measures. % % 'intscale' % Each intermediate output is scaled by 1/2. % % If 'intnoscale' is used, 'intscale' must be used in IUWPFBT (and vice % versa) in order to obtain a perfect reconstruction. % % Scaling of filters: % ------------------- % % When compared to WPFBT, the subbands produced by UWPFBT are % gradually more and more redundant with increasing depth in the tree. % This results in energy grow of the coefficients. There are 3 flags % defining filter scaling: % % 'sqrt' % Each filter is scaled by 1/sqrt(a), there a is the hop % factor associated with it. If the original filterbank is % orthonormal, the overall undecimated transform is a tight % frame. % This is the default. % % 'noscale' % Uses filters without scaling. % % 'scale' % Each filter is scaled by 1/a. % % If 'noscale' is used, 'scale' must be used in IUWPFBT (and vice % versa) in order to obtain a perfect reconstruction. % % Examples: % --------- % % A simple example of calling the UWPFBT function using the "full % decomposition" wavelet tree: % % [f,fs] = greasy; % J = 6; % [c,info] = uwpfbt(f,{'db10',J,'full'}); % plotwavelets(c,info,fs,'dynrange',90); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/uwpfbt.html} %@seealso{iuwpfbt, wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'UWPFBT'); definput.import = {'wfbtcommon','uwfbtcommon'}; definput.flags.interscaling = {'intsqrt', 'intscale', 'intnoscale'}; [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 = nodeBForder(0,wt); nodesUps = nodesFiltUps(wtPath,wt); rangeLoc = nodesLocOutRange(wtPath,wt); c = comp_uwpfbt(f,wt.nodes(wtPath),rangeLoc,nodesUps,flags.scaling,... flags.interscaling); %% ----- Optional : Fill the info struct. ----- if nargout>1 info.fname = 'uwpfbt'; info.wt = wt; info.fOrder = flags.forder; info.isPacked = 0; info.interscaling = flags.interscaling; info.scaling = flags.scaling; end ltfat/inst/wavelets/wfbtput.m0000664000175000017500000001444013026262303016244 0ustar susnaksusnakfunction 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 w to the filter % tree structure wt at level d and index(es) 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. % % Examples: % --------- % % This example shows magnitude frequency responses of a tree build from % the root: % % % Initialize empty struct % wt = wfbtinit(); % % Put root node to the empty struct % wt1 = wfbtput(0,0,'db8',wt); % % Connect a different nodes to both outputs of the root % wt2 = wfbtput(1,[0,1],'db10',wt1); % % Connect another nodes just to high-pass outputs of nodes just added % wt3 = wfbtput(2,[1,3],'db10',wt2); % % Add another node at level 3 % wt4 = wfbtput(3,1,'db16',wt3); % % % Create identical filterbanks % [g1,a1] = wfbt2filterbank(wt1,'freq'); % [g2,a2] = wfbt2filterbank(wt2,'freq'); % [g3,a3] = wfbt2filterbank(wt3,'freq'); % [g4,a4] = wfbt2filterbank(wt4,'freq'); % % % Plot frequency responses of the growing tree. Linear scale % % (both axis) is used and positive frequencies only are shown. % subplot(4,1,1); % filterbankfreqz(g1,a1,1024,'plot','linabs','posfreq'); % subplot(4,1,2); % filterbankfreqz(g2,a2,1024,'plot','linabs','posfreq'); % subplot(4,1,3); % filterbankfreqz(g3,a3,1024,'plot','linabs','posfreq'); % subplot(4,1,4); % filterbankfreqz(g4,a4,1024,'plot','linabs','posfreq'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtput.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa if nargin<4 error('%s: Too few input parameters.',upper(mfilename)); end %if isfield(wt,'dualnodes') % error('%s: Cannot modify the dual-tree struct.',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); oldnodecount = numel(wt.nodes); nodeschanged = []; [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.g)~=length(wt.nodes{rootId}.g)) error('%s: The replacing root have to have %d filters.',mfilename,length(wt.nodes{rootId}.g)); end end else error('%s: Root already defined. Use FORCE option to replace.',mfilename); end wt.nodes{rootId} = node; nodeschanged(end+1) = rootId; if isfield(wt,'dualnodes') wt.dualnodes{rootId} = node; end continue; end wt.nodes{end+1} = node; wt.parents(end+1) = nodeNo; wt.children{end+1} = []; if isfield(wt,'dualnodes') wt.dualnodes{end+1} = node; end continue; 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(node.g)~=length(wt.nodes{tmpnode}.g) error('%s: The replacing node must have %d filters.',mfilename,length(wt.nodes{tmpnode}.g)); end end wt.nodes{tmpnode} = node; nodeschanged(end+1) = tmpnode; if isfield(wt,'dualnodes') wt.dualnodes{tmpnode} = node; end % Since we are replacing a node, all links are already correct continue; 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); if isfield(wt,'dualnodes') wt.dualnodes{end+1} = node; end end % We have to correctly shuffle filters in the just added (or modified) filters % if the tree was already defined as frequency ordered. if wt.freqOrder wt = nat2freqOrder(wt,[nodeschanged,oldnodecount+1:numel(wt.nodes)]); end ltfat/inst/wavelets/dtwfbinit.m0000664000175000017500000002460413026262303016546 0ustar susnaksusnakfunction [dualwt,info] = dtwfbinit(dualwtdef,varargin) %-*- texinfo -*- %@deftypefn {Function} dtwfbinit %@verbatim %DTWFBINIT Dual-Tree Wavelet Filterbank Initialization % Usage: dualwt=dtwfbinit(dualwtdef); % % Input parameters: % dualwtdef : Dual-tree filterbank definition. % % Output parameters: % dualwt : Dual-tree filtarbank structure. % % dtwfinit() (a call without aguments) creates an empty structure. It % has the same fields as the struct. returned from WFBTINIT plus a field % to hold nodes from the second tree: % % .nodes Filterbank nodes of the first tree % % .dualnodes Filterbank nodes of the second tree % % .children Indexes of children nodes % % .parents Indexes of a parent node % % .forder Frequency ordering of the resultant frequency bands. % % dtwfinit({dualw,J,flag}) creates a structure representing a dual-tree % wavelet filterbank of depth J, using dual-tree wavelet filters % specified by dualw. The shape of the tree is controlled by flag. % Please see help on DTWFB or DTWFBREAL for description of the % parameters. % % [dualwt,info]=dtwfinit(...) additionally returns info struct which % provides some information about the computed window: % % info.tight % True if the overall tree construct a tight frame. % % info.dw % A structure containing basic dual-tree filters as returned from % fwtinit(dualwtdef,'wfiltdt_'). % % Additional optional flags % ------------------------- % % 'freq','nat' % Frequency or natural ordering of the resulting coefficient subbands. % Default ordering is 'freq'. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/dtwfbinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Output structure definition. % The structure has the same fields as returned by wfbtinit % but contains additional field .dualnodes containing % filters of the dual tree %%%%%%%%%%%%%%%%%%%%%%%%%%%%% dualwt = wfbtinit(); dualwt.dualnodes = {}; %%%%%%%%%%%%%%%%%%%%%%%%%%%%% info.istight = 0; if nargin < 1 return; end % Frequency or natural ordering definput.import = {'wfbtcommon'}; [flags,kv]=ltfatarghelper({},definput,varargin); % Strict throws an error if filterbank is not tight and ana: or syn: % is not specified. do_strict = 0; % Dual returns the 'other' filterbank. do_dual = 0; % Check 'strict' if iscell(dualwtdef) && ischar(dualwtdef{1}) && strcmpi(dualwtdef{1},'strict') do_strict = 1; dualwtdef = dualwtdef{2:end}; end % Check 'dual' if iscell(dualwtdef) && ischar(dualwtdef{1}) && strcmpi(dualwtdef{1},'dual') do_dual = 1; dualwtdef = dualwtdef{2:end}; end % FIRST, check if dtwdef is already a struct if isstruct(dualwtdef) if isfield(dualwtdef,'nodes') && isfield(dualwtdef,'dualnodes') dualwt = dualwtdef; if do_dual || do_strict nodesArg = dualwt.nodes; % Undo the frequency ordering if dualwt.freqOrder dualwt = nat2freqOrder(dualwt,'rev'); end doDualTreeFilt = cellfun(@(nEl) strcmp(nEl.wprefix,'wfiltdt_'),... nodesArg); if do_dual nodesArg = cellfun(@(nEl) {'dual',nEl},nodesArg,... 'UniformOutput',0); end if do_strict nodesArg = cellfun(@(nEl) {'strict',nEl},nodesArg,... 'UniformOutput',0); end info.istight = 1; dualwt.nodes = {}; dualwt.dualnodes = {}; rangeRest = 1:numel(nodesArg); rangeRest(dualwt.parents==0) = []; for ii=rangeRest if doDualTreeFilt(ii) % This is dual-tree specific filterbank [dualwt.nodes{ii},infotmp] = fwtinit(nodesArg{ii},'wfiltdt_'); dualwt.dualnodes{ii} = dualwt.nodes{ii}; dualwt.nodes{ii}.h(:,2) = []; dualwt.nodes{ii}.g(:,2) = []; dualwt.dualnodes{ii}.h(:,1) = []; dualwt.dualnodes{ii}.g(:,1) = []; else [dualwt.nodes{ii},infotmp] = fwtinit(nodesArg{ii}); dualwt.dualnodes{ii} = dualwt.nodes{ii}; end info.istight = info.istight && infotmp.istight; end % Treat root separately [rootNode,infotmp] = fwtinit(nodesArg{dualwt.parents==0}); dualwt = replaceRoots(dualwt,rootNode); info.istight = info.istight && infotmp.istight; % Do the filter frequency shuffling again, since the filters were % overwritten in fwtinit. if dualwt.freqOrder dualwt = nat2freqOrder(dualwt); end end % Do filter shuffling if flags.do_freq differs from the wt.freqOrder. % Frequency and natural oreding coincide for DWT. if dualwt.freqOrder && ~flags.do_freq dualwt = nat2freqOrder(dualwt,'rev'); dualwt.freqOrder = ~dualwt.freqOrder; elseif ~dualwt.freqOrder && flags.do_freq dualwt = nat2freqOrder(dualwt); dualwt.freqOrder = ~dualwt.freqOrder; end else error('%s: Invalid dual-tree structure format.',upper(mfilename)); end return; end % Parse the other params % Tree type definput.flags.treetype = {'dwt','full','doubleband','quadband',... 'octaband','root'}; % First stage filterbank definput.keyvals.first = []; % Leaf filterbank definput.keyvals.leaf = []; % Depth of the tree definput.keyvals.J = []; wdef = dualwtdef{1}; [flags2,kv2,J]=ltfatarghelper({'J'},definput,dualwtdef(2:end)); complainif_notposint(J,'J'); % Now dtwdef is this {dtw,J,flag,'first',w} if do_dual wdef = {'dual',wdef}; end if do_strict wdef = {'strict',wdef}; end if ~(ischar(wdef) || iscell(wdef)) error('%s: Unrecognized format of dual-tree filters.',upper(mfilename)); end % Get the dual-tree filters [w, dtinfo] = fwtinit(wdef,'wfiltdt_'); info.istight = dtinfo.istight; info.dw = w; % Determine the first-stage wavelet filters if ~isfield(dtinfo,'defaultfirst') && isempty(kv2.first) error('%s: No first stage wavelet filters specified.',upper(mfilename)); end if ~isempty(kv2.first) if do_dual kv2.first = {'dual',kv2.first}; end if do_strict kv2.first = {'strict',kv2.first}; end [kv2.first, firstinfo] = fwtinit(kv2.first); isfirsttight = firstinfo.istight; else kv2.first = dtinfo.defaultfirst; isfirsttight = dtinfo.defaultfirstinfo.istight; end isleaftight = []; if ~(flags2.do_dwt || flags2.do_root) % Determine leaf nodes (only valid for wavelet packets) if ~isfield(dtinfo,'defaultleaf') && isempty(kv2.leaf) error('%s: No leaf wavelet filters specified.',... upper(mfilename)); else if isempty(kv2.leaf) kv2.leaf = dtinfo.defaultleaf; isleaftight = dtinfo.defaultleafinfo.istight; else if do_dual kv2.leaf = {'dual',kv2.leaf}; end if do_strict kv2.leaf = {'strict',kv2.leaf}; end [kv2.leaf, leafinfo] = fwtinit(kv2.leaf); isleaftight = leafinfo.istight; end end end % Extract filters for dual trees % This is a bit clumsy... w1 = w; w1.h = w1.h(:,1); w1.g = w1.g(:,1); w2 = w; w2.h = w2.h(:,2); w2.g = w2.g(:,2); % Initialize both trees dualwt = wfbtinit({w1,J,flags2.treetype}, 'nat'); dtw2 = wfbtinit({w2,J,flags2.treetype}, 'nat'); % Merge tree definitions to a single struct. dualwt.dualnodes = dtw2.nodes; dualwt = replaceRoots(dualwt,kv2.first); % Replace the 'packet leaf nodes' (see Bayram) if ~(flags2.do_dwt || flags2.do_root) filtNo = numel(w1.g); if flags2.do_doubleband for jj=1:J-1 dualwt = wfbtput(2*(jj+1)-1,1:filtNo-1,kv2.leaf,dualwt,'force'); end elseif flags2.do_quadband idx = 1:filtNo-1; idx = [idx,idx+filtNo]; dualwt = wfbtput(2,idx,kv2.leaf,dualwt,'force'); for jj=1:J-1 dualwt = wfbtput(3*(jj+1)-2,1:filtNo-1,kv2.leaf,dualwt,'force'); dualwt = wfbtput(3*(jj+1)-1,1:2*filtNo-1,kv2.leaf,dualwt,'force'); end elseif flags2.do_octaband idx = 1:filtNo-1;idx = [idx,idx+filtNo]; dualwt = wfbtput(2,idx,kv2.leaf,dualwt,'force'); idx = 1:2*filtNo-1;idx = [idx,idx+2*filtNo]; dualwt = wfbtput(3,idx,kv2.leaf,dualwt,'force'); for jj=1:J-1 dualwt = wfbtput(4*(jj+1)-3,1:filtNo-1,kv2.leaf,dualwt,'force'); dualwt = wfbtput(4*(jj+1)-2,1:2*filtNo-1,kv2.leaf,dualwt,'force'); dualwt = wfbtput(4*(jj+1)-1,1:4*filtNo-1,kv2.leaf,dualwt,'force'); end elseif flags2.do_full for jj=2:J-1 idx = 1:filtNo^jj-1; idx(filtNo^(jj-1))=[]; dualwt = wfbtput(jj,idx,kv2.leaf,dualwt,'force'); end else error('%s: Something is seriously wrong!',upper(mfilename)); end end % Do filter shuffling if frequency ordering is required, dualwt.freqOrder = flags.do_freq; if flags.do_freq dualwt = nat2freqOrder(dualwt); end % info.istight = isfirsttight && info.istight; if ~isempty(isleaftight) info.istight = info.istight && isleaftight; end function dtw = replaceRoots(dtw,rootNode) % Replace the root nodes firstTmp = rootNode; firstTmp.h = cellfun(@(hEl) setfield(hEl,'offset',hEl.offset+1),... firstTmp.h,'UniformOutput',0); firstTmp.g = cellfun(@(gEl) setfield(gEl,'offset',gEl.offset+1),... firstTmp.g,'UniformOutput',0); % First tree root dtw.nodes{dtw.parents==0} = rootNode; % Second tree root (shifted by 1 sample) dtw.dualnodes{dtw.parents==0} = firstTmp; ltfat/inst/wavelets/wfbt.m0000664000175000017500000001170013026262303015507 0ustar susnaksusnakfunction [c,info]=wfbt(f,wt,varargin) %-*- texinfo -*- %@deftypefn {Function} wfbt %@verbatim %WFBT Wavelet FilterBank Tree % Usage: c=wfbt(f,wt); % c=wfbt(f,wt,ext); % [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. % % WFBT(f,wt) returns coefficients c obtained by applying a wavelet % filterbank tree defined by wt to the input data f. % % [c,info]=WFBT(f,wt) additionally 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' % Plain DWT tree (default). This gives one band per octave freq. % resolution when using 2 channel basic wavelet filterbank and % produces coefficients identical to the ones in FWT. % % 'full' % Full filterbank tree. Both (all) basic filterbank outputs are % decomposed further up to depth J achieving linear frequency band % division. % % 'doubleband','quadband','octaband' % The filterbank is designed such that it mimics 4-band, 8-band or % 16-band complex wavelet transform provided the basic filterbank % is 2 channel. In this case, J is treated such that it defines % number of levels of 4-band, 8-band or 16-band transform. % % 2) Structure returned by the WFBTINIT function and possibly % modified by WFBTPUT and WFBTREMOVE. % % Please see WFBTINIT for a detailed description and more options. % % 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'(default),'zero','odd','even' % Type of the boundary handling. Please see the help on FWT for a % description of the boundary condition flags. % % 'freq'(default),'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). % % 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.github.io/doc/wavelets/wfbt.html} %@seealso{iwfbt, wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'WFBT'); definput.import = {'fwt','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); % 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 [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt); c = comp_wfbt(f,wt.nodes(nodesBF),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 ltfat/inst/wavelets/ifwt2.m0000664000175000017500000000607313026262303015607 0ustar susnaksusnakfunction 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. % w : Wavelet filters definition. % J : Number of filterbank iterations. % Ls : Size of the reconstructed signal. % % Output parameters: % f : Reconstructed data. % % f = IFWT2(c,w,J) reconstructs signal f from the wavelet coefficients % c using a J*-iteration synthesis filterbank build from the basic % synthesis filterbank defined by w. f is a matrix with % size(f)==size(c). % % f = IFWT2(c,w,J,Ls) works as above but the result f is cut or % extended to size Ls if Ls is a two-element vector or to [Ls,Ls] % if Ls is a scalar. % % 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.github.io/doc/wavelets/ifwt2.html} %@seealso{fwt2, fwtinit, demo_imagecompression} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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; ltfat/inst/wavelets/wavfun.m0000664000175000017500000001100613026262303016052 0ustar susnaksusnakfunction [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+1 set to 1. xvals* % contains correct x-axis values. All but last columns 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.github.io/doc/wavelets/wavfun.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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 % Flipud because the impulse responses are time-reversed wtemp=flipud(wtemp); % 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 % Flipud because the impulse responses are time-reversed wtemp=flipud(wtemp); 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 ltfat/inst/wavelets/iuwfbt.m0000664000175000017500000000667513026262303016064 0ustar susnaksusnakfunction 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,wt : 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. % % Please see help for WFBT description of possible formats of wt. % % Filter scaling: % --------------- % % As in UWFBT, the function recognizes three flags controlling scaling % of the filters: % % 'sqrt' % Each filter is scaled by 1/sqrt(a), there a is the hop % factor associated with it. If the original filterbank is % orthonormal, the overall undecimated transform is a tight % frame. % This is the default. % % 'noscale' % Uses filters without scaling. % % 'scale' % Each filter is scaled by 1/a. % % If 'noscale' is used, 'scale' must have been used in UWFBT (and vice % versa) in order to obtain a perfect reconstruction. % % 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.github.io/doc/wavelets/iuwfbt.html} %@seealso{uwfbt, plotwavelets} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'IUWFBT'); if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IUWFBT'); wt = wfbtinit({'dual',par.wt},par.fOrder); scaling = par.scaling; % Use the "oposite" scaling if strcmp(scaling,'scale') scaling = 'noscale'; elseif strcmp(scaling,'noscale') scaling = 'scale'; end else %% PARSE INPUT definput.import = {'wfbtcommon','uwfbtcommon'}; flags=ltfatarghelper({},definput,varargin); % Initialize the wavelet tree structure wt = wfbtinit(par,flags.forder); scaling = flags.scaling; end %% ----- step 2 : Prepare input parameters [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt,'rev'); nodesUps = nodesFiltUps(nodesBF,wt); %% ----- step 3 : Run computation f = comp_iuwfbt(c,wt.nodes(nodesBF),nodesUps,rangeLoc,rangeOut,scaling); ltfat/inst/wavelets/wfilt_symtight.m0000664000175000017500000000703113026262303017624 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_symtight(K) %-*- texinfo -*- %@deftypefn {Function} wfilt_symtight %@verbatim %WFILT_SYMTIGHT Symmetric Nearly Shift-Invariant Tight Frame Wavelets % % Usage: [h,g,a] = wfilt_symtight(K); % % [h,g,a]=WFILT_SYMTIGHT(K) with K in {1,2} returns 4-band % symmetric nearly shift-invariant tight framelets. % % % % Examples: % --------- % : % wfiltinfo('symtight1'); % % : % wfiltinfo('symtight2'); % % References: % A. F. Abdelnour and I. W. Selesnick. Symmetric nearly shift-invariant % tight frame wavelets. IEEE Transactions on Signal Processing, % 53(1):231--239, 2005. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_symtight.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 1; a = [2;2;2;2]; switch(K) case 1 % Example 1. from the reference. hlp = [ -0.00055277114224 -0.00033767136406 -0.01132578895076 0.01854042113559 -0.03673606302189 -0.02613107863916 0.00608048256466 -0.21256591159938 0.23533603943029 -0.12220989795770 0.51430488230650 0.34270413842472 0.51430488230650 0.34270413842472 0.23533603943029 -0.12220989795770 0.00608048256466 -0.21256591159938 -0.03673606302189 -0.02613107863916 -0.01132578895076 0.01854042113559 -0.00055277114224 -0.00033767136406 ]; case 2 % Example 2. from the reference. hlp = [ -0.00006806716035 0.00033470718376 -0.00052662487214 -0.00010709617646 -0.00117716147891 -0.00083815645134 0.00133411634276 -0.00184900827809 0.01000587257073 0.00040715239482 0.01000587257073 0.01797012314831 -0.02668232685528 0.05528765033433 -0.07024530947614 0.00398035279221 0.00400234902829 -0.21067061941896 0.26015268683895 -0.15449251248712 0.52030537367790 0.28997740695853 0.52030537367790 0.28997740695853 0.26015268683895 -0.15449251248712 0.00400234902829 -0.21067061941896 -0.07024530947614 0.00398035279221 -0.02668232685528 0.05528765033433 0.01000587257073 0.01797012314831 0.01000587257073 0.00040715239482 0.00133411634276 -0.00184900827809 -0.00117716147891 -0.00083815645134 -0.00052662487214 -0.00010709617646 -0.00006806716035 0.00033470718376 ]; otherwise error('%s: No such SYMTIGHT filters.',upper(mfilename)); end harr = [hlp, ... (-1).^(0:size(hlp,1)-1).'.*hlp(:,2),... (-1).^(0:size(hlp,1)-1).'.*hlp(:,1)]; h=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h=cellfun(@(hEl) struct('h',hEl(:),'offset',-numel(hEl)/2),h,'UniformOutput',0); g = h; ltfat/inst/wavelets/wfilt_db.m0000664000175000017500000000745113026262303016347 0ustar susnaksusnakfunction [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 Lagrange 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 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.github.io/doc/wavelets/wfilt_db.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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); % Roots outside of the unit circle and in the right halfplane 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(sort(hroots,'descend'))); % normalize h{1}= h{1}/norm(h{1}); % QMF modulation low-pass -> highpass h{2}= (-1).^(0:flen-1).*h{1}(end:-1:1); % The reverse is here, because we use different convention for % filterbanks than in Ten Lectures on Wavelets h{1} = fliplr(h{1}); h{2} = fliplr(h{2}); Lh = numel(h{1}); % Default offset d = cellfun(@(hEl) -length(hEl)/2,h); if N>2 % Do a filter alignment according to "center of gravity" d(1) = -floor(sum((1:Lh).*abs(h{1}).^2)/sum(abs(h{1}).^2)); d(2) = -floor(sum((1:Lh).*abs(h{2}).^2)/sum(abs(h{2}).^2)); if rem(d(1)-d(2),2)==1 % Shift d(2) just a bit d(2) = d(2) + 1; end end % Format filters h{1} = struct('h',h{1},'offset',d(1)); h{2} = struct('h',h{2},'offset',d(2)); g=h; a = [2;2]; % This also means that g==h info.istight=1; ltfat/inst/wavelets/wpfbt2filterbank.m0000664000175000017500000001105413026262303020015 0ustar susnaksusnakfunction [g,a] = wpfbt2filterbank( wt, varargin) %-*- texinfo -*- %@deftypefn {Function} wpfbt2filterbank %@verbatim %WPFBT2FILTERBANK WPFBT equivalent non-iterated filterbank % Usage: [g,a] = wpfbt2filterbank(wt) % % Input parameters: % wt : Wavelet filter tree definition % % Output parameters: % g : Cell array containing filters % a : Vector of sub-/upsampling factors % % WPFBT2FILTERBANK(wt) calculates the impulse responses g and the % subsampling factors a of non-iterated filterbank, which is equivalent % to the wavelet packet filterbank tree described by wt. The returned % parameters can be used directly in FILTERBANK, UFILTERBANK or % FILTERBANK. % % Please see help on WFBT for description of wt. The function % additionally support the following flags: % % 'freq'(default),'nat' % The filters are ordered to produce subbands in the same order as % WPFBT with the same flag. % % 'intsqrt'(default),'intnoscale', 'intscale' % The filters in the filterbank tree are scaled to reflect the % behavior of WPFBT and IWPFBT with the same flags. % % 'scaling_notset'(default),'noscale','scale','sqrt' % Support for scaling flags as described in UWPFBT. By default, % the returned filterbank g and a is equivalent to WPFBT, % passing any of the non-default flags results in a filterbank % equivalent to UWPFBT i.e. scaled and with a(:)=1. % % 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] = wpfbt2filterbank({'db10',3,'dwt'}); % filterbankfreqz(g,a,1024,'plot','linabs','posfreq'); % % % In the second example, the filterbank is identical to the full % wavelet tree: % % [g,a] = wpfbt2filterbank({'db10',3,'full'}); % filterbankfreqz(g,a,1024,'plot','linabs','posfreq'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wpfbt2filterbank.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,1,'WPFBT2FILTERBANK'); definput.import = {'wfbtcommon','uwfbtcommon'}; definput.importdefaults = {'scaling_notset'}; definput.flags.interscaling={'intsqrt','intnoscale','intscale'}; [flags]=ltfatarghelper({},definput,varargin); % build the tree wt = wfbtinit({'strict',wt},flags.forder); wt = comp_wpfbtscale(wt,flags.interscaling); nIdx = nodesLevelsBForder(wt); % Now we need to walk the tree by levels g = {}; a = []; for ii=1:numel(nIdx) rangeLoc = cellfun(@(eEl) 1:numel(eEl.h),wt.nodes(nIdx{ii}),... 'UniformOutput',0); rangeOut = cellfun(@(eEl) numel(eEl.h),wt.nodes(nIdx{ii})); rangeOut = mat2cell(1:sum(rangeOut),1,rangeOut); [gtmp,atmp] = nodesMultid(nIdx{ii},rangeLoc,rangeOut,wt); g(end+1:end+numel(gtmp)) = gtmp; a(end+1:end+numel(atmp)) = atmp; end g = g(:); a = a(:); if ~flags.do_scaling_notset g = comp_filterbankscale(g,a,flags.scaling); a = ones(numel(g),1); end function nodesIdxs = nodesLevelsBForder(treeStruct) %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). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa offset = []; 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 ]; garr = flipud(garr); offset = [-4,-2,-2]; case 2 % 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 ]; garr = flipud(garr); offset = [-4]; case 3 % 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 ]; garr = flipud(garr); offset = [-4,-2,-2]; case 4 % 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 ]; garr = flipud(garr); offset = [-6]; case 5 % 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 ]; garr = flipud(garr); offset = [-6,-2,-2]; case 6 % 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 ]; offset = [-5]; otherwise error('%s: No such Double Density DWT filter',upper(mfilename)); end; g=mat2cell(garr,size(garr,1),ones(1,size(garr,2))); if isempty(offset) g = cellfun(@(gEl) struct('h',gEl,'offset',-floor((length(gEl)+1)/2)),g,'UniformOutput',0); elseif numel(offset)==1 g = cellfun(@(gEl) struct('h',gEl,'offset',offset),g,'UniformOutput',0); elseif isvector(offset) g = cellfun(@(gEl,ofEl) struct('h',gEl,'offset',ofEl),g,num2cell(offset),... 'UniformOutput',0); end h = g; a= [2;2;2]; info.istight=1; ltfat/inst/wavelets/dtwfb.m0000664000175000017500000002004213026262303015652 0ustar susnaksusnakfunction [c,info]=dtwfb(f,dualwt,varargin) %-*- texinfo -*- %@deftypefn {Function} dtwfb %@verbatim %DTWFB Dual-Tree Wavelet Filter Bank % Usage: c=dtwfb(f,dualwt); % c=dtwfb(f,{dualw,J}); % [c,info]=dtwfb(...); % % Input parameters: % f : Input data. % dualwt : Dual-tree Wavelet Filter bank definition. % % Output parameters: % c : Coefficients stored in a cell-array. % info : Additional transform parameters struct. % % c=DTWFBt(f,dualwt) computes dual-tree complex wavelet coefficients % of the signal f. The representation is approximately % time-invariant and provides analytic behaviour. Due to these facts, % the resulting subbands are nearly aliasing free making them suitable % for severe coefficient modifications. The representation is two times % redundant, provided critical subsampling of all involved filter banks. % % The shape of the filterbank tree and filters used is controlled by % dualwt (for possible formats see below). The output c is a % cell-array with each element containing a single subband. The subbands % are ordered with the increasing subband centre frequency. % % In addition, the function returns struct. info containing transform % parameters. It can be conveniently used for the inverse transform % IDTWFB e.g. fhat = iDTWFB(c,info). It is also required by % the PLOTWAVELETS function. % % If f is a matrix, the transform is applied to each column. % % Two formats of dualwt are accepted: % % 1) Cell array of parameters. First two elements of the array are % mandatory {dualw,J}. % % dualw % Basic dual-tree filters % J* % Number of levels of the filter bank tree % % Possible formats of dualw are the same as in FWTINIT except the % wfiltdt_ prefix is used when searching for function specifying % the actual impulse responses. These filters were designed specially % for the dual-tree filter bank to achieve the half-sample shift % ultimately resulting in analytic (complex) behaviour of the % transform. % % The default shape of the filter bank tree is DWT i.e. only low-pass % output is decomposed further (*J times in total). % % Different filter bank tree shapes can be obtained by passing % additional flag in the cell array. Supported flags (mutually % exclusive) are: % % 'dwt' % Plain DWT tree (default). This gives one band per octave freq. % resolution when using 2 channel basic wavelet filter bank. % % 'full' % Full filter bank tree. Both (all) basic filter bank outputs are % decomposed further up to depth J achieving linear frequency band % division. % % 'doubleband','quadband','octaband' % The filter bank is designed such that it mimics 4-band, 8-band or % 16-band complex wavelet transform provided the basic filter bank % is 2 channel. In this case, J is treated such that it defines % number of levels of 4-band, 8-band or 16-band transform. % % The dual-tree wavelet filter bank can use any basic wavelet % filter bank in the first stage of both trees, provided they are % shifted by 1 sample (done internally). A custom first stage % filter bank can be defined by passing the following % key-value pair in the cell array: % % 'first',w % w defines a regular basic filter bank. Accepted formats are the % same as in FWTINIT assuming the wfilt_ prefix. % % Similarly, when working with a filter bank tree containing % decomposition of high-pass outputs, some filters in both trees must % be replaced by a regular basic filter bank in order to achieve the % approximately analytic behaviour. A custom filter bank can be % specified by passing another key-value pair in the cell array: % % 'leaf',w % w defines a regular basic filter bank. Accepted formats are the % same as in FWTINIT assuming the wfilt_ prefix. % % 2) Another possibility is to pass directly a struct. returned by % DTWFBINIT and possibly modified by WFBTREMOVE. % % Optional args.: % --------------- % % In addition, the following flag groups are supported: % % 'freq','nat' % Frequency or natural (Paley) ordering of coefficient subbands. % By default, subbands are ordered according to frequency. The natural % ordering is how the subbands are obtained from the filter bank tree % without modifications. The ordering differs only in non-plain DWT % case. % % Boundary handling: % ------------------ % % In contrast with FWT, WFBT and WPFBT, this function supports % periodic boundary handling only. % % Examples: % --------- % % A simple example of calling the DTWFB function using the regular % DWT iterated filter bank. The second figure shows a magnitude frequency % response of an identical filter bank.: % % [f,fs] = greasy; % J = 6; % [c,info] = dtwfb(f,{'qshift3',J}); % figure(1); % plotwavelets(c,info,fs,'dynrange',90); % figure(2); % [g,a] = dtwfb2filterbank({'qshift3',J}); % filterbankfreqz(g,a,1024,'plot','linabs'); % % The second example shows a decomposition using a full filter bank tree % of depth J*: % % [f,fs] = greasy; % J = 5; % [c,info] = dtwfb(f,{'qshift4',J,'full'}); % figure(1); % plotwavelets(c,info,fs,'dynrange',90); % figure(2); % [g,a] = dtwfb2filterbank({'qshift4',J,'full'}); % filterbankfreqz(g,a,1024,'plot','linabs'); % % % References: % I. Selesnick, R. Baraniuk, and N. Kingsbury. The dual-tree complex % wavelet transform. Signal Processing Magazine, IEEE, 22(6):123 -- 151, % nov. 2005. % % N. Kingsbury. Complex wavelets for shift invariant analysis and % filtering of signals. Applied and Computational Harmonic Analysis, % 10(3):234 -- 253, 2001. % % I. Bayram and I. Selesnick. On the dual-tree complex wavelet packet and % m-band transforms. Signal Processing, IEEE Transactions on, % 56(6):2298--2310, June 2008. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/dtwfb.html} %@seealso{dtwfbreal, idtwfb, plotwavelets, dtwfb2filterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author: Zdenek Prusa % Date: 30.6.2014 complainif_notenoughargs(nargin,2,'DTWFB'); definput.import = {'wfbtcommon'}; flags =ltfatarghelper({},definput,varargin); % Initialize the wavelet tree structure dtw = dtwfbinit(dualwt,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,dtw,'per'); % Pad with zeros if the safe length L differs from the Ls. if(Ls~=L) f=postpad(f,L); end %% ----- step 3 : Run computation [nodesBF, rangeLoc, rangeOut] = treeBFranges(dtw); c = comp_dtwfb(f,dtw.nodes(nodesBF),dtw.dualnodes(nodesBF),rangeLoc,... rangeOut,'per',1); %% ----- Optionally : Fill info struct ---- if nargout>1 % Transform name info.fname = 'dtwfb'; % Dual-Tree struct. info.wt = dtw; % Periodic boundary handling info.ext = 'per'; % Lengths of subbands info.Lc = cellfun(@(cEl) size(cEl,1),c); % Signal length info.Ls = Ls; % Ordering of the subbands info.fOrder = flags.forder; % Cell format info.isPacked = 0; end ltfat/inst/wavelets/dtwfbreal.m0000664000175000017500000002041113026262303016516 0ustar susnaksusnakfunction [c,info]=dtwfbreal(f,dualwt,varargin) %-*- texinfo -*- %@deftypefn {Function} dtwfbreal %@verbatim %DTWFBREAL Dual-Tree Wavelet FilterBank for real-valued signals % Usage: c=dtwfbreal(f,dualwt); % c=dtwfbreal(f,{dualw,J}); % [c,info]=dtwfbreal(...); % % Input parameters: % f : Input data. % dualwt : Dual-tree Wavelet Filterbank definition. % % Output parameters: % c : Coefficients stored in a cell-array. % info : Additional transform parameters struct. % % c=dtwfbtreal(f,dualwt) computes dual-tree complex wavelet coefficients % of the real-valued signal f. The representation is approximately % time-invariant and provides analytic behavior. Due to these facts, % the resulting subbands are nearly aliasing free making them suitable % for severe coefficient modifications. The representation is two times % redundant, provided critical subsampling of all involved filterbanks, % but one half of the coefficients is complex conjugate of the other. % % The shape of the filterbank tree and filters used is controlled by % dualwt (for possible formats see below). The output c is a % cell-array with each element containing a single subband. The subbands % are ordered with increasing subband center frequency. % % In addition, the function returns struct. info containing transform % parameters. It can be conviniently used for the inverse transform % IDTWFBREAL e.g. fhat = iDTWFBREAL(c,info). It is also required by % the PLOTWAVELETS function. % % If f is a matrix, the transform is applied to each column. % % Two formats of dualwt are accepted: % % 1) Cell array of parameters. First two elements of the array are % mandatory {dualw,J}. % % dualw % Basic dual-tree filters % J* % Number of levels of the filterbank tree % % Possible formats of dualw are the same as in FWTINIT except the % wfiltdt_ prefix is used when searching for function specifying % the actual impulse responses. These filters were designed specially % for the dual-tree filterbank to achieve the half-sample shift % ultimatelly resulting in analytic (complex) behavior of the % transform. % % The default shape of the filterbank tree is DWT i.e. only low-pass % output is decomposed further (*J times in total). % % Different filterbank tree shapes can be obtained by passing % additional flag in the cell array. Supported flags (mutually % exclusive) are: % % 'dwt' % Plain DWT tree (default). This gives one band per octave freq. % resolution when using 2 channel basic wavelet filterbank. % % 'full' % Full filterbank tree. Both (all) basic filterbank outputs are % decomposed further up to depth J achieving linear frequency band % division. % % 'doubleband','quadband','octaband' % The filterbank is designed such that it mimics 4-band, 8-band or % 16-band complex wavelet transform provided the basic filterbank % is 2 channel. In this case, J is treated such that it defines % number of levels of 4-band, 8-band or 16-band transform. % % The dual-tree wavelet filterbank can use any basic wavelet % filterbank in the first stage of both trees, provided they are % shifted by 1 sample (done internally). A custom first stage % filterbank can be defined by passing the following % key-value pair in the cell array: % % 'first',w % w defines a regular basic filterbank. Accepted formats are the % same as in FWTINIT assuming the wfilt_ prefix. % % Similarly, when working with a filterbank tree containing % decomposition of high-pass outputs, some filters in both trees must % be replaced by a regular basic filterbank in order to achieve the % aproximatelly analytic behavior. A custom filterbank can be % specified by passing another key-value pair in the cell array: % % 'leaf',w % w defines a regular basic filterbank. Accepted formats are the % same as in FWTINIT assuming the wfilt_ prefix. % % 2) Another possibility is to pass directly a struct. returned by % DTWFBINIT and possibly modified by WFBTREMOVE. % % Optional args.: % --------------- % % In addition, the following flag groups are supported: % % 'freq','nat' % Frequency or natural (Paley) ordering of coefficient subbands. % By default, subbands are ordered according to frequency. The natural % ordering is how the subbands are obtained from the filterbank tree % without modifications. The ordering differ only in non-plain DWT % case. % % Boundary handling: % ------------------ % % In contrast with FWT, WFBT and WPFBT, this function supports % periodic boundary handling only. % % Examples: % --------- % % A simple example of calling the DTWFBREAL function using the regular % DWT iterated filterbank. The second figure shows a magnitude frequency % response of an identical filterbank.: % % [f,fs] = greasy; % J = 6; % [c,info] = dtwfbreal(f,{'qshift3',J}); % figure(1); % plotwavelets(c,info,fs,'dynrange',90); % figure(2); % [g,a] = dtwfb2filterbank({'qshift3',J},'real'); % filterbankfreqz(g,a,1024,'plot','linabs'); % % The second example shows a decomposition using a full filterbank tree % of depth J*: % % [f,fs] = greasy; % J = 5; % [c,info] = dtwfbreal(f,{'qshift4',J,'full'}); % figure(1); % plotwavelets(c,info,fs,'dynrange',90); % figure(2); % [g,a] = dtwfb2filterbank({'qshift4',J,'full'},'real'); % filterbankfreqz(g,a,1024,'plot','linabs'); % % % References: % I. Selesnick, R. Baraniuk, and N. Kingsbury. The dual-tree complex % wavelet transform. Signal Processing Magazine, IEEE, 22(6):123 -- 151, % nov. 2005. % % N. Kingsbury. Complex wavelets for shift invariant analysis and % filtering of signals. Applied and Computational Harmonic Analysis, % 10(3):234 -- 253, 2001. % % I. Bayram and I. Selesnick. On the dual-tree complex wavelet packet and % m-band transforms. Signal Processing, IEEE Transactions on, % 56(6):2298--2310, June 2008. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/dtwfbreal.html} %@seealso{dtwfb, idtwfbreal, plotwavelets, dtwfb2filterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author: Zdenek Prusa % Date: 30.6.2014 complainif_notenoughargs(nargin,2,'DTWFBREAL'); if ~isreal(f) error('%s: Input signal must be real.',upper(mfilename)); end definput.import = {'wfbtcommon'}; flags =ltfatarghelper({},definput,varargin); % Initialize the wavelet tree structure dtw = dtwfbinit(dualwt,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,dtw,'per'); % Pad with zeros if the safe length L differs from the Ls. if(Ls~=L) f=postpad(f,L); end %% ----- step 3 : Run computation [nodesBF, rangeLoc, rangeOut] = treeBFranges(dtw); c = comp_dtwfb(f,dtw.nodes(nodesBF),dtw.dualnodes(nodesBF),rangeLoc,... rangeOut,'per',0); %% ----- Optionally : Fill info struct ---- if nargout>1 % Transform name info.fname = 'dtwfbreal'; % Dual-Tree struct. info.wt = dtw; % Periodic boundary handling info.ext = 'per'; % Lengths of subbands info.Lc = cellfun(@(cEl) size(cEl,1),c); % Signal length info.Ls = Ls; % Ordering of the subbands info.fOrder = flags.forder; % Cell format info.isPacked = 0; end ltfat/inst/wavelets/wfbt2filterbank.m0000664000175000017500000000700313026262303017634 0ustar susnaksusnakfunction [g,a] = wfbt2filterbank( wt, varargin) %-*- texinfo -*- %@deftypefn {Function} wfbt2filterbank %@verbatim %WFBT2FILTERBANK WFBT equivalent non-iterated filterbank % Usage: [g,a] = wfbt2filterbank(wt) % % Input parameters: % wt : Wavelet filter tree definition % % Output parameters: % g : Cell array containing filters % a : Vector of sub-/upsampling factors % % [g,a]=WFBT2FILTERBANK(wt) calculates the impulse responses g and the % subsampling factors a of non-iterated filterbank, which is equivalent % to the wavelet filterbank tree described by wt used in WFBT. The % returned parameters can be used directly in FILTERBANK and other routines. % % [g,a]=WFBT2FILTERBANK({w,J,'dwt'}) does the same for the DWT (|FWT|) % filterbank tree. % % Please see help on WFBT for description of wt and help on FWT for % description of w and J. % % The function additionally support the following flags: % % 'freq'(default),'nat' % The filters are ordered to produce subbands in the same order as % WFBT with the same flag. % % 'scaling_notset'(default),'noscale','scale','sqrt' % Support for scaling flags as described in UWFBT. By default, % the returned filterbank g and a is equivalent to WFBT, % passing any of the non-default flags results in a filterbank % equivalent to UWFBT i.e. scaled and with a(:)=1. % % 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'}); % filterbankfreqz(g,a,1024,'plot','linabs','posfreq'); % % In the second example, the filterbank is identical to the full % wavelet tree: % % [g,a] = wfbt2filterbank({'db10',3,'full'}); % filterbankfreqz(g,a,1024,'plot','linabs','posfreq'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbt2filterbank.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,1,'WFBT2FILTERBANK'); definput.import = {'uwfbtcommon', 'wfbtcommon'}; definput.importdefaults = {'scaling_notset'}; flags = ltfatarghelper({},definput,varargin); % build the tree wt = wfbtinit({'strict',wt},flags.forder); % Pick just nodes with outputs % wtPath = 1:numel(wt.nodes); % wtPath(nodesOutputsNo(1:numel(wt.nodes),wt)==0)=[]; % % rangeLoc = nodesLocOutRange(wtPath,wt); % rangeOut = nodesOutRange(wtPath,wt); [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt); slice = ~cellfun(@isempty,rangeOut); % Limit to nodes with unconnected outputs [g,a] = nodesMultid(nodesBF(slice),rangeLoc(slice),rangeOut(slice),wt); if ~flags.do_scaling_notset g = comp_filterbankscale(g,a,flags.scaling); a = ones(numel(g),1); end ltfat/inst/wavelets/wfilt_qshiftb.m0000664000175000017500000000435213026262303017417 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_qshiftb(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_qshiftb %@verbatim %WFILT_QSHIFTB Improved Orthogonality and Symmetry properties % % Usage: [h,g,a] = wfilt_qshiftb(N); % % [h,g,a]=WFILT_QSHIFTB(N) with N in {1,2,3,4,5,6,7} returns % Kingsbury's Q-shift wavelet filters for tree B. % % Examples: % --------- % : % figure(1); % wfiltinfo('qshiftb3'); % % References: % N. G. Kingsbury. A dual-tree complex wavelet transform with improved % orthogonality and symmetry properties. In ICIP, pages 375--378, 2000. % % N. Kingsbury. Design of q-shift complex wavelets for image processing % using frequency domain energy minimization. In Image Processing, 2003. % ICIP 2003. Proceedings. 2003 International Conference on, volume 1, % pages I--1013--16 vol.1, Sept 2003. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_qshiftb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa [ha,~,a,info] = wfilt_qshifta(N); hlp = ha{1}.h; offset = -(numel(hlp)/2); range = (0:numel(hlp)-1) + offset; % Create the filters according to the reference paper. % % REMARK: The phase of the alternating +1 and -1 is crucial here. % harr = [... flipud(hlp),... (-1).^(range).'.*hlp,... ]; htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h(1:2,1) = cellfun(@(hEl)struct('h',hEl,'offset',offset),htmp(1:2),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/wfbtmanip/0000775000175000017500000000000013026262304016360 5ustar susnaksusnakltfat/inst/wavelets/wfbtmanip/nodesSub.m0000664000175000017500000000246313026262303020324 0ustar susnaksusnakfunction subNo = nodesSub(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 = nodesFiltUps(nodeNo,wt); nodesCount = numel(nodeNo); subNo = cell(1,nodesCount); for ii=1:nodesCount subNo{ii} = nodeNoUps(ii)*nodeNoa{ii}; end %-*- texinfo -*- %@deftypefn {Function} nodesSub %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/nodesSub.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/wavelets/wfbtmanip/wfbtmanipinit.m0000664000175000017500000000166213026262303021415 0ustar susnaksusnakstatus=2; %-*- texinfo -*- %@deftypefn {Function} wfbtmanipinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/wfbtmanipinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/wavelets/wfbtmanip/treeBFranges.m0000664000175000017500000000451513026262303021111 0ustar susnaksusnakfunction [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt,varargin) %-*- texinfo -*- %@deftypefn {Function} treeBFranges %@verbatim %TREEBFRANGES Tree nodes output ranges in BF order % Usage: [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt); % [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt,'rev'); % % Input parameters: % wt : Filterbank tree struct. % Output parameters: % nodesBF : All nodes in a breadth-first order % rangeLoc : Local ranges of unconnected (terminal) outputs % rangeOut : Global ranges of unconnected (terminal) outputs % % [nodesBF, rangeLoc, rangeOut] = TREEBFRANGES(wt) is a helper function % extracting all nodes of a tree in a BF order (root and low-pass first) % (numeric array of indexes nodesBF), and two cell arrays of ranges of % outputs. Each element of rangeLoc specifies range of unconnected % outputs of a node with at the corresponding position in nodesBF. % Elements rangeOut specify contain the resulting global indexes % (in the resulting coefficient cell array) of such unconnected nodes. % % [nodesBF, rangeLoc, rangeOut] = TREEBFRANGES(wt,'rev') does the same % but the arrays are reversed. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/treeBFranges.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . nodesBF = nodeBForder(0,wt); do_rev = 0; if ~isempty(varargin(strcmp('rev',varargin))); nodesBF = fliplr(nodesBF); do_rev = 1; end rangeLoc = nodesLocOutRange(nodesBF,wt); rangeOut = treeOutRange(wt); if do_rev %rangeOut = nodesOutRange(nodesBF,wt); rangeOut = rangeOut(end:-1:1); end ltfat/inst/wavelets/wfbtmanip/treeSub.m0000664000175000017500000000361313026262303020151 0ustar susnaksusnakfunction a = treeSub(wt) %-*- texinfo -*- %@deftypefn {Function} treeSub %@verbatim %TREESUB Identical subsampling factors % Usage: a = treeSub(wt) % % Input parameters: % wt : Structure containing description of the filter tree. % % Output parameters: % a : Subsampling factors. % % a = TREESUB(wt) returns subsampling factors asociated with the tree % subbands. For definition of the structure see WFBINIT. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/treeSub.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Get nodes in BF order nodesBF = nodeBForder(0,wt); % All nodes with at least one final output. termNslice = nodesOutputsNo(nodesBF,wt)~=0; termN = nodesBF(termNslice); % Range in filter outputs outRangeTermN = nodesLocOutRange(termN,wt); %cRangeTermN = nodesOutRange(termN,wt); rangeOut = treeOutRange(wt); % Get only nodes with some output cRangeTermN = rangeOut(termNslice); noOut = sum(cellfun(@numel,cRangeTermN)); % Subsampling factors of the terminal nodes subTermN = nodesSub(termN,wt); a = zeros(noOut, 1); for ii=1:numel(termN) a(cRangeTermN{ii}) = subTermN{ii}(outRangeTermN{ii}); end ltfat/inst/wavelets/wfbtmanip/nodesOutLen.m0000664000175000017500000000446613026262303021006 0ustar susnaksusnakfunction Lc = nodesOutLen(nodeNo,L,outRange,doNoExt,wt) %-*- texinfo -*- %@deftypefn {Function} nodesOutLen %@verbatim %NODESOUTLEN Length of the node output % Usage: Lc = nodesOutLen(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 % % NODESOUTLEN(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.github.io/doc/wavelets/wfbtmanip/nodesOutLen.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isempty(outRange) outRange = cellfun(@(nEl) 1:numel(nEl.g),wt.nodes(nodeNo),'UniformOutput',0); end Lc = zeros(sum(cellfun(@numel,outRange)),1); inLens = nodesInLen(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 ltfat/inst/wavelets/wfbtmanip/depthIndex2NodeNo.m0000664000175000017500000000445113026262303022022 0ustar susnaksusnakfunction [nodeNo,nodeChildIdx] = depthIndex2NodeNo(d,k,wt) %-*- texinfo -*- %@deftypefn {Function} depthIndex2NodeNo %@verbatim %DEPTHINDEX2NODENO Get node from depth and index in the tree % Usage: [nodeNo,nodeChildIdx] = depthIndex2NodeNo(d,k,wt) % % [nodeNo,nodeChildIdx] = DEPTHINDEX2NODENO(d,k,wt) returns node % nodeNo and an array of its children nodes nodeChildIdx positioned % in depth g and index k in the tree wt. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/depthIndex2NodeNo.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if(d==0) nodeNo=0; nodeChildIdx=0; return; end % find ordered nodes at depth d-1 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 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 = nodeBForder(0,wt); nbfTmp = nbf; tempd = 0; while tempd. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; end ltfat/inst/wavelets/wfbtmanip/nodesInLen.m0000664000175000017500000000441613026262303020600 0ustar susnaksusnakfunction L = nodesInLen(nodeNo,inLen,doNoExt,wt) %-*- texinfo -*- %@deftypefn {Function} nodesInLen %@verbatim %NODESINLEN Length of the node input signal % Usage: L = nodesInLen(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 % % NODESINLEN(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.github.io/doc/wavelets/wfbtmanip/nodesInLen.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/wavelets/wfbtmanip/nodesMultid.m0000664000175000017500000001063613026262303021032 0ustar susnaksusnakfunction [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.github.io/doc/wavelets/wfbtmanip/nodesMultid.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %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 = nodesFiltUps(iiNode,wt); tmpFilt = wt.nodes{iiNode}.g{locRange(jj)}; g{outRange(jj)} = struct(); g{outRange(jj)}.h = conv2(hmi,comp_ups(tmpFilt.h(:),tmpUpsFac,1)); g{outRange(jj)}.offset = -nodePredecesorsOrig(-tmpFilt.offset,iiNode,wt); end atmp = nodesSub(iiNode,wt); a(outRange) = atmp{1}(locRange); end % clean the cache nodePredecesorsMultId(); function hmi = nodePredecesorsMultId(nodeNo,wt) % 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,wt); 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 = wt.nodes{id}.g{wt.children{id}==pre(ii+1)}.h(:); hcurr = comp_ups(hcurr,nodesFiltUps(id,wt),1); hmi = conv2(hmi,hcurr); end function predori = nodePredecesorsOrig(baseOrig,nodeNo,wt) % Calculate total offset of a filter identical to a path from root to % node nodeNo in treeStruct. The last filter in the chain itself has % offset equal to baseOrig % Get nodes from the path from root to nodeNo pre = nodePredecesors(nodeNo,wt); pre = pre(end:-1:1); % Shortcut out if nodeNo is the root node if(isempty(pre)) predori = baseOrig; return; end % Add the curernt node to the list pre(end+1) = nodeNo; predori = 0; % Do from root to nodeNo for ii=1:length(pre)-1 % Get node id id = pre(ii); % Find which path to go childLogInd = wt.children{id}==pre(ii+1); % Obtain offset tmpOffset = -wt.nodes{id}.g{childLogInd}.offset; % Update te current offset predori = nodesFiltUps(id,wt)*tmpOffset + predori; end % We do not know here which filter from the node are we working with so % this line substitutes the last iteration of the previous loop predori = nodesFiltUps(nodeNo,wt)*baseOrig + predori; function pred = nodePredecesors(nodeNo,treeStruct) pred = []; tmpNodeNo = nodeNo; while treeStruct.parents(tmpNodeNo)~=0 tmpNodeNo = treeStruct.parents(tmpNodeNo); pred(end+1) = tmpNodeNo; end ltfat/inst/wavelets/wfbtmanip/nodeBForder.m0000664000175000017500000000503413026262303020730 0ustar susnaksusnakfunction nodesIdxs = nodeBForder(nodeNo,wt) %-*- texinfo -*- %@deftypefn {Function} nodeBForder %@verbatim %NODEBFORDER Nodes in the Breadth-First search order % Usage: nodesIdxs = nodeBForder(nodeNo,wt) % % Input parameters: % nodeNo : Id of a node. % wt : Structure containing description of the filter tree. % % Output parameters: % nodesIdxs : Node indexes in the Breadth-First search order. % % NODEBFORDER(nodeNo,wt) For definition of the structure see % wfbinit. nodeNo defaults to the root node if it is empty or equal % to 0. % % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/nodeBForder.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isempty(nodeNo) || nodeNo==0 %find root nodeNo = find(wt.parents==0); end complainif_notposint(nodeNo,'NODEBFORDER'); nodesIdxs = [nodeNo,nodeSubtreeBF(nodeNo,wt)]; function nodesIdxs = nodeSubtreeBF(nodeNo,wt) %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. % % 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 ltfat/inst/wavelets/wfbtmanip/nat2freqOrder.m0000664000175000017500000000767313026262303021270 0ustar susnaksusnakfunction wt = nat2freqOrder(wt,varargin) %-*- 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 and coefficient subbands. % For definition of the structure see WFBINIT and DTWFBINIT. % % NAT2FREQORDER(wt,nodes) does the same but works only with nodes % listed in nodes. % % NAT2FREQORDER(...,'rev') changes the frequency ordering back to % natural ordering. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/nat2freqOrder.html} %@seealso{wfbtinit, wfbtmultid, nodebforder} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'NAT2FREQORDER'); do_rev = ~isempty(varargin(strcmp('rev',varargin))); if do_rev %Remove the 'rev' flag from varargin varargin(strcmp('rev',varargin)) = []; end bftreepath = nodeBForder(0,wt); if isempty(varargin) treePath = bftreepath(2:end);% skip root else % Work with specified nodes only nodes = varargin{1}; % Omit root nodes(wt.parents(nodes)==0) = []; % Use the rest treePath = nodes; end % Dual-tree complex wavelet packets require some more tweaking. if isfield(wt,'dualnodes') locIdxs = arrayfun(@(tEl) find(wt.children{wt.parents(tEl)}==tEl,1),treePath); treeNodes = treePath(rem(locIdxs,2)~=1); % Root was removed so the following will not fail jj = treeNodes(find(treeNodes(wt.parents(wt.parents(treeNodes))==0),1)); while ~isempty(jj) && ~isempty(wt.children{jj}) sanChild = postpad(wt.children{jj},numel(wt.nodes{jj}.g)); % Reverse child nodes wt.children{jj} = sanChild(end:-1:1); if do_rev jj = wt.children{jj}(1); else jj = wt.children{jj}(end); end end end % Array indexed by nodeId reordered = zeros(size(bftreepath)); % Long version if 1 for nodeId=bftreepath ch = postpad(wt.children{nodeId},numel(wt.nodes{nodeId}.g)); odd = 1; if reordered(nodeId) && rem(numel(ch),2)==1 odd = 0; end for m=0:numel(ch)-1 if ch(m+1) ~= 0 if rem(m,2)==odd reordered(ch(m+1)) = 1; end end end end end % Reorder filters for nodeId=treePath(logical(reordered(treePath))) wt = reorderFilters(nodeId,wt); end function wt = reorderFilters(nodeId,wt) % now for the filter reordering wt.nodes{nodeId}.g = wt.nodes{nodeId}.g(end:-1:1); wt.nodes{nodeId}.h = wt.nodes{nodeId}.h(end:-1:1); wt.nodes{nodeId}.a = wt.nodes{nodeId}.a(end:-1:1); % Do the same with the dual tree if it exists if isfield(wt,'dualnodes') wt.dualnodes{nodeId}.g = wt.dualnodes{nodeId}.g(end:-1:1); wt.dualnodes{nodeId}.h = wt.dualnodes{nodeId}.h(end:-1:1); wt.dualnodes{nodeId}.a = wt.dualnodes{nodeId}.a(end:-1:1); end ltfat/inst/wavelets/wfbtmanip/nodesOutputsNo.m0000664000175000017500000000325213026262303021550 0ustar susnaksusnakfunction noOut = nodesOutputsNo(nodeNo,wt) %-*- texinfo -*- %@deftypefn {Function} nodesOutputsNo %@verbatim %NODESOUTPUTSNO Number of node Outputs % Usage: noOut = nodesOutputsNo(nodeNo,wt); % % Input parameters: % nodeNo : Node index. % wt : Structure containing description of the filter tree. % % Output parameters: % noOut : Number of node outputs. % % NODESOUTPUTSNO(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.github.io/doc/wavelets/wfbtmanip/nodesOutputsNo.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if(any(nodeNo>numel(wt.nodes))) error('%s: Invalid node index range. Number of nodes is %d.\n',upper(mfilename),numel(wt.nodes)); end noOut = cellfun(@(nEl) numel(nEl.g), wt.nodes(nodeNo)) -... cellfun(@(chEl) numel(chEl(chEl~=0)), wt.children(nodeNo)); ltfat/inst/wavelets/wfbtmanip/treeOutLen.m0000664000175000017500000000361013026262304020624 0ustar susnaksusnakfunction Lc = treeOutLen(L,doNoExt,wt) %-*- texinfo -*- %@deftypefn {Function} treeOutLen %@verbatim %TREEOUTLEN Lengths of tree subbands % Usage: Lc = treeOutLen(L,doNoExt,wt) % % Input parameters: % L : Input signal length. % doNoExt : Flag. Expansive = false, Nonexpansive=true % wt : Structure containing description of the filter tree. % % Output parameters: % Lc : Subband lengths. % % Lc = TREEOUTLEN(L,doNoExt,wt) returns lengths of tree subbands given % input signal length L and flag doNoExt. When true, the transform is % assumed to be non-expansive. % For definition of the structure see WFBINIT. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/treeOutLen.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . [termN, rangeLoc, rangeOut] = treeBFranges(wt); slice = ~cellfun(@isempty,rangeOut); % Limit to nodes with unconnected outputs rangeOut=rangeOut(slice); cRange = cell2mat(cellfun(@(rEl) rEl(:),rangeOut(:),... 'UniformOutput',0)); Lctmp = nodesOutLen(termN(slice),L,rangeLoc(slice),doNoExt,wt); Lc = zeros(size(Lctmp)); Lc(cRange) = Lctmp; ltfat/inst/wavelets/wfbtmanip/treeWpBFrange.m0000664000175000017500000000420313026262304021230 0ustar susnaksusnakfunction [pOutIdxs,chOutIdxs] = treeWpBFrange(wt) %-*- texinfo -*- %@deftypefn {Function} treeWpBFrange %@verbatim %TREEWPBFRANGE Wavelet packet tree output ranges in BF order % Usage: [pOutIdxs,chOutIdxs] = treeBFranges(wt); % % Input parameters: % wt : Filterbank tree struct. % Output parameters: % pOutIdxs : Array of parent nodes in BF order % chOutIdxs : Cell array of children nodes in BF order % % [pOutIdxs,chOutIdxs] = treeBFranges(wt) is a helper function % determining direct relationship between nodes in tree wt. % Elements in both returned arrays are ordered according to the BF order. % pOutIdxs is array of indices in the subbands % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/treeWpBFrange.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . treePath = nodeBForder(0,wt); trLen = numel(treePath); pOutIdxs = zeros(1,trLen); chOutIdxs = cell(1,trLen); pRunIdx = [0]; chRunIdx = 1; % do trough tree and look for nodeNo and its parent for ii=1:trLen tmpfiltNo = length(wt.nodes{treePath(ii)}.g); locRange = nodesLocOutRange(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 pOutIdxs = pOutIdxs(end:-1:1); chOutIdxs = chOutIdxs(end:-1:1); ltfat/inst/wavelets/wfbtmanip/nodeSubtreeDelete.m0000664000175000017500000000632413026262304022145 0ustar susnaksusnakfunction wt = nodeSubtreeDelete(nodeNo,wt) %-*- texinfo -*- %@deftypefn {Function} nodeSubtreeDelete %@verbatim %DELETESUBTREE Removes subtree with root node % Usage: wt = nodeSubtreeDelete(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.github.io/doc/wavelets/wfbtmanip/nodeSubtreeDelete.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'DELETESUBTREE'); complainif_notposint(nodeNo,'DELETESUBTREE'); % All nodes to be deleted in breadth-first order toDelete = nodeBForder(nodeNo,wt); % Start deleting from the deepest nodes to avoid deleting nodes with % children for ii = length(toDelete):-1:1 wt = nodeDelete(toDelete(ii),wt); biggerIdx = toDelete>toDelete(ii); toDelete(biggerIdx) = toDelete(biggerIdx) - 1; end %wt = nodeDelete(nodeNo,wt); function wt = nodeDelete(nodeNo,wt) %DELETENODE Removes specified node from the tree % Usage: wt = nodeDelete(nodeNo,wt) % % Input parameters: % nodeNo : Node index. % wt : Structure containing description of the filter tree. % % Output parameters: % wt : Modified wt. complainif_notenoughargs(nargin,2,'DELETENODE'); complainif_notposint(nodeNo,'DELETENODE'); if any(wt.children{nodeNo}~=0) error('%s: Deleting a non-leaf node!',upper(mfilename)); end % Removing a root node if wt.parents(nodeNo)==0 % Better clear all fields, than simply call wfbtinit fNames = fieldnames(wt); for ii=1:numel(fNames) wt.(fNames{ii})(:) = []; end return; end % Remove the node from it's parent children node list parId = wt.parents(nodeNo); wt.children{parId}(wt.children{parId}==nodeNo) = 0; % newIdx = 1:length(wt.nodes); % newIdx = newIdx(find(newIdx~=nodeNo)); % wt.nodes = wt.nodes(newIdx); % wt.parents = wt.parents(newIdx); % wt.children = wt.children(newIdx); % Remove the node from the structure completely wt.nodes(nodeNo) = []; if isfield(wt,'dualnodes') wt.dualnodes(nodeNo) = []; end wt.parents(nodeNo) = []; wt.children(nodeNo) = []; % Since node was removed, the interconnections are now wrong. % Let's fix that. for ii =1:length(wt.children) biggerIdx = wt.children{ii}>nodeNo; wt.children{ii}(biggerIdx) = wt.children{ii}(biggerIdx)-1; end % .. ant the same in the parents array biggerIdx = wt.parents>nodeNo; wt.parents(biggerIdx) = wt.parents(biggerIdx)-1; ltfat/inst/wavelets/wfbtmanip/nodesFiltUps.m0000664000175000017500000000355113026262304021161 0ustar susnaksusnakfunction upsNo = nodesFiltUps(nodeNo,wt) %-*- texinfo -*- %@deftypefn {Function} nodesFiltUps %@verbatim %NODEFILTUPS Node upsamplig factor % Usage: upsNo = nodesFiltUps(nodeNo,wt) % % Input parameters: % wt : Structure containing description of the filter tree. % % Output parameters: % upsNo : Accumulated upsampling factor along path to root. % % NODESFILTUPS(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.github.io/doc/wavelets/wfbtmanip/nodesFiltUps.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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 ltfat/inst/wavelets/wfbtmanip/treeOutRange.m0000664000175000017500000000521113026262304021141 0ustar susnaksusnakfunction outRange = treeOutRange(wt) %-*- texinfo -*- %@deftypefn {Function} treeOutRange %@verbatim %TREEOUTRANGE Index range of the outputs % Usage: outRange = treeOutRange(wt); % % Input parameters: % wt : Structure containing description of the filter tree. % % Output parameters: % outRange : Subband idx range. % % TREEOUTRANGE(nodeNo,wt) returns index range in the global % tree subbands associated. For definition of the % structure see wfbinit. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtmanip/treeOutRange.html} %@seealso{wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . nodesIdBF = nodeBForder(0,wt); nodesIdBFinv = zeros(size(nodesIdBF)); nodesIdBFinv(nodesIdBF) = 1:numel(nodesIdBF); % Filterbank structs in BF order nodesFbBF = wt.nodes(nodesIdBF); % Number of filters in each node in BF order M = cellfun(@(nEl) numel(nEl.h),nodesFbBF); % Number of unconnected outputs of nodes in BF order. Munc = cellfun(@(nEl,chEl) numel(nEl.h)-numel(chEl(chEl~=0)),... nodesFbBF,wt.children(nodesIdBF)); childrenBForder = wt.children(nodesIdBF); Munccumsum = [0,cumsum(Munc)]; outRange = zeros(1,sum(Munc)); idxLIFO = { {1,1,1} }; k = 1; % n indexes are indices of BF order while ~isempty(idxLIFO) % Pop first element [n,mstart,munc] = idxLIFO{end}{:}; idxLIFO = idxLIFO(1:end-1); for m=mstart:M(n) % If m is among children of the current node if m<=numel(childrenBForder{n}) && childrenBForder{n}(m) ~= 0 % Idex of next node in BF order nnext = nodesIdBFinv(childrenBForder{n}(m)); if m. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'IWPFBT'); if(~iscell(c)) error('%s: Unrecognized coefficient format.',upper(mfilename)); end if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IWPFBT'); if ~strcmpi(par.fname,'wpfbt') 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); Ls = par.Ls; ext = par.ext; interscaling = par.interscaling; % Use the "oposite" scaling if strcmp(interscaling,'intscale') interscaling = 'intnoscale'; elseif strcmp(interscaling,'intnoscale') interscaling = 'intscale'; end % 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.interscaling = {'intsqrt', 'intscale', 'intnoscale'}; [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin); complainif_notposint(Ls,'Ls'); ext = flags.ext; interscaling = flags.interscaling; % 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 = fliplr(nodeBForder(0,wt)); [pOutIdxs,chOutIdxs] = treeWpBFrange(wt); f = comp_iwpfbt(c,wt.nodes(wtPath),pOutIdxs,chOutIdxs,L,ext,interscaling); f = postpad(f,Ls); ltfat/inst/wavelets/wpbest.m0000664000175000017500000002574613026262304016071 0ustar susnaksusnakfunction [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. % % Please note that w should define orthonormal wavelet filters. % % 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,3,'WPBEST'); complainif_notposint(J,'J','WPBEST'); if numel(nonzeros(size(f)>1))>1 error('%s: Function accepts only single channel inputs.',upper(mfilename)); end definput.import = {'fwt','wfbtcommon'}; 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. [c,info] = wpfbt(normalize(f,'2'),{w,J,'full'},'nat',flags.ext,'intnoscale'); % Nodes in the reverse BF order treePath = fliplr(nodeBForder(0,info.wt)); % Relationships between nodes [pOutIdxs,chOutIdxs] = treeWpBFrange(info.wt); % Nodes to be removed removeNodes = []; % Energy normalization % totalE = sum(cellfun(@(cEl) sum(cEl.^2),c)); % c = cellfun(@(cEl) cEl.^2/totalE,c,'UniformOutput',0); % pre-calculate entropy of all subbands cEnt = cellfun(@(cEl) wcostwrap(cEl,kv.cost,0),c); if do_additive 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 for ii=1:length(pOutIdxs)-1 pEnt = cEnt(pOutIdxs(ii)); 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 % Search the pOutIdxs(ii) in chOutIdxs % There should be the only one.. foundId = cellfun(@(chEl)find(chEl==pOutIdxs(ii)),chOutIdxs,... 'UniformOutput',0); chId = find(~cellfun(@isempty,foundId)); chOutIdxs{chId}(chOutIdxs{chId} == pOutIdxs(ii)) = []; chOutIdxs{chId} = [chOutIdxs{chId},chOutIdxs{ii}]; end end end % Do tree prunning. for ii=1:length(removeNodes) [info.wt] = nodeSubtreeDelete(removeNodes(ii),info.wt); end end % Finally do the analysis using the created best tree. with correct % frequency bands order [c,info] = wfbt(f,info.wt,flags.ext,flags.forder); %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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa % 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 h = cellfun(@(gEl) struct('h',gEl,'offset',-floor((length(gEl))/2)),h,'UniformOutput',0); g = h; info.istight = 1; a = M*ones(M,1); ltfat/inst/wavelets/wpfbtclength.m0000664000175000017500000000350313026262304017237 0ustar susnaksusnakfunction [Lc,L]=wpfbtclength(Ls,wt,varargin) %-*- texinfo -*- %@deftypefn {Function} wpfbtclength %@verbatim %WPFBTCLENGTH WPFBT subband length from a signal length % Usage: Lc=wpfbtclength(Ls,wt); % [Lc,L]=wpfbtclength(Ls,wt); % % Lc=WPFBTCLENGTH(Ls,wt) returns the lengths of coefficient subbands % obtained from WPFBT for a signal of length Ls. Please see the help % on WPFBT for an explanation of the parameter wt. % % [Lc,L]=WPFBTCLENGTH(...) additionally 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.github.io/doc/wavelets/wpfbtclength.html} %@seealso{wpfbt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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 = nodeBForder(0,wt); Lc = nodesOutLen(wtPath,L,[],flags.do_per,wt); ltfat/inst/wavelets/wfilt_lemarie.m0000664000175000017500000000644013026262304017376 0ustar susnaksusnakfunction [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, must be even. % % [h,g,a]=WFILT_LEMARIE(N) calculates N (even) truncated coeficients % of orthonormal Battle-Lemarie wavelets. Filter coefficients are obtained % by frequency domain sampling and trunctating the impulse response. % Due to the truncation, the filterbank might not achieve a perfect % reconstruction. The filetrs are included nevertheless since they were % the original ones used in the first MRA paper. % % 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.github.io/doc/wavelets/wfilt_lemarie.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Original copyright goes to: % Copyright (C) 1994, 1995, 1996, by Universidad de Vigo % Author: Jose Martin Garcia % e-mail: Uvi_Wave@tsc.uvigo.es if rem(N,2)~=0 error('%s: Filter length must be even.',upper(mfilename)); end 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} = (hh); g{2} = -(-1).^(1:length(hh)).*g{1}(end:-1:1); g = cellfun(@(gEl) struct('h',gEl,'offset',-floor(numel(gEl)/2)),g,'UniformOutput',0); h = g; a= [2;2]; info.istight = 1; function [H,G] = wfreq_lemarie(L) %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: mallat89atheory % % % Original copyright goes to: % Copyright (C) 1994, 1995, 1996, by Universidad de Vigo % Author: Jose Martin Garcia % e-mail: Uvi_Wave@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}); ltfat/inst/wavelets/wpfbt.m0000664000175000017500000001077713026262304015705 0ustar susnaksusnakfunction [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. % % [c,info]=WPFBT(f,wt) additionally 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 WFBT, the cell array c contain every intermediate % output of each node in the tree. c{jj} are ordered according to % nodes taken in the breadth-first order. % % 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. % % Scaling of intermediate outputs: % -------------------------------- % % The following flags control scaling of intermediate outputs and % therefore the energy relations between coefficient subbands. An % intermediate output is an output of a node which is further used as an % input to a descendant node. % % 'intsqrt' % Each intermediate output is scaled by 1/sqrt(2). % If the filterbank in each node is orthonormal, the overall % undecimated transform is a tight frame. % This is the default. % % 'intnoscale' % No scaling of intermediate results is used. This is % necessaty for the WPBEST function to correctly work with % the cost measures. % % 'intscale' % Each intermediate output is scaled by 1/2. % % If 'intnoscale' is used, 'intscale' must be used in IWPFBT (and vice % versa) in order to obtain a perfect reconstruction. % % Please see help for WFBT description of possible formats of wt and % of the additional flags defining boundary handling. % % 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.github.io/doc/wavelets/wpfbt.html} %@seealso{wfbt, iwpfbt, wfbtinit, plotwavelets, wpbest} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'WPFBT'); definput.import = {'fwt','wfbtcommon'}; definput.flags.interscaling = {'intsqrt', 'intscale', 'intnoscale'}; [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 % 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 = nodeBForder(0,wt); rangeLoc = nodesLocOutRange(wtPath,wt); c = comp_wpfbt(f,wt.nodes(wtPath),rangeLoc,flags.ext,flags.interscaling); %% ----- 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.interscaling = flags.interscaling; end ltfat/inst/wavelets/iwfbt.m0000664000175000017500000000716613026262304015674 0ustar susnaksusnakfunction 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 filterbank 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 IDTWFB: % % f = gspi; % J = 7; % wt = {'db6',J}; % c = wfbt(f,wt); % fhat = iwfbt(c,wt,length(f)); % % The following should give (almost) zero % norm(f-fhat) % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/iwfbt.html} %@seealso{wfbt, wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'IWFBT'); if(~iscell(c)) error('%s: Unrecognized coefficient format.',upper(mfilename)); end if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IWFBT'); if ~strcmpi(par.fname,'wfbt') 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); Ls = par.Ls; ext = par.ext; L = wfbtlength(Ls,wt,ext); else complainif_notenoughargs(nargin,3,'IWFBT'); %% PARSE INPUT definput.keyvals.Ls=[]; definput.keyvals.dim=1; definput.import = {'fwt','wfbtcommon'}; [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin); complainif_notposint(Ls,'Ls'); 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 [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt,'rev'); outLengths = nodesInLen(nodesBF,L,strcmpi(ext,'per'),wt); outLengths(end) = L; f = comp_iwfbt(c,wt.nodes(nodesBF),outLengths,rangeLoc,rangeOut,ext); f = postpad(f,Ls); ltfat/inst/wavelets/iufwt.m0000664000175000017500000000756413026262304015721 0ustar susnaksusnakfunction 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 w 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. % % Filter scaling % -------------- % % As in UFWT, 3 flags defining scaling of filters are recognized: % % 'sqrt' % Each filter is scaled by 1/sqrt(a), there a is the hop % factor associated with it. If the original filterbank is % orthonormal, the overall undecimated transform is a tight % frame. % This is the default. % % 'noscale' % Uses filters without scaling. % % 'scale' % Each filter is scaled by 1/a. % % If 'noscale' is used, 'scale' must have been used in UFWT (and vice % versa) in order to obtain a perfect reconstruction. % % 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.github.io/doc/wavelets/iufwt.html} %@seealso{ufwt, plotwavelets} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'IUFWT'); if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IUFWT'); if ~strcmpi(par.fname,'ufwt') error(['%s: Wrong func name in info struct. ',... ' The info parameter was created by %s.'],... upper(mfilename),par.fname); end % Ensure we are using the correct wavelet filters w = fwtinit({'dual',par.wt}); J = par.J; scaling = par.scaling; % Use the "oposite" scaling if strcmp(scaling,'scale') scaling = 'noscale'; elseif strcmp(scaling,'noscale') scaling = 'scale'; end else complainif_notenoughargs(nargin,3,'IUFWT'); definput.keyvals.J = []; definput.import = {'uwfbtcommon'}; [flags, ~, J]=ltfatarghelper({'J'},definput,varargin); complainif_notposint(J,'J'); % Initialize the wavelet filters % It is up to user to use the correct ones. w = fwtinit(par); scaling = flags.scaling; end %% Run computation f = comp_iufwt(c,w.g,w.a,J,scaling); ltfat/inst/wavelets/dtwfbbounds.m0000664000175000017500000000455113026262304017075 0ustar susnaksusnakfunction [AF,BF]=dtwfbbounds(dualwt,L) %-*- texinfo -*- %@deftypefn {Function} dtwfbbounds %@verbatim %DTWFBBOUNDS Frame bounds of DTWFB % Usage: fcond=dtwfbbounds(dualwt,L); % [A,B]=dtwfbbounds(dualwt,L); % [...]=dtwfbbounds(dualwt); % % DTWFBBOUNDS(dualwt,L) calculates the ratio B/A of the frame bounds % of the dual-tree filterbank specified by dualwt for a system of % length L. The ratio is a measure of the stability of the system. % % DTWFBBOUNDS(dualwt) does the same thing, but L is the next compatible % length bigger than the longest filter in the identical filterbank. % % [A,B]=DTWFBBOUNDS(...) returns the lower and upper frame bounds % explicitly. % % See DTWFB for explanation of parameter dualwt. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/dtwfbbounds.html} %@seealso{dtwfb, filterbankbounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,1,'DTWFBBOUNDS'); dualwt = dtwfbinit({'strict',dualwt},'nat'); if nargin<2 L = []; end; if ~isempty(L) if L~=wfbtlength(L,dualwt) error(['%s: Specified length L is incompatible with the length of ' ... 'the time shifts.'],upper(mfilename)); end end % Do the equivalent filterbank using multirate identity property [gmultid,amultid] = dtwfb2filterbank(dualwt,'complex'); if isempty(L) L = wfbtlength(max(cellfun(@(gEl) numel(gEl.h),gmultid)),dualwt); end % 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 ltfat/inst/wavelets/wfilt_symds.m0000664000175000017500000002346713026262304017127 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_symds(K) %-*- texinfo -*- %@deftypefn {Function} wfilt_symds %@verbatim %WFILT_SYMDS Symmetric wavelets dyadic sibling % Usage: [h,g,a] = wfilt_symds(K); % % [h,g,a]=WFILT_SYMDS(K) with K in {1,2,3,4,5} returns symmetric % dyadic sibling wavelet frame filters from the reference. % % The returned filterbank has redundancy equal to 2 and it does not form % a tight frame. % % Examples: % --------- % : % wfiltinfo('ana:symds3'); % % : % 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.github.io/doc/wavelets/wfilt_symds.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 0; a = [2;2;2;2]; switch(K) 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; hoffset = [-4,-4,-4,-4]; 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; goffset = [-4,-4,-4,-4]; 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 ]; hoffset = [-3,-5,-5,-5]; 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 ]; goffset = [-3,-5,-5,-5]; 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 ]; hoffset = [-7,-7,-7,-5]; 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 % 0 0 0 0 ]; goffset = [-7,-7,-7,-5]; 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; hoffset = [-9,-9,-9,-7]; 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; goffset = [-9,-9,-9,-7]; 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; hoffset = [-5,-5,-5,-5]; 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; goffset = [-5,-5,-5,-5]; otherwise error('%s: No such filters.',upper(mfilename)); end g=mat2cell(garr,size(garr,1),ones(1,size(garr,2))); g = cellfun(@(gEl,ofEl) struct('h',gEl(:),'offset',ofEl),... g,num2cell(goffset),'UniformOutput',0); h=mat2cell(flipud(harr),size(harr,1),ones(1,size(harr,2))); h = cellfun(@(hEl,ofEl) struct('h',hEl(:),'offset',ofEl),... h,num2cell(hoffset),'UniformOutput',0); ltfat/inst/wavelets/ufwt.m0000664000175000017500000001173513026262304015543 0ustar susnaksusnakfunction [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. % % UFWT(f,w,J) computes redundant time (or shift) invariant % wavelet representation of the input signal f using wavelet filters % defined by w in the "a-trous" algorithm. % % For all accepted formats of the parameter w see the FWTINIT function. % % [c,info]=UFWT(f,w,J) additionally returns the info struct. % 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 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 respective subbands. % % 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. % % Filter scaling % -------------- % % When compared to FWT, UFWT subbands are gradually more and more % redundant with increasing level of the subband. If no scaling of the % filters is introduced, the energy of subbands tends to grow with increasing % level. % There are 3 flags defining filter scaling: % % 'sqrt' % Each filter is scaled by 1/sqrt(a), where a is the hop % factor associated with it. If the original filterbank is % orthonormal, the overall undecimated transform is a tight % frame. % This is the default. % % 'noscale' % Uses filters without scaling. % % 'scale' % Each filter is scaled by 1/a. % % If 'noscale' is used, 'scale' has to be used in IUFWT (and vice % versa) in order to obtain a perfect reconstruction. % % 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,fs] = greasy; % J = 8; % [c,info] = ufwt(f,'db8',J); % plotwavelets(c,info,fs,'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.github.io/doc/wavelets/ufwt.html} %@seealso{iufwt, plotwavelets} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,3,'UFWT'); complainif_notposint(J,'J'); definput.import = {'uwfbtcommon'}; [flags]=ltfatarghelper({},definput,varargin); % 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,w.a,J,flags.scaling); %% ----- Optionally : Fill info struct ---- if nargout>1 info.fname = 'ufwt'; info.wt = w; info.J = J; info.scaling = flags.scaling; end ltfat/inst/wavelets/wfiltdtinfo.m0000664000175000017500000001216013026262304017100 0ustar susnaksusnakfunction wfiltdtinfo(dw,varargin) %-*- texinfo -*- %@deftypefn {Function} wfiltdtinfo %@verbatim %WFILTDTINFO Plots dual-tree filters info % Usage: wfiltdtinfo(dw); % % Input parameters: % dw : Wavelet dual-tree filterbank % % WFILTDTINFO(w) plots impulse responses, frequency responses and % approximation of the scaling and of the wavelet function(s) associated % with the dual-tree wavelet filters defined by w in a single figure. % Format of dw is the same as in DTWFB. % % The figure is organized as follows: % % First row shows impulse responses of the first (real) tree. % % Second row shows impulse responses of the second (imag) tree. % % Third row contains plots of real (green), imaginary (red) and absolute % (blue) parts of approximation of scaling and wavelet function(s). % % Fourth and fifth row show magnitude and phase frequency responses % respectivelly of filters from rows 1 and 2 with matching colors. % % Optionally it is possible to define scaling of the y axis of the % frequency seponses. Supported are: % % 'db','lin' % dB or linear scale respectivelly. By deault a dB scale is used. % % Examples: % --------- % : % wfiltdtinfo('qshift4'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfiltdtinfo.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,1,'WFILTDTINFO'); definput.flags.freqzscale = {'db','lin'}; [flags]=ltfatarghelper({},definput,varargin); [dwstruct,info] = dtwfbinit({'strict',{dw,6,'dwt'}}); dw = info.dw; filtNo = size(dw.g,1); grayLevel = [0.6,0.6,0.6]; clf; colorAr ={repmat('rbk',1,filtNo),repmat('cmg',1,filtNo)}; for ii=1:2 subplot(5,filtNo,filtNo*(ii-1)+1); title(sprintf('Scaling imp. response, tree %i',ii)); loAna = dw.g{1,ii}.h; loShift = -dw.g{1,ii}.offset; xvals = -loShift + (0:length(loAna)-1); 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{ii}(1)); axis tight; hold off; end for ii=1:2 for ff=2:filtNo subplot(5,filtNo,ff+filtNo*(ii-1)); title(sprintf('Wavelet imp. response no: %i, tree %i',ff-1,ii)); filtAna = dw.g{ff,ii}.h; filtShift = -dw.g{ff,ii}.offset; xvals = -filtShift + (0:length(filtAna)-1); 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{ii}(ff)); axis tight; hold off; end end L = wfbtlength(1024,dwstruct,'per'); Lc = wfbtclength(L,dwstruct,'per'); c = wavpack2cell(zeros(sum([Lc;Lc(end:-1:1)]),1),... [Lc;Lc(end:-1:1)]); c{1}(1) = 1; sfn = idtwfb(c,dwstruct,L); subplot(5,filtNo,[2*filtNo+1]); xvals = ((-floor(L/2)+1:floor(L/2)).'); plot(xvals,fftshift([abs(sfn),real(sfn),imag(sfn)],1)); axis tight; title('Scaling function'); %legend({'abs','real','imag'},'Location','south','Orientation','horizontal') for ff=2:filtNo subplot(5,filtNo,[2*filtNo+ff]); c{ff-1}(1) = 0; c{ff}(1) = 1; wfn = idtwfb(c,dwstruct,L); plot(xvals,fftshift([abs(wfn),real(wfn),imag(wfn)],1)); axis tight; %legend({'abs','real','imag'},'Location','south','Orientation','horizontal') title(sprintf('Wavelet function: %i',ff-1)); end subplot(5,filtNo,3*filtNo + (1:filtNo) ); title('Magnitude frequency response'); maxLen=max(cellfun(@(gEl) numel(gEl.h),dw.g)); Ls = nextfastfft(max([maxLen,1024])); H = filterbankfreqz(dw.g(:),[dw.a(:);dw.a(:)],Ls); %[H] = wtfftfreqz(w.g); if flags.do_db plotH = 20*log10(abs(H)); elseif flags.do_lin plotH = abs(H); else error('%s: Unknown parameter',upper(mfilaname)); end xVals = linspace(0,1,numel(H(:,1))); hold on; for ii=1:2 for ff=1:filtNo plot(xVals,plotH(:,ff+(ii-1)*filtNo),colorAr{ii}(ff)); axis tight; end end if flags.do_db ylim([-30,max(plotH(:))]) end ylabel('|\itH|[dB]'); xlabel('\omega [-]') hold off; subplot(5,filtNo,4*filtNo + (1:filtNo) ); title('Phase frequency response'); hold on; for ii=1:2 for ff=1:filtNo plot(xVals,unwrap(angle((H(:,ff+(ii-1)*filtNo))))/pi,colorAr{ii}(ff)); axis tight; end end ylabel('arg H(\omega)[\pi rad]'); xlabel('\omega [-]') axis tight; % plot(unwrap(angle([H]))); % axis tight; hold off; ltfat/inst/wavelets/fwtinit.m0000664000175000017500000004025213026262304016236 0ustar susnaksusnakfunction [w,info] = fwtinit(wdef,prefix) %-*- texinfo -*- %@deftypefn {Function} fwtinit %@verbatim %FWTINIT Wavelet Filterbank Structure Initialization % Usage: w = fwtinit(wdef); % w = fwtinit(wdef,prefix); % [w,info]=fwtinit(...) % % Input parameters: % wdef : Wavelet filters specification. % prefix : Function name prefix % % Output parameters: % w : Structure defining the filterbank. % % FWTINIT(wdef) produces a structure describing the analysis % (field w.h) and synthesis (field w.g) filterbanks and a hop factors % (field w.a) of a basic wavelet-type filterbank defined by wdef. % % The analysis filterbank w.h is by default used in FWT and the % synthesis filterbank w.g in IFWT. % % Both w.h and w.g are cell arrays of structs defining FIR filters % compatible with FILTERBANK, IFILTERBANK and related functions. % More preciselly, each elemement of either cell array is a struct with % fields .h and .offset defining impulse response and the initial % shift respectivelly. % % [w,info]=FWTINIT(...) additionally returns a info struct which % provides some information about the wavelet filterbank: % % info.istight % Wavelet filterbank forms a tight frame. In such case, w.h and % w.g are identical. % % The function is a wrapper for calling all the functions with the % wfilt_ prefix defined in the LTFAT wavelets directory. % % The possible formats of the wdef are the following: % % 1) Cell array with first element being the name of the function defining % the basic wavelet filters (wfilt_ prefix) and the other elements % are the parameters of the function. % % 2) Character string as concatenation of the name of the wavelet % filters defining function (as above) and the numeric parameters % delimited by ':' character. Examples: % % {'db',10} or 'db10' % Daubechies with 10 vanishing moments. It calls wfilt_db(10) % internally. % % {'spline',4,4} or 'spline4:4' % Biorthogonal spline wavelet filters with 4 vanishing moments. % Calls wfilt_spline(4,4) internally. % % {'dden',1} or 'dden1' % Double density wavelet filters. Calls wfilt_dden(1) where % the filters are stored as numerical vectors. % % 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 a dual of whatever % is passed as the second argument. % % 6) Two element cell array. First element is the string 'strict' and the % second one is in format 1), 2), 4) or 5). This in the non tight case % the filters has to be defined explicitly using 'ana' and 'syn' % identifiers. See below. % % 7) Two element cell array. First element is a cell array of structures % defining FIR filterbank (.h and .offset fields) as in FILTERBANKWIN % and the second element is a numeric vector of subsampling factors. % % One can interchange the filter in w.h and w.g and use the % filterbank indended for synthesis in FWT and vice versa by % re-using 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'. % % This only makes difference if the filterbanks are biorthogonal % (e.g. wfilt_spline) or a general frame (e.g. 'symds2'), in other % cases, the analysis and synthesis filters are identical. % % 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 additional field: % % w.origArgs % Original parameters in format 1). % % % 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.github.io/doc/wavelets/fwtinit.html} %@seealso{fwt, ifwt, wfilt_db} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % **Remark:** Function names with the `wfilt_` prefix cannot contain numbers % and cannot start with 'ana' or 'syn'! % wavelet filters functions definition prefix wprefix = 'wfilt_'; waveletsDir = 'wavelets'; % output structure definition %%%%%%%%%%%%%%%%%%%%%%%%%%%%% w.origArgs = {}; w.wprefix = wprefix; w.h = {}; w.g = {}; w.a = []; %%%%%%%%%%%%%%%%%%%%%%%%%%%%% info.istight = 0; % 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 if nargin>1 if ischar(prefix) && ~isempty(prefix) wprefix = prefix; w.wprefix = wprefix; else error('%s: Bad format of prefix.',upper(mfilename)); end 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 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 built 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),[]); w.origArgs = wname; elseif iscell(wname{1}) && numel(wname)==2 && numel(wname{1})>1 complainDual(do_dual,'filterbank cell array'); g = wname{1}; a = wname{2}; [g,asan,infotmp]=filterbankwin(g,a,'normal'); if ~infotmp.isfir error('%s: Only FIR filters are supported.',upper(mfilename)); end w.h = g; w.g = g; w.a = asan(:,1); w.origArgs = wname; 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 if(wfiltNargout==3) [w.h, w.g, w.a] = feval(tmpFile,wname{2:end}); elseif(wfiltNargout==4) [w.h, w.g, 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; else info.istight = 0; 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]; % Hande the Dual-tree specific stuff if ~isempty(info) && isfield(info,'defaultfirst') info.defaultfirst.g = info.defaultfirst.h; info.defaultfirst.origArgs = [{'ana'},info.defaultfirst.origArgs]; end if ~isempty(info) && isfield(info,'defaultleaf') info.defaultleaf.g = info.defaultleaf.h; info.defaultleaf.origArgs = [{'ana'},info.defaultleaf.origArgs]; end else w.h = w.g; w.origArgs = [{'syn'}, w.origArgs]; % Hande the Dual-tree specific stuff if ~isempty(info) && isfield(info,'defaultfirst') info.defaultfirst.h = info.defaultfirst.g; info.defaultfirst.origArgs = [{'syn'},info.defaultfirst.origArgs]; end if ~isempty(info) && isfield(info,'defaultleaf') info.defaultleaf.h = info.defaultleaf.g; info.defaultleaf.origArgs = [{'syn'},info.defaultleaf.origArgs]; end 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)); if ~all(cellfun(@isempty,wfiltNames)) error('%s: Unknown wavelet filter definition string: %s.\nAccepted are:\n%s',upper(mfilename),wcharNoNum,dirListStr(1:end-2)); else error('%s: Cannot find %s%s',upper(mfilename),wprefix,wcharNoNum); end 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 ltfat/inst/wavelets/wavcell2pack.m0000664000175000017500000000437513026262304017136 0ustar susnaksusnakfunction [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.github.io/doc/wavelets/wavcell2pack.html} %@seealso{wavpack2cell, fwt, wfbt, wpfbt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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 ltfat/inst/wavelets/wfilt_matlabwrapper.m0000664000175000017500000000345713026262304020626 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_matlabwrapper(wname) %-*- texinfo -*- %@deftypefn {Function} wfilt_matlabwrapper %@verbatim %WFILT_MATLABWRAPPER Wrapper of the Matlab Wavelet Toolbox wfilters function % Usage: [h,g,a] = wfilt_matlabwrapper(wname); % % [h,g,a]=WFILT_MATLABWRAPPER(wname) calls Matlab Wavelet Toolbox % function wfilters and passes the parameter wname to it. % % This function requires the Matlab Wavelet Toolbox. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_matlabwrapper.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa if ~exist('wfilters',2) error('%s: Matlab Wavelet Toolbox is not present.',upper(mfilename)); end 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 g = cellfun(@(gEl) struct('h',gEl(:),'offset',-numel(gEl)/2),g,'UniformOutput',0); h = cellfun(@(hEl) struct('h',hEl(:),'offset',-numel(hEl)/2),h,'UniformOutput',0); ltfat/inst/wavelets/ifwt.m0000664000175000017500000001165313026262304015526 0ustar susnaksusnakfunction 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 filterbank 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.github.io/doc/wavelets/ifwt.html} %@seealso{fwt, wavpack2cell, wavcell2pack} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'IFWT'); if ~(iscell(c) || isnumeric(c)) || isempty(c) error('%s: Unrecognized coefficient format.',upper(mfilename)); end if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IFWT'); if ~strcmpi(par.fname,'fwt') error(['%s: Wrong func name in info struct. ',... ' The info parameter was created by %s.'],... upper(mfilename),par.fname); end % process info struct w = fwtinit({'dual',par.wt}); J = par.J; Lc = par.Lc; Ls = par.Ls; dim = par.dim; ext = par.ext; L = fwtlength(Ls,w,J,ext); else complainif_notenoughargs(nargin,4,'IFWT'); %% PARSE INPUT definput.import = {'fwt'}; definput.keyvals.dim = []; definput.keyvals.Ls = []; definput.keyvals.J = []; [flags,~,J,Ls,dim]=ltfatarghelper({'J','Ls','dim'},definput,varargin); complainif_notposint(J,'J'); complainif_notposint(Ls,'Ls'); 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,w.a,J,L,ext); f = postpad(f,Ls); %% ----- FINALIZE: Reshape back according to the dim. if(dim==2) f = f.'; end %END IFWT ltfat/inst/wavelets/wfbtbounds.m0000664000175000017500000000613013026262304016724 0ustar susnaksusnakfunction [AF,BF]=wfbtbounds(wt,varargin) %-*- texinfo -*- %@deftypefn {Function} wfbtbounds %@verbatim %WFBTBOUNDS Frame bounds of WFBT % Usage: fcond=wfbtbounds(wt,L); % [A,B]=wfbtbounds(wt,L); % [...]=wfbtbounds(wt); % % WFBTBOUNDS(wt,L) calculates the ratio B/A of the frame bounds % of the filterbank tree specified by wt for a system of length % L. The ratio is a measure of the stability of the system. % % WFBTBOUNDS({w,J,'dwt'},L) calculates the ratio B/A of the frame % bounds of the DWT (|FWT|) filterbank specified by w and J for a % system of length L. % % WFBTBOUNDS(wt) does the same thing, but L is assumed to be the % next compatible length bigger than the longest filter in the identical % filterbank. % % [A,B]=WFBTBOUNDS(...) returns the lower and upper frame bounds % explicitly. % % See WFBT for explanation of parameter wt and FWT for explanation % of parameters w and J. % % The function supports the following flag groups: % % 'scaling_notset'(default),'noscale','scale','sqrt' % Support for scaling flags as described in UWFBT. By default, % the bounds are computed for WFBT, passing any of the non-default % flags results in framebounds for UWFBT. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtbounds.html} %@seealso{wfbt, fwt, filterbankbounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,1,'WFBTBOUNDS'); % Frequency or natural ordering should not make a difference wt = wfbtinit({'strict',wt},'nat'); definput.keyvals.L = []; definput.import = {'uwfbtcommon'}; definput.importdefaults = {'scaling_notset'}; [flags,~,L]=ltfatarghelper({'L'},definput,varargin); if ~isempty(L) && flags.do_scaling_notset if L~=wfbtlength(L,wt) error(['%s: Specified length L is incompatible with the length of ' ... 'the time shifts.'],upper(mfilename)); end; end % Do the equivalent filterbank using multirate identity property [gmultid,amultid] = wfbt2filterbank(wt,flags.scaling); if isempty(L) L = wfbtlength(max(cellfun(@(gEl) numel(gEl.h),gmultid)),wt); end % Do the equivalent uniform filterbank if any(amultid~=amultid(1)) [gu,au] = nonu2ufilterbank(gmultid,amultid); else [gu,au] = deal(gmultid,amultid); end if nargout<2 AF = filterbankbounds(gu,au,L); elseif nargout == 2 [AF, BF] = filterbankbounds(gu,au,L); end ltfat/inst/wavelets/wfiltdt_qshift.m0000664000175000017500000000462113026262304017605 0ustar susnaksusnakfunction [h,g,a,info] = wfiltdt_qshift(N) %-*- texinfo -*- %@deftypefn {Function} wfiltdt_qshift %@verbatim %WFILTDT_QSHIFT Improved Orthogonality and Symmetry properties % % Usage: [h,g,a] = wfiltdt_qshift(N); % % [h,g,a]=WFILTDT_QSHIFT(N) with N in {1,2,3,4,5,6,7} returns % Kingsbury's Q-shift filters suitable for dual-tree complex wavelet % transform. % Filters in both trees are orthogonal and based on a single prototype % low-pass filter with a quarter sample delay. Other filters are % derived by modulation and time reversal such that they fulfil the % half-sample delay difference between the trees. % % Examples: % --------- % : % wfiltdtinfo('qshift3'); % % References: % N. G. Kingsbury. A dual-tree complex wavelet transform with improved % orthogonality and symmetry properties. In ICIP, pages 375--378, 2000. % % N. Kingsbury. Design of q-shift complex wavelets for image processing % using frequency domain energy minimization. In Image Processing, 2003. % ICIP 2003. Proceedings. 2003 International Conference on, volume 1, % pages I--1013--16 vol.1, Sept 2003. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfiltdt_qshift.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa [h(:,1),g(:,1),a,info] = wfilt_qshifta(N); [h(:,2),g(:,2)] = wfilt_qshiftb(N); % Default first and leaf filters % They are chosen to be orthonormal near-symmetric here in order not to % break the orthonormality of the overal representation. [info.defaultfirst, info.defaultfirstinfo] = fwtinit('symorth1'); [info.defaultleaf, info.defaultleafinfo] = ... deal(info.defaultfirst,info.defaultfirstinfo); ltfat/inst/wavelets/wfilt_algmband.m0000664000175000017500000000713313026262304017525 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_algmband(K) %-*- 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(K); % % [h,g,a]=WFILT_ALGMBAND(K) with K in {1,2} returns wavelet filters % from the reference paper. The filters are 3-band (K==1) and 4-band % (K==2) with critical subsampling. % % Examples: % --------- % : % wfiltinfo('algmband1'); % % : % 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.github.io/doc/wavelets/wfilt_algmband.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa switch(K) 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]; offset = [-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]; offset = [-12,-8,-8,-12]; otherwise error('%s: No such orthonormal M-band wavelet filter bank.',upper(mfilename)); end g=mat2cell(flipud(garr),size(garr,1),ones(1,size(garr,2))); g = cellfun(@(gEl,offEl) struct('h',gEl,'offset',offEl),g,num2cell(offset),... 'UniformOutput',0); h = g; info.istight=1; ltfat/inst/wavelets/idtwfb.m0000664000175000017500000000724313026262304016034 0ustar susnaksusnakfunction f=idtwfb(c,par,varargin) %-*- texinfo -*- %@deftypefn {Function} idtwfb %@verbatim %IDTWFB Inverse Dual-tree Filterbank % Usage: f=idtwfb(c,info); % f=idtwfb(c,dualwt,Ls); % % Input parameters: % c : Input coefficients. % info : Transform params. struct % dualwt : Dual-tree Wavelet Filterbank definition % Ls : Length of the reconstructed signal. % % Output parameters: % f : Reconstructed data. % % f = IDTWFB(c,info) reconstructs signal f from the coefficients c* % using parameters from info struct. both returned by DTWFB function. % % f = IDTWFB(c,dualwt,Ls) reconstructs signal f from the coefficients % c using dual-tree filterbank defined by dualwt. Plese see DTWFB % for supported formats. The Ls parameter is mandatory due to the % ambiguity of reconstruction lengths introduced by the subsampling % operation. % Note that the same flag as in the DTWFB function have to be used, % otherwise perfect reconstruction cannot be obtained. Please see help % for DTWFB for description of the flags. % % Examples: % --------- % % A simple example showing perfect reconstruction using IDTWFB: % % f = gspi; % J = 7; % wtdef = {'qshift3',J}; % c = dtwfb(f,wtdef); % fhat = idtwfb(c,wtdef,length(f)); % % The following should give (almost) zero % norm(f-fhat) % % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/idtwfb.html} %@seealso{dtwfb, dtwfbinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'IDTWFB'); if ~iscell(c) error('%s: Unrecognized coefficient format.',upper(mfilename)); end if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IDTWFB'); if ~strcmpi(par.fname,'dtwfb') error(['%s: Wrong func name in info struct. ',... ' The info parameter was created by %s.'],... upper(mfilename),par.fname); end dtw = dtwfbinit({'dual',par.wt},par.fOrder); Ls = par.Ls; ext = 'per'; L = wfbtlength(Ls,dtw,ext); else complainif_notenoughargs(nargin,3,'IDTWFB'); %% PARSE INPUT definput.keyvals.Ls=[]; definput.import = {'wfbtcommon'}; [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin); complainif_notposint(Ls,'Ls'); ext = 'per'; % Initialize the wavelet tree structure dtw = dtwfbinit(par,flags.forder); [Lc,L]=wfbtclength(Ls,dtw,ext); Lc = [Lc;Lc(end:-1:1)]; % 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 [nodesBF, rangeLoc, rangeOut] = treeBFranges(dtw,'rev'); outLengths = nodesInLen(nodesBF,L,strcmpi(ext,'per'),dtw); outLengths(end) = L; f = comp_idtwfb(c,dtw.nodes(nodesBF),dtw.dualnodes(nodesBF),outLengths,... rangeLoc,rangeOut,ext,1); f = postpad(f,Ls); ltfat/inst/wavelets/wfilt_oddevenb.m0000664000175000017500000000674213026262304017553 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_oddevenb(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_oddevenb %@verbatim %WFILT_ODDEVENB Kingsbury's symmetric odd filters % % Usage: [h,g,a] = wfilt_oddevenb(N); % % [h,g,a]=WFILT_ODDEVENB(N) with N in {1} returns Kingsbury's % odd filters. % % Examples: % --------- % : % figure(1); % wfiltinfo('ana:oddevenb1'); % % figure(2); % wfiltinfo('syn:oddevenb1'); % % References: % N. Kingsbury. Complex wavelets for shift invariant analysis and % filtering of signals. Applied and Computational Harmonic Analysis, % 10(3):234 -- 253, 2001. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_oddevenb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 0; a = [2;2]; switch(N) case 1 % Example 1. from the reference. Symmetric near-orthogonal garr = [ 0 0 0 -7.062639508928571e-05 0 0 -0.0017578125 1.341901506696429e-03 0 -1.883370535714286e-03 0.022265625 -7.156808035714285e-03 -0.046875 2.385602678571428e-02 -0.0482421875 5.564313616071428e-02 0.2968750 -5.168805803571428e-02 0.55546875 -2.997576032366072e-01 0.2968750 5.594308035714286e-01 -0.0482421875 -2.997576032366072e-01 -0.046875 -5.168805803571428e-02 0.022265625 5.564313616071428e-02 0 2.385602678571428e-02 -0.0017578125 -7.156808035714285e-03 0 -1.883370535714286e-03 0 1.341901506696429e-03 0 0 0 -7.062639508928571e-05 ]; % This scaling is not in the reference paper, but it is here to be % consistent garr = garr*sqrt(2); %garr = normalize(garr,'energy'); offset = -10; otherwise error('%s: No such filters.',upper(mfilename)); end %garr = [garr(:,3:4),garr(:,1:2)]; modrange = (-1).^((0:size(garr,1)-1) + offset+1).'; modrange2 = (-1).^((0:size(garr,1)-1) + offset).'; harr = [garr(:,2).*modrange2,... garr(:,1).*modrange,... ]; % In the biorthogonal case, the filters do not get time reversed garr = flipud(garr); htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h = cellfun(@(hEl)struct('h',hEl,'offset',offset),htmp(1:2),... 'UniformOutput',0); gtmp=mat2cell(garr,size(garr,1),ones(1,size(garr,2))); g = cellfun(@(gEl)struct('h',gEl,'offset',offset),gtmp(1:2),... 'UniformOutput',0); ltfat/inst/wavelets/wfilt_hden.m0000664000175000017500000001105113026262304016670 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_hden(K) %-*- texinfo -*- %@deftypefn {Function} wfilt_hden %@verbatim %WFILT_HDEN Higher DENsity dwt filters (tight frame, frame) % Usage: [h,g,a] = wfilt_hden(K); % % [h,g,a]=WFILT_HDEN(K) with K in {1,2,3,4} returns Higher DENsity % dwt filters (tight frame, frame) from the reference. The filterbanks % have 3 channels and unusual non-uniform subsamplig factors [2,2,1]. % % Examples: % --------- % : % wfiltinfo('hden3'); % % : % wfiltinfo('ana:hden4'); % % 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.github.io/doc/wavelets/wfilt_hden.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa a= [2;2;1]; info.istight = 1; switch(K) case 1 % from the paper Example 1. garr = [ 0 0 0 0.353553390593274 0.353553390593274 0.5 0.707106781186548 0 -0.5 0.353553390593274 -0.353553390593274 0 ]; d = [-2,-2,-2]; case 2 % from the paper Example 2. garr = [ 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 ]; d = [-3,-5,-5]; case 3 % from the paper Example 3. garr = [ 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 ]; d = [-6,-4,-4]; 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 ]; d = [-5,-5,-5]; harr = flipud(harr); h=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h=cellfun(@(gEl,dEl) struct('h',gEl,'offset',dEl),h,num2cell(d),... 'UniformOutput',0); 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))); g=cellfun(@(gEl,dEl) struct('h',gEl,'offset',dEl),g,num2cell(d),... 'UniformOutput',0); 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))); g = cellfun(@(gEl,dEl) struct('h',gEl,'offset',dEl),g,num2cell(d),'UniformOutput',0); h = g; ltfat/inst/wavelets/wfilt_spline.m0000664000175000017500000001564213026262304017256 0ustar susnaksusnakfunction [h,g,a,info]=wfilt_spline(m,n) %-*- texinfo -*- %@deftypefn {Function} wfilt_spline %@verbatim % WFILT_SPLINE Biorthogonal 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} % % [h,g,a]=WFILT_SPLINE(m,n) with m+n being even returns biorthogonal % spline wavelet filters. % % Examples: % --------- % : % wfiltinfo('ana:spline4:2'); % % : % wfiltinfo('syn:spline4:2'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_spline.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Original copyright goes to: % Copyright (C) 1994, 1995, 1996, by Universidad de Vigo % Author: Jose Martin Garcia % e-mail: Uvi_Wave@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 if m==1 && n==1 [h,g,a,info]=wfilt_db(1); return; 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 % Ajust the initial filter position if rem(m,2)==1 d = [-numel(h{1})/2, -numel(h{1})/2]; else d = [-numel(h{1})/2+1, -numel(h{1})/2-1]; end g = cellfun(@(gEl,dEl) struct('h',gEl(:),'offset',dEl),g,num2cell(d),... 'UniformOutput',0); h = cellfun(@(hEl,dEl) struct('h',flipud(hEl(:)),'offset',dEl),h,num2cell(d),... 'UniformOutput',0); %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@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 ltfat/inst/wavelets/wfilt_ddenb.m0000664000175000017500000000613413026262304017034 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_ddenb(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_ddenb %@verbatim %WFILT_DDENB Double-Density Dual-Tree DWT filters % % Usage: [h,g,a] = wfilt_ddenb(N); % % [h,g,a]=WFILT_DDENB(N) with N in {1,2} returns filters suitable % for dual-tree double density complex wavelet transform tree A. % % Examples: % --------- % : % wfiltinfo('ddena1'); % % References: % I. Selesnick. The double-density dual-tree DWT. Signal Processing, IEEE % Transactions on, 52(5):1304--1314, May 2004. % % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_ddenb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 1; a = [2;2;2]; switch(N) case 1 % Example 1. from the reference. harr = [ 0.0138231641 0.0003671189 0.0008108446 0.1825175668 0.0048473455 0.0107061875 0.5537956151 0.0129572726 0.0264224754 0.6403205201 -0.0061082309 -0.0424847245 0.2024025378 -0.0656840149 -0.2095602589 -0.1327035751 -0.0968519623 -0.0055184660 -0.0714378446 -0.0211208454 0.6504107366 0.0179754457 0.5492354832 -0.4735663386 0.0085233088 -0.4154148634 0.0427795440 -0.0010031763 0.0377726968 0 ]; d = [-3,-7,-7]; case 2 % Example 2. From the reference. harr = [ 0.0016678785 0.0000019623 0.0000067421 0.0427009907 0.0000502404 0.0001726122 0.2319241351 0.0002359631 0.0007854598 0.5459409911 -0.0003026422 -0.0016861130 0.6090383368 -0.0044343824 -0.0181424716 0.2145936637 -0.0123017187 -0.0350847982 -0.1629587558 -0.0156330903 0.0180629832 -0.1283958243 0.0044955076 0.1356963431 0.0309676536 0.0781684245 0.0980877181 0.0373820215 0.1319270081 -0.1963413775 -0.0038525812 -0.1244353736 -0.3762491967 -0.0053106600 -0.4465930970 0.5674107094 0.0003304362 0.5772994700 -0.2017431422 0.0001955983 -0.1972513705 0.0090245313 -0.0000103221 0.0087730988 0 ]; d = [-4,-12,-12]; otherwise error('%s: No such filters.',upper(mfilename)); end htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h = cellfun(@(hEl,dEl)struct('h',hEl,'offset',dEl),... htmp(1:3),num2cell(d(1:3)),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/wfilt_sym.m0000664000175000017500000003135713026262304016575 0ustar susnaksusnakfunction [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' % orthogonal wavelets or "symlets" with N vanishing moments and % length 2N. % Zeros of the trigonometrical polynomial the filters consist of in the % Z-plane are selected alternatingly inside and outside the unit circle. % % Remark: Filters generated by this routine differ slightly from the % ones in the reference (table 6.3, figure. 6.4) because of the ambiguity % in the algorithm. % % 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.github.io/doc/wavelets/wfilt_sym.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Original copyright goes to: % Copyright (C) 1994, 1995, 1996, by Universidad de Vigo % Author: Jose Martin Garcia % e-mail: Uvi_Wave@tsc.uvigo.es num_coefs = 2*N; a = [2;2]; info.istight = 1; if num_coefs==2 % Haar filters [h,g,a,info]=wfilt_db(1); 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); % Some odd values of N produce flipped filters % Bigger N jut take forever to calculate. if any(N==[7,9]) || ( N>=13 && rem(N,2) == 1) rh = rh(end:-1:1); end g{1} = rh; g{2} = -(-1).^(0:fLen-1).*g{1}(end:-1:1); Lh = numel(rh); d = cellfun(@(gEl) -length(gEl)/2,g); if N>2 % Do a filter alignment according to "center of mass" d(1) = -find(abs(g{1})==max(abs(g{1})),1,'first')+1; d(2) = -find(abs(g{2})==max(abs(g{2})),1,'first')+1; if abs(rem(d(1)-d(2),2))==1 % Shift d(2) just a bit d(2) = d(2) - 1; end end g = cellfun(@(gEl,dEl) struct('h',gEl(:),'offset',dEl),g,num2cell(d),'UniformOutput',0); 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@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)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 ltfat/inst/wavelets/wfilt_oddevena.m0000664000175000017500000000637513026262304017554 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_oddevena(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_oddevena %@verbatim %WFILT_ODDEVENA Kingsbury's symmetric even filters % % Usage: [h,g,a] = wfilt_oddevena(N); % % [h,g,a]=WFILT_ODDEVENA(N) with N in {1} returns Kingsbury's % even filters. % % Examples: % --------- % : % figure(1); % wfiltinfo('ana:oddevena1'); % % figure(2); % wfiltinfo('syn:oddevena1'); % % References: % N. Kingsbury. Complex wavelets for shift invariant analysis and % filtering of signals. Applied and Computational Harmonic Analysis, % 10(3):234 -- 253, 2001. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_oddevena.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 0; a = [2;2]; switch(N) case 1 % Example 1. from the reference. Symmetric near-orthogonal garr = [ 0 0 0 0 0 -0.0004645 0 0.0013349 -0.0058109 0.0022006 0.0166977 -0.0130127 -0.0000641 0.0015360 -0.0834914 0.0869008 0.0919537 0.0833552 0.4807151 -0.4885957 0.4807151 0.4885957 0.0919537 -0.0833552 -0.0834914 -0.0869008 -0.0000641 -0.0015360 0.0166977 0.0130127 -0.0058109 -0.0022006 0 -0.0013349 0 0.0004645 0 0 0 0 ]; % This scaling is not in the reference paper, but it is here to be % consistent garr = garr*sqrt(2); %garr = normalize(garr,'energy'); offset = -10; otherwise error('%s: No such filters.',upper(mfilename)); end %garr = [garr(:,3:4),garr(:,1:2)]; modrange = (-1).^((0:size(garr,1)-1) + offset+1).'; modrange2 = (-1).^((0:size(garr,1)-1) + offset).'; harr = [garr(:,2).*modrange2,... garr(:,1).*modrange,... ]; % In the biorthogonal case, the filters do not get time reversed garr = flipud(garr); htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h = cellfun(@(hEl)struct('h',hEl,'offset',offset),htmp(1:2),... 'UniformOutput',0); gtmp=mat2cell(garr,size(garr,1),ones(1,size(garr,2))); g = cellfun(@(gEl)struct('h',gEl,'offset',offset),gtmp(1:2),... 'UniformOutput',0); ltfat/inst/wavelets/wfilt_dgrid.m0000664000175000017500000000721213026262304017047 0ustar susnaksusnakfunction [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.github.io/doc/wavelets/wfilt_dgrid.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa switch(N) case 1 garr = [ 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 ]; offset = [-4,-4,-6,-6]; case 2 garr = [ -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 ]; offset = [-4,-4,-4,-4]; case 3 garr = [ -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 ]; offset = [-5,-5,-7,-7]; otherwise error('%s: No such Dense Grid Framelet filters.',upper(mfilename)); end; g = mat2cell(garr,size(garr,1),ones(1,size(garr,2))); g = cellfun(@(gEl,ofEl) struct('h',gEl,'offset',ofEl),g,num2cell(offset),... 'UniformOutput',0); h = g; a = [2;2;2;2]; info.istight=1; ltfat/inst/wavelets/fwt.m0000664000175000017500000001571313026262304015356 0ustar susnaksusnakfunction [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. % % FWT(f,w,J) returns discrete wavelet coefficients of the input signal % f using J iterations of the basic wavelet filterbank defined by % w using the fast wavelet transform algorithm (Mallat's algorithm). % The coefficients 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 filterbanks % with any number of the channels. In such case, the transform have a % different name. % % Several formats of the basic filterbank definition w are recognized. % One of them is a text string formed by a concatenation of a function % name with the wfilt_ prefix followed by a list of numerical arguments % delimited by :. For example 'db10' will result in a call to % wfilt_db(10) or 'spline4:4' in call to wfilt_spline(4,4) etc. % All filter defining functions can be listed by running % dir([ltfatbasepath,filesep,'wavelets',filesep,'wfilt_*']); % Please see help of the respective functions and follow references % therein. % % For other recognized formats of w please see FWTINIT. % % [c,info]=FWT(f,w,J) additionally returns struct. info containing % transform parameters. It can be conviniently used for the inverse % transform IFWT e.g. as fhat = iFWT(c,info). It is also required % by the PLOTWAVELETS function. % % If f is row/column vector, the subbands c are stored % in a single row/column in a consecutive order with respect to the % inceasing central frequency. 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 when used. % % 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: % % '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 using 'db8' wavelet % filters.: % % [f,fs] = greasy; % J = 10; % [c,info] = fwt(f,'db8',J); % plotwavelets(c,info,fs,'dynrange',90); % % Frequency bands of the transform with x-axis in a log scale and band % peaks normalized to 1. Only positive frequency band is shown. : % % [g,a] = wfbt2filterbank({'db8',10,'dwt'}); % filterbankfreqz(g,a,20*1024,'linabs','posfreq','plot','inf','flog'); % % % References: % S. Mallat. A wavelet tour of signal processing. Academic Press, San % Diego, CA, 1998. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/fwt.html} %@seealso{ifwt, plotwavelets, wavpack2cell, wavcell2pack, thresh} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,3,'FWT'); complainif_notposint(J,'J'); % 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,w.a,J,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 ltfat/inst/wavelets/wfiltdt_dden.m0000664000175000017500000000327013026262304017220 0ustar susnaksusnakfunction [h,g,a,info] = wfiltdt_dden(N) %-*- texinfo -*- %@deftypefn {Function} wfiltdt_dden %@verbatim %WFILTDT_DDEN Double-Density Dual-Tree DWT filters % % Usage: [h,g,a] = wfiltdt_dden(N); % % [h,g,a]=WFILTDT_DDEN(N) with N in {1,2} returns filters suitable % for dual-tree double density complex wavelet transform. % % Examples: % --------- % : % wfiltdtinfo('dden1'); % % : % wfiltdtinfo('dden2'); % % References: % I. Selesnick. The double-density dual-tree DWT. Signal Processing, IEEE % Transactions on, 52(5):1304--1314, May 2004. % % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfiltdt_dden.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa [h(:,1),g(:,1),a,info] = wfilt_ddena(N); [h(:,2),g(:,2)] = wfilt_ddenb(N); [info.defaultfirst, info.defaultfirstinfo] = fwtinit('symdden2'); [info.defaultleaf, info.defaultleafinfo] = ... deal(info.defaultfirst,info.defaultfirstinfo); ltfat/inst/wavelets/plotwavelets.m0000664000175000017500000001224313026262304017302 0ustar susnaksusnakfunction 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,...) % % PLOTWAVELETS(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. % % PLOTWAVELETS(c,info,fs) does the same plot assuming a sampling rate % fs Hz of the original signal. % % plowavelets(c,info,fs,'dynrange',dynrange) additionally limits the % dynamic range. % % C=PLOTWAVELETS(...) 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. % % PLOTWAVELETS supports optional parameters of TFPLOT. Please see % the help of TFPLOT for an exhaustive list. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/plotwavelets.html} %@seealso{fwt, tfplot, complainif_notenoughargs(nargin,2,'plotwavelets');} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if isempty(c) || ~(iscell(c) || isnumeric(c)) error('%s: c must be non-empty cell or numeric array.',upper(mfilename)); end if ~isstruct(info) || ~isfield(info,'fname') error(['%s: info must be struct obtained as the 2nd return param. ',... 'of the comp. routine.'],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 switch info.fname case {'ufwt','uwfbt','uwpfbt'} % Only one channel signals can be plotted. if(ndims(c)>2) error('%s: Multichannel not supported.',upper(mfilename)); end case {'wfbt','dtwfbreal','dtwfb','wpfbt'} if any(cellfun(@(cEl) size(cEl,2)>1,c)) error('%s: Multichannel input not supported.',upper(mfilename)); end end maxSubLen = 800; draw_ticks = 1; switch info.fname case '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,[])]'; case 'ufwt' subbNo = size(c,2); a = ones(subbNo,1); w = fwtinit(info.wt); filtNo = numel(w.h); J = info.J; case {'wfbt','dtwfbreal','dtwfb'} maxSubLen = max(cellfun(@(cEl) size(cEl,1),c)); a = treeSub(info.wt); subbNo = numel(c); draw_ticks = 0; case 'uwfbt' subbNo = size(c,2); a = ones(subbNo,1); draw_ticks = 0; case 'wpfbt' maxSubLen = max(cellfun(@(cEl) size(cEl,1),c)); aCell = nodesSub(nodeBForder(0,info.wt),info.wt); a = cell2mat(cellfun(@(aEl) aEl(:)',aCell,'UniformOutput',0)); draw_ticks = 0; case 'uwpfbt' subbNo = size(c,2); a = ones(subbNo,1); draw_ticks = 0; otherwise error('%s: Unknown function name %s.',upper(mfilename),info.fname); end % POST optional operations switch info.fname case 'dtwfb' % Do subband equivalent of fftshift [c(1:end/2), c(end/2+1:end)] = deal( c(end/2+1:end), c(1:end/2)); a = [a(end:-1:1);a]; 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 % To avoid printing all the coefficients in the command window when a % semicolon is forgotten if nargout < 1 clear C; end ltfat/inst/wavelets/wfiltinfo.m0000664000175000017500000000765713026262304016567 0ustar susnaksusnakfunction wfiltinfo(w,varargin) %-*- texinfo -*- %@deftypefn {Function} wfiltinfo %@verbatim %WFILTINFO Plots filters info % Usage: wfiltinfo(w); % % Input parameters: % w : Basic wavelet filterbank. % % WFILTINFO(w) plots impulse responses, frequency responses and % approximation of the scaling and of the wavelet function(s) associated % with the wavelet filters defined by w in a single figure. Format of % w is the same as in FWT. % % Optionally it is possible to define scaling of the y axis of the % frequency seponses. Supported are: % % 'db','lin' % dB or linear scale respectivelly. By deault a dB scale is used. % % 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.github.io/doc/wavelets/wfiltinfo.html} %@seealso{wfilt_db} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa definput.flags.freqzscale = {'db','lin'}; [flags]=ltfatarghelper({},definput,varargin); w = fwtinit({'strict',w}); clf; 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 + (0:length(loAna)-1); 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 + (0:length(filtAna)-1); 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 = filterbankfreqz(w.g,w.a,Ls); %[H] = wtfftfreqz(w.g); if flags.do_db plotH = 20*log10(abs(H)); elseif flags.do_lin plotH = abs(H); else error('%s: Unknown parameter',upper(mfilaname)); end xVals = linspace(0,1,numel(H(:,1))); hold on; for ff=1:filtNo plot(xVals,plotH(:,ff),colorAr(ff)); axis tight; end if flags.do_db ylim([-30,max(plotH(:))]) end 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; ltfat/inst/wavelets/fwtlength.m0000664000175000017500000000403413026262304016552 0ustar susnaksusnakfunction L=fwtlength(Ls,w,J,varargin) %-*- texinfo -*- %@deftypefn {Function} fwtlength %@verbatim %FWTLENGTH FWT length from signal % Usage: 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 w and J. % % If the returned length is longer than the signal length, the signal % will be zero-padded by FWT to length L. % % In addition, the function accepts flags defining boundary extension % technique as in FWT. The returned length can be longer than the % signal length only in case of 'per' (periodic extension). % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/fwtlength.html} %@seealso{fwt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notposint(Ls,'Ls','FWTLENGTH'); complainif_notposint(J,'J','FWTLENGTH'); % 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 ltfat/inst/wavelets/wfilt_ddena.m0000664000175000017500000000620713026262304017034 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_ddena(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_ddena %@verbatim %WFILT_DDENA Double-Density Dual-Tree DWT filters % % Usage: [h,g,a] = wfilt_ddena(N); % % [h,g,a]=wfil_ddena(N) with N in {1,2} returns filters suitable % for dual-tree double density complex wavelet transform tree A. % % Examples: % --------- % : % wfiltinfo('ddena1'); % % References: % I. Selesnick. The double-density dual-tree DWT. Signal Processing, IEEE % Transactions on, 52(5):1304--1314, May 2004. % % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_ddena.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 1; a = [2;2;2]; switch(N) case 1 % Example 1. from the reference. harr = [ 0.0691158205 0.0000734237 0.0001621689 0.3596612703 0.0003820788 0.0008438861 0.6657851023 -0.0059866448 -0.0136616968 0.4659189433 -0.0343385512 -0.0781278793 -0.0191014398 -0.0554428419 -0.0840435464 -0.1377522956 0.0018714327 0.2230705831 -0.0087922813 0.1386271745 0.3945086960 0.0194794983 0.3321168878 -0.6566499317 0.0000995795 -0.5661664438 0.2138977202 -0.0002006352 0.1888634841 0 ]; d = [-3,-7,-7]; case 2 % Example 2. From the reference. harr = [ 0.0116751500 0.0000002803 0.0000009631 0.1121045343 0.0000026917 0.0000092482 0.3902035988 -0.0000945824 -0.0003285657 0.6376600221 -0.0009828317 -0.0034113692 0.4515927116 -0.0032260080 -0.0098485834 -0.0177905271 -0.0033984723 0.0011435281 -0.1899509889 0.0053478454 0.0535846285 -0.0363317137 0.0269410607 0.0710003404 0.0511638041 0.0499929334 -0.0732656061 0.0130979774 -0.0076424664 -0.2335672955 -0.0081410874 -0.2115533011 -0.0478802585 -0.0016378610 -0.1367235355 0.5808457358 0.0005650673 0.6180972127 -0.4014544851 0.0000043492 -0.3981725189 0.0631717194 -0.0000014745 0.0614116921 0 ]; d = [-4,-12,-12]; otherwise error('%s: No such filters.',upper(mfilename)); end htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h = cellfun(@(hEl,dEl)struct('h',hEl,'offset',dEl),... htmp(1:3),num2cell(d(1:3)),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/idtwfbreal.m0000664000175000017500000000746713026262304016710 0ustar susnaksusnakfunction f=idtwfbreal(c,par,varargin) %-*- texinfo -*- %@deftypefn {Function} idtwfbreal %@verbatim %IDTWFBREAL Inverse Dual-tree Filterbank for real-valued signals % Usage: f=idtwfbreal(c,info); % f=idtwfbreal(c,dualwt,Ls); % % Input parameters: % c : Input coefficients. % info : Transform params. struct % dualwt : Dual-tree Wavelet Filterbank definition % Ls : Length of the reconstructed signal. % % Output parameters: % f : Reconstructed data. % % f = IDTWFBREAL(c,info) reconstructs real-valued signal f from the % coefficients c using parameters from info struct. both returned by % DTWFBREAL function. % % f = IDTWFBREAL(c,dualwt,Ls) reconstructs real-valued signal f from the % coefficients c using dual-tree filterbank defined by dualwt. Plese % see DTWFBREAL for supported formats. The Ls parameter is mandatory % due to the ambiguity of reconstruction lengths introduced by the % subsampling operation. % Note that the same flag as in the DTWFBREAL function have to be used, % otherwise perfect reconstruction cannot be obtained. Please see help % for DTWFBREAL for description of the flags. % % Examples: % --------- % % A simple example showing perfect reconstruction using IDTWFBREAL: % % f = gspi; % J = 7; % wtdef = {'qshift3',J}; % c = dtwfbreal(f,wtdef); % fhat = idtwfbreal(c,wtdef,length(f)); % % The following should give (almost) zero % norm(f-fhat) % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/idtwfbreal.html} %@seealso{dtwfbreal, dtwfbinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'IDTWFBREAL'); if(~iscell(c)) error('%s: Unrecognized coefficient format.',upper(mfilename)); end if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IDTWFBREAL'); if ~strcmpi(par.fname,'dtwfbreal') error(['%s: Wrong func name in info struct. ',... ' The info parameter was created by %s.'],... upper(mfilename),par.fname); end dtw = dtwfbinit({'dual',par.wt},par.fOrder); Ls = par.Ls; ext = 'per'; L = wfbtlength(Ls,dtw,ext); else complainif_notenoughargs(nargin,3,'IDTWFBREAL'); %% PARSE INPUT definput.keyvals.Ls=[]; definput.keyvals.dim=1; definput.import = {'wfbtcommon'}; [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin); complainif_notposint(Ls,'Ls'); ext = 'per'; % Initialize the wavelet tree structure dtw = dtwfbinit(par,flags.forder); [Lc,L]=wfbtclength(Ls,dtw,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 [nodesBF, rangeLoc, rangeOut] = treeBFranges(dtw,'rev'); outLengths = nodesInLen(nodesBF,L,strcmpi(ext,'per'),dtw); outLengths(end) = L; f = comp_idtwfb(c,dtw.nodes(nodesBF),dtw.dualnodes(nodesBF),outLengths,... rangeLoc,rangeOut,ext,0); f = postpad(f,Ls); ltfat/inst/wavelets/wavpack2cell.m0000664000175000017500000000612313026262304017127 0ustar susnaksusnakfunction [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 columns 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.github.io/doc/wavelets/wavpack2cell.html} %@seealso{wavcell2pack, fwt, wfbt, wpfbt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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); ltfat/inst/wavelets/wfbtinit.m0000664000175000017500000001715213026262304016403 0ustar susnaksusnak function [wt,info] = 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({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','doubleband','quadband','octaband' % Type of the tree to be created. % % WFBTINIT({w,J,flag,'mod',mod}) creates a filterbank tree as before, % but modified according to the value of mod. % Recognized options: % % 'powshiftable' % Changes subsampling factors of the root to 1. This results in redundant % near-shift invariant representation. % % The returned structure wt has the following fields: % % .nodes % Cell-array of structures obtained from FWTINIT. Each element % define a basic wavelet filterbank. % % .children % Indexes of children nodes % % .parents % Indexes of a parent node % % .forder % Frequency ordering of the resultant frequency bands. % % The structure together with functions from the wfbtmanip % subdirectory acts as an abstract data structure tree. % % Regular WFBTINIT 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.github.io/doc/wavelets/wfbtinit.html} %@seealso{wfbtput, wfbtremove} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa % 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; %%%%%%%%%%%%%%%%%%%%%%%%%%%%% info.istight = 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')) if isempty(wtdef.nodes) error('%s: The tree struct is empty.',upper(mfilename)); end 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 info.istight = 1; wt.nodes = {}; for ii=1:numel(nodesArg) % wt.nodes = cellfun(@(nEl) fwtinit(nEl),nodesArg,'UniformOutput',0); [wt.nodes{ii},infotmp] = fwtinit(nodesArg{ii}); if info.istight info.istight = infotmp.istight; end end % 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','doubleband','quadband',... 'octaband','root'}; definput.keyvals.mod = []; definput.keyvals.overcomplete = []; definput.keyvals.J = []; [flags2,kv2,J]=ltfatarghelper({'J'},definput,wtdef(2:end)); complainif_notposint(J,'J'); if do_dual wdef = {'dual',wdef}; end if do_strict wdef = {'strict',wdef}; end do_powshiftable = 0; % Is the first level filterbank different? if ~isempty(kv2.mod) if ischar(kv2.mod) if strcmpi(kv2.mod,'powshiftable') if ~flags2.do_dwt error('%s: powshiftable is only valid with the dwt flag.',... upper(mfilename)); end do_powshiftable = 1; else error('%s: Not recognized value for the mod key.',upper(mfilename)); end else error('%s: Not recognized value for the first key.',upper(mfilename)); end end if ~isempty(kv2.overcomplete) error('%s: TO DO: overcomplete.',upper(mfilename)); end [w, info] = fwtinit(wdef); % Doing one-node tree if flags2.do_root J = 1; end if flags2.do_dwt % 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 elseif flags2.do_doubleband % fill the structure to represent a double band tree for jj=0:J-1 % for ii=0:numel(w.g)^(jj)-1 wt = wfbtput(2*jj,0,w,wt); wt = wfbtput(2*jj+1,0:1,w,wt); % end end elseif flags2.do_quadband % fill the structure to represent a quad band tree for jj=0:J-1 % for ii=0:numel(w.g)^(jj)-1 wt = wfbtput(3*jj,0,w,wt); wt = wfbtput(3*jj+1,0:1,w,wt); wt = wfbtput(3*jj+2,0:3,w,wt); % end end elseif flags2.do_octaband % fill the structure to represent a octa band tree for jj=0:J-1 % for ii=0:numel(w.g)^(jj)-1 wt = wfbtput(4*jj,0,w,wt); wt = wfbtput(4*jj+1,0:1,w,wt); wt = wfbtput(4*jj+2,0:3,w,wt); wt = wfbtput(4*jj+3,0:7,w,wt); % end end end % Do filter shuffling if frequency ordering is required, wt.freqOrder = flags.do_freq; if flags.do_freq wt = nat2freqOrder(wt); end if do_powshiftable % Change subsampling factors of the root to 1 wt.nodes{wt.parents==0}.a(:) = 1; end ltfat/inst/wavelets/wfilt_symorth.m0000664000175000017500000001106713026262304017466 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_symorth(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_symorth %@verbatim %WFILT_SYMORTH Symmetric nearly-orthogonal and orthogonal nearly-symmetric % % Usage: [h,g,a] = wfilt_symorth(N); % % [h,g,a]=WFILT_SYMORTH(N) with Nin {1,2,3} returns orthogonal % near-symmetric (N==1) and symmetric near-orthogonal (N==[2,3]) % wavelet filters from the reference. % % The filters exhibit a coiflet-like behavior i.e. the scaling filter % has vanishing moments too. % % Examples: % --------- % : % wfiltinfo('ana:symorth2'); % % : % wfiltinfo('syn:symorth2'); % % References: % F. Abdelnour and I. W. Selesnick. Symmetric nearly orthogonal and % orthogonal nearly symmetric wavelets. The Arabian Journal for Science % and Engineering, 29(2C):3 -- 16, 2004. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_symorth.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 0; a = [2;2]; offset = []; switch(N) case 1 % Example 3. From the reference. Orthogonal near-symmetric % K=2 wanishing moments A = -sqrt(2)/4+sqrt(30)/16; hlp = [-sqrt(2)/16,... sqrt(2)/16,... A+sqrt(2)/2,... A+sqrt(2)/2,... sqrt(2)/16,... -sqrt(2)/16,... -A,... -A... ].'; harr = [flipud(hlp), (-1).^(1:numel(hlp)).'.*hlp]; garr = harr; info.istight = 1; offset = [-5,-3]; case 2 % Example 2. From the reference. Symmetric near-orthogonal % K=3 wanishing moments hlp = [ -0.0019128844 0.0033707110 0.0092762126 -0.0855138167 0.0851905285 0.6966960301 0.6966960301 0.0851905285 -0.0855138167 0.0092762126 0.0033707110 -0.0019128844 ]; glp = [ 0.0025454063 0.0044852837 0.0037033492 -0.0855138167 0.0851905285 0.6966960301 0.6966960301 0.0851905285 -0.0855138167 0.0037033492 0.0044852837 0.0025454063 ]; harr = [hlp, (-1).^(0:numel(glp)-1).'.*flipud(glp)]; garr = [glp, (-1).^(0:numel(hlp)-1).'.*flipud(hlp)]; offset = [-6,-6]; case 3 % Example 1. from the reference. Symmetric near-orthogonal % K=5 vanishing moments (both low and high pass) % L=8 first zero derivatives of frequency response ar omega=0 hlp = [ 0.0001605988 0.0002633873 -0.0028105671 -0.0022669755 0.0246782363 -0.0061453735 -0.1137025792 0.1226794070 0.6842506470 0.6842506470 0.1226794070 -0.1137025792 -0.0061453735 0.0246782363 -0.0022669755 -0.0028105671 0.0002633873 0.0001605988 ]; glp = [ 0.0002809102 -0.0004607019 -0.0014760379 -0.0016765216 0.0192309116 -0.0001723898 -0.1099707039 0.1091804942 0.6921708203 0.6921708203 0.1091804942 -0.1099707039 -0.0001723898 0.0192309116 -0.0016765216 -0.0014760379 -0.0004607019 0.0002809102 ]; harr = [hlp, (-1).^(1:numel(glp)).'.*glp]; garr = [glp, (-1).^(1:numel(hlp)).'.*hlp]; offset = [-9,-9]; otherwise error('%s: No such filters.',upper(mfilename)); end h=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h=cellfun(@(hEl,offEl) struct('h',hEl(:),'offset',offEl),h,num2cell(offset),'UniformOutput',0); g=mat2cell(garr,size(garr,1),ones(1,size(garr,2))); g=cellfun(@(gEl,offEl) struct('h',gEl(:),'offset',offEl),g,num2cell(offset),'UniformOutput',0); ltfat/inst/wavelets/wfilt_remez.m0000664000175000017500000003450313026262304017103 0ustar susnaksusnakfunction [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 (regularity) at z=-1. % B : Normalized transition bandwidth. % % [h,g,a]=WFILT_REMEZ(L,K,B) calculates a set of wavelet filters. % Regularity, frequency selectivity, and length of the filters can be % controlled by K, B and L parameters respectivelly. % % The filter desigh algorithm is based on a Remez algorithm and a % factorization of 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.github.io/doc/wavelets/wfilt_remez.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Original copyright goes to: % Copyright (C) 1994, 1995, 1996, by Universidad de Vigo % Author: Jose Martin Garcia % e-mail: Uvi_Wave@tsc.uvigo.es if(nargin<3) error('%s: Too few input parameters.',upper(mfilename)); end complainif_notposint(L,'L',mfilename); complainif_notposint(L,'K',mfilename); if B>0.2 error(['%s: Bandwidth of the transition band should not be',... ' bigger than 0.2.'],upper(mfilename)); end poly=remezwav(L,K,B); rh=fc_cceps(poly); g{1} = flipud(rh(:)); g{2} = -(-1).^(1:length(rh)).'.*flipud(g{1}); % Default offset d = [0,0]; % Do a filter alignment according to "center of gravity" d(1) = -floor(sum((1:L)'.*abs(g{1}).^2)/sum(abs(g{1}).^2)); d(2) = -floor(sum((1:L)'.*abs(g{2}).^2)/sum(abs(g{2}).^2)); if rem(d(1)-d(2),2)==1 % Shift d(2) just a bit d(2) = d(2) + 1; end g = cellfun(@(gEl,dEl) struct('h',gEl,'offset',dEl),g,num2cell(d),... 'UniformOutput',0); 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@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@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@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@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; ltfat/inst/wavelets/wfilt_symdden.m0000664000175000017500000000624713026262304017430 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_symdden(K) %-*- texinfo -*- %@deftypefn {Function} wfilt_symdden %@verbatim %WFILT_SYMDDEN Symmetric Double-Density DWT filters (tight frame) % Usage: [h,g,a] = wfilt_symdden(K); % % [h,g,a]=WFILT_SYMDDEN(K) with K in {1,2} returns oversampled % symmetric double-density DWT filters. % The redundancy of the basic filterbank is equal to 1.5. % % Examples: % --------- % : % wfiltinfo('symdden1'); % % : % wfiltinfo('symdden2'); % % References: % I. Selesnick and A. Abdelnour. Symmetric wavelet tight frames with two % generators. Appl. Comput. Harmon. Anal., 17(2):211--225, 2004. % % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_symdden.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa switch(K) case 1 garr = [ 0.00069616789827 0.00120643067872 -0.00020086099895 -0.02692519074183 -0.04666026144290 0.00776855801988 -0.04145457368921 -0.05765656504458 0.01432190717031 0.19056483888762 -0.21828637525088 -0.14630790303599 0.58422553883170 0.69498947938197 -0.24917440947758 0.58422553883170 -0.24917440947758 0.69498947938197 0.19056483888762 -0.14630790303599 -0.21828637525088 -0.04145457368921 0.01432190717031 -0.05765656504458 -0.02692519074183 0.00776855801988 -0.04666026144290 0.00069616789827 -0.00020086099895 0.00120643067872 ]; offset = [-5,-5,-5]; case 2 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 ]; offset = [-5,-5,-5]; otherwise error('%s: No such Double Density DWT filter',upper(mfilename)); end; g=mat2cell(garr,size(garr,1),ones(1,size(garr,2))); g = cellfun(@(gEl,ofEl) struct('h',gEl(:),'offset',ofEl),... g,num2cell(offset),'UniformOutput',0); h = g; a= [2;2;2]; info.istight=1; ltfat/inst/wavelets/Contents.m0000664000175000017500000001474413026262304016356 0ustar susnaksusnak% LTFAT - Wavelets % % Zdenek Prusa, 2013 - 2016. % % 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 coefficient subbands % % Advanced analysis/synthesis % WFBT - Transform using general Wavelet Filter Bank Tree % IWFBT - Inverse transform using general Wavelet Filter Bank Tree % UWFBT - Undecimated transform using general Wavelet Filter Bank Tree % IUWFBT - Inverse Undecimated transform using general Wavelet Filter Bank Tree % WPFBT - Wavelet Packet Transform using general Wavelet Filter Bank Tree % IWPFBT - Inverse Wavelet Packet Transform using general Wavelet Filter Bank Tree % UWPFBT - Undecimated Wavelet Packet Transform using general Wavelet Filter Bank Tree % IUWPFBT - Inverse Undecimated Wavelet Packet Transform using general Wavelet Filter Bank Tree % WPBEST - Best Tree selection % WFBTLENGTH - Length of Wavelet filter bank system to expand a signal % WFBTCLENGTH - Lengths of Wavelet filter bank coefficient subbands % WPFBTCLENGTH - Lengths of Wavelet Packet transform coefficient subbands % % Dual-tree complex wavelet transform % DTWFB - Dual-Tree Wavelet Filter Bank % IDTWFB - Inverse Dual-Tree Wavelet Filter Bank % DTWFBREAL - Dual-Tree Wavelet Filter Bank for real-valued signals % IDTWFBREAL - Inverse Dual-Tree Wavelet Filter Bank for real-valued signals % % Wavelet Filterbank trees manipulation % WFBTINIT - Wavelet Filter Bank tree structure initialization % DTWFBINIT - Dual-Tree wavelet filter bank structure initialization % WFBTPUT - Puts node (basic filter bank) to the specific tree coordinates % WFBTREMOVE - Removes node (basic filter bank) from the specific tree coordinates % WFBT2FILTERBANK - WFBT or FWT non-iterated filter bank using the multi-rate identity % WPFBT2FILTERBANK - WPFBT non-iterated filter bank using the multi-rate identity % DTWFB2FILTERBANK - DTWFB or DTWFBREAL non-iterated filter bank % FWTINIT - Basic Wavelet Filters structure initialization % % Frame properties of wavelet filter banks: % WFBTBOUNDS - Frame bounds of WFBT and FWT (or UWFBT and UFWT) % WPFBTBOUNDS - Frame bounds of WPFBT or UWPFBT % DTWFBBOUNDS - Frame bounds of DTWFB % % Plots % PLOTWAVELETS - Plot wavelet coefficients % WFILTINFO - Plot wavelet filters impulse and frequency responses and approximation of scaling and wavelet functions % WFILTDTINFO - Plot the same as WFILTINFO but for dual-tree wavelet transform % % Auxilary % WAVFUN - Approximate of the continuous scaling and wavelet functions % WAVCELL2PACK - Changes wavelet coefficient storing format % WAVPACK2CELL - Changes wavelet coefficient storing format back % % Wavelet Filters defined in the time-domain % WFILT_ALGMBAND - An ALGebraic construction of orthonormal M-BAND wavelets with perfect reconstruction % WFILT_CMBAND - M-Band cosine modulated wavelet filters % WFILT_COIF - Coiflets % WFILT_DB - DauBechies orthogonal filters (ortonormal base) % WFILT_DDEN - Double-DENsity dwt filters (tight frame) % WFILT_DGRID - Dense GRID framelets (tight frame, symmetric) % WFILT_HDEN - Higher DENsity dwt filters (tight frame, frame) % WFILT_LEMARIE - Battle and Lemarie quadrature filters % WFILT_MATLABWRAPPER - Wrapper of the wfilters function from the Matlab Wavelet Toolbox % WFILT_MBAND - M-band filters % 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 % WFILT_SYMDDEN - Symmetric Double-DENsity dwt filters (tight frame) % WFILT_SYMORTH - Symmetric nearly-orthogonal and orthogonal nearly-symmetric wav. filters % WFILT_SYMTIGHT - Symmetric nearly shift-invariant tight frame wavelets % WFILT_QSHIFTA - First tree filters from WFILTDT_QSHIFT % WFILT_QSHIFTB - Second tree filters from WFILTDT_QSHIFT % WFILT_ODDEVENA - First tree filters from WFILTDT_ODDEVEN % WFILT_ODDEVENB - Second tree filters from WFILTDT_ODDEVEN % WFILT_OPTSYMA - First tree filters from WFILTDT_OPTSYM % WFILT_OPTSYMB - Second tree filters from WFILTDT_OPTSYM % WFILT_DDENA - First tree filters from WFILTDT_DDEN % WFILT_DDENB - Second tree filters from WFILTDT_DDEN % % Dual-Tree Filters % WFILTDT_QSHIFT - Kingsbury's quarter-shift filters % WFILTDT_OPTSYM - Optimizatized Symmetric Self-Hilbertian Filters % WFILTDT_ODDEVEN - Kingsbury's symmetric odd and even biorthogonal filters % WFILTDT_DDEN - Double-density dual-tree filters % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/wavelets/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/wavelets/wfilt_optsyma.m0000664000175000017500000000625313026262304017456 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_optsyma(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_optsyma %@verbatim %WFILT_OPTSYMA Optimizatized Symmetric Self-Hilbertian Filters % % Usage: [h,g,a] = wfilt_optsyma(N); % % [h,g,a]=wfiltdt_optsyma(N) with N in {1,2,3} returns filters % suitable with optimized symmetry suitable for for dual-tree complex % wavelet transform tree A. % % Examples: % --------- % : % wfiltinfo('optsyma3'); % % References: % B. Dumitrescu, I. Bayram, and I. W. Selesnick. Optimization of % symmetric self-hilbertian filters for the dual-tree complex wavelet % transform. IEEE Signal Process. Lett., 15:146--149, 2008. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_optsyma.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 1; a = [2;2]; switch(N) case 1 hlp = [ -0.0023380687 0.0327804569 -0.0025090221 -0.1187657989 0.2327030100 0.7845762950 0.5558782330 0.0139812814 -0.0766273710 -0.0054654533 0 0 ]; case 2 % hlp = [ 0.0001598067 0.0000007274 0.0235678740 0.0015148138 -0.0931304005 0.2161894746 0.7761070855 0.5778162235 0.0004024156 -0.0884144581 0 0 0 0 ]; case 3 hlp = [ 0.0017293259 -0.0010305604 -0.0128374477 0.0018813576 0.0359457035 -0.0395271550 -0.1048144141 0.2663807401 0.7636351894 0.5651724402 0.0101286691 -0.1081211791 0.0133197551 0.0223511379 0 0 0 0 ]; otherwise error('%s: No such filters.',upper(mfilename)); end % numel(hlp) must be even offset = -(floor(numel(hlp)/2)); range = (0:numel(hlp)-1) + offset; % Create the filters according to the reference paper. % % REMARK: The phase of the alternating +1 and -1 is crucial here. % harr = [... hlp,... (-1).^(range).'.*flipud(hlp),... %flipud(hlp),... %(-1).^(range).'.*hlp,... ]; htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h = cellfun(@(hEl)struct('h',hEl,'offset',offset),htmp(1:2),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/wfilt_mband.m0000664000175000017500000000564313026262304017045 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_mband(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_mband %@verbatim %WFILT_MBAND Generates 4-band coder % Usage: [h,g,a] = wfilt_mband(N); % % [h,g,a]=WFILT_MBAND(1) returns linear-phase 4-band filters % from the reference. % % The filters are not actually proper wavelet filters, because the % scaling filter is not regular, therefore it is not stable under % iterations (does not converge to a scaling function). % % % 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.github.io/doc/wavelets/wfilt_mband.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa 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))); g=cellfun(@(gEl) struct('h',gEl,'offset',-numel(gEl)/2),g,'UniformOutput',0); h = g; info.istight = 1; ltfat/inst/wavelets/wpfbtbounds.m0000664000175000017500000000653413026262304017114 0ustar susnaksusnakfunction [AF,BF]=wpfbtbounds(wt,varargin) %-*- texinfo -*- %@deftypefn {Function} wpfbtbounds %@verbatim %WPFBTBOUNDS Frame bounds of WPFBT % Usage: fcond=wpfbtbounds(wt,L); % [A,B]=wpfbtbounds(wt,L); % [...]=wpfbtbounds(wt); % % WPFBTBOUNDS(wt,L) calculates the ratio B/A of the frame bounds % of the wavelet packet filterbank specified by wt for a system of length % L. The ratio is a measure of the stability of the system. % % WPFBTBOUNDS(wt) does the same, except L is chosen to be the next % compatible length bigger than the longest filter from the identical % filterbank. % % [A,B]=WPFBTBOUNDS(...) returns the lower and upper frame bounds % explicitly. % % See WFBT for explanation of parameter wt. % % Additionally, the function accepts the following flags: % % 'intsqrt'(default),'intnoscale', 'intscale' % The filters in the filterbank tree are scaled to reflect the % behavior of WPFBT and IWPFBT with the same flags. % % 'scaling_notset'(default),'noscale','scale','sqrt' % Support for scaling flags as described in UWPFBT. By default, % the bounds are caltulated for WPFBT, passing any of the non-default % flags results in bounds for UWPFBT. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wpfbtbounds.html} %@seealso{wpfbt, filterbankbounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,1,'WPFBTBOUNDS'); definput.keyvals.L = []; definput.flags.interscaling = {'intsqrt', 'intscale', 'intnoscale'}; definput.import = {'uwfbtcommon'}; definput.importdefaults = {'scaling_notset'}; [flags,~,L]=ltfatarghelper({'L'},definput,varargin); wt = wfbtinit({'strict',wt},'nat'); if ~isempty(L) && flags.do_scaling_notset if L~=wfbtlength(L,wt) error(['%s: Specified length L is incompatible with the length of ' ... 'the time shifts.'],upper(mfilename)); end; end for ii=1:numel(wt.nodes) a = wt.nodes{ii}.a; assert(all(a==a(1)),sprintf(['%s: One of the basic wavelet ',... 'filterbanks is not uniform.'],... upper(mfilename))); end % Do the equivalent filterbank using multirate identity property [gmultid,amultid] = wpfbt2filterbank(wt,flags.interscaling,flags.scaling); if isempty(L) L = wfbtlength(max(cellfun(@(gEl) numel(gEl.h),gmultid)),wt); end % Do the equivalent uniform filterbank if any(amultid~=amultid(1)) [gu,au] = nonu2ufilterbank(gmultid,amultid); else [gu,au] = deal(gmultid,amultid); end if nargout<2 AF = filterbankbounds(gu,au,L); elseif nargout == 2 [AF, BF] = filterbankbounds(gu,au,L); end ltfat/inst/wavelets/wfilt_qshifta.m0000664000175000017500000001531013026262304017413 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_qshifta(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_qshifta %@verbatim %WFILT_QSHIFTA Improved Orthogonality and Symmetry properties % % Usage: [h,g,a] = wfilt_qshifta(N); % % [h,g,a]=wfilt_qshift(N) with N in {1,2,3,4,5,6,7} returns % Kingsbury's Q-shift wavelet filters for tree A. % % Examples: % --------- % : % figure(1); % wfiltinfo('qshifta3'); % % References: % N. G. Kingsbury. A dual-tree complex wavelet transform with improved % orthogonality and symmetry properties. In ICIP, pages 375--378, 2000. % % N. Kingsbury. Design of q-shift complex wavelets for image processing % using frequency domain energy minimization. In Image Processing, 2003. % ICIP 2003. Proceedings. 2003 International Conference on, volume 1, % pages I--1013--16 vol.1, Sept 2003. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_qshifta.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa info.istight = 1; a = [2;2]; switch(N) case 1 % Example 1. from the reference 1. Symmetric near-orthogonal % More precise values (more decimal places) were taken from % the Python DTCWT package hlp = [ 0.0351638365714947 % z^4 0 -0.0883294244510729 % z^2 0.233890320607236 % z^1 0.760272369066126 % z^0 <-- origin 0.587518297723561 % z^-1 0 -0.114301837144249 % z^-3 0 0 ]; case 2 % hlp = [ 0.0511304052838317 -0.0139753702468888 -0.109836051665971 0.263839561058938 0.766628467793037 0.563655710127052 0.000873622695217097 -0.100231219507476 -0.00168968127252815 -0.00618188189211644 ]; case 3 % Example 2. From the reference 1. hlp = [ 0.00325314276365318 -0.00388321199915849 0.0346603468448535 -0.0388728012688278 -0.117203887699115 0.275295384668882 0.756145643892523 % <-- origin 0.568810420712123 0.0118660920337970 -0.106711804686665 0.0238253847949203 0.0170252238815540 -0.00543947593727412 -0.00455689562847549 ]; case 4 % hlp = [ -0.00476161193845591 -0.000446022789262285 -7.14419732796501e-05 0.0349146123068422 -0.0372738957998980 -0.115911457427441 0.276368643133032 0.756393765199037 0.567134484100133 0.0146374059644734 -0.112558884257522 0.0222892632669227 0.0184986827241562 -0.00720267787825835 -0.000227652205897772 0.00243034994514868 ]; case 5 % Example 3. From the reference 1. hlp = [ -0.00228412744027053 % z^8 0.00120989416307344 % z^7 -0.0118347945154308 % z^6 0.00128345699934440 % z^5 0.0443652216066170 % z^4 -0.0532761088030473 % z^3 -0.113305886362143 % z^2 0.280902863222187 % z^1 0.752816038087856 % z^0 <-- origin 0.565808067396459 % z^-1 0.0245501524336666 % z^-2 -0.120188544710795 % z^-3 0.0181564939455465 % z^-4 0.0315263771220847 % z^-5 -0.00662879461243006 % z^-6 -0.00257617430660079 % z^-7 0.00127755865380700 % z^-8 0.00241186945666628 % z^-9 ]; case 6 % From reference 2 % Generated using software by Prof. Nick Kingsbury % http://sigproc.eng.cam.ac.uk/foswiki/pub/Main/NGK/qshiftgen.zip % hlp = qshiftgen([26,1/3,1,1,1]); hlp = hlp/norm(hlp); hlp = [9.69366641745754e-05;3.27432154422329e-05;... -0.000372508343063683;0.000265822010615719;0.00420106192587724;... -0.000851685012123638;-0.0194099330331787;0.0147647107515980;... 0.0510823932256706;-0.0665925933116249;-0.111697066192884;... 0.290378669551088;0.744691179589718;0.565900493333378;... 0.0350864022239272;-0.130600567220340;0.0106673205278386;... 0.0450881734744377;-0.0116452911371123;-0.0119726865351617;... 0.00464728269258923;0.00156428519208473;-0.000193257944314871;... -0.000997377567082884;-4.77392249288136e-05;0.000126793092000602]; case 7 % hlp = qshiftgen([38,1/3,1,1,1]); hlp = hlp/norm(hlp); hlp = [-5.60092763439975e-05;5.48406024854987e-05;... 9.19038839527110e-05;-8.70402717115631e-05;... -0.000220539629671714;0.000281927965110883;... 0.000785261918054103;-0.000284818785208508;... -0.00347903355232634;0.00106170047948173;0.0112918523131508;... -0.00661418560030456;-0.0275662474083655;0.0256353066092428;... 0.0558968886331913;-0.0797279144129786;-0.109398280267440;... 0.299471557624693;0.735969669961052;0.565697237934440;... 0.0456103326499340;-0.139358668718518;0.00372525621820399;... 0.0578449676250133;-0.0102649107519070;-0.0227204202705973;... 0.00707541881254841;0.00739220672191233;-0.00294716840272524;... -0.00194108140290843;0.000711544068828577;0.000568969033823645;... -0.000141696506233205;-0.000156935421570824;... -9.35020254608262e-07;-2.40218618976427e-05;... 2.34727799564078e-05;1.31525730967674e-05]; otherwise error('%s: No such filters.',upper(mfilename)); end % numel(hlp) must be even offset = -(numel(hlp)/2); range = (0:numel(hlp)-1) + offset; % Create the filters according to the reference paper. % % REMARK: The phase of the alternating +1 and -1 is crucial here. % harr = [... hlp,... (-1).^(range).'.*flipud(hlp),... % flipud(hlp),... % (-1).^(range).'.*hlp,... ]; htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h(1:2,1) = cellfun(@(hEl)struct('h',hEl,'offset',offset),htmp(1:2),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/wfbtclength.m0000664000175000017500000000351713026262304017064 0ustar susnaksusnakfunction [Lc,L]=wfbtclength(Ls,wt,varargin) %-*- texinfo -*- %@deftypefn {Function} wfbtclength %@verbatim %WFBTCLENGTH WFBT subband lengths from a signal length % Usage: Lc=wfbtclength(Ls,wt); % [Lc,L]=wfbtclength(...); % % Lc=WFBTCLENGTH(Ls,wt) returns the lengths of coefficient subbands % obtained from WFBT for a signal of length Ls. Please see the help % on WFBT for an explanation of the parameters wt. % % [Lc,L]=WFBTCLENGTH(...) additionally 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.github.io/doc/wavelets/wfbtclength.html} %@seealso{wfbt, wfbtlength} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notposint(Ls,'Ls','WFBTCLENGTH'); 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 ltfat/inst/wavelets/wfilt_optsymb.m0000664000175000017500000000406213026262304017453 0ustar susnaksusnakfunction [h,g,a,info] = wfilt_optsymb(N) %-*- texinfo -*- %@deftypefn {Function} wfilt_optsymb %@verbatim %WFILT_OPTSYMB Optimizatized Symmetric Self-Hilbertian Filters % % Usage: [h,g,a] = wfilt_optsymb(N); % % [h,g,a]=wfiltdt_optsymb(N) with N in {1,2,3} returns filters % suitable with optimized symmetry suitable for for dual-tree complex % wavelet transform tree B. % % Examples: % --------- % : % wfiltinfo('optsymb3'); % % References: % B. Dumitrescu, I. Bayram, and I. W. Selesnick. Optimization of % symmetric self-hilbertian filters for the dual-tree complex wavelet % transform. IEEE Signal Process. Lett., 15:146--149, 2008. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfilt_optsymb.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa [ha,~,a,info] = wfilt_optsyma(N); hlp = ha{1}.h; offset = -(numel(hlp)/2); range = (0:numel(hlp)-1) + offset; % Create the filters according to the reference paper. % % REMARK: The phase of the alternating +1 and -1 is crucial here. % harr = [... flipud(hlp),... (-1).^(range).'.*hlp,... ]; htmp=mat2cell(harr,size(harr,1),ones(1,size(harr,2))); h(1:2,1) = cellfun(@(hEl)struct('h',hEl,'offset',offset),htmp(1:2),... 'UniformOutput',0); g = h; ltfat/inst/wavelets/fwtclength.m0000664000175000017500000000525513026262304016723 0ustar susnaksusnakfunction [Lc,L]=fwtclength(Ls,w,J,varargin) %-*- texinfo -*- %@deftypefn {Function} fwtclength %@verbatim %FWTCLENGTH FWT subbands lengths from a signal length % Usage: Lc=fwtclength(Ls,w,J); % [Lc,L]=fwtclength(...); % % Lc=FWTCLENGTH(Ls,w,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 w and J. % % [Lc,L]=FWTCLENGTH(...) additianally 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.github.io/doc/wavelets/fwtclength.html} %@seealso{fwt, fwtlength} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notposint(Ls,'Ls','FWTCLENGTH'); complainif_notposint(J,'J','FWTCLENGTH'); 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; ltfat/inst/wavelets/wfiltdt_oddeven.m0000664000175000017500000000344413026262304017735 0ustar susnaksusnakfunction [h,g,a,info] = wfiltdt_oddeven(N) %-*- texinfo -*- %@deftypefn {Function} wfiltdt_oddeven %@verbatim %WFILTDT_ODDEVEN Kingsbury's symmetric odd and even filters % % Usage: [h,g,a] = wfiltdt_oddeven(N); % % [h,g,a]=wfilt_oddeven(N) with N in {1} returns the original odd % and even symmetric filters suitable for dual-tree complex wavelet % transform. The filters in individual trees are biorthogonal. % % Examples: % --------- % : % wfiltdtinfo('ana:oddeven1'); % % References: % N. Kingsbury. Complex wavelets for shift invariant analysis and % filtering of signals. Applied and Computational Harmonic Analysis, % 10(3):234 -- 253, 2001. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfiltdt_oddeven.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa [h(:,1),g(:,1),a,info] = wfilt_oddevena(N); [h(:,2),g(:,2)] = wfilt_oddevenb(N); [info.defaultfirst, info.defaultfirstinfo] = fwtinit('oddevenb1'); [info.defaultleaf, info.defaultleafinfo] = ... deal(info.defaultfirst,info.defaultfirstinfo); ltfat/inst/wavelets/wfbtremove.m0000664000175000017500000000734513026262304016740 0ustar susnaksusnakfunction wt = wfbtremove(d,kk,wt,varargin) %-*- texinfo -*- %@deftypefn {Function} wfbtremove %@verbatim %WFBTREMOVE Remove node(s) 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 (it is not a leaf node). % % WFBTREMOVE(d,k,wt,'force') does the same, but any childern of the % node are removed too. % % Examples: % --------- % % The following example shows magnitude frequency responses of filterbank % tree before and after prunning.: % % % Create a full filterbank tree usinf 'db10' basic filterbank. % wt1 = wfbtinit({'db10',4,'full'}); % % Remove a subtree starting by root's high-pass filter. Force flag % % is used because we are removing a non-leaf node. % wt2 = wfbtremove(1,1,wt1,'force'); % % % Create identical filterbanks % [g1,a1] = wfbt2filterbank(wt1,'freq'); % [g2,a2] = wfbt2filterbank(wt2,'freq'); % % % Plot the frequency responses % subplot(2,1,1); % filterbankfreqz(g1,a1,1024,'plot','posfreq','linabs'); % subplot(2,1,2); % filterbankfreqz(g2,a2,1024,'plot','posfreq','linabs'); % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtremove.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,3,'WFBTREMOVE'); definput.flags.force = {'noforce','force'}; flags=ltfatarghelper({},definput,varargin); if isempty(wt.nodes) error('%s: Tree is empty.',mfilename); end for k=kk [nodeNo,nodeChildIdx] = depthIndex2NodeNo(d,k,wt); if(nodeNo==0) % removing root rootNo = find(wt.parents==0); % check for any children of the root if any(wt.children{rootNo}~=0) && ~flags.do_force error(['%s: Deleting root node. To delete the whole tree ',... 'use FORCE option.'],mfilename,d,k); else wt = nodeSubtreeDelete(rootNo,wt); continue; 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 any(wt.children{nodeToDelete}~=0) && ~flags.do_force error(['%s: Deleting a non-leaf node. To delete whole subtree use ',... 'FORCE option.'],mfilename); else wt = nodeSubtreeDelete(nodeToDelete,wt); end end ltfat/inst/wavelets/wfbtlength.m0000664000175000017500000000353713026262304016723 0ustar susnaksusnakfunction L=wfbtlength(Ls,wt,varargin); %-*- texinfo -*- %@deftypefn {Function} wfbtlength %@verbatim %WFBTLENGTH WFBT length from signal % Usage: 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. % % In addition, the function accepts flags defining boundary extension % technique as in WFBT. The returned length can be longer than the % signal length only in case of 'per' (periodic extension). % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtlength.html} %@seealso{wfbt, fwt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notposint(Ls,'Ls','WFBTLENGTH'); definput.import = {'fwt'}; [flags,kv]=ltfatarghelper({},definput,varargin); % Initialize the wavelet filters structure if ~isstruct(wt) wt = wfbtinit(wt); end if(flags.do_per) a = treeSub(wt); L = filterbanklength(Ls,a); else L = Ls; end ltfat/inst/wavelets/uwfbt.m0000664000175000017500000000772613026262304015712 0ustar susnaksusnakfunction [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. % % UWFBT(f,wt) computes redundant time (or shift) invariant % representation 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 nodes of the tree. % % [c,info]=UWFBT(f,wt) additionally 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. % % Filter scaling % -------------- % % When compared to WFBT, the subbands produced by UWFBT are % gradually more and more redundant with increasing depth in the tree. % This results in energy grow of the coefficients. There are 3 flags % defining filter scaling: % % 'sqrt' % Each filter is scaled by 1/sqrt(a), there a is the hop % factor associated with it. If the original filterbank is % orthonormal, the overall undecimated transform is a tight % frame. % This is the default. % % 'noscale' % Uses filters without scaling. % % 'scale' % Each filter is scaled by 1/a. % % If 'noscale' is used, 'scale' has to be used in IUWFBT (and vice % versa) in order to obtain a perfect reconstruction. % % 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.github.io/doc/wavelets/uwfbt.html} %@seealso{iuwfbt, wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'UWFBT'); definput.import = {'wfbtcommon','uwfbtcommon'}; 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 [nodesBF, rangeLoc, rangeOut] = treeBFranges(wt); nodesUps = nodesFiltUps(nodesBF,wt); %% ----- step 3 : Run computation c = comp_uwfbt(f,wt.nodes(nodesBF),nodesUps,rangeLoc,rangeOut,flags.scaling); %% ----- Optional : Fill the info struct. ----- if nargout>1 info.fname = 'uwfbt'; info.wt = wt; info.fOrder = flags.forder; info.isPacked = 0; info.scaling = flags.scaling; end ltfat/inst/wavelets/dtwfb2filterbank.m0000664000175000017500000001234413026262304020005 0ustar susnaksusnakfunction [g,a,info] = dtwfb2filterbank( dualwt, varargin) %-*- texinfo -*- %@deftypefn {Function} dtwfb2filterbank %@verbatim %DTWFB2FILTERBANK DTWFB equivalent non-iterated filterbank % Usage: [g,a] = dtwfb2filterbank(dualwt) % [g,a,info] = dtwfb2filterbank(...) % % Input parameters: % dualwt : Dual-tree wavelet filterbank specification. % % Output parameters: % g : Cell array of filters. % a : Downsampling rate for each channel. % info : Additional information. % % [g,a] = DTWFB2FILTERBANK(dualwt) constructs a set of filters g and % subsampling factors a of a non-iterated filterbank, which is % equivalent to the dual-tree wavelet filterbank defined by dualwt. % The returned parameters can be used directly in FILTERBANK and other % routines. The format of dualwt is the same as in DTWFB and % DTWFBREAL. % % The function internally calls DTWFBINIT and passes dualwt and all % additional parameters to it. % % [g,a,info] = DTWFB2FILTERBANK(...) additionally outputs a info* % struct containing equivalent filterbanks of individual real-valued % trees as fields info.g1 and info.g2. % % Additional parameters: % ---------------------- % % 'real' % By default, the function returns a filtebank equivalent to DTWFB. % The filters can be restricted to cover only the positive frequencies % and to be equivivalent to DTWFBREAL by passing a 'real' flag. % % 'freq'(default),'nat' % The filters are ordered to produce subbands in the same order as % DTWFB or DTWFBREAL with the same flag. % % Examples: % --------- % % The following two examples create a multirate identity filterbank % using a duel-tree of depth 3: % % [g,a] = dtwfb2filterbank({'qshift3',3},'real'); % filterbankfreqz(g,a,1024,'plot','linabs'); % % In the second example, the filterbank is identical to the full % wavelet tree: % % [g,a] = dtwfb2filterbank({'qshift3',3,'full'},'real'); % filterbankfreqz(g,a,1024,'plot','linabs'); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/dtwfb2filterbank.html} %@seealso{dtwfbinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'DTWFB2FILTERBANK'); % Search for the 'real' flag do_real = ~isempty(varargin(strcmp('real',varargin))); if do_real %Remove the 'real' flag from varargin varargin(strcmp('real',varargin)) = []; end if ~isempty(varargin(strcmp('complex',varargin))) %Remove the 'complex' flag from varargin %It is not used elsewhere anyway varargin(strcmp('complex',varargin)) = []; end % Initialize the dual-tree dtw = dtwfbinit({'strict',dualwt},varargin{:}); % Determine relation between the tree nodes [wtPath, rangeLoc, rangeOut] = treeBFranges(dtw); slice = ~cellfun(@isempty,rangeOut); % Limit to nodes with unconnected outputs wtPath = wtPath(slice); rangeLoc = rangeLoc(slice); rangeOut = rangeOut(slice); % Multirate identity filters of the first tree [g1,a] = nodesMultid(wtPath,rangeLoc,rangeOut,dtw); % Multirate identity filters of the second tree dtw.nodes = dtw.dualnodes; g2 = nodesMultid(wtPath,rangeLoc,rangeOut,dtw); if nargin>2 % Return the filterbanks before doing the alignment info.g1 = cellfun(@(gEl) setfield(gEl,'h',gEl.h/2),g1,'UniformOutput',0); info.g2 = cellfun(@(gEl) setfield(gEl,'h',gEl.h/2),g2,'UniformOutput',0); end % Align filter offsets so they can be summed for ii = 1:numel(g1) % Sanity checks assert(g1{ii}.offset<=0,sprintf('%s: Invalid wavelet filters.',upper(mfilename))); assert(g2{ii}.offset<=0,sprintf('%s: Invalid wavelet filters.',upper(mfilename))); % Insert zeros and update offsets offdiff = g1{ii}.offset-g2{ii}.offset; if offdiff>0 g1{ii}.offset = g1{ii}.offset - offdiff; g1{ii}.h = [zeros(offdiff,1);g1{ii}.h(:)]; elseif offdiff<0 g2{ii}.offset = g2{ii}.offset + offdiff; g2{ii}.h = [zeros(-offdiff,1);g2{ii}.h(:)]; end % Pad with zeros to a common length lendiff = numel(g1{ii}.h) - numel(g2{ii}.h); if lendiff~=0 maxLen = max(numel(g1{ii}.h),numel(g2{ii}.h)); g1{ii}.h = postpad(g1{ii}.h,maxLen); g2{ii}.h = postpad(g2{ii}.h,maxLen); end end % Filters covering the positive frequencies g = cellfun(@(gEl,g2El) setfield(gEl,'h',(gEl.h+1i*g2El.h)/2),g1,g2,'UniformOutput',0); % Mirror the filters when negative frequency filters are required too if ~do_real gneg = cellfun(@(gEl,g2El) setfield(gEl,'h',(gEl.h-1i*g2El.h)/2),g1,g2,'UniformOutput',0); g = [g;gneg(end:-1:1)]; a = [a;a(end:-1:1)]; end ltfat/inst/wavelets/waveletsinit.m0000664000175000017500000000164713026262304017275 0ustar susnaksusnakstatus = 1; %-*- texinfo -*- %@deftypefn {Function} waveletsinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/waveletsinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/wavelets/iuwpfbt.m0000664000175000017500000001163213026262304016232 0ustar susnaksusnakfunction 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 L xM matrix. % info,wt : Transform parameters struct/Wavelet tree definition. % % Output parameters: % f : Reconstructed data. % % f = IUWPFBT(c,info) reconstructs signal f from the wavelet packet % coefficients c using parameters from info struct. both returned by % the UWPFBT function. % % f = IUWPFBT(c,wt) reconstructs signal f from the wavelet packet % coefficients c using the undecimated wavelet filterbank tree % described by wt. % % Please see help for WFBT description of possible formats of wt. % % Filter scaling: % --------------- % % As in UWPFBT, the function recognizes three flags controlling scaling % of filters: % % 'sqrt' % Each filter is scaled by 1/sqrt(a), there a is the hop % factor associated with it. If the original filterbank is % orthonormal, the overall undecimated transform is a tight % frame. % This is the default. % % 'noscale' % Uses filters without scaling. % % 'scale' % Each filter is scaled by 1/a. % % If 'noscale' is used, 'scale' must have been used in UWPFBT (and vice % versa) in order to obtain a perfect reconstruction. % % Scaling of intermediate outputs: % -------------------------------- % % The following flags control scaling of the intermediate coefficients. % The intermediate coefficients are outputs of nodes which ale also % inputs to nodes further in the tree. % % 'intsqrt' % Each intermediate output is scaled by 1/sqrt(2). % If the filterbank in each node is orthonormal, the overall % undecimated transform is a tight frame. % This is the default. % % 'intnoscale' % No scaling of intermediate results is used. % % 'intscale' % Each intermediate output is scaled by 1/2. % % If 'intnoscale' is used, 'intscale' must have been used in UWPFBT % (and vice versa) in order to obtain a perfect reconstruction. % % 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.github.io/doc/wavelets/iuwpfbt.html} %@seealso{wfbt, wfbtinit} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'IUWPFBT'); if isempty(c) || ~isnumeric(c) error('%s: Unrecognized coefficient format.',upper(mfilename)); end if(isstruct(par)&&isfield(par,'fname')) complainif_toomanyargs(nargin,2,'IUWPFBT'); 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); scaling = par.scaling; interscaling = par.interscaling; % Use the "oposite" scaling of intermediate node outputs if strcmp(interscaling,'intscale') interscaling = 'intnoscale'; elseif strcmp(interscaling,'intnoscale') interscaling = 'intscale'; end % Use the "oposite" scaling of filters if strcmp(scaling,'scale') scaling = 'noscale'; elseif strcmp(scaling,'noscale') scaling = 'scale'; end else definput.import = {'wfbtcommon','uwfbtcommon'}; definput.flags.interscaling = {'intsqrt', 'intscale', 'intnoscale'}; [flags]=ltfatarghelper({},definput,varargin); scaling = flags.scaling; interscaling = flags.interscaling; % Initialize the wavelet tree structure wt = wfbtinit(par,flags.forder); end wtPath = fliplr(nodeBForder(0,wt)); [pOutIdxs,chOutIdxs] = treeWpBFrange(wt); nodesUps = nodesFiltUps(wtPath,wt); f = comp_iuwpfbt(c,wt.nodes(wtPath),nodesUps,pOutIdxs,chOutIdxs,scaling,... interscaling); ltfat/inst/filterbank/0000775000175000017500000000000013026262304014660 5ustar susnaksusnakltfat/inst/filterbank/filterbanksynchrosqueeze.m0000664000175000017500000001316413026262304022174 0ustar susnaksusnakfunction [cr,repos,Lc]=filterbanksynchrosqueeze(c,tgrad,var) %-*- texinfo -*- %@deftypefn {Function} filterbanksynchrosqueeze %@verbatim %FILTERBANKSYNCHROSQUEEZE Synchrosqueeze filterbank spectrogram % Usage: cr = filterbanksynchrosqueeze(c,tgrad,cfreq); % cr = filterbanksynchrosqueeze(c,tgrad,g); % [cr,repos,Lc] = filterbanksynchrosqueeze(...); % % Input parameters: % c : Coefficients to be synchrosqueezed. % tgrad : Instantaneous frequency relative to original position. % cfreq : Vector of relative center frequencies in ]-1,1]. % g : Set of filters. % Output parameters: % cr : Synchrosqueezed filterbank coefficients. % repos : Reassigned positions. % Lc : Subband lengths. % % FILTERBANKSYNCHROSQUEEZE(c,tgrad,cfreq) will reassign the values of % the filterbank coefficients c according to instantaneous frequency % tgrad. The frequency center frequencies of filters are given by cfreq. % The filterbank coefficients c are assumed to be obtained from a % non-subsampled filterbank (a=1). % % FILTERBANKSYNCHROSQUEEZE(s,tgrad,g) will do the same thing except % the center frequencies are estimated from a set of filters g. % % [sr,repos,Lc]=FILTERBANKSYNCHROSQUEEZE(...) does the same thing, but % in addition returns a vector of subband lengths Lc (Lc = cellfun(@numel,s)) % and cell array repos with sum(Lc) elements. Each element corresponds % to a single coefficient obtained by cell2mat(sr) and it is a vector % of indices identifying coefficients from cell2mat(s) assigned to % the particular time-frequency position. % % The arguments s, tgrad must be cell-arrays of vectors % of the same lengths. Arguments cfreq or g must have the % same number of elements as the cell arrays with coefficients. % % Examples: % --------- % % This example shows how to synchrosqueeze a ERB filterbank spectrogram: % % % Genrate 3 chirps half a second long % L = 22050; fs = 44100; l = 0:L-1; % % f = sin(2*pi*(l/35+(l/300).^2)) + ... % sin(2*pi*(l/10+(l/300).^2)) + ... % sin(2*pi*(l/5-(l/450).^2)); % f = 0.7*f'; % % % Create ERB filterbank % [g,~,fc]=erbfilters(fs,L,'uniform','spacing',1/12,'warped'); % % % Compute phase gradient % [tgrad,~,~,c]=filterbankphasegrad(f,g,1); % % Do the reassignment % sr=filterbanksynchrosqueeze(c,tgrad,cent_freqs(fs,fc)); % figure(1); subplot(211); % plotfilterbank(c,1,fc,fs,60); % title('ERBlet spectrogram of 3 chirps'); % subplot(212); % plotfilterbank(sr,1,fc,fs,60); % title('Synchrosqueezed ERBlet spectrogram of 3 chirps'); % % % References: % N. Holighaus, Z. Průša, and P. L. Soendergaard. Reassignment and % synchrosqueezing for general time-frequency filter banks, subsampling % and processing. Signal Processing, 125:1--8, 2016. [1]http ] % % References % % 1. http://www.sciencedirect.com/science/article/pii/S0165168416000141 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbanksynchrosqueeze.html} %@seealso{filterbankphasegrad, gabreassign} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Nicki Holighaus. % Sanity checks complainif_notenoughargs(nargin,3,'FILTERBANKSYNCHROSQUEEZE'); if isempty(c) || ~iscell(c) error('%s: s should be a nonempty cell array.',upper(mfilename)); end if isempty(tgrad) || ~iscell(tgrad) || any(~cellfun(@isreal,tgrad)) error('%s: tgrad should be a nonempty cell array.',upper(mfilename)); end if any(cellfun(@(sEl,tEl) ~isvector(sEl) || ~isvector(tEl) ... , c,tgrad)) error('%s: s, tgrad, must be cell arrays of numeric vectors.',... upper(mfilename)); end if ~isequal(size(c),size(tgrad)) || ... any(cellfun(@(sEl,tEl) ~isequal(size(sEl),size(tEl)), ... c,tgrad)) error('%s: s, tgrad does not have the same format.',upper(mfilename)); end W = cellfun(@(sEl)size(sEl,2),c); if any(W>1) error('%s: Only one-channel signals are supported.',upper(mfilename)); end % Number of channels M = numel(c); % Number of elements in channels Lc = cellfun(@(sEl)size(sEl,1),c); % Check if a comply with subband lengths L = Lc; if any(abs(L-L(1))>1e-6) error(['%s: Subsampling factors and subband lengths do not ',... 'comply.'],upper(mfilename)); end L = L(1); % Determine center frequencies if isempty(var) || numel(var)~=M || ~isvector(var) && ~iscell(var) error(['%s: cfreq must be length-M numeric vector or a cell-array ',... 'containg M filters.'],upper(mfilename)); else if iscell(var) cfreq = cent_freqs(var,L); else cfreq = var; end end % Dummy fgrad fgrad = tgrad; for m=1:numel(fgrad); fgrad{m} = zeros(L,1); end a = ones(M,1); % Do the computations if nargout>1 [cr,repos] = comp_filterbankreassign(c,tgrad,fgrad,a,cfreq); else cr = comp_filterbankreassign(c,tgrad,fgrad,a,cfreq); end ltfat/inst/filterbank/filterbanklengthcoef.m0000664000175000017500000000357413026262304021227 0ustar susnaksusnakfunction 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.github.io/doc/filterbank/filterbanklengthcoef.html} %@seealso{filterbank, filterbanklength} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,upper(mfilename)); if iscell(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); ltfat/inst/filterbank/filterbank.m0000664000175000017500000000564013026262304017164 0ustar susnaksusnakfunction 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.github.io/doc/filterbank/filterbank.html} %@seealso{ufilterbank, ifilterbank, pfilt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; definput.import={'pfilt'}; definput.keyvals.L=[]; [~,kv,L]=ltfatarghelper({'L'},definput,varargin); [f,Ls]=comp_sigreshape_pre(f,'FILTERBANK',0); if ~isnumeric(a) || isempty(a) error('%s: a must be non-empty numeric.',upper(mfilename)); end; if isempty(L) L=filterbanklength(Ls,a); end; [g,asan]=filterbankwin(g,a,L,'normal'); % if size(a,1)>1 % if size(a,1)~= numel(g); % error(['%s: The number of entries in "a" must match the number of ' ... % 'filters.'],upper(mfilename)); % end; % end; f=postpad(f,L); g=comp_filterbank_pre(g,asan,L,kv.crossover); c=comp_filterbank(f,g,asan); ltfat/inst/filterbank/filterbankinit.m0000664000175000017500000000165413026262304020051 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} filterbankinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/filterbank/filterbankrealtight.m0000664000175000017500000000760413026262304021072 0ustar susnaksusnakfunction gtout=filterbankrealtight(g,a,L) %-*- texinfo -*- %@deftypefn {Function} filterbankrealtight %@verbatim %FILTERBANKREALTIGHT Tight filters of filterbank for real signals only % Usage: gt=filterbankrealtight(g,a,L); % gt=filterbankrealtight(g,a); % % filterabankrealtight(g,a,L) computes the canonical tight filters of % g for a channel subsampling rate of a (hop-size) and a system % length L. L must be compatible with subsampling rate a as % L==filterbanklength(L,a). 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. % % filterabankrealtight(g,a) does the same, but the filters must be FIR % filters, as the transform length is unspecified. L will be set to % next suitable length equal or bigger than the longest impulse response. % % The format of the filters g are described in the help of FILTERBANK. % % REMARK: The resulting system is tight for length L. In some cases, % using tight system calculated for shorter L might work but check the % reconstruction error. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankrealtight.html} %@seealso{filterbank, ufilterbank, ifilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FILTERBANKREALTIGHT'); if nargin<3 L = []; end [g,asan,info]=filterbankwin(g,a,L,'normal'); if isempty(L) if info.isfir % Pick shortest possible length for FIR filterbank L = filterbanklength(info.longestfilter,asan); else % Just thow an error, nothing reasonable can be done without L error(['%s: L must be specified when not working with FIR ',...' 'filterbanks.'], upper(mfilename)); end end M=info.M; if 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 a=a(1); % Transfer functions of individual filters as cols G = filterbankfreqz(g,a,L); thisclass = class(G); N=L/a; gt=zeros(M,N,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 was created transposed because the indexing gt(:,idx_a) % is much faster than gt(idx_a,:) gt = gt.'; gt=ifft(gt)*sqrt(a); % Matrix cols to cell elements + cast gtout = cellfun(@(gtEl) cast(gtEl,thisclass), num2cell(gt,1),... 'UniformOutput',0); else if info.ispainless gtout = comp_painlessfilterbank(g,asan,L,'tight',1); 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; ltfat/inst/filterbank/filterbankresponse.m0000664000175000017500000000654113026262304020744 0ustar susnaksusnakfunction 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); % % gf=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. % % CAUTION: This function computes a sum of squares of modulus of the % frequency responses, which is also the diagonal of the Fourier % transform of the frame operator. % Use FILTERBANKFREQZ for evaluation or plotting of frequency responses % of filters. % % 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. % % gf=FILTERBANKRESPONSE(g,a,L,'individual') returns responses % in frequency of individual filters as columns of a matrix. The total % response can be obtained by gf = sum(gf,2). % % 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 or PLOTFFT. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankresponse.html} %@seealso{filterbank, filterbankbounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,asan]=filterbankwin(g,a,L,'normal'); M=numel(g); gf = zeros(L,M); for m=1:M gf(:,m) = comp_filterbankresponse(g(m),asan(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; ltfat/inst/filterbank/filterbanktight.m0000664000175000017500000000744313026262304020227 0ustar susnaksusnakfunction gtout=filterbanktight(g,a,L) %-*- texinfo -*- %@deftypefn {Function} filterbanktight %@verbatim %FILTERBANKTIGHT Tight filterbank % Usage: gt=filterbanktight(g,a,L); % gt=filterbanktight(g,a); % % FILTERBANKTIGHT(g,a,L) computes the canonical tight filters of g % for a channel subsampling rate of a (hop-size) and a system length L. % L must be compatible with subsampling rate a as % L==filterbanklength(L,a). % % FILTERBANKTIGHT(g,a,L) does the same, but the filters must be FIR % filters, as the transform length is unspecified. L will be set to % next suitable length equal or bigger than the longest impulse response. % % The input and output format of the filters g are described in the % help of FILTERBANK. % % REMARK: The resulting system is tight for length L. In some cases, % using tight system calculated for shorter L might work but check the % reconstruction error. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbanktight.html} %@seealso{filterbank, filterbankdual, ufilterbank, ifilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FILTERBANKTIGHT'); if nargin<3 L = []; end [g,asan,info]=filterbankwin(g,a,L,'normal'); if isempty(L) if info.isfir % Pick shortest possible length for FIR filterbank L = filterbanklength(info.longestfilter,asan); else % Just thow an error, nothing reasonable can be done without L error(['%s: L must be specified when not working with FIR ',...' 'filterbanks.'], upper(mfilename)); end end M=info.M; if 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 a=a(1); % Transfer functions of individual filters as cols G = filterbankfreqz(g,a,L); thisclass = class(G); N=L/a; gt=zeros(M,N,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 was created transposed because the indexing gt(:,idx_a) % is much faster than gt(idx_a,:) gt = gt.'; gt=ifft(gt)*sqrt(a); % Matrix cols to cell elements + cast gtout = cellfun(@(gtEl) cast(gtEl,thisclass), num2cell(gt,1),... 'UniformOutput',0); % All filters in gdout will be treated as FIR of length L. Convert them % to a struct with .h and .offset format. gtout = filterbankwin(gtout,a); else if info.ispainless gtout = comp_painlessfilterbank(g,asan,L,'tight',0); 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; ltfat/inst/filterbank/ifilterbankiter.m0000664000175000017500000001065313026262304020221 0ustar susnaksusnakfunction [f,iter,relres]=ifilterbankiter(c,g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} ifilterbankiter %@verbatim %IFILTERBANKITER Filter bank iterative inversion % Usage: f=ifilterbankiter(c,g,a); % % IFILTERBANKITER(c,g,a) iteratively synthesizes a signal f from the % coefficients c which were obtained using the filters stored in g for % a channel subsampling rate of a (the hop-size). % % The filter bank g and the subsampling rate a must be the same % as used in FILTERBANK or UFILTERBANK. % % This function is useful if there is no way how to explicitly compute % a dual system using FILTERBANKDUAL or FILTERBANKREALDUAL. % % Additional parameters % --------------------- % % The function calls FRSYNITER and passes all the optional arguments to it. % Please refer to help of FRSYNITER for further details. % % Please note that by default, the function expects filterbank g* % to be created for real signals i.e. g cover only the positive frequencies. % Additional flag 'complex' is required if the filterbank is defined for % positive and negative frequencies. % % Examples: % --------- % % The following example compares convergence rates of CG and PCG for a % filterbank which forms a frame, but it is neither uniform or painless: % % [f,fs] = greasy; L = size(f,1); % [g,a,fc]=erbfilters(fs,L,'fractional','bwmul',0.6,'redmul',4/5,'complex'); % filterbankfreqz(g,a,L,'plot','linabs'); % % Filterbankdual does not work % try % gd=filterbankdual(g,a,L); % catch % disp('FILTERBANKDUAL exited with error.'); % end % % c = filterbank(f,g,a); % [fpcg,~,iterpcg] = ifilterbankiter(c,g,a,'complex','pcg'); % [fcg,~,itercg] = ifilterbankiter(c,g,a,'complex','cg'); % % fprintf('CG achieved error %e in %d iterations.n',norm(f-fcg), itercg); % fprintf('PCG achieved error %e in %d iterations.n',norm(f-fpcg), iterpcg); % % Similar example with real filterbank: % % [f,fs] = greasy; L = size(f,1); % [g,a,fc]=erbfilters(fs,L,'fractional','bwmul',0.6,'redmul',4/5); % filterbankfreqz(g,a,L,'plot','linabs'); % % Filterbankrealdual does not work % try % gd=filterbankrealdual(g,a,L); % catch % disp('FILTERBANKREALDUAL exited with error.'); % end % % c = filterbank(f,g,a); % [fpcg,~,iterpcg] = ifilterbankiter(c,g,a,'pcg'); % [fcg,~,itercg] = ifilterbankiter(c,g,a,'cg'); % % fprintf('CG achieved error %e in %d iterations.n',norm(f-fcg), itercg); % fprintf('PCG achieved error %e in %d iterations.n',norm(f-fpcg), iterpcg); % % % 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.github.io/doc/filterbank/ifilterbankiter.html} %@seealso{filterbank, ufilterbank, ifilterbank, filterbankdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,3,'IFILTERBANKITER'); tolchooser.double=1e-9; tolchooser.single=1e-5; definput.keyvals.Ls=[]; definput.keyvals.tol=tolchooser.(class(c{1})); definput.keyvals.maxit=100; definput.flags.alg={'pcg','cg'}; definput.flags.real={'real','complex'}; [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin); if flags.do_real F = frame('filterbankreal',g,a,numel(g)); else F = frame('filterbank',g,a,numel(g)); end [f,iter,relres] = frsyniter(F,framenative2coef(F,c),'Ls',Ls,flags.alg,'maxit',kv.maxit,'tol',kv.tol); ltfat/inst/filterbank/filterbankdual.m0000664000175000017500000001105013026262304020022 0ustar susnaksusnakfunction gdout=filterbankdual(g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} filterbankdual %@verbatim %FILTERBANKDUAL Dual filters % Usage: gd=filterbankdual(g,a,L); % gd=filterbankdual(g,a); % % % FILTERBANKDUAL(g,a,L) computes the canonical dual filters of g for a % channel subsampling rate of a (hop-size) and system length L. % L must be compatible with subsampling rate a as % L==filterbanklength(L,a). This will create a dual frame valid for % signals of length L. % % filterabankrealdual(g,a) does the same, but the filters must be FIR % filters, as the transform length is unspecified. L will be set to % next suitable length equal or bigger than the longest impulse response % such that L=filterbanklength(gl_longest,a). % % The input and output format of the filters g are described in the % help of FILTERBANK. % % In addition, the funtion recognizes a 'forcepainless' flag which % forces treating the filterbank g and a as a painless case % filterbank. % % To actually invert the output of a filterbank, use the dual filters % together with the IFILTERBANK function. % % REMARK: In general, perfect reconstruction can be obtained for signals % of length L. In some cases, using dual system calculated for shorter % L might work but check the reconstruction error. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankdual.html} %@seealso{filterbank, ufilterbank, ifilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FILTERBANKDUAL'); definput.import={'filterbankdual'}; [flags,~,L]=ltfatarghelper({'L'},definput,varargin); [g,asan,info]=filterbankwin(g,a,L,'normal'); if isempty(L) if info.isfir % Pick shortest possible length for FIR filterbank L = filterbanklength(info.longestfilter,asan); else % Just thow an error, nothing reasonable can be done without L error(['%s: L must be specified when not working with FIR ',...' 'filterbanks.'], upper(mfilename)); end end M=info.M; % Force usage of the painless algorithm if flags.do_forcepainless info.ispainless = 1; end % Check user defined L if 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 both are suitable if info.isuniform && info.ispainless info.isuniform = 0; end % Factorization of frame operator to block-diagonal matrix if info.isuniform % Uniform filterbank, use polyphase representation a=a(1); % Transfer functions of individual filters as cols G = filterbankfreqz(g,a,L); N=L/a; gd=zeros(M,N,class(G)); 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 was created transposed because the indexing gd(:,idx_a) % is much faster than gd(idx_a,:) gd = gd.'; gd=ifft(gd)*a; % Matrix cols to cell elements + cast gdout = cellfun(@(gdEl) cast(gdEl,class(G)), num2cell(gd,1),... 'UniformOutput',0); % All filters in gdout will be treated as FIR of length L. Convert them % to a struct with .h and .offset format. gdout = filterbankwin(gdout,a); elseif info.ispainless % Factorized frame operator is diagonal. gdout = comp_painlessfilterbank(g,asan,L,'dual',0); else error(['%s: The canonical dual frame of this system is not a ' ... 'filterbank. You must either call an iterative ' ... 'method to perform the desired inverstion or transform ',... 'or transform the filterbank to uniform one. Please see ' ... 'FRANAITER or FRSYNITER for the former and ',... 'NONU2UFILTERBANK for the latter case.'],upper(mfilename)); end; ltfat/inst/filterbank/ufilterbank.m0000664000175000017500000000541113026262304017345 0ustar susnaksusnakfunction 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 a 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.github.io/doc/filterbank/ufilterbank.html} %@seealso{ifilterbank, filterbankdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; if isempty(a) || ~all(a(:,1)==a(1)) ... || ~isnumeric(a) || any(rem(a(:),1)~=0) error(['%s: a has to be either scalar or a numel(g) vector of equal',... ' integers.'], upper(mfilename)); end definput.import={'pfilt'}; definput.keyvals.L=[]; [~,kv,L]=ltfatarghelper({'L'},definput,varargin); [f,Ls,W]=comp_sigreshape_pre(f,'UFILTERBANK',0); a=a(1); if isempty(L) L=filterbanklength(Ls,a); end; [g,asan]=filterbankwin(g,a,L,'normal'); M=numel(g); N=L/a; f=postpad(f,L); g = comp_filterbank_pre(g,asan,L,kv.crossover); ctmp=comp_filterbank(f,g,asan); c=zeros(N,M,W,assert_classname(f)); for m=1:M c(:,m,:)=ctmp{m}; end; ltfat/inst/filterbank/plotfilterbank.m0000664000175000017500000001610013026262304020054 0ustar susnaksusnakfunction C = 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.github.io/doc/filterbank/plotfilterbank.html} %@seealso{filterbank, ufilterbank, tfplot, sgram} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); C = coef; if iscell(C) M=numel(C); 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(C{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=C{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; C=coef2; delta_t=L/N; else a=a(1); Nc=size(C,1); N=kv.xres; M=size(C,2); C=interp1(linspace(0,1,Nc),C,... linspace(0,1,N),'nearest'); C=C.'; delta_t=a*Nc/N; end; % Freq. pos is just number of the channel. yr=1:M; if size(C,3)>1 error('Input is multidimensional.'); end; % Apply transformation to coefficients. if flags.do_db C=20*log10(abs(C)+realmin); end; if flags.do_dbsq C=10*log10(abs(C)+realmin); end; if flags.do_linsq C=abs(C).^2; end; if flags.do_linabs C=abs(C); end; if flags.do_lin if ~isreal(C) 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(C(:)); kv.clim=[maxclim-kv.dynrange,maxclim]; end; % Handle clim by thresholding and cutting if ~isempty(kv.clim) C(Ckv.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,C); else imagesc(xr,yr,C,kv.clim); end; case 'contour' contour(xr,yr,C); case 'surf' surf(xr,yr,C,'EdgeColor','none'); case 'pcolor' pcolor(xr,yr,C); 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; % To avoid printing all the coefficients in the command window when a % semicolon is forgotten if nargout < 1 clear C; end ltfat/inst/filterbank/ierblett.m0000664000175000017500000000503513026262304016653 0ustar susnaksusnakfunction fr = ierblett(c,g,shift,Ls,dual) %-*- texinfo -*- %@deftypefn {Function} ierblett %@verbatim %IERBLETT ERBlet non-stationary 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. % % % 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.github.io/doc/filterbank/ierblett.html} %@seealso{erblett} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author: Nicki Holighaus % Date: 10.04.13 if ~exist('dual','var') dual = 1; end fr = comp_insdgfb(c,g,shift,Ls,dual); ltfat/inst/filterbank/ifilterbank.m0000664000175000017500000000531013026262304017327 0ustar susnaksusnakfunction [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.github.io/doc/filterbank/ifilterbank.html} %@seealso{filterbank, ufilterbank, filterbankdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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,asan]=filterbankwin(g,a,L,'normal'); if numel(g)~=M error(['%s: Number of filters must be equal to the number of channels ' ... 'of coefficients.'],upper(mfilename)); 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(mfilename)); end; end; g = comp_filterbank_pre(g,asan,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,asan,L); % Cut or extend f to the correct length, if desired. if ~isempty(Ls) f=postpad(f,Ls); else Ls=L; end; ltfat/inst/filterbank/cqt.m0000664000175000017500000002333513026262304015633 0ustar susnaksusnakfunction [c,Ls,g,shift,M] = cqt(f,fmin,fmax,bins,fs,varargin) %-*- texinfo -*- %@deftypefn {Function} cqt %@verbatim %CQT Constant-Q non-stationary 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 non-stationary 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.github.io/doc/filterbank/cqt.html} %@seealso{icqt, firwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/filterbank/filterbankphasegrad.m0000664000175000017500000001105513026262304021040 0ustar susnaksusnakfunction [tgrad,fgrad,s,c]=filterbankphasegrad(f,g,a,L,minlvl) %-*- texinfo -*- %@deftypefn {Function} filterbankphasegrad %@verbatim %FILTERBANKPHASEGRAD Phase gradient of a filterbank representation % Usage: [tgrad,fgrad,s,c] = filterbankphasegrad(f,g,a,L,minlvl); % [tgrad,fgrad,s,c] = filterbankphasegrad(f,g,a,L); % [tgrad,fgrad,s,c] = filterbankphasegrad(f,g,a,minlvl); % [tgrad,fgrad,s,c] = filterbankphasegrad(f,g,a); % [tgrad,fgrad,s] = filterbankphasegrad(...) % [tgrad,fgrad] = filterbankphasegrad(...) % % Input parameters: % f : Signal to be analyzed. % g : Cell array of filters % a : Vector of time steps. % L : Signal length (optional). % minlvl: Regularization parameter (optional, required < 1). % Output parameters: % tgrad : Instantaneous frequency relative to original position. % fgrad : Group delay relative to original position. % cs : Filterbank spectrogram. % c : Filterbank coefficients. % % [tgrad,fgrad,s,c] = FILTERBANKPHASEGRAD(f,g,a,L) computes the group % delay fgrad and instantaneous frequency tgrad of the filterbank % spectrogram s obtained from the signal f and filterbank % parameters g and a. Both quantities are specified relative to the % original coefficient position. tgrad is given in samples, while % fgrad is given as values on the unit circle, easily converted into % relative frequencies by log(tgrad)/(pi*i). % This routine uses the equivalence of the filterbank coefficients in % each channel with coefficients obtained from an STFT obtained with a % certain window (possibly different for every channel). As a consequence % of this equivalence, the formulas derived in the reference apply. % % 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. % % N. Holighaus, Z. Průša, and P. L. Soendergaard. Reassignment and % synchrosqueezing for general time-frequency filter banks, subsampling % and processing. Signal Processing, 125:1--8, 2016. [1]http ] % % References % % 1. http://www.sciencedirect.com/science/article/pii/S0165168416000141 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankphasegrad.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Nicki Holighaus. complainif_notenoughargs(nargin,3,'FILTERBANKPHASEGRAD'); % Reshape input signal [f,~,W]=comp_sigreshape_pre(f,'FILTERBANKPHASEGRAD',0); Ls = size(f,1); if W>1 error('%s: Only one-channel signals supported.',upper(mfilename)); end if nargin < 5 if nargin < 4 L = filterbanklength(Ls,a); minlvl = eps; else if ~(isscalar(L) && isnumeric(L) ) && L>0 error('%s: Fourth argument shoud be a positive number.',... upper(mfilename)); end if L >= 1 minlvl = eps; else minlvl = L; end; end end; complainif_notposint(L,'L','FILTERBANKPHASEGRAD'); Luser = filterbanklength(L,a); if Luser~=L error(['%s: Incorrect transform length L=%i specified. ', ... 'Next valid length is L=%i. See the help of ',... 'FILTERBANKLENGTH for the requirements.'],... upper(mfilename),L,Luser); end % Unify format of coefficients [g,asan]=filterbankwin(g,a,L,'normal'); % Precompute filters [gh, gd, g] = comp_phasegradfilters(g, asan, L); f=postpad(f,L); c=comp_filterbank(f,g,asan); % Compute filterbank coefficients with frequency weighted window ch=comp_filterbank(f,gh,asan); % Compute filterbank coefficients with time weighted window cd=comp_filterbank(f,gd,asan); % Run the computation [tgrad,fgrad,s] = comp_filterbankphasegrad(c,ch,cd,L,minlvl); ltfat/inst/filterbank/filterbankbounds.m0000664000175000017500000000746413026262304020405 0ustar susnaksusnakfunction [AF,BF]=filterbankbounds(g,a,L) %-*- texinfo -*- %@deftypefn {Function} filterbankbounds %@verbatim %FILTERBANKBOUNDS Frame bounds of a filterbank % Usage: fcond=filterbankbounds(g,a,L); % [A,B]=filterbankbounds(g,a,L); % [...]=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. % % FILTERBANKBOUNDS(g,a) does the same, but the filters must be FIR % filters, as the transform length is unspecified. L will be set to % next suitable length equal or bigger than the longest impulse response % such that L=filterbanklength(gl_longest,a). % % [A,B]=FILTERBANKBOUNDS(...) returns the lower and upper frame bounds % explicitly. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankbounds.html} %@seealso{filterbank, filterbankdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FILTERBANKBOUNDS'); if nargin<3 L = []; end [g,asan,info]=filterbankwin(g,a,L,'normal'); if isempty(L) if info.isfir % Pick shortest possible length for FIR filterbank L = filterbanklength(info.longestfilter,asan); else % Just thow an error, nothing reasonable can be done without L error(['%s: L must be specified when not working with FIR ',...' 'filterbanks.'], upper(mfilename)); end end M=info.M; if L~=filterbanklength(L,asan) error(['%s: Specified length L is incompatible with the length of ' ... 'the time shifts.'],upper(mfilename)); end; AF=Inf; BF=0; % Prioritize painless over uniform algorithm if info.isuniform && info.ispainless info.isuniform = 0; end 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)=cast(comp_transferfunction(g{ii},L),thisclass); 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,asan,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; ltfat/inst/filterbank/audfilters.m0000664000175000017500000005460113026262304017206 0ustar susnaksusnakfunction [g,a,fc,L]=audfilters(fs,Ls,varargin) %-*- texinfo -*- %@deftypefn {Function} audfilters %@verbatim %AUDFILTERS Generates filters equidistantly spaced on auditory frequency scales % Usage: [g,a,fc,L]=audfilters(fs,Ls); % [g,a,fc,L]=audfilters(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,L]=AUDFILTERS(fs,Ls) constructs a set of filters g that are % equidistantly spaced on a perceptual frequency scale (see FREQTOAUD) between % 0 and the Nyquist frequency. The filter bandwidths are proportional to the % critical bandwidth 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 the ERB scale is chosen but other frequency scales are % possible. Currently supported scales are 'erb', 'erb83', 'bark', 'mel' % and 'mel1000', and can be changed by passing the associated string as % an optional parameter. See FREQTOAUD for more information on the % supported frequency scales. % % By default, a Hann window shape is chosen as prototype frequency % response for all filters. The prototype frequency response can be % changed by passing any of the window types from FIRWIN or FREQWIN % as an optional parameter. % % [g,a,fc,L]=AUDFILTERS(fs,Ls,fmin,fmax) constructs a set of filters % between fmin and fmax. The filters are equidistantly spaced on the % selected frequency scale. One additional filter will be positioned at % the 0 and Nyquist frequencies each, so as to cover the full range of % positive frequencies. % The values of fmin and fmax can be instead specified using a % key/value pair as: % % [g,a,fc,L]=audfilters(fs,Ls,...,'fmin',fmin,'fmax',fmax) % % Default values are fmin=0 and fmax=fs/2. % % For more details on the construction of the filters, please see the % given references. % % Downsampling factors % -------------------- % % The integer downsampling rates of the channels must all divide the % signal length, FILTERBANK will only work for input signal lengths % being multiples of the least common multiple of the downsampling rates. % See the help of FILTERBANKLENGTH. % The fractional downsampling rates restrict the filterbank to a single % length L=Ls. % % [g,a]=AUDFILTERS(...,'regsampling') constructs a non-uniform % filterbank with integer subsampling factors. % % [g,a]=AUDFILTERS(...,'uniform') constructs a uniform filterbank % where the integer downsampling rate is the same for all the channels. This % results in most redundant representation which produces nice plots. % % [g,a]=AUDFILTERS(...,'fractional') constructs a filterbank with % fractional downsampling rates a. % This results in the least redundant system. % % [g,a]=AUDFILTERS(...,'fractionaluniform') constructs a filterbank with % fractional downsampling rates a, which are uniform for all filters % except the "filling" low-pass and high-pass filters which can have different % fractional downsampling rates. This is useful when uniform subsampling % and low redundancy at the same time are desirable. % % Additional parameters % --------------------- % % AUDFILTERS accepts the following optional parameters: % % 'spacing',b Specify the spacing between the filters, measured in % scale units. Default value is b=1 for the scales % 'erb', 'erb83' and 'bark'; the default is b=100 for % 'mel' and 'mel1000'. % % 'bwmul',bwmul Bandwidth of the filters relative to the bandwidth % returned by AUDFILTBW. Default value is bwmul=1 for % the scales 'erb', 'erb83' and 'bark'; the default is % b=100 for 'mel' and 'mel1000'. % % '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. % % 'M',M Specify the total number of filters between fmin and % fmax. If this parameter is specified, it overwrites the % 'spacing' parameter. % % 'symmetric' Create filters that are symmetric around their centre % frequency. This is the default. % % 'warped' Create asymmetric filters that are asymmetric on the % auditory scale. % % 'complex' Construct a filterbank that covers the entire % frequency range instead of just the positive % frequencies this allows the analysis of complex % valued signals. % % 'trunc_at' When using a prototype defined in FREQWIN, a hard % thresholding of the filters at the specified threshold % value is performed to reduce their support size. % The default value is trunc_at=10e-5. When no % truncation is desired, trunc_at=0 should be chosen. % This value is ignored when a prototype shape from % FIRWIN was chosen. % % '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 on the ERB scale and visualize the result: % % [f,fs]=greasy; % Get the test signal % [g,a,fc,L]=audfilters(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. The second plot shows frequency responses of % filters used for analysis (top) and synthesis (bottom). : % % [f,fs]=greasy; % Get the test signal % L=length(f); % [g,a,fc]=audfilters(fs,L,'fractional'); % c=filterbank(f,{'realdual',g},a); % r=2*real(ifilterbank(c,g,a)); % norm(f-r) % % % Plot the response % figure(1); % 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'); % % % Plot frequency responses of individual filters % gd=filterbankrealdual(g,a,L); % figure(2); % subplot(2,1,1); % filterbankfreqz(gd,a,L,fs,'plot','linabs','posfreq'); % % subplot(2,1,2); % filterbankfreqz(g,a,L,fs,'plot','linabs','posfreq'); % % % % 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. % % T. Necciari, N. Holighaus, P. Balazs, Z. Průša, and P. Majdak. Can % frames provide gammatone filter banks with perfect reconstruction? % submitted. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/audfilters.html} %@seealso{filterbank, ufilterbank, ifilterbank, ceil23} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Authors: Peter L. Soendergaard (original 'erbfilters' function) % Modified by: Thibaud Necciari, Nicki Holighaus % Date: 16.12.16 complainif_notenoughargs(nargin,2,upper(mfilename)); complainif_notposint(fs,'fs',upper(mfilename)); complainif_notposint(Ls,'Ls',upper(mfilename)); firwinflags=getfield(arg_firwin,'flags','wintype'); freqwinflags=getfield(arg_freqwin,'flags','wintype'); definput.flags.wintype = [ firwinflags, freqwinflags]; definput.keyvals.M=[]; definput.keyvals.redmul=1; definput.keyvals.min_win = 4; definput.keyvals.bwmul=[]; definput.keyvals.spacing=[]; definput.keyvals.trunc_at=10^(-5); definput.keyvals.fmin=0; definput.keyvals.fmax=fs/2; definput.flags.audscale={'erb','erb83','bark','mel','mel1000'}; definput.flags.warp = {'symmetric','warped'}; definput.flags.real = {'real','complex'}; definput.flags.sampling = {'regsampling','uniform','fractional',... 'fractionaluniform'}; % Search for window given as cell array candCellId = cellfun(@(vEl) iscell(vEl) && any(strcmpi(vEl{1},definput.flags.wintype)),varargin); winCell = {}; % If there is such window, replace cell with function name so that % ltfatarghelper does not complain if ~isempty(candCellId) && any(candCellId) candCellIdLast = find(candCellId,1,'last'); winCell = varargin{candCellIdLast}; varargin(candCellId) = []; % But remove all varargin{end+1} = winCell{1}; end [flags,kv]=ltfatarghelper({'fmin','fmax'},definput,varargin); if isempty(winCell), winCell = {flags.wintype}; end switch flags.audscale case {'mel','mel1000'} % The mel scales are very fine, therefore default spacing is adjusted definput.keyvals.bwmul=100; definput.keyvals.spacing=100; otherwise definput.keyvals.bwmul=1; definput.keyvals.spacing=1; end [flags,kv]=ltfatarghelper({'fmin','fmax'},definput,varargin); if flags.do_bark && (fs > 44100) error(['%s: Bark scale is not suitable for sampling rates higher than 44.1 kHz. ',... 'Please choose another scale.'],upper(mfilename)); end if ~isscalar(kv.bwmul) || kv.bwmul <= 0 error('%s: bwmul must be a positive scalar.',upper(mfilename)); end if ~isscalar(kv.redmul) || kv.redmul <= 0 error('%s: relmul must be a positive scalar.',upper(mfilename)); end if kv.fmax <= kv.fmin || kv.fmin < 0 || kv.fmax > fs/2 error('%s: fmax must be bigger than fmin and in the range [0,fs/2].',upper(mfilename)); end if kv.trunc_at > 1 || kv.trunc_at < 0 error('%s: trunc_at must be in range [0,1].',upper(mfilename)); end if ~isscalar(kv.min_win) || rem(kv.min_win,1) ~= 0 || kv.min_win < 1 error('%s: min_win must be an integer bigger or equal to 1.',upper(mfilename)); end if ~isempty(kv.M) complainif_notposint(kv.M,'M',upper(mfilename)); kv.spacing = (freqtoaud(kv.fmax,flags.audscale) - freqtoaud(kv.fmin,flags.audscale))/(kv.M-1); end probelen = 10000; switch flags.wintype case firwinflags winbw=norm(firwin(flags.wintype,probelen)).^2/probelen; % This is the ERB-type bandwidth of the prototype if flags.do_symmetric filterfunc = @(fsupp,fc,scal)... blfilter(winCell,fsupp,fc,'fs',fs,'scal',scal,... 'inf','min_win',kv.min_win); else fsupp_scale=1/winbw*kv.bwmul; filterfunc = @(fsupp,fc,scal)... warpedblfilter(winCell,fsupp_scale,fc,fs,... @(freq) freqtoaud(freq,flags.audscale),@(aud) audtofreq(aud,flags.audscale),'scal',scal,'inf'); end bwtruncmul = 1; case freqwinflags if flags.do_warped error('%s: TODO: Warping is not supported for windows from freqwin.',... upper(mfilename)); end probebw = 0.01; % Determine where to truncate the window H = freqwin(winCell,probelen,probebw); winbw = norm(H).^2/(probebw*probelen/2); bwrelheight = 10^(-3/10); if kv.trunc_at <= eps bwtruncmul = inf; else try bwtruncmul = winwidthatheight(abs(H),kv.trunc_at)/winwidthatheight(abs(H),bwrelheight); catch bwtruncmul = inf; end end filterfunc = @(fsupp,fc,scal)... freqfilter(winCell, fsupp, fc,'fs',fs,'scal',scal,... 'inf','min_win',kv.min_win,... 'bwtruncmul',bwtruncmul); end % Construct the AUD filterbank fmin = max(kv.fmin,audtofreq(kv.spacing,flags.audscale)); fmax = min(kv.fmax,fs/2); innerChanNum = floor((freqtoaud(fmax,flags.audscale)-freqtoaud(fmin,flags.audscale))/kv.spacing)+1; fmax = audtofreq(freqtoaud(fmin,flags.audscale)+(innerChanNum-1)*kv.spacing,flags.audscale); % Make sure that fmax < fs/2, and F_ERB(fmax) = F_ERB(fmin)+k/spacing, for % some k. count = 0; while fmax >= fs/2 count = count+1; fmax = audtofreq(freqtoaud(fmin,flags.audscale)+(innerChanNum-count-1)*kv.spacing,flags.audscale); end innerChanNum = innerChanNum-count; if fmax <= fmin || fmin > fs/4 || fmax < fs/4 error(['%s: Bad combination of fs, fmax and fmin.'],upper(mfilename)); end fc=audspace(fmin,fmax,innerChanNum,flags.audscale).'; fc = [0;fc;fs/2]; M2 = innerChanNum+2; ind = (2:M2-1)'; %% Compute the frequency support % fsupp is measured in Hz fsupp=zeros(M2,1); aprecise=zeros(M2,1); if flags.do_symmetric fsupp(ind)=audfiltbw(fc(ind),flags.audscale)/winbw*kv.bwmul; % Generate lowpass filter parameters fsupp(1) = 0; fc_temp = audtofreq(freqtoaud(fc(2),flags.audscale)-kv.spacing,flags.audscale); fsupp_temp = audfiltbw(fc_temp,flags.audscale)/winbw*kv.bwmul; aprecise(1) = max(fs./(2*max(fc_temp,0)+fsupp_temp*kv.redmul),1); % Generate highpass filter parameters fsupp(end) = 0; fc_temp = audtofreq(freqtoaud(fc(end-1),flags.audscale)+kv.spacing,flags.audscale); fsupp_temp = audfiltbw(fc_temp,flags.audscale)/winbw*kv.bwmul; aprecise(end) = max(fs./(2*(fc(end)-min(fc_temp,fs/2))+fsupp_temp*kv.redmul),1); else % fsupp_scale is measured on the selected auditory scale % The scaling is incorrect, it does not account for the warping (NH: % I do think it is correct.) fsupp_scale=1/winbw*kv.bwmul; % Convert fsupp into the correct widths in Hz, necessary to compute % "a" in the next if-statement fsupp(ind)=audtofreq(freqtoaud(fc(ind),flags.audscale)+fsupp_scale/2,flags.audscale)-... audtofreq(freqtoaud(fc(ind),flags.audscale)-fsupp_scale/2,flags.audscale); % Generate lowpass filter parameters fsupp(1) = 0; fc_temp = max(audtofreq(freqtoaud(fc(2),flags.audscale)-kv.spacing,flags.audscale),0); fsupp_temp=2*(audtofreq(freqtoaud(fc_temp,flags.audscale)+fsupp_scale/2,flags.audscale)-fc_temp); aprecise(1) = max(fs./(2*fc_temp+fsupp_temp*kv.redmul),1); % Generate highpass filter parameters fsupp(end) = 0; fc_temp = min(audtofreq(freqtoaud(fc(end-1),flags.audscale)+kv.spacing,flags.audscale),fs/2); fsupp_temp=2*(fc_temp-audtofreq(freqtoaud(fc_temp,flags.audscale)-fsupp_scale/2,flags.audscale)); aprecise(end) = max(fs./(2*(fc(end)-fc_temp)+fsupp_temp*kv.redmul),1); 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(ind)=fs./fsupp(ind)/kv.redmul; aprecise=aprecise(:); if any(aprecise<1) error('%s: Invalid subsampling rates. Decrease redmul.',upper(mfilename)) end %% 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 a=[a;flipud(a(2:M2-1,:))]; scal=[scal;flipud(scal(2:M2-1))]; fc =[fc; -flipud(fc(2:M2-1))]; fsupp=[fsupp;flipud(fsupp(2:M2-1))]; ind = [ind;numel(fc)+2-(M2-1:-1:2)']; end; %% Compute the filters % This is actually much faster than the vectorized call. g = cell(1,numel(fc)); for m=ind.' g{m}=filterfunc(fsupp(m),fc(m),scal(m)); end % Generate lowpass filter g{1} = audlowpassfilter(filterfunc,g(1:M2),a(1:M2,:),fmin,fs,winbw,scal(1),bwtruncmul,kv,flags); % Generate highpass filter g{M2} = audhighpassfilter(filterfunc,g(1:M2),a(1:M2,:),fmax,fs,winbw,scal(M2),bwtruncmul,kv,flags); function glow = audlowpassfilter(filterfunc,g,a,fmin,fs,winbw,scal,bwtruncmul,kv,flags) next_fc = max(audtofreq(freqtoaud(fmin,flags.audscale)-kv.spacing,flags.audscale),0); temp_fc = []; % Temporary center frequencies and bandwidths for lowpass while next_fc >= -123.5604 % F^{-1}_{ERB}(-4) = -123.5604 temp_fc(end+1) = next_fc; next_fc = audtofreq(freqtoaud(next_fc,flags.audscale)-kv.spacing,flags.audscale); end if flags.do_symmetric temp_bw=audfiltbw(abs(temp_fc),flags.audscale)/winbw*kv.bwmul; plateauWidth = max(2*temp_fc(1),0); Lw = @(L) min(ceil((plateauWidth+temp_bw(1)*bwtruncmul)*L/fs),L); else fsupp_scale=1/winbw*kv.bwmul; temp_bw = audtofreq(freqtoaud(temp_fc,flags.audscale)+fsupp_scale/2,flags.audscale)-... audtofreq(freqtoaud(temp_fc,flags.audscale)-fsupp_scale/2,flags.audscale); Lw = @(L) min(ceil(2*audtofreq(freqtoaud(temp_fc(1),flags.audscale)+fsupp_scale/2,flags.audscale)*L/fs),L); end temp_g = cell(1,numel(temp_fc)); for m=1:numel(temp_g) temp_g{m}=filterfunc(temp_bw(m),temp_fc(m),1); end temp_fun = @(L) filterbankresponse(temp_g,1,L); temp_fbresp = @(L) filterbankresponse(g(2:end-1),a(2:end-1,:),L); glow.H = @(L) fftshift(long2fir(sqrt(max(... postpad(1-min(10.*max((1:floor(L/2)+1).'./L-1/4,0),1),L).* ... (temp_fun(L) - flipud(circshift(temp_fbresp(L),-1))) + ... flipud(postpad(1-min(10.*max((1:ceil(L/2)-1).'./L-1/4,0),1),L).* ... (circshift(temp_fun(L),-1) - flipud(temp_fbresp(L)))) ... ,0)),Lw(L)))*scal; glow.foff = @(L) -floor(Lw(L)/2); glow.realonly = 0; glow.delay = 0; glow.fs = g{2}.fs; function ghigh = audhighpassfilter(filterfunc,g,a,fmax,fs,winbw,scal,bwtruncmul,kv,flags) wrap_around = freqtoaud(fs/2,flags.audscale); next_fc = audtofreq(freqtoaud(fmax,flags.audscale)+kv.spacing,... flags.audscale); %Temporary filters are created up to this frequency fc_lim = audtofreq(freqtoaud(fs/2,'erb')+4,'erb'); temp_fc = []; % Temporary center frequencies and bandwidths for lowpass while (next_fc <= fc_lim) %(next_fc > 0) || (next_fc <= fc_lim) temp_fc(end+1) = next_fc; next_fc = audtofreq(freqtoaud(next_fc,flags.audscale)+kv.spacing,... flags.audscale); end if flags.do_symmetric temp_bw=audfiltbw(abs(temp_fc),flags.audscale)/winbw*kv.bwmul; plateauWidth = max(2*(fs/2-temp_fc(1)),0); Lw = @(L) min(ceil((plateauWidth+temp_bw(1)*bwtruncmul)*L/fs),L); else fsupp_scale=1/winbw*kv.bwmul; temp_bw = audtofreq(freqtoaud(temp_fc,flags.audscale)+fsupp_scale/2,flags.audscale)-... audtofreq(freqtoaud(temp_fc,flags.audscale)-fsupp_scale/2,flags.audscale); temp_low = audtofreq(freqtoaud(temp_fc(1),flags.audscale)-fsupp_scale/2,flags.audscale); Width = max(2*(fs/2-temp_low),0); Lw = @(L) min(ceil(Width*L/fs),L); end temp_g = cell(1,numel(temp_fc)); for m=1:numel(temp_g) temp_g{m}=filterfunc(temp_bw(m),temp_fc(m),1); end temp_fun = @(L) filterbankresponse(temp_g,1,L); temp_fbresp = @(L) filterbankresponse(g(2:end-1),a(2:end-1,:),L); ghigh.H = @(L) fftshift(long2fir(fftshift(sqrt(max(... postpad(min(10.*max((1:floor(L/2)+1).'./L-1/4,0),1),L).* ... (temp_fun(L) - flipud(circshift(temp_fbresp(L),-1))) + ... flipud(postpad(min(10.*max((1:ceil(L/2)-1).'./L-1/4,0),1),L).* ... (circshift(temp_fun(L),-1) - flipud(temp_fbresp(L)))) ... ,0))),Lw(L)))*scal; ghigh.foff = @(L) ceil(L/2)-floor(Lw(L)/2)-1; ghigh.realonly = 0; ghigh.delay = 0; ghigh.fs = g{2}.fs; function width = winwidthatheight(gnum,atheight) width = zeros(size(atheight)); for ii=1:numel(atheight) gl = numel(gnum); gmax = max(gnum); frac= 1/atheight(ii); fracofmax = gmax/frac; ind =find(gnum(1:floor(gl/2)+1)==fracofmax,1,'first'); if isempty(ind) %There is no sample exactly half of the height ind1 = find(gnum(1:floor(gl/2)+1)>fracofmax,1,'last'); ind2 = find(gnum(1:floor(gl/2)+1). % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Authors: Peter L. Soendergaard, Zdenek Prusa, Nicki Holighaus [g,a,fc,L]=audfilters(fs,Ls,varargin{:},'erb'); ltfat/inst/filterbank/u2nonucfmt.m0000664000175000017500000000651713026262304017147 0ustar susnaksusnakfunction c = u2nonucfmt(cu, p) %-*- texinfo -*- %@deftypefn {Function} u2nonucfmt %@verbatim %U2NONUCFMT Uniform to non-uniform filterbank coefficient format % Usage: c=u2nonucfmt(cu,pk) % % Input parameters: % cu : Uniform filterbank coefficients. % % Output parameters: % c : Non-uniform filterbank coefficients. % p : Numbers of copies of each filter. % % c = U2NONUCFMT(cu,pk) changes the coefficient format from % uniform filterbank coefficients cu (M=sum(p) channels) to % non-uniform coefficients c (numel(p) channels) such that each % channel of c consinst of p(m) interleaved channels of cu. % % The output c is a cell-array in any case. % % % References: % S. Akkarakaran and P. Vaidyanathan. Nonuniform filter banks: New % results and open problems. In P. M. C.K. Chui and L. Wuytack, editors, % Studies in Computational Mathematics: Beyond Wavelets, volume 10, pages % 259 --301. Elsevier B.V., 2003. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/u2nonucfmt.html} %@seealso{nonu2ufilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,mfilename); if isempty(cu) error('%s: cu must be non-empty.',upper(mfilename)); end if iscell(cu) if any(cellfun(@isempty,cu)); error('%s: Elements of cu must be non-empty.',upper(mfilename)); end M = numel(cu); W = size(cu{1},2); Lc = size(cu{1},1); if any(Lc~=cellfun(@(cEl)size(cEl,1),cu)) error('%s: Coefficient subbands do not have an uniform length',... upper(mfilename)); end elseif isnumeric(cu) M = size(cu,2); W = size(cu,3); Lc = size(cu,1); else error('%s: cu must be a cell array or numeric.',upper(mfilename)); end if isempty(p) || ~isvector(p) error('%s: p must be a non-empty vector.',upper(mfilename)); end if sum(p) ~= M error(['%s: Total number of filters in p does not comply with ',... 'number of channels'],upper(mfilename)); end Mnonu = numel(p); c = cell(Mnonu,1); p = p(:); pkcumsum = cumsum([1;p]); crange = arrayfun(@(pEl,pcEl)pcEl:pcEl+pEl-1,p,pkcumsum(1:end-1),'UniformOutput',0); if iscell(cu) for m=1:Mnonu ctmp = [cu{crange{m}}].'; c{m} = reshape(ctmp(:),W,[]).'; end else for m=1:Mnonu c{m} = zeros(p(m)*Lc,W,assert_classname(cu)); for w=1:W c{m}(:,w) = reshape(cu(:,crange{m},w).',1,[]); end end end % Post check whether there is the same number of coefficients if sum(cellfun(@(cEl) size(cEl,1),c)) ~= M*Lc error(['%s: Invalid number of coefficients in subbands.'],upper(mfilename)); end ltfat/inst/filterbank/filterbanklength.m0000664000175000017500000000343513026262304020366 0ustar susnaksusnakfunction 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.github.io/doc/filterbank/filterbanklength.html} %@seealso{filterbank, filterbanklengthcoef} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,upper(mfilename)); complainif_notposint(Ls,'Ls',upper(mfilename)); if ~isnumeric(a) || any(a(:)<=0) error('%s: "a" must be numeric consisting of positive numbers ony.',... upper(mfilename)); end; if isvector(a) a= a(:); 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; ltfat/inst/filterbank/icqt.m0000664000175000017500000000510113026262304015773 0ustar susnaksusnakfunction fr = icqt(c,g,shift,Ls,dual) %-*- texinfo -*- %@deftypefn {Function} icqt %@verbatim %ICQT Constant-Q non-stationary 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. % % % 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.github.io/doc/filterbank/icqt.html} %@seealso{cqt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Author: Nicki Holighaus % Date: 10.04.13 if ~exist('dual','var') dual = 1; end fr = comp_insdgfb(c,g,shift,Ls,dual); ltfat/inst/filterbank/Contents.m0000664000175000017500000000607413026262304016642 0ustar susnaksusnak% LTFAT - Filterbanks % % Peter L. Soendergaard, 2011 - 2016 % % Transforms and basic routines % FILTERBANK - Filter bank % UFILTERBANK - Uniform Filter bank % IFILTERBANK - Inverse normal/uniform filter bank % IFILTERBANKITER - Iteratively inverse filter bank % FILTERBANKWIN - Evaluate filter bank window % FILTERBANKLENGTH - Length of filter bank to expand signal % FILTERBANKLENGTHCOEF - Length of filter bank to expand coefficients % % Auditory inspired filter banks % CQT - Constant-Q transform % ICQT - Inverse constant-Q transform % ERBLETT - Erb-let transform % IERBLETT - Inverse Erb-let transform % % Filter generators % CQTFILTERS - Logarithmically spaced filters % ERBFILTERS - ERB-spaced filters % WARPEDFILTERS - Frequency-warped filters % AUDFILTERS - Filters based on auditory scales % % Window construction and bounds % FILTERBANKDUAL - Canonical dual filters % FILTERBANKTIGHT - Canonical tight filters % FILTERBANKREALDUAL - Canonical dual filters for real-valued signals % FILTERBANKREALTIGHT - Canonical tight filters for real-valued signals % FILTERBANKBOUNDS - Frame bounds of filter bank % FILTERBANKREALBOUNDS - Frame bounds of filter bank for real-valued signals % FILTERBANKRESPONSE - Total frequency response (a frame property) % % Auxilary % FILTERBANKFREQZ - Frequency responses of filters % FILTERBANKSCALE - Scaling and normalization of filters % NONU2UFILTERBANK - Non-uni. to uniform filter bank transformation % U2NONUCFMT - Change format of coefficients % NONU2UCFMT - Change format of coefficients back % % Plots % PLOTFILTERBANK - Plot normal/uniform filter bank coefficients % % Reassignment and phase gradient % FILTERBANKPHASEGRAD - Instantaneous time/frequency from signal % FILTERBANKREASSIGN - Reassign filterbank spectrogram % FILTERBANKSYNCHROSQUEEZE - Synchrosqueeze filterbank spectrogram % % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/filterbank/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/filterbank/cent_freqs.m0000664000175000017500000000562413026262304017176 0ustar susnaksusnakfunction cfreq = cent_freqs(g,L) %-*- texinfo -*- %@deftypefn {Function} cent_freqs %@verbatim %CENT_FREQS Determine relative center frequencies % Usage: cfreq = cent_freqs(g); % cfreq = cent_freqs(g,L); % cfreq = cent_freqs(fs,fc); % cfreq = cent_freqs(g,fc); % % Input parameters: % g : Set of filters. % L : Signal length. % fs : Sampling rate (in Hz). % fc : Vector of center frequencies (in Hz). % Output parameters: % cfreq : Vector of relative center frequencies in ]-1,1]. % % CENT_FREQS(g) will compute the center frequencies of the filters % contained in g by determining their circular center of gravity. To % that purpose, the transfer function of each filter will be computed for % a default signal length on 10000 samples. For improved accuracy, the % factual signal length L can be supplied as an optional parameter. % Alternatively, the center frequencies can be obtained from a set of % center frequencies fc (in Hz) and the sampling rate fs. The % sampling rate can also be determined from the field fs of the filter % set g. % % Note: If g.H contains full-length, numeric transfer functions, L* % must be specified for correct results. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/cent_freqs.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'FILTERBANKCENTFREQS'); if nargin > 1 % Try to determine cfreq from fc and fs in Hz if numel(g) == 1 && isnumeric(g) && numel(L) > 1 cfreq = modcent(2*L/g,2); return elseif numel(g) == numel(L) && ( numel(g) > 1 || isfield(g,'fs') ) cfreq = cellfun(@(fcEl,gEl) modcent(2*fcEl/gEl.fs,2),num2cell(L),g.'); return end else L = 10000; % Default value end g = filterbankwin(g,1,L,'normal'); % Compute l1-normalized absolute value of the transfer functions gH = cellfun(@(gEl) comp_transferfunction(gEl,L),g,'UniformOutput',false); gH = cellfun(@(gHEl) abs(gHEl)./norm(gHEl,1),gH,'UniformOutput',false); % Compute circular center of gravity circInd = exp(2*pi*1i*(0:L-1)/L).'; cfreq = cellfun(@(gHEl) sum(circInd.*gHEl),gH.'); cfreq = real((pi*1i)\log(cfreq)); ltfat/inst/filterbank/cqtfilters.m0000664000175000017500000003223313026262304017221 0ustar susnaksusnakfunction [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,fmin,fmax,bins,Ls,varargin); % % % 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 % remaining 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 chosen, but the % window can be changed by passing any of the window types from % FIRWIN as an optional parameter. % Run getfield(getfield(arg_firwin,'flags'),'wintype') to get a cell % array of window types available. % % 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 % filter bank. 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 filter bank % 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 filter bank with % fractional downsampling rates a. The rates are constructed such % that the filter bank 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 filter bank 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 useful 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: % % '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 filter bank 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. % % Examples: % --------- % % In the first example, we construct a highly redundant uniform % filter bank and visualize the result: % % [f,fs]=greasy; % Get the test signal % [g,a,fc]=cqtfilters(fs,100,fs,32,length(f),'uniform'); % c=filterbank(f,g,a); % plotfilterbank(c,a,fc,fs,90,'audtick'); % % In the second example, we construct a non-uniform filter bank with % fractional sampling that works for this particular signal length, and % test the reconstruction. The plot displays the response of the % filter bank to verify that the filters are well-behaved both on a % normal and an log scale. The second plot shows frequency responses of % filters used for analysis (top) and synthesis (bottom). : % % [f,fs]=greasy; % Get the test signal % L=length(f); % [g,a,fc]=cqtfilters(fs,100,fs,8,L,'fractional'); % c=filterbank(f,{'realdual',g},a); % r=2*real(ifilterbank(c,g,a)); % norm(f-r) % % % Plot the response % figure(1); % 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'); % % % Plot frequency responses of individual filters % gd=filterbankrealdual(g,a,L); % figure(2); % subplot(2,1,1); % filterbankfreqz(gd,a,L,fs,'plot','linabs','posfreq'); % % subplot(2,1,2); % filterbankfreqz(g,a,L,fs,'plot','linabs','posfreq'); % % % 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.github.io/doc/filterbank/cqtfilters.html} %@seealso{erbfilters, cqt, firwin, filterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Authors: Nicki Holighaus, Gino Velasco % Date: 10.04.13 % Modified by: Zdenek Prusa % Date: 10.02.14 %% Check input arguments complainif_notenoughargs(nargin,5,upper(mfilename)); complainif_notposint(fs,'fs',upper(mfilename)); complainif_notposint(fmin,'fmin',upper(mfilename)); complainif_notposint(fmax,'fmax',upper(mfilename)); complainif_notposint(bins,'bins',upper(mfilename)); complainif_notposint(Ls,'Ls',upper(mfilename)); 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 % This will leave the first bigger than fmax it it is lower than 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] 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 % Do that only for the constant Q filters fsupp(2:end-1) = kv.Qvar*fsupp(2:end-1); % Lowpass and highpass filters has to be treated differently fsupp([1,end]) = fsupp([1,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; aprecise=aprecise(:); if any(aprecise<1) error(['%s: Bandwidth of one of the filters is bigger than fs. ',... 'Check fmin and fmax, number of bins and Qval'],upper(mfilename)); end aprecise=aprecise/kv.redmul; 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 = [{aprecise(1)};aocts;aprecise(end)]; %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 a=[a;flipud(a(2:M2-1,:))]; 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,numel(fc)); for m=1:numel(g) g{m} = blfilter(flags.wintype,fsupp(m),fc(m),'fs',fs,'scal',scal(m),... 'inf','min_win',kv.min_win); 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 ltfat/inst/filterbank/erblett.m0000664000175000017500000001467213026262304016511 0ustar susnaksusnakfunction [c,Ls,g,shift,M] = erblett(f,bins,fs,varargin) %-*- texinfo -*- %@deftypefn {Function} erblett %@verbatim %ERBLETT ERBlet non-stationary 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 non-stationary % 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.github.io/doc/filterbank/erblett.html} %@seealso{ierblett, firwin} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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 ltfat/inst/filterbank/nonu2ufilterbank.m0000664000175000017500000001012013026262304020320 0ustar susnaksusnakfunction [gu,au,p]=nonu2ufilterbank(g,a) %-*- texinfo -*- %@deftypefn {Function} nonu2ufilterbank %@verbatim %NONU2UFILTERBANK Non-uniform to uniform filterbank transform % Usage: [gu,au]=nonu2ufilterbank(g,a) % % Input parameters: % g : Filters as a cell array of structs. % a : Subsampling factors. % % Output parameters: % gu : Filters as a cell array of structs. % au : Uniform subsampling factor. % pk : Numbers of copies of each filter. % % [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(k)=au/a(k) advanced versions of itself such that % 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 FILTERBANKREALDUAL which do not work % with non-uniform filterbanks. % % One can change between the coefficient formats of gu, au and % g, a using NONU2UCFMT and U2NONUCFMT in the reverse direction. % % % References: % S. Akkarakaran and P. Vaidyanathan. Nonuniform filter banks: New % results and open problems. In P. M. C.K. Chui and L. Wuytack, editors, % Studies in Computational Mathematics: Beyond Wavelets, volume 10, pages % 259 --301. Elsevier B.V., 2003. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/nonu2ufilterbank.html} %@seealso{ufilterbank, filterbank, filterbankbounds, filterbankdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'NONU2UFILTERBANK'); try [g,asan] = filterbankwin(g,a,'normal'); catch err = lasterror; if strcmp(err.identifier,'L:undefined') % If it blotched because of the undefined L, explain that. % This should capture only formats like {'dual',...} and {'gauss'} error(['%s: Function cannot handle g in a format which ',... 'requires L. Consider pre-formatting the filterbank by ',... 'calling g = FILTERBANKWIN(g,a,L).'],upper(mfilename)); else % Otherwise just rethrow the error error(err.message); end end % This function does not work for fractional subsampling if size(asan,2)==2 && ~all(asan(:,2)==1) && rem(asan(:,1),1)~=0 error(['%s: Filterbanks with fractional subsampling are not',... ' supported.'],upper(mfilename)); end % This is effectivelly lcm(a) au=filterbanklength(1,asan); % Numbers of copies of each filter p = au./asan(:,1); if all(asan(:,1)==asan(1,1)) % Filterbank is already uniform, there is nothing to be done. gu = g; au = asan; return; end % Do the actual filter copies % This only changes .delay or .offset gu=cell(sum(p),1); auIdx = 1; for m=1:numel(g) for ii=0:p(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-asan(m)*ii; end if(isfield(gu{auIdx},'h')) if(~isfield(gu{auIdx},'offset')) gu{auIdx}.offset = 0; end gu{auIdx}.offset = gu{auIdx}.offset-asan(m)*ii; end auIdx = auIdx+1; end end ltfat/inst/filterbank/filterbankfreqz.m0000664000175000017500000000426313026262304020234 0ustar susnaksusnakfunction gf = filterbankfreqz(g,a,L,varargin) %-*- texinfo -*- %@deftypefn {Function} filterbankfreqz %@verbatim %FILTERBANKFREQZ Filterbank frequency responses % Usage: gf = filterbankfreqz(g,a,L) % % gf = FILTERBANKFREQZ(g,a,L) calculates length L frequency responses % of filters in g and returns them as columns of gf. % % If an optional parameters 'plot' is passed to FILTERBANKFREQZ, % the frequency responses will be plotted using PLOTFFT. Any % optional parameter undestood by PLOTFFT can be passed in addition % to 'plot'. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankfreqz.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,3,'FILTERBANKFREQZ'); complainif_notposint(L,'L','FILTERBANKFREQZ'); % Wrap g if it is not a cell. The format of g will be checked % further in filterbankwin. if ~iscell(g) g = {g}; end % The only place we need a % It is necessary for cases when filterbank is given by e.g. % {'dual',g} g = filterbankwin(g,a,L,'normal'); M = numel(g); G1=comp_transferfunction(g{1},L); gf = zeros(L,M,class(G1)); gf(:,1) = G1; for m=2:M gf(:,m) = cast(comp_transferfunction(g{m},L),class(G1)); end % Search for the 'plot' flag do_plot = any(strcmp('plot',varargin)); if do_plot % First remove the 'plot' flag from the arguments varargin(strcmp('plot',varargin)) = []; % and pass everything else to plotfft plotfft(gf,varargin{:}); end; if nargout<1 clear gf; end ltfat/inst/filterbank/filterbankrealdual.m0000664000175000017500000001115313026262304020672 0ustar susnaksusnakfunction gdout=filterbankrealdual(g,a,varargin) %-*- texinfo -*- %@deftypefn {Function} filterbankrealdual %@verbatim %FILTERBANKREALDUAL Dual filters of filterbank for real signals only % Usage: gd=filterbankrealdual(g,a,L); % gd=filterbankrealdual(g,a); % % FILTERBANKREALDUAL(g,a,L) computes the canonical dual filters of g* % for a channel subsampling rate of a (hop-size) and a system length L. % L must be compatible with subsampling rate a as % L==filterbanklength(L,a). 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. % % filterabankrealdual(g,a) does the same, but the filters must be FIR % filters, as the transform length is unspecified. L will be set to % next suitable length equal or bigger than the longest impulse response. % % The format of the filters g are described in the help of FILTERBANK. % % In addition, the function recognizes a 'forcepainless' flag which % forces treating the filterbank g and a as a painless case % filterbank. % % To actually invert the output of a filterbank, use the dual filters % together with 2*real(ifilterbank(...)). % % REMARK: Perfect reconstruction can be obtained for signals of length % L. In some cases, using dual system calculated for shorter L might % work but check the reconstruction error. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankrealdual.html} %@seealso{filterbank, ufilterbank, ifilterbank} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FILTERBANKREALDUAL'); definput.import={'filterbankdual'}; [flags,~,L]=ltfatarghelper({'L'},definput,varargin); [g,asan,info]=filterbankwin(g,a,L,'normal'); if isempty(L) if info.isfir % Pick shortest possible length for FIR filterbank L = filterbanklength(info.longestfilter,asan); else % Just thow an error, nothing reasonable can be done without L error(['%s: L must be specified when not working with FIR ',...' 'filterbanks.'], upper(mfilename)); end end M=info.M; % Force usage of the painless algorithm if flags.do_forcepainless info.ispainless = 1; end if 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 a=a(1); % Transfer functions of individual filters as cols G = filterbankfreqz(g,a,L); thisclass = class(G); 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(M,N,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; % The gd was created transposed because the indexing gd(:,idx_a) % is much faster than gd(idx_a,:) gd=gd.'; gd=ifft(gd)*a; gdout = cellfun(@(gdEl) cast(gdEl,thisclass), num2cell(gd,1),... 'UniformOutput',0); % All filters in gdout will be treated as FIR of length L. Convert them % to a struct with .h and .offset format. gdout = filterbankwin(gdout,a); elseif info.ispainless gdout = comp_painlessfilterbank(g,asan,L,'dual',1); else error(['%s: The canonical dual frame of this system is not a ' ... 'filterbank. You must call an iterative ' ... 'method to perform the desired inversion. Please see ' ... 'FRANAITER or FRSYNITER.'],upper(mfilename)); end; ltfat/inst/filterbank/filterbankreassign.m0000664000175000017500000001355013026262304020717 0ustar susnaksusnakfunction [sr,repos,Lc]=filterbankreassign(s,tgrad,fgrad,a,var) %-*- texinfo -*- %@deftypefn {Function} filterbankreassign %@verbatim %FILTERBANKREASSIGN Reassign filterbank spectrogram % Usage: sr = filterbankreassign(s,tgrad,fgrad,a,cfreq); % sr = filterbankreassign(s,tgrad,fgrad,a,g); % [sr,repos,Lc] = filterbankreassign(...); % % Input parameters: % s : Spectrogram to be reassigned. % tgrad : Instantaneous frequency relative to original position. % fgrad : Group delay relative to original position. % a : Vector of time steps. % cfreq : Vector of relative center frequencies in ]-1,1]. % g : Set of filters. % Output parameters: % sr : Reassigned filterbank spectrogram. % repos : Reassigned positions. % Lc : Subband lengths. % % FILTERBANKREASSIGN(s,tgrad,fgrad,a,cfreq) will reassign the values of % the filterbank spectrogram s using the group delay fgrad and % instantaneous frequency tgrad. The time-frequency sampling % pattern is determined from the time steps a and the center % frequencies cfreq. % % FILTERBANKREASSIGN(s,tgrad,fgrad,a,g) will do the same thing except % the center frequencies are estimated from a set of filters g. % % [sr,repos,Lc]=FILTERBANKREASSIGN(...) does the same thing, but in addition % returns a vector of subband lengths Lc (Lc = cellfun(@numel,s)) % and cell array repos with sum(Lc) elements. Each element corresponds % to a single coefficient obtained by cell2mat(sr) and it is a vector % of indices identifying coefficients from cell2mat(s) assigned to % the particular time-frequency position. % % The arguments s, tgrad and fgrad must be cell-arrays of vectors % of the same lengths. Arguments a and cfreq or g must have the % same number of elements as the cell arrays with coefficients. % % Examples: % --------- % % This example shows how to reassign a ERB filterbank spectrogram: % % % Genrate 3 chirps 1 second long % L = 44100; fs = 44100; l = 0:L-1; % % f = sin(2*pi*(l/35+(l/300).^2)) + ... % sin(2*pi*(l/10+(l/300).^2)) + ... % sin(2*pi*(l/5-(l/450).^2)); % f = 0.7*f'; % % % Create ERB filterbank % [g,a,fc]=erbfilters(fs,L,'fractional','spacing',1/12,'warped'); % % % Compute phase gradient % [tgrad,fgrad,cs,c]=filterbankphasegrad(f,g,a); % % Do the reassignment % sr=filterbankreassign(cs,tgrad,fgrad,a,cent_freqs(fs,fc)); % figure(1); subplot(211); % plotfilterbank(cs,a,fc,fs,60); % title('ERBlet spectrogram of 3 chirps'); % subplot(212); % plotfilterbank(sr,a,fc,fs,60); % title('Reassigned ERBlet spectrogram of 3 chirps'); % % % References: % N. Holighaus, Z. Průša, and P. L. Soendergaard. Reassignment and % synchrosqueezing for general time-frequency filter banks, subsampling % and processing. Signal Processing, 125:1--8, 2016. [1]http ] % % References % % 1. http://www.sciencedirect.com/science/article/pii/S0165168416000141 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankreassign.html} %@seealso{filterbankphasegrad, gabreassign} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Nicki Holighaus. % Sanity checks complainif_notenoughargs(nargin,5,'FILTERBANKREASSIGN'); if isempty(s) || ~iscell(s) error('%s: s should be a nonempty cell array.',upper(mfilename)); end if isempty(tgrad) || ~iscell(tgrad) || any(~cellfun(@isreal,tgrad)) error('%s: tgrad should be a nonempty cell array of real vectors.',... upper(mfilename)); end if isempty(fgrad) || ~iscell(fgrad) || any(~cellfun(@isreal,fgrad)) error('%s: fgrad should be a nonempty cell array of real vectors.',... upper(mfilename)); end if any(cellfun(@(sEl,tEl,fEl) ~isvector(sEl) || ~isvector(tEl) || ... ~isvector(fEl), s,tgrad,fgrad)) error('%s: s, tgrad, fgrad must be cell arrays of numeric vectors.',... upper(mfilename)); end if ~isequal(size(s),size(tgrad),size(fgrad)) || ... any(cellfun(@(sEl,tEl,fEl) ~isequal(size(sEl),size(tEl),size(fEl)), ... s,tgrad,fgrad)) error('%s: s, tgrad, fgrad does not have the same format.',upper(mfilename)); end W = cellfun(@(sEl)size(sEl,2),s); if any(W>1) error('%s: Only one-channel signals are supported.',upper(mfilename)); end % Number of channels M = numel(s); % Number of elements in channels Lc = cellfun(@(sEl)size(sEl,1),s); % Sanitize a a=comp_filterbank_a(a,M); a = a(:,1)./a(:,2); % Check if a comply with subband lengths L = Lc.*a; if any(abs(L-L(1))>1e-6) error(['%s: Subsampling factors and subband lengths do not ',... 'comply.'],upper(mfilename)); end L = L(1); % Determine center frequencies if isempty(var) || numel(var)~=M || ~isvector(var) && ~iscell(var) error(['%s: cfreq must be length-M numeric vector or a cell-array ',... 'containg M filters.'],upper(mfilename)); else if iscell(var) cfreq = cent_freqs(var,L); else cfreq = var; end end % Do the computations if nargout>1 [sr,repos] = comp_filterbankreassign(s,tgrad,fgrad,a,cfreq); else sr = comp_filterbankreassign(s,tgrad,fgrad,a,cfreq); end ltfat/inst/filterbank/filterbankscale.m0000664000175000017500000001744513026262304020202 0ustar susnaksusnakfunction g = filterbankscale(g,varargin) %-*- texinfo -*- %@deftypefn {Function} filterbankscale %@verbatim %FILTERBANKSCALE Scale filters in filterbank % Usage: g=filterbankscale(g,scal) % g=filterbankscale(g,'flag') % g=filterbankscale(g,L,'flag') % % g=FILTERBANKSCALE(g,s) scales each filter in g by multiplying it % with scal. scal can be either scalar or a vector of the same length % as g. % The function only works with filterbanks already instantiated % (returned from a function with a filter (of filters) suffix or run trough % FILTERBANKWIN) such that the elements of g must be either structs % with .h or .H fields or be plain numeric vectors. % % g=FILTERBANKSCALE(g,'flag') instead normalizes each filter to have % unit norm defined by 'flag'. It can be any of the flags recognized by % NORMALIZE. The normalization is done in the time domain by default. % The normalization can be done in frequency by passing extra flag 'freq'. % % g=FILTERBANKSCALE(g,L,'flag') works as before, but some filters require % knowing L to be instantialized to obtain their norm. The normalization % will be valid for the lengh L only. % % In any case, the returned filters will be in exactly the same format as % the input filters. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankscale.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %AUTHOR: Zdenek Prusa complainif_notenoughargs(nargin,2,'FILTERBANKSCALE'); definput.import={'normalize'}; definput.importdefaults={'norm_notset'}; definput.flags.normfreq = {'nofreq','freq'}; definput.keyvals.arg1 = []; [flags,kv,arg1]=ltfatarghelper({'arg1'},definput,varargin); % Try running filterbankwin without L. This should fail % for any strange filter definitions like 'gauss','hann',{'dual',...} try filterbankwin(g,1,'normal'); catch err = lasterror; if strcmp(err.identifier,'L:undefined') % If it blotched because of the undefined L, explain that. % This should capture only formats like {'dual',...} and {'gauss'} error(['%s: Function cannot handle g in such format. ',... 'Consider pre-formatting the filterbank by ',... 'calling g = FILTERBANKWIN(g,a) or ',... 'g = FILTERBANKWIN(g,a,L) first.'],upper(mfilename)); else % Otherwise just rethrow the error error(err.message); end end % At this point, elements of g can only be: % struct with numeric field .h, % struct with numeric field .H % struct with function handle in .H % numeric vectors if flags.do_norm_notset % No flag from normalize was set s = scalardistribute(arg1,ones(size(g))); for ii=1:numel(g) if isstruct(g{ii}) % Only work with .h or .H, any other struct field is not % relevant if isfield(g{ii},'h') if ~isnumeric(g{ii}.h) error('%s: g{ii}.h must be numeric',upper(mfilename)); end g{ii}.h = s(ii)*g{ii}.h; elseif isfield(g{ii},'H') if isa(g{ii}.H,'function_handle') g{ii}.H = @(L) s(ii)*g{ii}.H(L); elseif isnumeric(g{ii}.H) g{ii}.H = s(ii)*g{ii}.H; else error(['%s: g{ii}.H must be either numeric or a ',... ' function handle'],upper(mfilename)); end else error('%s: SENTINEL. Unrecognized filter struct format',... upper(mfilename)); end elseif isnumeric(g{ii}) % This is easy g{ii} = s(ii)*g{ii}; else error('%s: SENTINEL. Unrecognized filter format',... upper(mfilename)); end end else % Normalize flag was set for ii=1:numel(g) L = arg1; % can be still empty % Run again with L specified [g2,~,info] = filterbankwin(g,1,L,'normal'); if ~isempty(L) && L < max(info.gl) error('%s: One of the windows is longer than the transform length.',upper(mfilename)); end; if isstruct(g{ii}) if isfield(g{ii},'h') if ~isnumeric(g{ii}.h) error('%s: g{ii}.h must be numeric',upper(mfilename)); end % Normalize either in time or in the frequency domain if flags.do_freq complain_L(L); % Get frequency response and it's norm H = comp_transferfunction(g2{ii},L); [~,fn] = normalize(H,flags.norm); g{ii}.h = g{ii}.h/fn; else if isfield(g{ii},'fc') && g{ii}.fc~=0 complain_L(L); % L is required to do a proper modulation else L = numel(g2{ii}.h); end % Get impulse response with all the fields applied tmpg = comp_filterbank_pre(g2(ii),1,L,inf); [~,fn] = normalize(tmpg{1}.h,flags.norm); g{ii}.h = g{ii}.h/fn; end elseif isfield(g{ii},'H') if isa(g{ii}.H,'function_handle') complain_L(L); H = comp_transferfunction(g2{ii},L); if flags.do_freq [~,fn] = normalize(H,flags.norm); g{ii}.H = @(L) g{ii}.H(L)/fn; else [~,fn] = normalize(ifft(H),flags.norm); g{ii}.H = @(L) g{ii}.H(L)/fn; end elseif isnumeric(g{ii}.H) if ~isfield(g{ii},'L') error('%s: g.H is numeric, but .L field is missing',... upper(mfilename)); end if isempty(L) L = g{ii}.L; else if L ~= g{ii}.L error('%s: L and g.L are not equal',... upper(mfilename)); end end H = comp_transferfunction(g2{ii},L); if flags.do_freq [~,fn] = normalize(H,flags.norm); g{ii}.H = g{ii}.H/fn; else [~,fn] = normalize(ifft(H),flags.norm); g{ii}.H = g{ii}.H/fn; end end else error('%s: SENTINEL. Unrecognized filter struct format',... upper(mfilename)); end elseif isnumeric(g{ii}) % This one is not so easy if flags.do_freq complain_L(L); % We must use g2 here [~, fn] = normalize(fft(g2{ii}.h,L),flags.norm); g{ii} = g{ii}/fn; else g{ii} = normalize(g{ii},flags.norm); end else error('%s: SENTINEL. Unrecognized filter format',... upper(mfilename)); end end end function complain_L(L) if isempty(L) error('%s: L must be specified',upper(mfilename)); end complainif_notposint(L,'L',mfilename) ltfat/inst/filterbank/filterbankrealbounds.m0000664000175000017500000001014513026262304021237 0ustar susnaksusnakfunction [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,L); % [A,B]=filterbankrealbounds(g,a,L); % [...]=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. % % FILTERBANKREALBOUNDS(g,a) does the same, but the filters must be FIR % filters, as the transform length is unspecified. L will be set to % next suitable length equal or bigger than the longest impulse response % such that L=filterbanklength(gl_longest,a). % % [A,B]=FILTERBANKREALBOUNDS(g,a) returns the lower and upper frame % bounds explicitly. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/filterbankrealbounds.html} %@seealso{filterbank, filterbankdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FILTERBANKREALBOUNDS'); if nargin<3 L = []; end [g,asan,info]=filterbankwin(g,a,L,'normal'); if isempty(L) if info.isfir % Pick shortest possible length for FIR filterbank L = filterbanklength(info.longestfilter,asan); else % Just thow an error, nothing reasonable can be done without L error(['%s: L must be specified when not working with FIR ',...' 'filterbanks.'], upper(mfilename)); end end M=info.M; if L~=filterbanklength(L,asan) error(['%s: Specified length L is incompatible with the length of ' ... 'the time shifts.'],upper(mfilename)); end; AF=Inf; BF=0; % Prioritize painless over uniform algorithm if info.isuniform && info.ispainless info.isuniform = 0; end 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)=cast(comp_transferfunction(g{ii},L),thisclass); 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,asan,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; ltfat/inst/filterbank/warpedfilters.m0000664000175000017500000003573413026262304017725 0ustar susnaksusnakfunction [g,a,fc,L]=warpedfilters(freqtoscale,scaletofreq,fs,fmin,fmax,bins,Ls,varargin) %-*- texinfo -*- %@deftypefn {Function} warpedfilters %@verbatim %WARPEDFILTERS Frequency-warped band-limited filters % Usage: [g,a,fc]=warpedfilters(freqtoscale,scaletofreq,fs,fmin,fmax,bins,Ls); % % Input parameters: % freqtoscale : Function converting frequency (Hz) to scale units % scaletofreq : Function converting scale units to frequency (Hz) % 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 (in Hz). % L : Next admissible length suitable for the generated filters. % % [g,a,fc]=WARPEDFILTERS(freqtoscale,scaletofreq,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 scale unit. The % filters are always centered at full (fractional k/bins) scale units, % where the first filter is selected such that its center is lower than % fmin. % % 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. % Run getfield(getfield(arg_firwin,'flags'),'wintype') to get a cell % array of window types available. % % With respect to the selected scale, all filters have equal bandwidth % and are uniformly spaced on the scale axis, e.g. if freqtoscale is % log(x), then we obtain constant-Q filters with geometric spacing. % The remaining frequency intervals not covered by these filters are % captured one or two additional filters (high-pass always, low-pass if % necessary). The signal length Ls is required in order to obtain the % optimal normalization factors. % % Attention: When using this function, the user needs to be aware of a % number of things: % % a) Although the freqtoscale and scaletofreq can be chosen % freely, it is assumed that freqtoscale is an invertible, % increasing function from {R} or {R}^+ onto % {R} and that freqtoscale is the inverse function. % b) If freqtoscale is from {R}^+ onto {R}, then % necessarily freqtoscale(0) = -infty. % c) If the slope of freqtoscale is (locally) too steep, then % there is the chance that some filters are effectively 0 or % have extremely low bandwidth (1-3 samples), and consequently % very poor localization in time. If freqtoscale is from % {R}^+ onto {R} then this usually occurs close % to the DC component and can be alleviated by increasing fmin. % d) Since the input parameter bins is supposed to be integer, % freqtoscale and scaletofreq have to be scaled % appropriately. Note that freqtoscale(fs) is in some sense % proportional to the resulting number of frequency bands and % inversely proportional to the filter bandwidths. For example, % the ERB scale defined by 21.4log_{10}(1+f/228.8) works % nicely out of the box, while the similar mel scale % 2595log_{10}(1+f/700) most likely has to be rescaled in % order not to provide a filter bank with 1000s of channels. % % If any of these guidelines are broken, this function is likely to break % or give undesireable results. % % By default, a Hann window is chosen as the transfer function prototype, % but the window can be changed by passing any of the window types from % FIRWIN as an optional parameter. % % The integer downsampling rates of the channels must all divide the % signal length, FILTERBANK will only work for input signal lengths % being multiples of the least common multiple of the downsampling rates. % See the help of FILTERBANKLENGTH. % The fractional downsampling rates restrict the filterbank to a single % length L=Ls. % % [g,a]=WARPEDFILTERS(...,'regsampling') constructs a non-uniform % filterbank with integer subsampling factors. % % [g,a]=WARPEDFILTERS(...,'uniform') constructs a uniform filterbank % where the the downsampling rate is the same for all the channels. This % results in most redundant representation, which produces nice plots. % % [g,a]=WARPEDFILTERS(...,'fractional') constructs a filterbank with % fractional downsampling rates a. This results in the % least redundant system. % % [g,a]=WARPEDFILTERS(...,'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. % % WARPEDFILTERS accepts the following optional parameters: % % 'bwmul',bwmul % 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. % % 'complex' % Construct a filterbank that covers the entire % frequency range. When missing, only positive % frequencies are covered. % % '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. % % Examples: % --------- % % In the first example, we use the ERB scale functions freqtoerb and % erbtofreq to construct a filter bank and visualize the result: % % [s,fs] = gspi; % Get a test signal % Ls = numel(gspi); % % % Fix some parameters % fmax = fs/2; % bins = 1; % % % Compute filters, using fractional downsampling % [g,a,fc]=warpedfilters(@freqtoerb,@erbtofreq,fs,0,fmax,bins,... % Ls,'bwmul',1.5,'real','fractional'); % % % Plot the filter transfer functions % figure(1); % filterbankfreqz(g,a,Ls,'plot','linabs','posfreq'); % title('ERBlet filter transfer functions'); % % % Compute the frame bounds % gf=filterbankresponse(g,a,Ls,'real'); framebound_ratio = max(gf)/min(gf); % disp(['Painless system frame bound ratio of ERBlets: ',... % num2str(framebound_ratio)]); % % % Plot the filter bank coefficients of the test signal % figure(2); % c=filterbank(s,g,a); % plotfilterbank(c,a,fc,fs,60); % title('ERBlet transform of the test signal'); % % In the second example, we look at the same test signal using a % constant-Q filter bank with 4 bins per scale unit and the standard % (semi-regular) sampling scheme: % % [s,fs] = gspi; % Get a test signal % Ls = numel(gspi); % % % Fix some parameters % fmax = fs/2; % bins = 1; % % % Define the frequency-to-scale and scale-to-frequency functions % warpfun_log = @(x) 10*log(x); % invfun_log = @(x) exp(x/10); % % bins_hi = 4; % Select bins/unit parameter % fmin = 50; % The logarithm's derivative 1/x tends to Inf for x towards 0 % % % Compute filters, using fractional downsampling % [g,a,fc]=warpedfilters(warpfun_log,invfun_log,fs,fmin,fmax,bins_hi,Ls,'bwmul',1,'real'); % % % Plot the filter transfer functions % figure(1); % filterbankfreqz(g,a,Ls,'plot','linabs','posfreq'); % title('constant-Q filter transfer functions (4 bins)'); % % % Compute the frame bounds % gf=filterbankresponse(g,a,Ls,'real'); framebound_ratio = max(gf)/min(gf); % disp(['Painless system frame bound ratio (constant-Q - 4 bins): ', num2str(framebound_ratio)]); % % % Plot the filter bank coefficients of the test signal % figure(2); % c=filterbank(s,g,a); % plotfilterbank(c,a,fc,fs,60); % title('constant-Q transform of the test signal (4 bins)'); % % % References: % N. Holighaus, Z. Průša, and C. Wiesmeyr. Designing tight filter bank % frames for nonlinear frequency scales. Sampling Theory and Applications % 2015, submitted, 2015. % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/warpedfilters.html} %@seealso{erbfilters, cqtfilters, firwin, filterbank, warpedblfilter} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % Authors: Nicki Holighaus, Zdenek Prusa % Date: 14.01.15 %% Check input arguments capmname = upper(mfilename); complainif_notenoughargs(nargin,7,capmname); complainif_notposint(fs,'fs',capmname); complainif_notposint(fmin+1,'fmin',capmname); complainif_notposint(fmax,'fmax',capmname); complainif_notposint(bins,'bins',capmname); complainif_notposint(Ls,'Ls',capmname); if ~isa(freqtoscale,'function_handle') error('%s: freqtoscale must be a function handle',capmname) end if ~isa(scaletofreq,'function_handle') error('%s: scaletofreq must be a function handle',capmname) end if fmin>=fmax error('%s: fmin has to be less than fmax.',capmname); end definput.import = {'firwin'}; definput.keyvals.bwmul = 1; definput.keyvals.redmul = 1; definput.keyvals.min_win = 1; definput.flags.real = {'real','complex'}; definput.flags.sampling = {'regsampling','uniform',... 'fractional','fractionaluniform'}; [flags,kv]=ltfatarghelper({},definput,varargin); if ~isscalar(kv.bwmul) error('%s: bwmul must be scalar',capmname) end if ~isscalar(kv.redmul) error('%s: redmul must be scalar',capmname) end if ~isscalar(kv.min_win) error('%s: min_win must be scalar',capmname) end % Nyquist frequency nf = fs/2; % Limit fmax if fmax > nf fmax = nf; end % Limit fmin if fmin <= 0 && freqtoscale(0) == -Inf fmin = scaletofreq(freqtoscale(1)); end %Determine range/number of windows chan_min = floor(bins*freqtoscale(fmin))/bins; if chan_min >= fmax; error('%s: Invalid frequency scale, try lowering fmin',... upper(mfilename)); end chan_max = chan_min; while scaletofreq(chan_max) <= fmax chan_max = chan_max+1/bins; end while scaletofreq(chan_max+kv.bwmul) >= nf chan_max = chan_max-1/bins; end % Prepare frequency centers in Hz scalevec = (chan_min:1/bins:chan_max)'; fc = [scaletofreq(scalevec);nf]; if fmin~=0 fc = [0;fc]; end M = length(fc); %% ---------------------------------- % Set bandwidths fsupp = zeros(M,1); % Bandwidth of the low-pass filter around 0 (Check whether floor and/or +1 % is sufficient!!!) fsuppIdx = 1; if fmin~=0 fsupp(1) = ceil(2*scaletofreq(chan_min-1/bins+kv.bwmul))+2; fsuppIdx = 2; end fsupp(fsuppIdx:M-1) = ceil(scaletofreq(scalevec+kv.bwmul)-scaletofreq(scalevec-kv.bwmul))+2; fsupp(M) = ceil(2*(nf-scaletofreq(chan_max+1/bins-kv.bwmul)))+2; % Find suitable channel subsampling rates % Do not apply redmul to channels 1 and M as it produces uneccesarily % badly conditioned frames aprecise=fs./fsupp; aprecise(2:end-1)=aprecise(2:end-1)/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 % 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,M,1),N]; elseif flags.do_fractionaluniform L = Ls; N=ceil(Ls./min(aprecise)); a= repmat([Ls,N],M,1); elseif flags.do_uniform a=floor(min(aprecise)); L=filterbanklength(Ls,a); a = repmat(a,M,1); end; % Get an expanded "a" afull=comp_filterbank_a(a,M,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(M)=scal(M)/sqrt(2); else % Replicate the centre frequencies and sampling rates, except the first and % last a=[a;flipud(a(2:M-1,:))]; scal=[scal;flipud(scal(2:M-1))]; fc =[fc; -flipud(fc(2:M-1))]; fsupp=[fsupp;flipud(fsupp(2:M-1))]; end; g = cell(1,numel(fc)); gIdxStart = 1; if fmin~=0 % Low-pass filter g{1} = zerofilt(flags.wintype,fs,chan_min,freqtoscale,scaletofreq,scal(1),kv.bwmul,bins,Ls); gIdxStart = gIdxStart + 1; end % High-pass filter g{M} = nyquistfilt(flags.wintype,fs,chan_max,freqtoscale,scaletofreq,scal(M),kv.bwmul,bins,Ls); symmetryflag = 'nonsymmetric'; if freqtoscale(0) < -1e10, symmetryflag = 'symmetric'; end; % All the other filters for gIdx = [gIdxStart:M-1,M+1:numel(fc)] g{gIdx}=warpedblfilter(flags.wintype,kv.bwmul*2,fc(gIdx),fs,freqtoscale,scaletofreq, ... 'scal',scal(gIdx),'inf',symmetryflag); end function g = nyquistfilt(wintype,fs,chan_max,freqtoscale,scaletofreq,scal,bwmul,bins,Ls) % This function constructs a high-pass filter centered at the Nyquist % frequency such that the summation properties of the filter bank % remain intact. g=struct(); % Inf normalization as standard g.H = @(L) comp_nyquistfilt(wintype,fs,chan_max,freqtoscale,scaletofreq,bwmul,bins,Ls)*scal; g.foff=@(L) floor(L/2)+1-(numel(g.H(L))+1)/2; g.fs=fs; function g = zerofilt(wintype,fs,chan_min,freqtoscale,scaletofreq,scal,bwmul,bins,Ls) % This function constructs a low-pass filter centered at the zero % frequency such that the summation properties of the filter bank % remain intact. g=struct(); % Inf normalization as standard g.H = @(L) comp_zerofilt(wintype,fs,chan_min,freqtoscale,scaletofreq,bwmul,bins,Ls)*scal; g.foff=@(L) -(numel(g.H(L))+1)/2+1; g.fs=fs; ltfat/inst/filterbank/nonu2ucfmt.m0000664000175000017500000000710713026262304017143 0ustar susnaksusnakfunction cu = nonu2ucfmt(c, p) %-*- texinfo -*- %@deftypefn {Function} nonu2ucfmt %@verbatim %NONU2UCFMT Non-uniform to uniform filterbank coefficient format % Usage: cu=nonu2ucfmt(c,pk) % % Input parameters: % c : Non-uniform filterbank coefficients. % % Output parameters: % cu : Uniform filterbank coefficients. % p : Numbers of copies of each filter. % % cu = NONU2UCFMT(c,p) changes the coefficient format from % non-uniform filterbank coefficients c (M=numel(p) channels) to % uniform coefficients c (sum(p) channels) such that each % channel of cu consinst of de-interleaved samples of channels of c. % % The output cu is a cell-array in any case. % % % References: % S. Akkarakaran and P. Vaidyanathan. Nonuniform filter banks: New % results and open problems. In P. M. C.K. Chui and L. Wuytack, editors, % Studies in Computational Mathematics: Beyond Wavelets, volume 10, pages % 259 --301. Elsevier B.V., 2003. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/filterbank/nonu2ucfmt.html} %@seealso{nonu2ufilterbank, u2nonucfmt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,mfilename); if isempty(c) error('%s: c must be non-empty.',upper(mfilename)); end if isempty(p) || ~isvector(p) error('%s: pk must be a non-empty vector.',upper(mfilename)); end if iscell(c) M = numel(c); Lc = cellfun(@(cEl) size(cEl,1),c); if all(Lc==Lc(1)) if ~all(p==1) || numel(p)~=M error('%s: Bad format of p for uniform coefficients.',... upper(mfilename)); else cu = c; % End here, this is already uniform. return; end end elseif isnumeric(c) M = size(c,2); if ~all(p==1) || numel(p)~=M error('%s: Bad format of p for uniform coefficients.',... upper(mfilename)); end % Just convert to cell-array and finish cu = cell(M,1); for m=1:M cu{m}=squeeze(c(:,m,:)); end; % End here, there is nothing else to do. return; else error('%s: c must be a cell array or numeric.',upper(mfilename)); end if numel(p) ~= M error(['%s: Number of elements of p does not comply with ',... 'number of channels passed.'],upper(mfilename)); end p = p(:); Mu = sum(p); cu = cell(Mu,1); pkcumsum = cumsum([1;p]); crange = arrayfun(@(pEl,pcEl)pcEl:pcEl+pEl-1,p,pkcumsum(1:end-1),... 'UniformOutput',0); % c can be only cell array at this point for m=1:M for k=1:p(m) cu{crange{m}(k)} = c{m}(k:p(m):end,:); end end % Post check whether the output is really uniform and the numbers of % coefficients are equal Lcu = cellfun(@(cEl) size(cEl,1),cu); if any(Lcu~=Lcu(1)) || sum(Lcu)~=sum(Lc) error(['%s: The combination of c and p does not result in uniform ',... 'coefficients.'],upper(mfilename)); end ltfat/inst/filterbank/filterbankwin.m0000664000175000017500000001573513026262304017710 0ustar susnaksusnakfunction [g,asan,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.github.io/doc/filterbank/filterbankwin.html} %@seealso{filterbank, filterbankdual, filterbankrealdual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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(s) g must be a cell array.',upper(mfilename)); end; if isempty(g) || any(cellfun(@isempty,g)) error('%s: Window(s) 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'} optArgs = g(3:end); [g,~,info.auxinfo] = filterbankwin(g{2},a,L); g = filterbankdual(g,a,L,optArgs{:}); info.isdual=1; case {'realdual'} optArgs = g(3:end); [g,~,info.auxinfo] = filterbankwin(g{2},a,L); g = filterbankrealdual(g,a,L,optArgs{:}); 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; do_info = nargout>2; 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 do_info if isfield(g{m},'H') % Here we only want to find out the frequency support if isa(g{m}.H,'function_handle') if isempty(L) error('L:undefined',... ['%s: L is necessary for determining support ',... 'of g.H'],upper(mfilename)); end tmpH=g{m}.H(L); elseif isnumeric(g{m}.H) tmpH=g{m}.H; if isempty(L) || L == g{m}.L; % There has to be g{m}.L already present L = g{m}.L; else % In case L ~= g{m}.L we cannot be sure whether g is % still band-limited info.ispainless=0; end end; % Check the painless condition if numel(tmpH) > L/asan(m,1)*asan(m,2); info.ispainless=0; end else % No subsampling means painless case for any filter if ~(info.isuniform && asan(m,1) == 1) info.ispainless=0; end info.gl(m)=numel(g{m}.h); info.offset(m)=g{m}.offset; end; end if info_win.isfir && asan(m,2) ~=1 % FIR filter cannot have a fractional subsampling if rem(asan(m,1)/asan(m,2),1)==0 % ... but this is still an integer subsampling asan = [asan(m,1)/asan(m,2),1]; info.a(m,:) = asan; else error(['%s: Fractional subsampling cannot be used with FIR '... 'filters.'],upper(mfilename)); end 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); % Does not evaluate as true if L is empty if L> Time-frequency analysis and Wavelets signals ctestfun noise pinknoise expchirp bat batmask greasy cocktailparty gspi linus ltfatlogo otoclick traindoppler cameraman lichtenstein ltfattext quadratic ambiguityfunction wignervilledist drihaczekdist quadtfdist plotquadtfdist operators operatornew operator ioperator operatoradj operatorappr operatoreigs operatormatrix framemul iframemul framemuladj framemulappr framemuleigs gabmulappr spreadop spreadinv spreadadj spreadfun spreadeigs deprecated convolve gabelitistlasso gabgrouplasso gablasso gabmuleigs gabmul framematrix iufilterbank iunsdgt iunsdgtreal tfmat uwfbtbounds uwpfbtbounds sigproc rms normalize gaindb crestfactor uquant firwin firkaiser fir2long long2fir freqwin firfilter blfilter warpedblfilter freqfilter pfilt magresp transferfunction pgrpdelay 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 projkern 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 gabphasederiv gabreassign gabreassignadjust constructphase constructphasereal phaselock phaseunlock phaselockreal phaseunlockreal symphase matrix2latticetype latticetype2matrix shearfind noshearlength tfplot plotdgt plotdgtreal plotdwilt plotwmdct sgram gabimagepars resgram instfreqplot phaseplot blockproc block blockdevices blockread blockplay blockpanel blockpanelget blockdone blockwrite blockframeaccel blockframepairaccel blockana blocksyn blockfigure blockplot ltfatplay demos demo_dgt demo_gabfir demo_wavelets demo_imagecompression demo_audiocompression demo_audiodenoise demo_ofdm demo_audioshrink demo_gabmulappr demo_bpframemul demo_frsynabs demo_filterbanksynchrosqueeze demo_nsdgt demo_pgauss demo_pbspline demo_gabmixdual demo_framemul demo_phaseplot demo_phaseret demo_nextfastfft demo_filterbanks demo_audscales demo_auditoryfilterbank demo_wfbt demo_blockproc_basicloop demo_blockproc_paramequalizer demo_blockproc_denoising demo_blockproc_slidingsgram demo_blockproc_slidingcqt demo_blockproc_slidingerblets demo_blockproc_dgtequalizer demo_blockproc_effects 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 wfbtclength wpfbtclength dtwfb idtwfb dtwfbreal idtwfbreal wfbtinit dtwfbinit wfbtput wfbtremove wfbt2filterbank wpfbt2filterbank dtwfb2filterbank fwtinit wfbtbounds wpfbtbounds dtwfbbounds plotwavelets wfiltinfo wfiltdtinfo wavfun wavcell2pack wavpack2cell wfilt_algmband wfilt_cmband wfilt_coif wfilt_db wfilt_dden wfilt_dgrid wfilt_hden wfilt_lemarie wfilt_matlabwrapper wfilt_mband wfilt_remez wfilt_symds wfilt_spline wfilt_sym wfilt_symdden wfilt_symorth wfilt_symtight wfilt_qshifta wfilt_qshiftb wfilt_oddevena wfilt_oddevenb wfilt_optsyma wfilt_optsymb wfilt_ddena wfilt_ddenb wfiltdt_qshift wfiltdt_optsym wfiltdt_oddeven wfiltdt_dden filterbank filterbank ufilterbank ifilterbank ifilterbankiter filterbankwin filterbanklength filterbanklengthcoef cqt icqt erblett ierblett cqtfilters erbfilters warpedfilters audfilters filterbankdual filterbanktight filterbankrealdual filterbankrealtight filterbankbounds filterbankrealbounds filterbankresponse filterbankfreqz filterbankscale nonu2ufilterbank u2nonucfmt nonu2ucfmt plotfilterbank filterbankphasegrad filterbankreassign filterbanksynchrosqueeze fourier fftindex modcent floor23 floor235 ceil23 ceil235 nextfastfft dft idft fftreal ifftreal gga chirpzt fftgram plotfft plotfftreal involute peven podd pconv pxcorr lconv lxcorr isevenfunction middlepad expwave pchirp pgauss psech pbspline shah pheaviside prect psinc ptpfun pebfun ptpfundual pebfundual pherm hermbasis dfracft ffracft fftresample dctresample pderiv fftanalytic dcti dctii dctiii dctiv dsti dstii dstiii dstiv frames frame framepair framedual frametight frameaccel frana frsyn frsynmatrix frgramian frameoperator framediag franaiter frsyniter plotframe framegram framebounds framered framelength framelengthcoef frameclength framecoef2native framenative2coef framecoef2tf frametf2coef framecoef2tfplot franabp franalasso franagrouplasso frsynabs base ltfatstart ltfatstop ltfathelp ltfatmex ltfatbasepath isoctave ltfatarghelper ltfatgetdefaults ltfatsetdefaults scalardistribute mulaclab ltfat/inst/ltfat/DESCRIPTION0000664000175000017500000000155313026262276015373 0ustar susnaksusnakName: LTFAT Version: 2.2.0 Date: 2016-12-20 Author: Peter L. Soendergaard 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+ Depends: octave (>= 3.8.0) BuildRequires: fftw3 [Debian] libfftw3-3, lapack [Debian] liblapack3, blas [Debian] libblas3, portaudio [Debian] portaudio19-dev Java Runtime [Debian] default-jre Url: http://ltfat.github.io/ ltfat/inst/ltfat/inst/0000775000175000017500000000000013026262304014626 5ustar susnaksusnakltfat/inst/ltfat/inst/CITATION0000664000175000017500000000301013026262276015765 0ustar susnaksusnakTo 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" } and/or Zdeněk Průša, Peter L. Søndergaard, Nicki Holighaus, Christoph Wiesmeyr, Peter Balazs. The Large Time-Frequency Analysis Toolbox 2.0. Sound, Music, and Motion, Lecture Notes in Computer Science 2014, pp 419-442 A BibTex entry for LaTex users: @incollection{ltfatnote030, year={2014}, isbn={978-3-319-12975-4}, booktitle={Sound, Music, and Motion}, series={Lecture Notes in Computer Science}, editor={Aramaki, Mitsuko and Derrien, Olivier and Kronland-Martinet, Richard and Ystad, S{\o}lvi}, title={{The Large Time-Frequency Analysis Toolbox 2.0}}, publisher={Springer International Publishing}, author={Pr\r{u}\v{s}a, Zden\v{e}k and S{\o}ndergaard, Peter L. and Holighaus, Nicki and Wiesmeyr, Christoph and Balazs, Peter}, pages={419-442}, url={{http://dx.doi.org/10.1007/978-3-319-12976-1_25}}, doi={{10.1007/978-3-319-12976-1_25}}, } ltfat/inst/ltfat/inst/AUTHORS0000664000175000017500000000046313026262276015711 0ustar susnaksusnakPeter Soendergaard Zdenek Prusa Nicki Holighaus Christoph Wiesmeyr Peter Balazs Bruno Torresani ltfat/inst/ltfat/inst/INDEX0000664000175000017500000001224513026262276015434 0ustar susnaksusnakltfat >> Time-frequency analysis and Wavelets signals ctestfun noise pinknoise expchirp bat batmask greasy cocktailparty gspi linus ltfatlogo otoclick traindoppler cameraman lichtenstein ltfattext quadratic ambiguityfunction wignervilledist drihaczekdist quadtfdist plotquadtfdist operators operatornew operator ioperator operatoradj operatorappr operatoreigs operatormatrix framemul iframemul framemuladj framemulappr framemuleigs gabmulappr spreadop spreadinv spreadadj spreadfun spreadeigs deprecated convolve gabelitistlasso gabgrouplasso gablasso gabmuleigs gabmul framematrix iufilterbank iunsdgt iunsdgtreal tfmat uwfbtbounds uwpfbtbounds sigproc rms normalize gaindb crestfactor uquant firwin firkaiser fir2long long2fir freqwin firfilter blfilter warpedblfilter freqfilter pfilt magresp transferfunction pgrpdelay 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 projkern 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 gabphasederiv gabreassign gabreassignadjust constructphase constructphasereal phaselock phaseunlock phaselockreal phaseunlockreal symphase matrix2latticetype latticetype2matrix shearfind noshearlength tfplot plotdgt plotdgtreal plotdwilt plotwmdct sgram gabimagepars resgram instfreqplot phaseplot blockproc block blockdevices blockread blockplay blockpanel blockpanelget blockdone blockwrite blockframeaccel blockframepairaccel blockana blocksyn blockfigure blockplot ltfatplay demos demo_dgt demo_gabfir demo_wavelets demo_imagecompression demo_audiocompression demo_audiodenoise demo_ofdm demo_audioshrink demo_gabmulappr demo_bpframemul demo_frsynabs demo_filterbanksynchrosqueeze demo_nsdgt demo_pgauss demo_pbspline demo_gabmixdual demo_framemul demo_phaseplot demo_phaseret demo_nextfastfft demo_filterbanks demo_audscales demo_auditoryfilterbank demo_wfbt demo_blockproc_basicloop demo_blockproc_paramequalizer demo_blockproc_denoising demo_blockproc_slidingsgram demo_blockproc_slidingcqt demo_blockproc_slidingerblets demo_blockproc_dgtequalizer demo_blockproc_effects 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 wfbtclength wpfbtclength dtwfb idtwfb dtwfbreal idtwfbreal wfbtinit dtwfbinit wfbtput wfbtremove wfbt2filterbank wpfbt2filterbank dtwfb2filterbank fwtinit wfbtbounds wpfbtbounds dtwfbbounds plotwavelets wfiltinfo wfiltdtinfo wavfun wavcell2pack wavpack2cell wfilt_algmband wfilt_cmband wfilt_coif wfilt_db wfilt_dden wfilt_dgrid wfilt_hden wfilt_lemarie wfilt_matlabwrapper wfilt_mband wfilt_remez wfilt_symds wfilt_spline wfilt_sym wfilt_symdden wfilt_symorth wfilt_symtight wfilt_qshifta wfilt_qshiftb wfilt_oddevena wfilt_oddevenb wfilt_optsyma wfilt_optsymb wfilt_ddena wfilt_ddenb wfiltdt_qshift wfiltdt_optsym wfiltdt_oddeven wfiltdt_dden filterbank filterbank ufilterbank ifilterbank ifilterbankiter filterbankwin filterbanklength filterbanklengthcoef cqt icqt erblett ierblett cqtfilters erbfilters warpedfilters audfilters filterbankdual filterbanktight filterbankrealdual filterbankrealtight filterbankbounds filterbankrealbounds filterbankresponse filterbankfreqz filterbankscale nonu2ufilterbank u2nonucfmt nonu2ucfmt plotfilterbank filterbankphasegrad filterbankreassign filterbanksynchrosqueeze fourier fftindex modcent floor23 floor235 ceil23 ceil235 nextfastfft dft idft fftreal ifftreal gga chirpzt fftgram plotfft plotfftreal involute peven podd pconv pxcorr lconv lxcorr isevenfunction middlepad expwave pchirp pgauss psech pbspline shah pheaviside prect psinc ptpfun pebfun ptpfundual pebfundual pherm hermbasis dfracft ffracft fftresample dctresample pderiv fftanalytic dcti dctii dctiii dctiv dsti dstii dstiii dstiv frames frame framepair framedual frametight frameaccel frana frsyn frsynmatrix frgramian frameoperator framediag franaiter frsyniter plotframe framegram framebounds framered framelength framelengthcoef frameclength framecoef2native framenative2coef framecoef2tf frametf2coef framecoef2tfplot franabp franalasso franagrouplasso frsynabs base ltfatstart ltfatstop ltfathelp ltfatmex ltfatbasepath isoctave ltfatarghelper ltfatgetdefaults ltfatsetdefaults scalardistribute mulaclab ltfat/inst/ltfat/inst/INSTALL-Matlab0000664000175000017500000001232413026262276017067 0ustar susnaksusnak-------- 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 ------------------------------------------- The GCC compiler is needed to compile the LTFAT on Mac OS X. When the Xcode Command Line Tools are installed the compilation of the LTFAT should work without any problem. Alternatively, Clang could be used to compile the LTFAT. The BLAS, LAPACK and FFTW libraries are taken directly from the Matlab installation and doesn’t have to be installed separately. --------- 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. - Ensure there is not another MinGW/MSYS toolchain in PATH and, expecially, that there is no sh.exe in PATH. - 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. This step is necessary since the FFTW lib shipped with Matlab does not contain some of the routines we need. - 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 taken directly from Matlab installation and you should not need to install anything. Just typing "ltfatmex" should do the trick. ----------------------------------------------------------------------- --------- 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 ------------ It is recommended to compile PortAudio v19 to use with the block processing framework. PortAudio v19 only compiles on OS X version 10.4 or later. Several versions of the Java Development Kit, which is needed to compile the JAVA classes, could be downloaded through the Apple Developer Downloads. --------- 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. To use a custom (or system) portaudio lib, adjust the symbolic link found here >>[matlabroot, filesep, 'bin', filesep, computer('arch')] ltfat/inst/ltfat/inst/INSTALL0000664000175000017500000000143013026262276015665 0ustar susnaksusnak --------- 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 ltfat/inst/ltfat/inst/README0000664000175000017500000000260413026262276015520 0ustar susnaksusnakTo use the toolbox, 'cd' to the LTFAT directory and execute 'ltfatstart'. In Octave you can put this command in your ~/.octaverc file. Directory struture. The toolbox is organized in subdirectories including the following: fourier - Fourier analysis, DCT/DST transforms and filtering. gabor - Gabor, Wilson and WMDCT analysis/synthesis functions. wavelets - Wavelet analysis/synthesis, wavelet filter banks filterbank - General and auditory inspired filterbanks. nonstatgab - Non-stationary Gabor frames. quadratic - Quadratic distributions frames - Frame objects and linear operators associated with frames. sigproc - A collection of simple, signal processing tools. blockproc - Methods for block processing and block-adapted transforms. auditory - Auditory scales and common filters types. demos - Demos showing applications or aspects of LTFAT functions. 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.ltfat/inst/ltfat/inst/COPYING0000664000175000017500000010451313026262276015675 0ustar susnaksusnak GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . 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: Copyright (C) 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 . 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 . ltfat/inst/ltfat/inst/ChangeLog0000664000175000017500000004363213026262276016420 0ustar susnaksusnakVersion 2.2.0 24/12 2016 * New Gabor window generating functions: ptpfun, ptpfundual, pebfun, pebfundual * New filterbank functions: filterbankscale, ifilterbankiter * New window and filter generating functions: freqwin, freqfilter * New functions for changing DGT phase convention: phaselockreal, phaseunlockreal * Included new colormaps: ltfat_inferno, ltfat_magma, ltfat_plasma, ltfat_viridis, ltfat_nicecolormap * erbfilters and audfilters can now generate Gammatone and other filters * Removed deprication warnings in test_all_ltfat * Mulaclab no longer requires the Image processing toolbox to be installed (for the basic functionality). * Mulaclab now works on GNU Octave (thanks to Florent Jaillet). Version 2.1.2 x/3 2016 * Improved functions for DGT and DGTREAL phase reconstruction: constructphase, constructphasereal * The backend library is now in separate repository: https://github.com/ltfat/libltfat and it is included as a subtree in subdirectory libltfat/ (replacing src/) Version 2.1.1 x/10 2015 * New function for computing higher order phase derivatives: gabphasederiv * New function doing the adjustable reassignment: gabreassignadjust * New function for the Gabor transform phase reconstruction: constructphase, constructphasereal * New filterbank-generating function: audfilters * New generic quadratic TF distribution function: quadtfdist * New functions for reading and writing wav files (since wavread and wavwrite were removed in Matlab 2015b): wavload, wavsave (taken from VOICEBOX http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html) * Added 'nojava' flag to ltfatstart to optionally disable adding the blockproc JAVA classes to the classpath. * Updated the lBFGS method in frsynabs according to the new paper. * Fixed bug in gabphasegrad which prevented it from being used with any window other than Gaussian. * Fixed bug in comp_ifilterbank_fftbl for non-painless filterbanks. Version 2.1.0 6/5 2015 * New filterbank-generating function: warpedfilters * New filterbank spectrogram reassignment function: filterbankreassign * ltfatarghelper is now also implemented as a MEX file. * The block function can now handle synchronized simultaneous playback and recording. E.g. {'rec','file.wav'} plays a wav file while recording. This is different from the option 'playrec', which works the "other way" i.e. it records and play the recorded. * Function framebounds(...,'iter') now uses pcg to represent the inverse of the frame operator when calculating the lowest eigenvalue using eigs. * Added implementation of some quadratic time-frequency representations: Rihaczek, Wigner-Ville * Fixed #112 (Sourceforge): Octave package now compiles on Windows (mxe version) thanks to John Donoghue. * Related to #111 (Sourceforge): Wavelet filters were hand-centered around the origin. * comp_filterbank, comp_ifilterbank and ltfatarghelper can be compiled as MEX files on Octave. Version 2.0.1 8/10 2014 (released only at Octave-Forge) * Included test suite. Version 2.0.0 7/10 2014 * Fixed bug in filterbankdual and filterbankrealdual for the uniform case. Also the routines are now much faster. * Added possibility to force treatment of a filterbank as a painless filterbank using 'forcepainless' flag in filterbank(real)dual routines. * Fixed bug in comp_ifilterbank MEX causing crashes for mixed type filterbanks. * Added implementation of dual-tree wavelet transform, general dual-tree wavelet filterbanks and *M*-band transforms. * New dual-tree wavelet filters: wfiltdt_qshift, wfiltdt_oddeven, wfiltdt_optsym, wfiltdt_dden * New regular DWT filters: wfilt_symorth, wfilt_symtight * wfilt_ functions now return filters in a format compatible with LTFAT filter format (struct with .h and .offset fields). * Closed #100 FEATURE: Add on-the-fly sample rate conversion to the blockproc framework. It effectivelly allows recording and playback at arbitrary sampling rates. * Added support for cross-compilation (src/Makefile_crossmingw): Producing Windows binaries on an Unix system using MXE (http://mxe.cc/). Works only with MEX files for Matlab. * Blockproc. framework now supports any sampling rate from interval 4-96kHz trough on-the-fly resampling in the background. * Fixed compilation issue with gcc 4.7. Version 1.4.5 7/5 2014 * Phase locking in DGT ('timeinv' flag) moved to the C backend. It was too slow in Octave. * Added franabp - solving a basis pursuit problem argmin ||c||_1 s.t. Fc = f for an arbitrary frame F. * The lambda parameter in franabp and franalasso can now be a vector. => thresh acceps such lambda too. * New demos to accompany the LTFAT 2.0 paper: demo_filterbanks, demo_wavelets, demo_wfbt, demo_bpframemul, demo_phaseret * New blockproc demo: demo_blockproc_effects * blockproc framework can be now used offline without a single call to the playrec MEX. * Closed #49: blockwrite method. Allows blockwise storage of audio data to a wav file. * All wavelet routines were correctly included in the frames framework. Correct computation of canonical dual and tight frames for undecimated wavelet filterbanks. * New wrapper frame types in the frames framework: erbletfb, cqtfb * Removed demo_blockproc_pitchshift. It is now part of demo_blockproc_effects. * Removed some esoteric wavelet filters. 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 ltfat/inst/ltfat/inst/Contents.m0000664000175000017500000000314513026262304016604 0ustar susnaksusnak% LTFAT - Base routines % % Peter L. Soendergaard, 2009 - 2016. % % 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 visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/ltfat/inst/isoctave.m0000664000175000017500000000240513026262304016622 0ustar susnaksusnakfunction 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.github.io/doc/isoctave.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard. % TESTING: NA % REFERENCE: NA persistent inout; if isempty(inout), inout = exist('OCTAVE_VERSION','builtin') ~= 0; end; t = inout; ltfat/inst/ltfat/inst/NEWS0000664000175000017500000001100513026262276015332 0ustar susnaksusnakVersion 2.2.0 * New Gabor window generating functions: ptpfun, ptpfundual, pebfun, pebfundual * Introduced Mulaclab, a GUI for editing time-frequency representations. * Included new colormaps: ltfat_inferno, ltfat_magma, ltfat_plasma, ltfat_viridis, ltfat_nicecolormap Version 2.1.2 * Improved functions for DGT and DGTREAL phase reconstruction: constructphase, constructphasereal Version 2.1.1 * New function for computing higher order phase derivatives: gabphasederiv * New function doing the adjustable reassignment: gabreassignadjust * New function for the Gabor transform phase reconstruction: constructphase, constructphasereal * New filterbank-generating function: audfilters * New generic quadratic TF distribution function: quadtfdist * New functions for reading and writing wav files (since wavread and wavwrite were removed in Matlab 2015b): wavload, wavsave (taken from VOICEBOX http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html) Version 2.1.0 * New general filterbank generating routine: warpedfilters * New filterbank spectrogram reassignment function: filterbankreassign * New quadratic time-frequency distributions * Octave package compiles on Windows (MXE-Octave). * Better alignment of wavelet filters. Version 2.0.1 * Included a test suite (test_all_ltfat). -------- LTFAT 2.0 --------------------------------------------- Main features of LTFAT 2.0 are the the wavelets module, the frames framework and the real-time block processing framework. Actual news: * Added dual-tree complex wavelet transform, general dual-tree wavelet filterbanks and $M$-band transforms. * Blockproc. framework now supports any sampling rate from interval 4-96kHz trough on-the-fly resampling in the background. * Fixed compilation issue with gcc 4.7. * Warning is shown if portaudio is not found during package installation. * Warning is shown if JRE is run in a headless mode during package loading. Version 1.4.5 * Added franabp - solving a basis pursuit problem argmin ||c||_1 s.t. Fc = f for an arbitrary frame * Wavelet routines correctly included in the frames framework. * Added blockwrite method for a blockwise storage of audio data to a wav file. * New demos: demo_blockproc_effects, demo_filterbanks, demo_wavelets, demo_wfbt, demo_bpframemul, demo_phaseret 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. ltfat/inst/ltfat/inst/DESCRIPTION0000664000175000017500000000155313026262276016350 0ustar susnaksusnakName: LTFAT Version: 2.2.0 Date: 2016-12-20 Author: Peter L. Soendergaard 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+ Depends: octave (>= 3.8.0) BuildRequires: fftw3 [Debian] libfftw3-3, lapack [Debian] liblapack3, blas [Debian] libblas3, portaudio [Debian] portaudio19-dev Java Runtime [Debian] default-jre Url: http://ltfat.github.io/ ltfat/inst/ltfat/inst/Makefile0000664000175000017500000001415413026262276016303 0ustar susnaksusnak## Copyright 2015-2016 Carnë Draug ## Copyright 2015-2016 Oliver Heimlich ## Copyright 2015-2016 Zdeněk Průša ## ## Copying and distribution of this file, with or without modification, ## are permitted in any medium without royalty provided the copyright ## notice and this notice are preserved. This file is offered as-is, ## without any warranty. ## This makefile requires ## python 2.x --- python and modules are not checked in this Makefile ## pygments ## docutils ## ## javac ## lynx ## dos2unix ## bibtex2html ## mat2doc https://github.com/ltfat/mat2doc <-- pulled automatically ## ## Note the use of ':=' (immediate set) and not just '=' (lazy set). ## http://stackoverflow.com/a/448939/1609556 PACKAGE := ltfat VERSION := $(shell cat "ltfat_version") ## This are the files that will be created for the releases. TARGET_DIR := ~/publish/$(PACKAGE)-octaveforge RELEASE_DIR := $(TARGET_DIR)/$(PACKAGE)-$(VERSION) TMP_DIR := $(TARGET_DIR)/$(PACKAGE)-tmp RELEASE_TARBALL := $(TARGET_DIR)/$(PACKAGE)-$(VERSION).tar.gz HTML_DIR := $(TARGET_DIR)/$(PACKAGE)-html HTML_TARBALL := $(TARGET_DIR)/$(PACKAGE)-html.tar.gz MAT2DOC := $(TARGET_DIR)/mat2doc/mat2doc.py ## These can be set by environment variables which allow to easily ## test with different Octave versions. OCTAVE ?= octave MKOCTFILE ?= mkoctfile HAS_BIBTEX2HTML := $(shell which bibtex2html) HAS_JAVAC := $(shell which javac) HAS_LYNX := $(shell which lynx) HAS_DOS2UNIX := $(shell which dos2unix) HAS_AUTOCONF := $(shell which autoconf) ifndef HAS_BIBTEX2HTML $(error "Please install bibtex2html. E.g. sudo apt-get install bibtex2html") endif ifndef HAS_JAVAC $(error "Please install javac. E.g. sudo apt-get install openjdk-X-jdk, where X is at least 6") endif ifndef HAS_LYNX $(error "Please install lynx. E.g. sudo apt-get install lynx") endif ifndef HAS_DOS2UNIX $(error "Please install dos2unix utility. E.g. sudo apt-get install dos2unix") endif ## If autoconf is missing, a broken package would be silently created. ifndef HAS_AUTOCONF $(error "Please install development utilities like autoconf.") endif ## Targets that are not filenames. ## https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html .PHONY: help dist html release install all check run clean update ## make will display the command before runnning them. Use @command ## to not display it (makes specially sense for echo). help: @echo "Targets:" @echo " dist - Create $(RELEASE_TARBALL) for release" @echo " html - Create $(HTML_TARBALL) for release" @echo " release - Create both of the above and store md5sums in $(RELEASE_DIR).md5" @echo @echo " install - Install the package in GNU Octave" @echo " all - Build all oct files" @echo " check - Execute package tests (w/o install)" @echo " run - Run Octave with development in PATH (no install)" @echo @echo " clean - Remove releases, html documentation, and oct files" $(MAT2DOC): git clone -b notestargets https://github.com/ltfat/mat2doc $(TARGET_DIR)/mat2doc update: ( cd $(TARGET_DIR)/mat2doc ; \ git pull ; ) ## dist and html targets are only PHONY/alias targets to the release ## and html tarballs. dist: $(RELEASE_TARBALL) html: $(HTML_TARBALL) ## An implicit rule with a recipe to build the tarballs correctly. $(RELEASE_TARBALL): $(MAT2DOC) update @python2 $(MAT2DOC) . mat --script=release_keep_tests.py --octpkg --unix --outputdir=$(TMP_DIR) --projectname=$(PACKAGE) mv $(TMP_DIR)/$(PACKAGE)-files/$(PACKAGE)-$(VERSION).tar.gz $(RELEASE_TARBALL) mv $(TMP_DIR)/$(PACKAGE)-mat/$(PACKAGE) $(RELEASE_DIR) $(HTML_TARBALL): $(HTML_DIR) ( cd $(TARGET_DIR) ; \ tar -cvf $(PACKAGE)-html.tar.gz $(PACKAGE)-html ; ) ## install is a prerequesite to the html directory (note that the html ## tarball will use the implicit rule for ".tar.gz" files). $(HTML_DIR): install $(RM) -r "$@" $(OCTAVE) --no-window-system --silent \ --eval "pkg load generate_html; " \ --eval "pkg load $(PACKAGE);" \ --eval 'generate_package_html ("${PACKAGE}", "$@", "octave-forge");' chmod -R a+rX,u+w,go-w $@ ## To make a release, build the distribution and html tarballs. release: dist html md5sum $(RELEASE_TARBALL) $(HTML_TARBALL) > $(RELEASE_DIR).md5 @echo "Upload @ https://sourceforge.net/p/octave/package-releases/new/" @echo " and inform to rebuild release with commit hash '$$(git rev-parse --short HEAD)'" @echo 'Execute: git tag -l "of-v${VERSION}"' install: $(RELEASE_TARBALL) @echo "Installing package locally ..." $(OCTAVE) --eval 'pkg ("install", "-verbose", "$(RELEASE_TARBALL)")' # This will not clean all older builds. # To make a stronger clean you could replace with # $(RM) -r $(TARGET_DIR) # But be careful, TARGET_DIR will be deleted! # That is, be careful what you set in that variable clean: @echo "Cleaning ..." $(RM) -r $(RELEASE_DIR) $(RELEASE_TARBALL) $(HTML_TARBALL) $(HTML_DIR) $(TARGET_DIR)/*.md5 $(TMP_DIR) pushforge: git push https://git.code.sf.net/p/octave/ltfat octaveforge:master ## ## Recipes for testing purposes ## ## Build any requires oct files. all: (cd $(RELEASE_DIR)/src ; \ ./configure ; \ make -j4 ; ) ## Start an Octave session with the package directories on the path for ## interactice test of development sources. run: all (cd $(RELEASE_DIR) ; \ $(OCTAVE) --persist --path "$(RELEASE_DIR)/inst/" --path "$(RELEASE_DIR)/src/" \ --eval 'if(!isempty("$(DEPENDS)")); pkg load $(DEPENDS); endif;' \ --eval 'ltfatstart();' ; ) # ## Test example blocks in the documentation. Needs doctest package # ## https://octave.sourceforge.io/doctest/index.html # doctest: all # $(OCTAVE) --path "inst/" --path "src/" \ # --eval '${PKG_ADD}' \ # --eval 'pkg load doctest;' \ # --eval "targets = '$(shell (ls inst; ls src | grep .oct) | cut -f2 -d@ | cut -f1 -d.)';" \ # --eval "targets = strsplit (targets, ' ');" \ # --eval "doctest (targets);" ## check: all (cd $(RELEASE_DIR) ; \ $(OCTAVE) --path "$(RELEASE_DIR)/inst/" --path "$(RELEASE_DIR)/src/" \ --eval 'if(!isempty("$(DEPENDS)")); pkg load $(DEPENDS); endif;' \ --eval 'ltfatstart();' \ --eval 'test_all_ltfat();' ; ) #--eval '__run_test_suite__ ({"inst", "src"}, {});' ltfat/inst/ltfat/inst/INSTALL-Octave0000664000175000017500000001115213026262276017106 0ustar susnaksusnak-------- Compatibility ---------------------------------- The toolbox should work and compile on all versions of Octave later than version 3.4, but it is generally recommended to upgrade Octave to the latest stable release. For demos etc. to work, you will need to install some of the Octave-forge packages. All versions of LTFAT from 1.4.2 are also itself an Octave-forge package and the easiest way to install the toolbox is by typing the command pkg install -forge ltfat on the Octave prompt, which downloads LTFAT directly from the Octave-forge and compiles everything. This was tested on Linux, on Windows with MXE-Octave and Mac X unsing Octave from Homebrew. 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 libraries and some additional MEX files. Block processing framework (optional, experimental) - 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 ------------------------------------------ The GCC compiler is needed to compile the LTFAT on Mac OS X. When the Xcode Command Line Tools are installed the compilation of the LTFAT should work without any problem. Alternatively, Clang could be used to compile the LTFAT. The BLAS, LAPACK and FFTW libraries are taken directly from the Octave installation and doesn’t have to be installed separately. --------- Compiling on Microsoft Windows ------------------------------ Currently, there is no direct way of compiling ltfat on MXE-Octave. Please use the Octave-forge package. --------- 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 ———------------ --------------------------------------------------------------------------- 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. From Octave 3.8.0 the JAVA package is part of core Octave, so it doesn’t have to be installed separately. 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 ------------ It is recommended to compile PortAudio v19 to use with the block processing framework. PortAudio v19 only compiles on OS X version 10.4 or later. For any version of Octave older than 3.8.0 the JAVA package should be installed which requires the Java Development Kit to be installed. The Java Development Kit could be downloaded through the Apple Developer Downloads. --------- Compiling on Microsoft Windows -------------------------- Currently, there is no direct way of compiling ltfat on MXE-Octave. Please use the Octave-forge package. --------- Compiling on Linux ------------------------------------ - On Redhat / Fedora, TBD - On Debian / Ubuntu, install the packages 'portaudio19-dev', 'openjdk-7-jdk' ltfat/inst/Makefile0000664000175000017500000001415413026262276014214 0ustar susnaksusnak## Copyright 2015-2016 Carnë Draug ## Copyright 2015-2016 Oliver Heimlich ## Copyright 2015-2016 Zdeněk Průša ## ## Copying and distribution of this file, with or without modification, ## are permitted in any medium without royalty provided the copyright ## notice and this notice are preserved. This file is offered as-is, ## without any warranty. ## This makefile requires ## python 2.x --- python and modules are not checked in this Makefile ## pygments ## docutils ## ## javac ## lynx ## dos2unix ## bibtex2html ## mat2doc https://github.com/ltfat/mat2doc <-- pulled automatically ## ## Note the use of ':=' (immediate set) and not just '=' (lazy set). ## http://stackoverflow.com/a/448939/1609556 PACKAGE := ltfat VERSION := $(shell cat "ltfat_version") ## This are the files that will be created for the releases. TARGET_DIR := ~/publish/$(PACKAGE)-octaveforge RELEASE_DIR := $(TARGET_DIR)/$(PACKAGE)-$(VERSION) TMP_DIR := $(TARGET_DIR)/$(PACKAGE)-tmp RELEASE_TARBALL := $(TARGET_DIR)/$(PACKAGE)-$(VERSION).tar.gz HTML_DIR := $(TARGET_DIR)/$(PACKAGE)-html HTML_TARBALL := $(TARGET_DIR)/$(PACKAGE)-html.tar.gz MAT2DOC := $(TARGET_DIR)/mat2doc/mat2doc.py ## These can be set by environment variables which allow to easily ## test with different Octave versions. OCTAVE ?= octave MKOCTFILE ?= mkoctfile HAS_BIBTEX2HTML := $(shell which bibtex2html) HAS_JAVAC := $(shell which javac) HAS_LYNX := $(shell which lynx) HAS_DOS2UNIX := $(shell which dos2unix) HAS_AUTOCONF := $(shell which autoconf) ifndef HAS_BIBTEX2HTML $(error "Please install bibtex2html. E.g. sudo apt-get install bibtex2html") endif ifndef HAS_JAVAC $(error "Please install javac. E.g. sudo apt-get install openjdk-X-jdk, where X is at least 6") endif ifndef HAS_LYNX $(error "Please install lynx. E.g. sudo apt-get install lynx") endif ifndef HAS_DOS2UNIX $(error "Please install dos2unix utility. E.g. sudo apt-get install dos2unix") endif ## If autoconf is missing, a broken package would be silently created. ifndef HAS_AUTOCONF $(error "Please install development utilities like autoconf.") endif ## Targets that are not filenames. ## https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html .PHONY: help dist html release install all check run clean update ## make will display the command before runnning them. Use @command ## to not display it (makes specially sense for echo). help: @echo "Targets:" @echo " dist - Create $(RELEASE_TARBALL) for release" @echo " html - Create $(HTML_TARBALL) for release" @echo " release - Create both of the above and store md5sums in $(RELEASE_DIR).md5" @echo @echo " install - Install the package in GNU Octave" @echo " all - Build all oct files" @echo " check - Execute package tests (w/o install)" @echo " run - Run Octave with development in PATH (no install)" @echo @echo " clean - Remove releases, html documentation, and oct files" $(MAT2DOC): git clone -b notestargets https://github.com/ltfat/mat2doc $(TARGET_DIR)/mat2doc update: ( cd $(TARGET_DIR)/mat2doc ; \ git pull ; ) ## dist and html targets are only PHONY/alias targets to the release ## and html tarballs. dist: $(RELEASE_TARBALL) html: $(HTML_TARBALL) ## An implicit rule with a recipe to build the tarballs correctly. $(RELEASE_TARBALL): $(MAT2DOC) update @python2 $(MAT2DOC) . mat --script=release_keep_tests.py --octpkg --unix --outputdir=$(TMP_DIR) --projectname=$(PACKAGE) mv $(TMP_DIR)/$(PACKAGE)-files/$(PACKAGE)-$(VERSION).tar.gz $(RELEASE_TARBALL) mv $(TMP_DIR)/$(PACKAGE)-mat/$(PACKAGE) $(RELEASE_DIR) $(HTML_TARBALL): $(HTML_DIR) ( cd $(TARGET_DIR) ; \ tar -cvf $(PACKAGE)-html.tar.gz $(PACKAGE)-html ; ) ## install is a prerequesite to the html directory (note that the html ## tarball will use the implicit rule for ".tar.gz" files). $(HTML_DIR): install $(RM) -r "$@" $(OCTAVE) --no-window-system --silent \ --eval "pkg load generate_html; " \ --eval "pkg load $(PACKAGE);" \ --eval 'generate_package_html ("${PACKAGE}", "$@", "octave-forge");' chmod -R a+rX,u+w,go-w $@ ## To make a release, build the distribution and html tarballs. release: dist html md5sum $(RELEASE_TARBALL) $(HTML_TARBALL) > $(RELEASE_DIR).md5 @echo "Upload @ https://sourceforge.net/p/octave/package-releases/new/" @echo " and inform to rebuild release with commit hash '$$(git rev-parse --short HEAD)'" @echo 'Execute: git tag -l "of-v${VERSION}"' install: $(RELEASE_TARBALL) @echo "Installing package locally ..." $(OCTAVE) --eval 'pkg ("install", "-verbose", "$(RELEASE_TARBALL)")' # This will not clean all older builds. # To make a stronger clean you could replace with # $(RM) -r $(TARGET_DIR) # But be careful, TARGET_DIR will be deleted! # That is, be careful what you set in that variable clean: @echo "Cleaning ..." $(RM) -r $(RELEASE_DIR) $(RELEASE_TARBALL) $(HTML_TARBALL) $(HTML_DIR) $(TARGET_DIR)/*.md5 $(TMP_DIR) pushforge: git push https://git.code.sf.net/p/octave/ltfat octaveforge:master ## ## Recipes for testing purposes ## ## Build any requires oct files. all: (cd $(RELEASE_DIR)/src ; \ ./configure ; \ make -j4 ; ) ## Start an Octave session with the package directories on the path for ## interactice test of development sources. run: all (cd $(RELEASE_DIR) ; \ $(OCTAVE) --persist --path "$(RELEASE_DIR)/inst/" --path "$(RELEASE_DIR)/src/" \ --eval 'if(!isempty("$(DEPENDS)")); pkg load $(DEPENDS); endif;' \ --eval 'ltfatstart();' ; ) # ## Test example blocks in the documentation. Needs doctest package # ## https://octave.sourceforge.io/doctest/index.html # doctest: all # $(OCTAVE) --path "inst/" --path "src/" \ # --eval '${PKG_ADD}' \ # --eval 'pkg load doctest;' \ # --eval "targets = '$(shell (ls inst; ls src | grep .oct) | cut -f2 -d@ | cut -f1 -d.)';" \ # --eval "targets = strsplit (targets, ' ');" \ # --eval "doctest (targets);" ## check: all (cd $(RELEASE_DIR) ; \ $(OCTAVE) --path "$(RELEASE_DIR)/inst/" --path "$(RELEASE_DIR)/src/" \ --eval 'if(!isempty("$(DEPENDS)")); pkg load $(DEPENDS); endif;' \ --eval 'ltfatstart();' \ --eval 'test_all_ltfat();' ; ) #--eval '__run_test_suite__ ({"inst", "src"}, {});' ltfat/inst/test_all_ltfat.m0000664000175000017500000000764013026262304015725 0ustar susnaksusnakfunction [total_tests_failed,list_of_failed_tests]=test_all_ltfat(prec,varargin) global LTFAT_TEST_TYPE; definput.keyvals.tests=[]; definput.keyvals.ignore={}; [flags,kv]=ltfatarghelper({'tests'},definput,varargin); tests_todo={ 'dgt','dwilt','wmdct',... 'dgt_fb','multiwin','gabfirtight',... 'purefreq','zak',... 'gabmulappr',... 'dgt2','dwilt2','wmdct2',... 'firwin',... 'spread', 'dsft', 'thresh',... 'pconv','lconv','involute',... 'signals','realout','windrivers',... 'nsdgt','filterbank',... 'pgauss','pfilt',... 'rangecompress',... 'gabmuleigs','phaselock',... 'fwt','blockfwt','ufwt','wfbt','uwfbt','wpfbt','uwpfbt','fwt2','undeceq',... 'wfbt2filterbank','freqorder','gga','chirpzt',... 'frames', 'frametf', 'frft', 'nonu2ufilterbank', 'dtwfb', 'dtwfb2filterbank',... 'ambiguityfunction','wignervilledist','constructphase' }; if ~isempty(kv.tests) if ischar(kv.tests) kv.tests = {kv.tests}; end tests_todo = kv.tests; end if ~isempty(kv.ignore) if ischar(kv.ignore) kv.ignore = {kv.ignore}; end if ~iscell(kv.ignore) error('%s: Ignored tests list is incorrect.',upper(mfilename)); end ignoreList = []; ignoreUsed = []; ignoreCell = kv.ignore; for ii=1:numel(tests_todo) res = cellfun(@(iEl) strcmpi(tests_todo{ii},iEl) , ignoreCell); if any(res) ignoreList(end+1) = ii; disp(sprintf('Ignoring test: %s',tests_todo{ii})) end [~,idx]=find(res>0); ignoreUsed(end+1:end+numel(idx)) = idx; end if ~isempty(ignoreList) tests_todo(ignoreList) = []; end if numel(ignoreUsed)~=numel(ignoreCell) ignoreCell(ignoreUsed) = []; strToPlot = cellfun(@(iEl) [iEl,', '],ignoreCell,'UniformOutput',0); strToPlot = cell2mat(strToPlot); error('%s: The following ignored tests were not found: %s',... upper(mfilename),strToPlot(1:end-2)); end end precarray={'double','single'}; if nargin >0 && ~strcmpi(prec,'all') if any(cellfun(@(pEl)strcmpi(pEl,prec),precarray)) precarray={prec}; else error('%s: Unknown data precision.',upper(mfilename)); end end %-*- texinfo -*- %@deftypefn {Function} test_all_ltfat %@verbatim % Testing of pbspline has been removed, as it causes too much trouble. %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/testing/test_all_ltfat.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . total_tests_failed=0; list_of_failed_tests={}; for precidx=1:numel(precarray) prec=precarray{precidx}; LTFAT_TEST_TYPE=prec; for ii=1:length(tests_todo) test_failed=feval(['test_',tests_todo{ii}]); total_tests_failed=total_tests_failed+test_failed; if test_failed>0 list_of_failed_tests{end+1}=['test_',tests_todo{ii},' ',prec]; end; end; end; clear -global LTFAT_TEST_TYPE; disp(' '); if total_tests_failed==0 disp('ALL TESTS PASSED'); else s=sprintf('%i TESTS FAILED',total_tests_failed); disp(s); disp('The following test scripts contained failed tests'); for ii=1:length(list_of_failed_tests) disp([' ',list_of_failed_tests{ii}]); end; end; ltfat/inst/fourier/0000775000175000017500000000000013026262304014212 5ustar susnaksusnakltfat/inst/fourier/fftanalytic.m0000664000175000017500000000514413026262304016700 0ustar susnaksusnakfunction z = fftanalytic(f,varargin) %-*- texinfo -*- %@deftypefn {Function} fftanalytic %@verbatim %FFTANALYTIC Compute analytic representation % Usage: z = fftanalytic(f); % z = fftanalytic(f,L); % z = fftanalytic(f,L,dim); % % Input parameters: % f : Input data. % L : Extend or truncate f to this length. % dim : Dimension to along which to apply the computations. % Output parameters: % z : Analytic signal. % % FFTANALYTIC(f) computes the analytic representation of a % real-valued signal f. The analytic representation is computed % through the FFT of f. The computations are done along the first % non-singleton dimension. % % FFTANALYTIC(f,L) acts as before but f is padded with zeros or % truncated to length L. % % FFTANALYTIC(f,L,dim) in addition allows specifying the dimension % along which the computation should be done. % % The real part of the analytic representation z equals the signal % f and the imaginary part is the Hilbert transform of f. % % The instananeous amplitude (a Hilbert envelope) of the signal f can % be computed as: % % abs(fftanalytic(f)); % % The instantaneous phase of the function f can be computed as: % % angle(fftanalytic(f)); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/fftanalytic.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven if ~isreal(f) error('%s: The input should be a real-valued numeric array.',... upper(mfilename)); end; definput.keyvals.dim=[]; definput.keyvals.L=[]; [~,~,L,dim]=ltfatarghelper({'L','dim'},definput,varargin); % Pre-shape the signal [f,L,~,~,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,upper(mfilename)); f = postpad(f,L); % Run the computation z = comp_fftanalytic(f); % Post-shape the signal z = assert_sigreshape_post(z,dim,permutedsize,order); ltfat/inst/fourier/dctii.m0000664000175000017500000000646413026262304015476 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dctii.html} %@seealso{dctiii, dctiv, dstii} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/middlepad.m0000664000175000017500000001153113026262304016314 0ustar susnaksusnakfunction 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.github.io/doc/fourier/middlepad.html} %@seealso{isevenfunction, fir2long, fftresample} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/pxcorr.m0000664000175000017500000000317113026262304015707 0ustar susnaksusnakfunction h=pxcorr(f,g,varargin) %-*- texinfo -*- %@deftypefn {Function} pxcorr %@verbatim %PXCORR Periodic cross correlation % Usage: h=pxcorr(f,g) % % PXCORR(f,g) computes the periodic 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.github.io/doc/fourier/pxcorr.html} %@seealso{dft, pfilt, involute} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, Jordy van Velthoven definput.flags.type={'nonormalize','normalize'}; flags = ltfatarghelper({},definput,varargin); h = pconv(f, g, 'r'); if flags.do_normalize h = h/(norm(f)*norm(g)); end ltfat/inst/fourier/ptpfun.m0000664000175000017500000001663313026262304015715 0ustar susnaksusnakfunction g = ptpfun(L,w,varargin) %-*- texinfo -*- %@deftypefn {Function} ptpfun %@verbatim %PTPFUN Sampled, periodized totally positive function of finite type % Usage: g=ptpfun(L,w) % g=ptpfun(L,w,width) % % Input parameters: % L : Window length. % w : Vector of reciprocals w_j=1/delta_j in Fourier representation of g* % width: Integer stretching factor for the essential support of g % % Output parameters: % g : The periodized totally positive function. % % PTPFUN(L,w) computes samples of a periodized totally positive % function of finite type >=2 with weights w for a system of length L. % The Fourier representation of the continuous TP function is given as: % % m % ghat(f) = prod (1+2pijf/w(i))^(-1), % i=1 % % where m=numel(w)>= 2. The samples are obtained by discretizing % the Zak transform of the function. % % w controls the function decay in the time domain. More specifically % the function decays as exp(max(w)x) for x->infty and exp(min(w)x) % for x->-infty assuming w contains both positive and negative % numbers. % % PTPFUN(L,w,width) additionally stretches the function by a factor of % width. % % % References: % K. Groechenig and J. Stoeckler. Gabor frames and totally positive % functions. Duke Math. J., 162(6):1003--1031, 2013. % % S. Bannert, K. Groechenig, and J. Stoeckler. Discretized Gabor frames of % totally positive functions. Information Theory, IEEE Transactions on, % 60(1):159--169, 2014. % % T. Kloos and J. Stockler. Full length article: Zak transforms and gabor % frames of totally positive functions and exponential b-splines. J. % Approx. Theory, 184:209--237, Aug. 2014. [1]http ] % % T. Kloos. Gabor frames total-positiver funktionen endlicher ordnung. % Master's thesis, University of Dortmund, Dortmund, Germany, 2012. % % References % % 1. http://dx.doi.org/10.1016/j.jat.2014.05.010 % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/ptpfun.html} %@seealso{dgt, ptpfundual, gabdualnorm, normalize} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Joachim Stoeckler, Tobias Kloos 2012, 2014 complainif_notenoughargs(nargin,2,upper(mfilename)); complainif_notposint(L,'L',upper(mfilename)); if isempty(w) || ~isnumeric(w) || numel(w)<2 error(['%s: w must be a nonempty numeric vector with at least',... ' 2 elements.'], upper(mfilename)); end if any(w==0) error('%s: All weights w must be nonzero.', upper(mfilename)); end % Define initial value for flags and key/value pairs. %definput.import={'normalize'}; definput.keyvals.width=floor(sqrt(L)); [flags,~,width]=ltfatarghelper({'width'},definput,varargin); complainif_notposint(width,'width',upper(mfilename)); w = -sort(w(:))*L/width; x = [0:L-1]'/L; n = length(w); x = repmat(x,1,2*n-1) + repmat([-n+1:n-1],L,1); x = x(:)'; Y = zeros(n-1,length(x)); for k = 1:n-1 if w(k) == w(k+1) if w(k) < 0 Y(k,(n-1)*L+1:(n+1)*L) = w(k)^2/(1-exp(w(k)))^2*[x((n-1)*L+1:n*L).*exp(w(k)*x((n-1)*L+1:n*L)) , ... (2-x(n*L+1:(n+1)*L)).*exp(w(k)*x(n*L+1:(n+1)*L))]; else Y(k,(n-1)*L+1:(n+1)*L) = w(k)^2/(exp(-w(k))-1)^2*[x((n-1)*L+1:n*L).*exp(w(k)*(x((n-1)*L+1:n*L)-2)) , ... (2-x(n*L+1:(n+1)*L)).*exp(w(k)*(x(n*L+1:(n+1)*L)-2))]; end else if w(k) < 0 && w(k+1) < 0 Y(k,(n-1)*L+1:(n+1)*L) = w(k)/(1-exp(w(k)))*w(k+1)/(1-exp(w(k+1)))*[(exp(w(k)*x((n-1)*L+1:n*L))-exp(w(k+1)*x((n-1)*L+1:n*L)))/(w(k)-w(k+1)) , ... (exp(w(k))*exp(w(k+1)*(x(n*L+1:(n+1)*L)-1))-exp(w(k+1))*exp(w(k)*(x(n*L+1:(n+1)*L)-1)))/(w(k)-w(k+1))]; elseif w(k) > 0 && w(k+1) < 0 Y(k,(n-1)*L+1:(n+1)*L) = w(k)/(exp(-w(k))-1)*w(k+1)/(1-exp(w(k+1)))*[(exp(w(k)*(x((n-1)*L+1:n*L)-1))-exp(-w(k))*exp(w(k+1)*x((n-1)*L+1:n*L)))/(w(k)-w(k+1)) , ... (exp(w(k+1)*(x(n*L+1:(n+1)*L)-1))-exp(w(k+1))*exp(w(k)*(x(n*L+1:(n+1)*L)-2)))/(w(k)-w(k+1))]; elseif w(k) < 0 && w(k+1) > 0 Y(k,(n-1)*L+1:(n+1)*L) = w(k+1)/(exp(-w(k+1))-1)*w(k)/(1-exp(w(k)))*[(exp(w(k+1)*(x((n-1)*L+1:n*L)-1))-exp(-w(k+1))*exp(w(k)*x((n-1)*L+1:n*L)))/(w(k+1)-w(k)) , ... (exp(w(k)*(x(n*L+1:(n+1)*L)-1))-exp(w(k))*exp(w(k+1)*(x(n*L+1:(n+1)*L)-2)))/(w(k+1)-w(k))]; elseif w(k) > 0 && w(k+1) > 0 Y(k,(n-1)*L+1:(n+1)*L) = w(k)/(exp(-w(k))-1)*w(k+1)/(exp(-w(k+1))-1)*[(exp(-w(k+1))*exp(w(k)*(x((n-1)*L+1:n*L)-1))-exp(-w(k))*exp(w(k+1)*(x((n-1)*L+1:n*L)-1)))/(w(k)-w(k+1)) , ... (exp(w(k+1)*(x(n*L+1:(n+1)*L)-2))-exp(w(k)*(x(n*L+1:(n+1)*L)-2)))/(w(k)-w(k+1))]; end end end for k = 2:n-1 for j = 1:n-k if w(j) == w(j+k) if w(j) < 0 Y(j,(k-1)*L+1:end) = -w(j)/(1-exp(w(j)))*(x((k-1)*L+1:end)/k .* Y(j,(k-1)*L+1:end) + ... exp(w(j))*(k+1-x((k-1)*L+1:end))/k .* Y(j,(k-2)*L+1:end-L)); else Y(j,(k-1)*L+1:end) = -w(j)/(exp(-w(j))-1)*(exp(-w(j))*x((k-1)*L+1:end)/k .* Y(j,(k-1)*L+1:end) + ... (k+1-x((k-1)*L+1:end))/k .* Y(j,(k-2)*L+1:end-L)); end else if w(j) < 0 && w(j+k) < 0 Y(j,(k-1)*L+1:end) = ( (-w(j)*(Y(j+1,(k-1)*L+1:end) - exp(w(j))*Y(j+1,(k-2)*L+1:end-L)))/(1-exp(w(j))) - ... (-w(j+k)*(Y(j,(k-1)*L+1:end) - exp(w(j+k))*Y(j,(k-2)*L+1:end-L)))/(1-exp(w(j+k))) )/ ... (w(j+k)-w(j)); elseif w(j) > 0 && w(j+k) < 0 Y(j,(k-1)*L+1:end) = ( (-w(j)*(exp(-w(j))*Y(j+1,(k-1)*L+1:end) - Y(j+1,(k-2)*L+1:end-L)))/(exp(-w(j))-1) - ... (-w(j+k)*(Y(j,(k-1)*L+1:end) - exp(w(j+k))*Y(j,(k-2)*L+1:end-L)))/(1-exp(w(j+k))) )/ ... (w(j+k)-w(j)); elseif w(j) < 0 && w(j+k) > 0 Y(j,(k-1)*L+1:end) = ( (-w(j)*(Y(j+1,(k-1)*L+1:end) - exp(w(j))*Y(j+1,(k-2)*L+1:end-L)))/(1-exp(w(j))) - ... (-w(j+k)*(exp(-w(j+k))*Y(j,(k-1)*L+1:end) - Y(j,(k-2)*L+1:end-L)))/(exp(-w(j+k))-1) )/ ... (w(j+k)-w(j)); elseif w(j) > 0 && w(j+k) > 0 Y(j,(k-1)*L+1:end) = ( (-w(j)*(exp(-w(j))*Y(j+1,(k-1)*L+1:end) - Y(j+1,(k-2)*L+1:end-L)))/(exp(-w(j))-1) - ... (-w(j+k)*(exp(-w(j+k))*Y(j,(k-1)*L+1:end) - Y(j,(k-2)*L+1:end-L)))/(exp(-w(j+k))-1) )/ ... (w(j+k)-w(j)); end end end end if n == 1 if w < 0 g = -w/(1-exp(w))*exp(w*x(1:L)) * sqrt(width) / L; else g = -w/(exp(-w)-1)*exp(w*(x(1:L)-1)) * sqrt(width) / L; end else g = sum(reshape(Y(1,end-n*L+1:end),L,n),2) * sqrt(width) / L; end %g = normalize(g(:),flags.norm); g = g(:); end ltfat/inst/fourier/plotfftreal.m0000664000175000017500000001164713026262304016723 0ustar susnaksusnakfunction 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. % % 'flog' Use logarithmic scale for the frequency axis. % % % 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.github.io/doc/fourier/plotfftreal.html} %@seealso{plotfft, fftreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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.flags.freqscale={'flin','flog'}; 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/fourier/pderiv.m0000664000175000017500000000453513026262304015670 0ustar susnaksusnakfunction 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.github.io/doc/fourier/pderiv.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/dfracft.m0000664000175000017500000000513613026262304016006 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dfracft.html} %@seealso{ffracft, dft, hermbasis, pherm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/dctiv.m0000664000175000017500000000625713026262304015513 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dctiv.html} %@seealso{dctii, dctiii, dstii} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/floor23.m0000664000175000017500000000620613026262304015662 0ustar susnaksusnakfunction [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.github.io/doc/fourier/floor23.html} %@seealso{ceil23, floor235, nextfastfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/pbspline.m0000664000175000017500000002663513026262304016220 0ustar susnaksusnakfunction [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.github.io/doc/fourier/pbspline.html} %@seealso{pgauss, firwin, middlepad, normalize, demo_pbspline} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/prect.m0000664000175000017500000000414413026262304015510 0ustar susnaksusnakfunction 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.github.io/doc/fourier/prect.html} %@seealso{psinc} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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); ltfat/inst/fourier/isevenfunction.m0000664000175000017500000000437613026262304017441 0ustar susnaksusnakfunction 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.github.io/doc/fourier/isevenfunction.html} %@seealso{middlepad, peven} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/fftreal.m0000664000175000017500000000343613026262304016021 0ustar susnaksusnakfunction 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.github.io/doc/fourier/fftreal.html} %@seealso{ifftreal, dft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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'); if ~isempty(N) f=postpad(f,N); end 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); ltfat/inst/fourier/nextfastfft.m0000664000175000017500000000751213026262304016731 0ustar susnaksusnakfunction [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 a 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.github.io/doc/fourier/nextfastfft.html} %@seealso{ceil23, ceil235, demo_nextfastfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/lconv.m0000664000175000017500000000601713026262304015515 0ustar susnaksusnakfunction h=lconv(f,g,varargin) %-*- texinfo -*- %@deftypefn {Function} lconv %@verbatim %LCONV Linear convolution % Usage: h=lconv(f,g); % % LCONV(f,g) computes the linear convolution of f and g. The linear % convolution is given by % % Lh-1 % h(l+1) = sum f(k+1) * g(l-k+1) % k=0 % % with L_{h} = L_{f} + L_{g} - 1 where L_{f} and L_{g} are the lengths of f and g, % respectively. % % LCONV(f,g,'r') computes the linear convolution of f and g where g is reversed. % This type of convolution is also known as linear cross-correlation and is given by % % Lh-1 % h(l+1) = sum f(k+1) * conj(g(k-l+1)) % k=0 % % LCONV(f,g,'rr') computes the alternative where both f and g are % reversed given by % % Lh-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_{h}. % % The input arrays f and g can be 1D vectors or one of them can be % a multidimensional array. In either case, the convolution is performed % along columns with row vectors transformed to columns. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/lconv.html} %@seealso{pconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven % TESTING: TEST_LCONV % REFERENCE: REF_LCONV complainif_notenoughargs(nargin, 2, 'LCONV'); definput.keyvals.L=[]; definput.keyvals.dim=[]; definput.flags.type={'default', 'r', 'rr'}; [flags,~,L,dim]=ltfatarghelper({'L','dim'},definput,varargin); [f,~,Lf,Wf,dimoutf,permutedsize_f,order_f]=assert_sigreshape_pre(f,L,dim,'LCONV'); [g,~,Lg,Wg,dimoutg,permutedsize_g,order_g]=assert_sigreshape_pre(g,L,dim,'LCONV'); 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. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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).'; ltfat/inst/fourier/peven.m0000664000175000017500000000235513026262304015512 0ustar susnaksusnakfunction 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.github.io/doc/fourier/peven.html} %@seealso{podd, dft, involute, pconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin==1 f=(f+involute(f))/2; else f=(f+involute(f,dim))/2; end; ltfat/inst/fourier/fftgram.m0000664000175000017500000000511213026262304016015 0ustar susnaksusnakfunction fftgram(f, varargin) %-*- texinfo -*- %@deftypefn {Function} fftgram %@verbatim %FFTGRAM Plot the energy of the discrete Fourier transform % Usage: fftgram(f) % fftgram(f, fs) % % FFTGRAM(f) plots the energy of the discrete Fourier transform computed % from the function f. The function forms a Fourier pair with the periodic % autocorrelation function. % % FFTGRAM(f,fs) does the same for a signal sampled with a sampling % frequency of fs Hz. If fs is no specified, the plot will display % normalized frequencies. % % FFTGRAM(f,fs,dynrange) additionally specifies the dynamic range to % display on the figure. % % Additional arguments for FFTGRAM: % % 'db' Plots the energy on a dB scale. This is the default. % % 'lin' Plots the energy on a linear scale. % % In addition to these parameters, FFTGRAM accepts any of the flags from % NORMALIZE. The input signal will be normalized as specified. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/fftgram.html} %@seealso{dft, plotfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven % Assert correct number of input parameters. complainif_notenoughargs(nargin, 1, 'FFTGRAM'); definput.import={'ltfattranslate','normalize'}; definput.keyvals.fs=[]; definput.keyvals.clim=[]; definput.keyvals.dynrange=[]; definput.flags.powscale={'db', 'lin'}; [flags, kv] = ltfatarghelper({'fs','dynrange'},definput,varargin); if isreal(f) p = (fftreal(f).*conj(fftreal(f))); else p = (fft(f).*conj(fft(f))); end; p = normalize(p, flags.norm); if flags.do_db if isreal(f) plotfftreal(p,kv.fs, kv.dynrange); else plotfft(p,kv.fs, kv.dynrange); end; ylabel('Energy (dB)'); end; if flags.do_lin if isreal(f) plotfftreal(p, kv.fs, kv.dynrange, 'lin'); else plotfft(p, kv.fs, kv.dynrange,'lin'); end; ylabel('Energy'); end; ltfat/inst/fourier/ceil235.m0000664000175000017500000000605013026262304015537 0ustar susnaksusnakfunction [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.github.io/doc/fourier/ceil235.html} %@seealso{floor235, ceil23, nextfastfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/pgauss.m0000664000175000017500000001450413026262304015676 0ustar susnaksusnakfunction [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 -6dB or to width at the % half of the height. % This is equivalent to calling PGAUSS(L,pi*s^2/4L*log(2)). % % 'atheight',ah Used only in conjuction with 'width'. Forces the % Gaussian to width s at the ah fraction of the % height. % % '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.github.io/doc/fourier/pgauss.html} %@seealso{dgtlength, psech, firwin, pbspline, normalize, demo_pgauss} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; definput.keyvals.atheight=[]; [flags,keyvals,tfr]=ltfatarghelper({'tfr'},definput,varargin); if (prod(size(tfr,1))~=1 || ~isnumeric(tfr)) error('tfr must be a scalar.'); end; if ~isempty(keyvals.atheight) && ~flags.do_width error(['%s: Param. ''atheight'' must be used together with param.',... ' ''width''. '],upper(mfilename)); end if isempty(keyvals.atheight) keyvals.atheight = 0.5; end if keyvals.atheight >= 1 || keyvals.atheight <=0 error('%s: Param. ''atheight'' must be in the range ]0,1[.',... upper(mfilename)); end fs=keyvals.fs; if flags.do_wp cent=0; else cent=0.5; end; if isempty(fs) if flags.do_width tfr=pi/(4*log(1/keyvals.atheight))*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); ltfat/inst/fourier/dctiii.m0000664000175000017500000000643413026262304015644 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dctiii.html} %@seealso{dctii, dctiv, dstii} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,:); ltfat/inst/fourier/dctresample.m0000664000175000017500000000405613026262304016700 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dctresample.html} %@seealso{fftresample, middlepad, dctiii} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/dstiv.m0000664000175000017500000000571513026262304015531 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dstiv.html} %@seealso{dstii, dstiii, dctii} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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)); ltfat/inst/fourier/pebfun.m0000664000175000017500000001173113026262304015652 0ustar susnaksusnakfunction [g,nlen] = pebfun(L,w,varargin) %-*- texinfo -*- %@deftypefn {Function} pebfun %@verbatim %PEBFUN Sampled, periodized EB-spline % Usage: g=pebfun(L,w) % g=pebfun(L,w,width) % [g,nlen]=pebfun(...) % % Input parameters: % L : Window length. % w : Vector of weights of g* % width : integer stretching factor, the support of g is width*length(w) % % Output parameters: % g : The periodized EB-spline. % nlen : Number of non-zero elements in out. % % PEBFUN(L,w) computes samples of a periodized EB-spline with weights % w for a system of length L. % % PEBFUN(L,w,width) additionally stretches the function by a factor of % width. % % [g,nlen]=ptpfundual(...) as g might have a compact support, % nlen contains a number of non-zero elements in g. This is the case % when g is symmetric. If g is not symmetric, nlen is extended % to twice the length of the longer tail. % % If nlen = L, g has a 'full' support meaning it is a periodization % of a EB spline function. % % If nlen < L, additional zeros can be removed by calling % g=middlepad(g,nlen). % % % References: % K. Groechenig and J. Stoeckler. Gabor frames and totally positive % functions. Duke Math. J., 162(6):1003--1031, 2013. % % S. Bannert, K. Groechenig, and J. Stoeckler. Discretized Gabor frames of % totally positive functions. Information Theory, IEEE Transactions on, % 60(1):159--169, 2014. % % T. Kloos and J. Stockler. Full length article: Zak transforms and gabor % frames of totally positive functions and exponential b-splines. J. % Approx. Theory, 184:209--237, Aug. 2014. [1]http ] % % T. Kloos. Gabor frames total-positiver funktionen endlicher ordnung. % Master's thesis, University of Dortmund, Dortmund, Germany, 2012. % % T. Kloos, J. Stockler, and K. Groechenig. Implementation of discretized % gabor frames and their duals. IEEE Transactions on Information Theory, % 62(5):2759--2771, May 2016. % % References % % 1. http://dx.doi.org/10.1016/j.jat.2014.05.010 % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/pebfun.html} %@seealso{dgt, pebfundual, gabdualnorm, normalize} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Joachim Stoeckler, Tobias Kloos 2012, 2016 complainif_notenoughargs(nargin,2,upper(mfilename)); complainif_notposint(L,'L',upper(mfilename)) if isempty(w) || ~isnumeric(w) || numel(w)<2 error(['%s: w must be a nonempty numeric vector with at least',... ' 2 elements.'], upper(mfilename)); end if any(w==0) error('%s: All weights w must be nonzero.', upper(mfilename)); end %TODO: Sanity check for w e.g. % pebfun(1000,[1000,300]) is degenerate %definput.import={'normalize'}; definput.keyvals.width=floor(sqrt(L)); [flags,~,width]=ltfatarghelper({'width'},definput,varargin); complainif_notposint(width,'width',upper(mfilename)); w = sort(w); n = length(w); x = linspace(0,n-1/width,n*width); x = x(:); m = length(x); x = repmat(x,1,n) + repmat([-n+1:0],m,1); x = x(:)'; Y = zeros(n-1,length(x)); for k = 1:n-1 if w(k) == w(k+1) Y(k,:) = x.*exp(w(k)*x).*(x>=0).*(x<=1) + ... (2-x).*exp(w(k)*x).*(x>1).*(x<=2); else Y(k,:) = (exp(w(k)*x)-exp(w(k+1)*x))/(w(k)-w(k+1)).*(x>=0).*(x<=1) + ... (exp(w(k)-w(k+1))*exp(w(k+1)*x)-exp(w(k+1)-w(k))*exp(w(k)*x))/(w(k)-w(k+1)).*(x>1).*(x<=2); end end for k = 2:n-1 for j = 1:n-k if w(j) == w(j+k) Y(j,(k-1)*m+1:end) = x((k-1)*m+1:end)/k .* Y(j,(k-1)*m+1:end) + ... exp(w(j))*(k+1-x((k-1)*m+1:end))/k .* Y(j,(k-2)*m+1:end-m); else Y(j,(k-1)*m+1:end) = ( Y(j,(k-1)*m+1:end) - Y(j+1,(k-1)*m+1:end) + ... exp(w(j))*Y(j+1,(k-2)*m+1:end-m) - exp(w(j+k))*Y(j,(k-2)*m+1:end-m) )/ ... (w(j)-w(j+k)); end end end if n == 1 y = exp(w*x).*(x>=0).*(x<=1); else y = Y(1,end-m+1:end); end if m <= L g = [y,zeros(1,L-m)]/sqrt(width); else y = [y,zeros(1,ceil(m/L)*L-m)]; g = sum(reshape(y,L,ceil(m/L)),2).'/sqrt(width); end nlen = min([L,m]); g = g(:); %g = normalize(g(:),flags.norm); % Shift the window back %[~,maxidx] = max(abs(g)); %g = circshift(g,-maxidx+1); end ltfat/inst/fourier/gga.m0000664000175000017500000001032113026262304015123 0ustar susnaksusnakfunction 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 % ckgga = gga(f,freq,fs); % % % Plot modulus of coefficients % figure(1);clf;hold on; % stem(k/L*fs,2*abs(ck)/L,'k'); % stem(freq,2*abs(ckgga)/L,'r:'); % set(gca,'XLim',[freq(1)-50,freq(end)+50]); % set(gca,'YLim',[0 6]); % xlabel('f[Hz]'); % ylabel('|c(k)|'); % hold off; % % % Plot phase of coefficients % figure(2);clf;hold on; % stem(k/L*fs,angle(ck),'k'); % stem(freq,angle(ckgga),'r:'); % set(gca,'XLim',[freq(1)-50,freq(end)+50]); % set(gca,'YLim',[-pi pi]); % xlabel('f[Hz]'); % ylabel('angle(c(k))'); % hold off; % % % 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.github.io/doc/fourier/gga.html} %@seealso{chirpzt} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/lxcorr.m0000664000175000017500000000321413026262304015701 0ustar susnaksusnakfunction h=lxcorr(f,g,varargin) %-*- texinfo -*- %@deftypefn {Function} lxcorr %@verbatim %LXCORR Linear crosscorrelation % Usage: h=lxcorr(f,g) % % LXCORR(f) computes the linear crosscorrelation of the input signal f and g. % The linear cross-correlation is computed by % % Lh-1 % h(l+1) = sum f(k+1) * conj(g(k-l+1)) % k=0 % % with L_{h} = L_{f} + L_{g} - 1 where L_{f} and L_{g} are the lengths of f and g, % respectively. % % LXCORR(f,'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.github.io/doc/fourier/lxcorr.html} %@seealso{pxcorr, lconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven definput.flags.type={'nonormalize','normalize'}; flags = ltfatarghelper({},definput,varargin); h = lconv(f, g, 'r'); if flags.do_normalize h = h/(norm(f)*norm(g)); end ltfat/inst/fourier/psinc.m0000664000175000017500000000340413026262304015505 0ustar susnaksusnakfunction 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.github.io/doc/fourier/psinc.html} %@seealso{prect} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/fourier/dsti.m0000664000175000017500000000576213026262304015345 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dsti.html} %@seealso{dcti, dstiii, dstiv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/pebfundual.m0000664000175000017500000002551013026262304016520 0ustar susnaksusnakfunction [gd,nlen] = pebfundual(w,a,M,L,varargin) %-*- texinfo -*- %@deftypefn {Function} pebfundual %@verbatim %PEBFUNDUAL Dual window of sampled, periodized EB-spline % Usage: g=pebfundual(w,a,M,L) % g=pebfundual({w,width},a,M,L) % g=pebfundual(...,inc) % % Input parameters: % w : vector of weights of g % width : integer stretching factor of the window g* % a : time shift, given by an integer number of sampling points % M : number of channels % L : length of a period % inc : number of additional columns to compute window function % % Output parameters: % gd : Periodized dual window for the discrete EB-spline % % PEBFUNDUAL(w,a,M,L) computes samples of a dual window of EB spline % with weights w. Please see PEBFUN for definition of EB splines. % The lattice parameters a,M must satisfy M > a to ensure the % system is a frame. % % PEBFUNDUAL({w,width},a,M,L) works as above but in addition the width* % parameter determines the integer stretching factor of the original EB % spline. For explanation see help of PEBFUN. % % PEBFUNDUAL(...,inc) or PEBFUNDUAL(...,'inc',inc) works as above, % but integer inc denotes number of additional columns to compute window % function gd. 'inc'-many are added at each side. It should be smaller than % 100 to have comfortable execution-time. The higher the number the % closer gd is to the canonical dual window. % The default value is 10. % % Examples: % --------- % % The following example compares dual windows computed using 2 different % approaches.: % % w = [-3,-1,1,3];a = 25; M = 31; inc = 1; % L = 1e6; L = dgtlength(L,a,M); % width = M; % % % Create the window % g = pebfun(L,w,width); % % % Compute a dual window using pebfundual % tic % [gd,nlen] = pebfundual({w,width},a,M,L,inc); % tebfundual=toc; % % % We know that gd has only nlen nonzero samples, lets shrink it. % gd = middlepad(gd,nlen); % % % Compute the canonical window using gabdual % tic % gdLTFAT = gabdual(g,a,M,L); % tgabdual=toc; % % fprintf('PEBFUNDUAL elapsed time %f sn',tebfundual); % fprintf('GABDUAL elapsed time %f sn',tgabdual); % % % Test on random signal % f = randn(L,1); % % fr = idgt(dgt(f,g,a,M),gd,a,numel(f)); % fprintf('Reconstruction error PEBFUNDUAL: %en',norm(f-fr)/norm(f)); % % fr = idgt(dgt(f,g,a,M),gdLTFAT,a,numel(f)); % fprintf('Reconstruction error GABDUAL: %en',norm(f-fr)/norm(f)); % % % References: % K. Groechenig and J. Stoeckler. Gabor frames and totally positive % functions. Duke Math. J., 162(6):1003--1031, 2013. % % S. Bannert, K. Groechenig, and J. Stoeckler. Discretized Gabor frames of % totally positive functions. Information Theory, IEEE Transactions on, % 60(1):159--169, 2014. % % T. Kloos and J. Stockler. Full length article: Zak transforms and gabor % frames of totally positive functions and exponential b-splines. J. % Approx. Theory, 184:209--237, Aug. 2014. [1]http ] % % T. Kloos. Gabor frames total-positiver funktionen endlicher ordnung. % Master's thesis, University of Dortmund, Dortmund, Germany, 2012. % % T. Kloos, J. Stockler, and K. Groechenig. Implementation of discretized % gabor frames and their duals. IEEE Transactions on Information Theory, % 62(5):2759--2771, May 2016. % % References % % 1. http://dx.doi.org/10.1016/j.jat.2014.05.010 % % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/pebfundual.html} %@seealso{dgt, idgt, pebfun} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: (c) Joachim Stoeckler, Tobias Kloos, 2012-2016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % check input %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% complainif_notenoughargs(nargin,4,upper(mfilename)); complainif_notposint(L,'L',upper(mfilename)); complainif_notposint(a,'a',upper(mfilename)); complainif_notposint(M,'M',upper(mfilename)); % Check lattice if M<=a error('%s: Lattice parameters must satisfy M>a.',upper(mfilename)); end % Check w if iscell(w) if numel(w)~=2 error('%s: w must be a 2 element cell array.',upper(mfilename)); end width = w{2}; w = w{1}; complainif_notposint(width,'width',upper(mfilename)); else width = floor(sqrt(L)); end if isempty(w) || ~isnumeric(w) || numel(w)<2 error(['%s: w must be a nonempty numeric vector with at least',... ' 2 elements.'], upper(mfilename)); end if any(w==0) error('%s: All weights w must be nonzero.', upper(mfilename)); % TO DO: Also add a warning if w is very small or big? end % Define initial value for flags and key/value pairs. %definput.import={'normalize'}; definput.keyvals.inc = 10; %definput.flags.scale = {'nomatchscale','matchscale'}; [flags,~,inc]=ltfatarghelper({'inc'},definput,varargin); complainif_notnonnegint(inc,'inc',upper(mfilename)); w = sort(w(:)); % sort and make it a column vector m = length(w); alpha = a/width; beta = width/M; % check alpha beta if (alpha<=0) || (beta<=0) error('lattice parameters alpha, beta must be positive') end if (alpha*beta>=1) error('lattice parameters must satisfy alpha*beta<1') end if (alpha >= m) error('a/width must be smaller than length(w)') end check = 1; if (1/beta == floor(1/beta)) check = 0; elseif (alpha == floor(alpha)) check = 0; elseif (1/alpha == floor(1/alpha)) && (beta < 1) check = 0; end if check == 1 warning('output may not be a dual window; M/width should be a small integer') end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % preparations specially for computation of gamma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% k1 = -(ceil(beta*(1/2*(m+alpha)+alpha*inc)/(1-alpha*beta))-1); k2 = ceil(beta*(1/2*(m+alpha)+alpha*inc)/(1-alpha*beta))-1; i1 = floor(m/2/alpha+(k1-1)/(alpha*beta)-1); i2 = ceil((k2+1)/(alpha*beta)-(m-alpha)/2/alpha+1); % minimal values for x and y x = (i1-1)*alpha:alpha:(i2+1)*alpha; i0 = abs(i1-1)+1; % index of "central" row of P(x) y = k1/beta:1/beta:k2/beta; k0 = abs(k1)+1; % index of "central" column of P(x) [yy,xx] = meshgrid(y,x); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % discretization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t = 0:1/width:(a-1)/width;% for stepping through the interval [0,alpha) j0 = ceil((m*width-a)/2); t = t + j0/width; tt = i1*alpha:1/width:i2*alpha; % choose same stepsize for t and tt % left and right bounds large enough for the support of gamma tt0 = abs(i1*a)+1; % index for tt == 0 gd = zeros(1,length(tt)); % dual window c0 = zeros(1,length(t)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % computation of gamma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %wait = waitbar(0,'Computing dual windows. Please wait...'); for k = 1:length(t) % step through the interval [0,alpha) x0 = t(k); % compute dual window at points (x+j*alpha) k1x = -(ceil((beta*(m-x0+alpha*inc))/(1-alpha*beta))-1) + k0; k2x = ceil((beta*(x0+alpha*inc))/(1-alpha*beta))-1 + k0; i1x = ceil((m*beta+(k1x-k0)-1-x0*beta)/(alpha*beta)) + i0; i2x = floor(((k2x-k0)+1-x0*beta)/(alpha*beta)) + i0; % Computation of P0(x0) % z0 is the matrix of the abscissa x0+j*alpha-k/beta, j=i1:i2, k=k1:k2, % z1 puts all these abscissae into a row vector. % The computation of g(z1) is done as described above for the % vector tt. z0 = x0+xx(:,k1x:k2x)-yy(:,k1x:k2x); z1 = z0(:)'; lz1 = length(z1); z1 = repmat(z1.',1,m) + repmat([-m+1:0],lz1,1); z1 = z1(:)'; Y = zeros(m-1,length(z1)); index = find( (z1>=0) & (z1<=2)); zinit = z1(index); % only these are needed for initialization of Y for q = 1:m-1 if w(q) == w(q+1) Y(q,index) = zinit.*exp(w(q)*zinit).*(zinit<=1) + ... (2-zinit).*exp(w(q)*zinit).*(zinit>1); else Y(q,index) = (exp(w(q)*zinit)-exp(w(q+1)*zinit))/(w(q)-w(q+1)).*(zinit<=1) + ... (exp(w(q)-w(q+1))*exp(w(q+1)*zinit)-exp(w(q+1)-w(q))*exp(w(q)*zinit))/(w(q)-w(q+1)).*(zinit>1); end end for q = 2:m-1 for j = 1:m-q if w(j) == w(j+q) Y(j,(q-1)*lz1+1:end) = z1((q-1)*lz1+1:end)/q .* Y(j,(q-1)*lz1+1:end) + ... exp(w(j))*(q+1-z1((q-1)*lz1+1:end))/q .* Y(j,(q-2)*lz1+1:end-lz1); else Y(j,(q-1)*lz1+1:end) = ( Y(j,(q-1)*lz1+1:end) - Y(j+1,(q-1)*lz1+1:end) + ... exp(w(j))*Y(j+1,(q-2)*lz1+1:end-lz1) - exp(w(j+q))*Y(j,(q-2)*lz1+1:end-lz1) )/ ... (w(j)-w(j+q)); end end end if m == 1 index = find( (z1>=0) & (z1<=1)); zinit = z1(index); % only these are needed for m=1 A0(index) = exp(w*zinit); else A0 = Y(1,end-lz1+1:end); end A0 = reshape(A0,size(z0)); P0 = A0(i1x:i2x,:); % computation of pseudo-inverse matrix of P0 P0inv = pinv(P0); gd(k-1+tt0+j0+a*(i1x-i0):a:k-1+tt0+j0+a*(i2x-i0)) = beta*P0inv(k0-k1x+1,:); % row index k0-k1a+1 % points to the "j=0" row of P0inv end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % periodization of gamma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nlen = numel(gd); nr = ceil(length(gd)/L); v = zeros(1,nr*L); v(1:length(gd)) = gd; v = [v(tt0:end),v(1:tt0-1)]; % Determine nlen if nlen. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, Jordy van Velthoven % TESTING: TEST_DFT % REFERENCE: REF_DFT 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); ltfat/inst/fourier/floor235.m0000664000175000017500000000645213026262304015752 0ustar susnaksusnakfunction [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.github.io/doc/fourier/floor235.html} %@seealso{floor23, ceil235, nextfastfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/modcent.m0000664000175000017500000000230313026262304016017 0ustar susnaksusnakfunction 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.github.io/doc/fourier/modcent.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . x=mod(x,r); idx=x>r/2; x(idx)=x(idx)-r; ltfat/inst/fourier/shah.m0000664000175000017500000000377413026262304015326 0ustar susnaksusnakfunction 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.github.io/doc/fourier/shah.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/dstii.m0000664000175000017500000000600213026262304015502 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dstii.html} %@seealso{dctii, dstiii, dstiv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/Contents.m0000664000175000017500000000773113026262304016175 0ustar susnaksusnak% LTFAT - Basic Fourier and DCT analysis. % % Peter L. Soendergaard, 2008 - 2016. % % 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. % FFTGRAM - Plot energy of FFT. % 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. % PXCORR - Periodic crosscorrelation. % LCONV - Linear convolution. % LXCORR - Linear crosscorrelation. % ISEVENFUNCTION - Test if function is even. % MIDDLEPAD - Cut or extend even function. % % Periodic functions % EXPWAVE - Complex exponential wave. % PCHIRP - Periodic chirp. % PGAUSS - Periodic Gaussian. % PSECH - Periodic SECH. % PBSPLINE - Periodic B-splines. % SHAH - Shah distribution. % PHEAVISIDE - Periodic Heaviside function. % PRECT - Periodic rectangle function. % PSINC - Periodic sinc function. % PTPFUN - Periodic totally positive function of finite type. % PEBFUN - Periodic EB spline. % % Specialized dual windows % PTPFUNDUAL - Dual window for PTPFUN % PEBFUNDUAL - Dual window for PEBFUN % % 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. % FFTANALYTIC - Analytic representation of a 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 visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/fourier/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/fourier/chirpzt.m0000664000175000017500000001105713026262304016057 0ustar susnaksusnakfunction 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.github.io/doc/fourier/chirpzt.html} %@seealso{gga} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . %% 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); ltfat/inst/fourier/ffracft.m0000664000175000017500000000760613026262304016014 0ustar susnaksusnakfunction 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.github.io/doc/fourier/ffracft.html} %@seealso{dfracft, hermbasis, pherm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/plotfft.m0000664000175000017500000001272313026262304016053 0ustar susnaksusnakfunction 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. % % 'flog' Use logarithmic scale for the frequency axis. This flag is % only valid in conjuction with the 'posfreq' flag. % % % 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.github.io/doc/fourier/plotfft.html} %@seealso{plotfftreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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.flags.freqscale={'flin','flog'}; definput.keyvals.fs=[]; definput.keyvals.dynrange=[]; definput.keyvals.opts={}; definput.keyvals.dim=[]; [flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin); if flags.do_nf && flags.do_flog warning(sprintf(['%s: Disabling the ''flog'' flag. It cannot be used ',... 'in plot containing negative frequences.'],... upper(mfilename))); flags.do_flog = 0; end [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=2 with weights w. Please see % PTPFUN for definition of totally positive functions. % The lattice parameters a,M must satisfy M > a to ensure the % system is a frame. % % PTPFUNDUAL({w,width},a,M,L) works as above but in addition the width* % parameter determines the integer stretching factor of the original TP % function. For explanation see help of PTPFUN. % % PTPFUNDUAL(...,inc) or PTPFUNDUAL(...,'inc',inc) works as above, % but integer inc denotes number of additional columns to compute window % function gd. 'inc'-many are added at each side. It should be smaller % than 100 to have comfortable execution-time. The higher the number the % closer gd is to the canonical dual window. % The default value is 10. % % [gd,nlen]=PTPFUNDUAL(...) as gd might have a compact support, % nlen contains a number of non-zero elements in gd. This is the case % when gd is symmetric. If gd is not symmetric, nlen is extended % to twice the length of the longer tail. % % If nlen = L, gd has a 'full' support meaning it is a periodization % of a dual TP function. % % If nlen < L, additional zeros can be removed by calling % gd=middlepad(gd,nlen). % % Examples: % --------- % % The following example compares dual windows computed using 2 different % approaches.: % % w = [-3,-1,1,3];a = 25; M = 31; inc = 10; % L = 1e6; L = dgtlength(L,a,M); % width = M; % % % Create the window % g = ptpfun(L,w,width); % % % Compute a dual window using pebfundual % tic % [gd,nlen] = ptpfundual({w,width},a,M,L,inc); % ttpfundual=toc; % % % We know that gd has only nlen nonzero samples, lets shrink it. % gd = middlepad(gd,nlen); % % % Compute the canonical window using gabdual % tic % gdLTFAT = gabdual(g,a,M,L); % tgabdual=toc; % % fprintf('PTPFUNDUAL elapsed time %f sn',ttpfundual); % fprintf('GABDUAL elapsed time %f sn',tgabdual); % % % Test on random signal % f = randn(L,1); % % fr = idgt(dgt(f,g,a,M),gd,a,numel(f)); % fprintf('Reconstruction error PTPFUNDUAL: %en',norm(f-fr)/norm(f)); % % fr = idgt(dgt(f,g,a,M),gdLTFAT,a,numel(f)); % fprintf('Reconstruction error GABDUAL: %en',norm(f-fr)/norm(f)); % % % References: % K. Groechenig and J. Stoeckler. Gabor frames and totally positive % functions. Duke Math. J., 162(6):1003--1031, 2013. % % S. Bannert, K. Groechenig, and J. Stoeckler. Discretized Gabor frames of % totally positive functions. Information Theory, IEEE Transactions on, % 60(1):159--169, 2014. % % T. Kloos and J. Stockler. Full length article: Zak transforms and gabor % frames of totally positive functions and exponential b-splines. J. % Approx. Theory, 184:209--237, Aug. 2014. [1]http ] % % T. Kloos. Gabor frames total-positiver funktionen endlicher ordnung. % Master's thesis, University of Dortmund, Dortmund, Germany, 2012. % % References % % 1. http://dx.doi.org/10.1016/j.jat.2014.05.010 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/ptpfundual.html} %@seealso{dgt, idgt, ptpfun} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Joachim Stoeckler, Tobias Kloos, 2012-2014 complainif_notenoughargs(nargin,4,upper(mfilename)); complainif_notposint(L,'L',upper(mfilename)); complainif_notposint(a,'a',upper(mfilename)); complainif_notposint(M,'M',upper(mfilename)); % Check lattice if M<=a error('%s: Lattice parameters must satisfy M>a.',upper(mfilename)); end % Check w if iscell(w) if numel(w)~=2 error('%s: w must be a 2 element cell array.',upper(mfilename)); end width = w{2}; w = w{1}; complainif_notposint(width,'width',upper(mfilename)); else width = floor(sqrt(L)); end if isempty(w) || ~isnumeric(w) || numel(w)<2 error(['%s: w must be a nonempty numeric vector with at least',... ' 2 elements.'], upper(mfilename)); end if any(w==0) error('%s: All weights w must be nonzero.', upper(mfilename)); % TO DO: Also add a warning if w is very small or big? end % Define initial value for flags and key/value pairs. %definput.import={'normalize'}; definput.keyvals.inc = 10; %definput.flags.scale = {'nomatchscale','matchscale'}; [flags,~,inc]=ltfatarghelper({'inc'},definput,varargin); complainif_notnonnegint(inc,'inc',upper(mfilename)); % TP functions are scale invariant so we do scaling directly on w. wloc = w/width; % Converting a, M to alpha, beta alpha = a; beta = 1/M; % check alpha beta if (alpha<=0) || (beta<=0) error('lattice parameters alpha, beta must be positive') end if (width*beta > 10) warning('width/M should be smaller than 10: numerical instability may occur') end % compute m n and check that a has nonzero entries if all(wloc<0) wloc = -wloc; case0 = 2; else case0 = 0; end m = length(find(wloc>0)); n = length(find(wloc<0)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % preparations specially for computation of gd %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% r = floor(1/(1-alpha*beta)+eps); % check special cases according to n and m if n == 0 if m >= 2 k2 = (m-1)*(r+1)-1; k1 = -k2; if case0 == 0 case0 = 1; end end elseif n == 1 N = m*(r+1)+1; % minimal column size k1 = -m*(r+1)+1; % column index k1 from the paper k2 = k1+N-1; % column index k2 from the paper else N = (m+n-1)*(r+1); % minimal column size k1 = -m*(r+1)+1; % column index k1 from the paper k2 = k1+N-1; % column index k2 from the paper end k1 = k1-inc; k2 = k2+inc; % minimal values for x and y varl = floor((k1+m-1)/(alpha*beta))-1; varr = ceil((k2-n+1)/(alpha*beta))+1; x = varl*alpha:alpha:varr*alpha; i0 = abs(varl)+1; % index of "central" row of P(x) y = (k1-1)/beta:(1/beta):(k2+1)/beta; k0 = abs(k1-1)+1; % index of "central" column of P(x) [yy,xx] = meshgrid(y,x); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % discretization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t = 0:(a-1); % for stepping through the interval [0,alpha) tt = varl*alpha:varr*alpha; % choose same stepsize for t and tt % left and right bounds large enough for the support of gamma tt0 = abs(varl*a)+1; % index for tt == 0 gd = zeros(1,length(tt)); % dual window %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % computation of gamma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% k1 = k1+k0; k2 = k2+k0; for k=1:length(t) % step through the interval [0,alpha) x0 = t(k); % compute dual window at points (x+j*alpha) % row indices for rectangular P0 i1 = floor((k1-k0+m-1)/alpha/beta-x0/alpha)+1+i0; i2 = ceil((k2-k0-n+1)/alpha/beta-x0/alpha)-1+i0; % Computation of P0(x0) % z0 is the matrix of the abscissa x0+j*alpha-k/beta, j=i1:i2, k=k1:k2, % z1 puts all these abscissae into a row vector. % The computation of g(z1) is done as described above for the % vector tt. z0 = x0+xx(:,k1:k2)-yy(:,k1:k2); z1 = z0(:)'; Y = zeros((n+m)-1,length(z1)); for q = 1:(n+m)-1 if wloc(q) == wloc(q+1) Y(q,:) = abs(wloc(q))^2*abs((z1.*((wloc(q)*z1)>=0))).*exp(-wloc(q)*(z1.*((wloc(q)*z1)>=0))).*((wloc(q)*z1)>=0); else if wloc(q)*wloc(q+1) < 0 Y(q,:) = abs(wloc(q)*wloc(q+1))/(abs(wloc(q))+abs(wloc(q+1)))*(exp(-wloc(q)*(z1.*((wloc(q)*z1)>=0))).*((wloc(q)*z1)>=0) + ... exp(-wloc(q+1)*(z1.*((wloc(q+1)*z1)>=0))).*((wloc(q+1)*z1)>0)); else Y(q,:) = wloc(q)*wloc(q+1)/(abs(wloc(q+1))-abs(wloc(q)))*(exp(-wloc(q)*(z1.*((wloc(q)*z1)>=0)))-exp(-wloc(q+1)*(z1.*((wloc(q)*z1)>=0)))).*((wloc(q)*z1)>=0); end end end for q = 2:(n+m)-1 for j = 1:(n+m)-q if wloc(j) == wloc(j+q) Y(j,:) = Y(j,:).*abs(z1)/q*abs(wloc(j)); else Y(j,:) = (wloc(j)*Y(j+1,:)-wloc(j+q)*Y(j,:))/(wloc(j)-wloc(j+q)); end end end if (n+m) == 1 A0 = abs(wloc)*exp(-wloc*(z1.*((wloc*z1)>=0))).*((wloc*z1)>=0); else A0 = Y(1,:); end A0 = reshape(A0,size(z0))*sqrt(width);%*L^(1/4); P0 = A0(i1:i2,:); % computation of pseudo-inverse matrix of P0 P0inv = pinv(P0); gd(k-1+tt0-a*(i0-i1):a:k-1+tt0+a*(i2-i0)) = beta*P0inv(k0-k1+1,:); % row index k0-k1a+1 % points to the "j=0" row of P0inv end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % periodization of gamma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nlen = length(gd); nr = ceil(nlen/L); v = zeros(1,nr*L); v(1:length(gd)) = gd; v = [v(tt0:end),v(1:tt0-1)]; gd = sum(reshape(v,L,nr),2); gd = gd(:); if case0 == 2 gd = flipud(gd); gd = [gd(end);gd(1:end-1)]; end % Determine nlen if nlen. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/dcti.m0000664000175000017500000000706113026262304015317 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dcti.html} %@seealso{dctii, dctiv, dsti} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/podd.m0000664000175000017500000000234313026262304015320 0ustar susnaksusnakfunction 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.github.io/doc/fourier/podd.html} %@seealso{peven, dft, involute, pconv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if nargin==1 f=(f-involute(f))/2; else f=(f-involute(f,dim))/2; end; ltfat/inst/fourier/fftindex.m0000664000175000017500000000315213026262304016200 0ustar susnaksusnakfunction n=fftindex(N,nyquistzero) %-*- 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 they 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.github.io/doc/fourier/fftindex.html} %@seealso{dft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/pherm.m0000664000175000017500000001446213026262304015512 0ustar susnaksusnakfunction [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.github.io/doc/fourier/pherm.html} %@seealso{hermbasis, pgauss, psech} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/fftresample.m0000664000175000017500000000405013026262304016677 0ustar susnaksusnakfunction 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.github.io/doc/fourier/fftresample.html} %@seealso{dctresample, middlepad} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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. % In addition, postpad is explicitly told to pad with zeros. if isreal(f) L2=floor(L/2)+1; f=ifftreal(postpad(fftreal(f,[],1),L2,0,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); ltfat/inst/fourier/pchirp.m0000664000175000017500000000476713026262304015673 0ustar susnaksusnakfunction 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.github.io/doc/fourier/pchirp.html} %@seealso{dft, expwave} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/fourier/pheaviside.m0000664000175000017500000000362213026262304016514 0ustar susnaksusnakfunction 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.github.io/doc/fourier/pheaviside.html} %@seealso{middlepad, involute, fftindex} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/hermbasis.m0000664000175000017500000001027513026262304016352 0ustar susnaksusnakfunction [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.github.io/doc/fourier/hermbasis.html} %@seealso{dft, pherm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/fourier/pconv.m0000664000175000017500000000605513026262304015523 0ustar susnaksusnakfunction h=pconv(f,g,varargin) %-*- texinfo -*- %@deftypefn {Function} pconv %@verbatim %PCONV Periodic convolution % Usage: h=pconv(f,g) % h=pconv(f,g,ftype); % % 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(f,g,'r') 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(f,g,'rr') 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. % % The input arrays f and g can be 1D vectors or one of them can be % a multidimensional array. In either case, the convolution is performed % along columns with row vectors transformed to columns. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/fourier/pconv.html} %@seealso{dft, involute} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, Jordy van Velthoven % TESTING: TEST_PCONV % REFERENCE: REF_PCONV complainif_notenoughargs(nargin, 2, 'PCONV'); definput.keyvals.L=[]; definput.keyvals.dim=[]; definput.flags.type={'default', 'r', 'rr'}; [flags,~,L,dim]=ltfatarghelper({'L','dim'},definput,varargin); [f,~,~,Wf,dimout,permutedsize_f,order_f]=assert_sigreshape_pre(f,L,dim,'PCONV'); [g,~,~,Wg,dimout,permutedsize_g,order_g]=assert_sigreshape_pre(g,L,dim,'PCONV'); if (Wf>1) && (Wg>1) error('%s: Only one of the inputs can be multi-dimensional.',upper(mfilename)); end; if size(f,1)~=size(g,1) error(['%s: f and g must have the same size in the direction of the',... ' convolution.'],upper(mfilename)); end; W=max(Wf,Wg); if Wf1 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.github.io/doc/fourier/psech.html} %@seealso{pgauss, pbspline, pherm} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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))); ltfat/inst/fourier/idft.m0000664000175000017500000000362213026262304015321 0ustar susnaksusnakfunction f=idft(c,N,dim) %-*- texinfo -*- %@deftypefn {Function} idft %@verbatim %IDFT Inverse normalized Discrete Fourier Transform % Usage: f=idft(c); % f=idft(c,N,dim); % % IDFT computes a normalized or unitary inverse discrete Fourier transform. % The unitary discrete Fourier transform is computed by % % L-1 % f(l+1) = 1/sqrt(L) * sum c(k+1)*exp(2*pi*i*k*l/L) % k=0 % % for l=0,...,L-1. % % The output of IDFT is 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.github.io/doc/fourier/idft.html} %@seealso{dft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Peter L. Soendergaard, Jordy van Velthoven % TESTING: TEST_IDFT % REFERENCE: TEST_DFT error(nargchk(1,3,nargin)); if nargin<3 dim=[]; end; if nargin<2 N=[]; end; [c,N,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(c,N,dim,'IDFT'); % Force IFFT along dimension 1, since we have permuted the dimensions % manually f=ifft(c,N,1)*sqrt(N); f=assert_sigreshape_post(f,dim,permutedsize,order); ltfat/inst/fourier/ifftreal.m0000664000175000017500000000330213026262304016162 0ustar susnaksusnakfunction 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.github.io/doc/fourier/ifftreal.html} %@seealso{fftreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Peter L. Soendergaard error(nargchk(2,3,nargin)); if nargin==2 dim=[]; end; N2=floor(N/2)+1; [c,~,~,~,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); ltfat/inst/fourier/dstiii.m0000664000175000017500000000601413026262304015656 0ustar susnaksusnakfunction 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.github.io/doc/fourier/dstiii.html} %@seealso{dctii, dstii, dstiv} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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,:); ltfat/inst/fourier/ceil23.m0000664000175000017500000000561613026262304015461 0ustar susnaksusnakfunction [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.github.io/doc/fourier/ceil23.html} %@seealso{floor23, ceil235, nextfastfft} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/frames/0000775000175000017500000000000013026262304014014 5ustar susnaksusnakltfat/inst/frames/framecoef2tfplot.m0000664000175000017500000000427413026262304017443 0ustar susnaksusnakfunction coef=framecoef2tfplot(F,coef) %-*- texinfo -*- %@deftypefn {Function} framecoef2tfplot %@verbatim %FRAMECOEF2TFPLOT Convert coefficients to time-frequency plane matrix % Usage: cout=framecoef2tfplot(F,cin); % % FRAMECOEF2TFPLOT(F,coef) converts the frame coefficients coef into % the time-frequency plane layout matrix. The frame object F must have % been created using FRAME. The function acts exactly as % FRAMECOEF2TF for frames which admit regular (rectangular) sampling % of a time-frequency plane and converts irregularly sampled coefficients % to a rectangular matrix. This is usefull for custom plotting. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/framecoef2tfplot.html} %@seealso{frame, frametf2coef, framecoef2native, blockplot} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRAMECOEF2TFPLOT'); complainif_notvalidframeobj(F,'FRAMECOEF2TFPLOT'); switch(F.type) % We could have done a try-catch block here, but it is slow case {'dgt','dgtreal','dwilt','wmdct','ufilterbank','ufwt','uwfbt','uwpfbt'} coef=framecoef2tf(F,coef); return; case 'fwt' coef = comp_fwtpack2cell(F,coef); case {'wfbt','wpfbt','filterbank','filterbankreal'} coef = F.coef2native(coef,size(coef)); end switch(F.type) case {'fwt','wfbt','wpfbt','filterbank','filterbankreal'} coef = comp_cellcoef2tf(coef); otherwise error('%s: TF-plane plot not supported for this transform.',upper(mfilename)); end; ltfat/inst/frames/frsynabs.m0000664000175000017500000002516013026262304016025 0ustar susnaksusnakfunction [f,relres,iter,c]=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,c]=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. % c : Coefficients with the reconstructed phase % % 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. % % [f,relres,iter,c]=FRSYNABS(...,'griflim'|'fgriflim') additionally returns % coefficients c with the reconstructed phase prior to the final reconstruction. % This is usefull for determining the consistency (energy lost in the nullspace % of F) of the reconstructed spectrogram. c will only be equal to frana(F,f) % if the spectrogram is already consistent (i.e. already in the range space of F*). % This is possible only for 'griflim' and 'fgriflim' methods. % % 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 coefficients 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. % % Initial phase guess: % % '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. % % The Griffin-Lim algorithm related parameters: % % 'griflim' Use the Griffin-Lim iterative method. This is the % default. % % 'fgriflim' Use the Fast Griffin-Lim iterative method. % % % 'Fd',Fd A canonical dual frame object or an anonymous function % acting as the synthesis operator of the canonical dual frame. % If not provided, the function attempts to create one using % Fd=framedual(F). % % 'alpha',a Parameter of the Fast Griffin-Lim algorithm. It is % ignored if not used together with 'fgriflim' flag. % % The BFGS method related paramaters: % % 'bfgs' Use the limited-memory Broyden Fletcher Goldfarb % Shanno (BFGS) method. % % 'p',p Parameter for the compressed version of the obj. function % in the l-BFGS method. It is ignored if not used together % with 'bfgs' flag. % % Other: % % '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; % % The BFGS method makes use of the minFunc software. To use the BFGS method, % please install the minFunc software from: % http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html. % % % % 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. % % N. Perraudin, P. Balazs, and P. L. Soendergaard. A fast Griffin-Lim % algorithm. In Applications of Signal Processing to Audio and Acoustics % (WASPAA), 2013 IEEE Workshop on, pages 1--4, Oct 2013. % % R. Decorsiere, P. Soendergaard, E. MacDonald, and T. Dau. Inversion of % auditory spectrograms, traditional spectrograms, and other envelope % representations. Audio, Speech, and Language Processing, IEEE/ACM % Transactions on, 23(1):46--56, Jan 2015. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frsynabs.html} %@seealso{frana, frsyn, demo_frsynabs, demo_phaseret} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR : Remi Decorsiere and Peter L. Soendergaard. % REFERENCE: OK % Check input paramameters. complainif_notenoughargs(nargin,2,'FRSYNABS'); complainif_notvalidframeobj(F,'FRSYNABS'); definput.keyvals.Ls=[]; definput.keyvals.tol=1e-6; definput.keyvals.Fd=[]; definput.keyvals.maxit=100; definput.keyvals.printstep=10; definput.keyvals.alpha=0.99; definput.keyvals.p=2; 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); if isempty(kv.Fd) try Fd=frameaccel(framedual(F),L); Fdfrsyn = @(insig) Fd.frsyn(insig); catch % Canonical dual frame cannot be creted explicitly % TO DO: use pcg error('%s: The canonical dual frame is not available.',upper(mfilename)); end else if isstruct(kv.Fd) && isfield(kv.Fd,'frsyn') % The canonical dual frame was passed explicitly as a frame object Fd = frameaccel(kv.Fd,L); Fdfrsyn = @(insig) Fd.frsyn(insig); elseif isa(kv.Fd,'function_handle') % The anonymous function is expected to do (FF*)^(-1)F Fdfrsyn = kv.Fd; else error('%s: Invalid format of Fd.',upper(mfielname)); end end % Initialize windows to speed up computation F=frameaccel(F,L); if flags.do_griflim for iter=1:kv.maxit f=Fdfrsyn(c); c2=F.frana(f); c=s.*exp(1i*angle(c2)); relres(iter)=norm(abs(c2)-s,'fro')/norm_s; 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)3 error('%s: 4th argument cannot be returned when using the BFGS method.',... upper(mfilename)); end % Setting up the options for minFunc opts = struct; if flags.do_quiet opts.Display = 'off'; end opts.MaxIter = kv.maxit; opts.optTol = kv.tol; opts.progTol = kv.tol; if nargout>1 % This custom function is called after each iteration. % We cannot use the objective function itself as it might be called % several times in a single iteration. % We use outputFcn to keep track of norm(abs(c)+s) % because the objective function is different: norm(abs(c).^p+s.^p) opts.outputFcn = @outputFcn; opts.outputFcn('init',kv.maxit,F,s); end % Don't limit the number of function evaluations, just the number of % time-steps. opts.MaxFunEvals = 1e9; opts.usemex = 0; f0 = Fdfrsyn(c); if kv.p ~= 2 objfun = @(x) gradfunp(x,F,s,kv.p); else objfun = @(x) gradfun(x,F,s); end [f,~,~,output] = minFunc(objfun,f0,opts); if nargout > 1 iter = output.iterations; res = opts.outputFcn('getRes'); relres = res/norm_s; end 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]=gradfun(x,F,s) % f obj function value % df gradient value c=F.frana(x); inner = abs(c).^2-s.^2; f = norm(inner,'fro')^2; df = 4*real(conj(F.frsyn(inner.*c))); % Subfunction to compute the p-compressed objective function for the BFGS method. function [f,df]=gradfunp(x,F,s,p) c=F.frana(x); inner = abs(c).^p-s.^p; f = norm(inner,'fro')^2; df = 2*p*real(conj(F.frsyn( inner.*abs(c).^(p/2-1).*c))); function stop = outputFcn(x,iterationType,itNo,funEvals,f,t,gtd,g,d,optCond) % This is unfortunatelly a messy function. % Moreover, it computes one more analysis persistent res; persistent F; persistent s; if ischar(x) switch x case 'init' res = zeros(iterationType,1); F = itNo; s = funEvals; return; case 'getRes' stop = res; F = []; s=[]; res = []; return; end end if isempty(res) error('OUTPUTFCN: Initialize res first!'); end res(itNo+1) = norm(abs(F.frana(x)) - s,'fro'); stop = 0; ltfat/inst/frames/framecoef2native.m0000664000175000017500000000310513026262304017411 0ustar susnaksusnakfunction coef=framecoef2native(F,coef) %-*- texinfo -*- %@deftypefn {Function} framecoef2native %@verbatim %FRAMECOEF2NATIVE Convert coefficients to native format % Usage: coef=framecoef2native(F,coef); % % 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.github.io/doc/frames/framecoef2native.html} %@seealso{frame, framenative2coef, framecoef2tf} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRAMECOEF2NATIVE'); complainif_notvalidframeobj(F,'FRAMECOEF2NATIVE'); [MN,W]=size(coef); % .coef2native field is not mandatory since for some frames, both % coefficient formats are identical if isfield(F,'coef2native') coef=F.coef2native(coef,size(coef)); end; ltfat/inst/frames/frsyniter.m0000664000175000017500000001476013026262304016227 0ustar susnaksusnakfunction [f,relres,iter]=frsyniter(F,c,varargin) %-*- texinfo -*- %@deftypefn {Function} frsyniter %@verbatim %FRSYNITER Iterative synthesis % Usage: f=frsyniter(F,c); % f=frsyniter(F,c,Ls); % [f,relres,iter]=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. Please note that preconditioning is not supported % for all frame types. % % 'print' Display the progress. % % 'quiet' Don't print anything, this is the default. % % Algorithms % ---------- % % The function uses the (Preconditioned) Conjugate Gradient algorithm % to solve the following problem: % % FF*f=Fc % % The preconditioning alters the equations such that % % inv(M)FF*f=inv(M)Fc % % 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.github.io/doc/frames/frsyniter.html} %@seealso{frame, frana, frsyn, franaiter} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Nicki Holighaus & Peter L. Soendergaard complainif_notenoughargs(nargin,2,'FRSYNITER'); complainif_notvalidframeobj(F,'FRSYNITER'); tolchooser.double=1e-9; tolchooser.single=1e-5; definput.keyvals.Ls=[]; definput.keyvals.tol=tolchooser.(class(c)); definput.keyvals.maxit=100; definput.keyvals.Fd = []; definput.flags.alg={'cg','pcg'}; definput.keyvals.printstep=10; definput.flags.print={'quiet','print'}; [flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin); % if flags.do_auto % varargin2 = varargin; % varargin2(strcmpi(varargin2,'auto')) = []; % % try % varargin2{end+1} = 'pcg'; % [f,relres,iter]=frsyniter(F,c,varargin2{:}); % catch % if ~flags.do_quiet % warning(sprintf('%s: Falling back to regular CG.',upper(mfilename))); % end % varargin2{end+1} = 'cg'; % [f,relres,iter]=frsyniter(F,c,varargin2{:}); % end % return; % end L=framelengthcoef(F,size(c,1)); Fd = kv.Fd; % Compute the preconditioner if flags.do_pcg && isempty(Fd) try d = cast(1./framediag(F,L),class(c)); catch switch F.type case {'filterbank','ufilterbank'} Fd = frame(F.type,{'dual',F.g,'forcepainless'},F.a,numel(F.g)); case {'filterbankreal','ufilterbankreal'} Fd = frame(F.type,{'realdual',F.g,'forcepainless'},F.a,numel(F.g)); otherwise error('%s: No preconditioning method available for given frame type.',... upper(mfilename)); end end end 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 && isempty(Fd) [f,flag,~,iter,relres]=pcg(A,F.frsyn(c),kv.tol,kv.maxit,@(x)d.*x); elseif flags.do_pcg Fd = frameaccel(Fd,L); A=@(x) Fd.frsyn(F.frana(x)); [f,flag,~,iter,relres]=pcg(A,Fd.frsyn(c),kv.tol,kv.maxit); 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 ltfat/inst/frames/framelength.m0000664000175000017500000000304113026262304016464 0ustar susnaksusnakfunction 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.github.io/doc/frames/framelength.html} %@seealso{frame, framelengthcoef, frameclength} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . callfun = upper(mfilename); complainif_notenoughargs(nargin,2,callfun); complainif_notposint(Ls,'Ls',callfun); complainif_notvalidframeobj(F,callfun); % .length field is mandatory L=F.length(Ls); ltfat/inst/frames/framebounds.m0000664000175000017500000001630513026262304016504 0ustar susnaksusnakfunction [AF,BF]=framebounds(F,varargin); %-*- texinfo -*- %@deftypefn {Function} framebounds %@verbatim %FRAMEBOUNDS Frame bounds % Usage: fcond=framebounds(F); % [A,B]=framebounds(F); % [...]=framebounds(F,Ls); % % FRAMEBOUNDS(F) calculates the ratio B/A of the frame bounds of the % frame given by F. The length of the system the frame bounds are % calculated for is given by L=framelength(F,1). % % FRAMEBOUNDS(F,Ls) additionally specifies a signal length for which % the frame should work. The actual length used is L=framelength(F,Ls). % % [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 of eighs is less than the % specified tolerance. Default is 1e-9 % % 'maxit',n Do at most n iterations in eigs. Default is 100. % % 'pcgtol',t Stop if relative residual error of pcg is less than the % specified tolerance. Default is 1e-6 % % 'pcgmaxit',n Do at most n iterations in pcg. Default is 150. % % '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 chosen % automatically by eigs. % % 'print' Display the progress. % % 'quiet' Don't print anything, this is the default. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/framebounds.html} %@seealso{frame, framered} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'FRAMEBOUNDS'); complainif_notvalidframeobj(F,'FRAMEBOUNDS'); % 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.pcgmaxit=150; definput.keyvals.pcgtol=1e-6; definput.keyvals.crossover=200; definput.keyvals.p=[]; 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]=wfbtbounds({g,F.J,'dwt'},L); case 'wfbt' [AF,BF]=wfbtbounds(g,L); case 'ufwt' [AF,BF]=wfbtbounds({g,F.J,'dwt'},L,F.flags.scaling); case 'uwfbt' [AF,BF]=wfbtbounds(g,L,F.flags.scaling); case 'wpfbt' [AF,BF]=wpfbtbounds(g,L,F.flags.interscaling); case 'uwpfbt' [AF,BF]=wpfbtbounds(g,L,F.flags.interscaling,F.flags.scaling); 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 = F.realinput; opts.maxit = kv.maxit; opts.tol = kv.tol; opts.issym = 0; if ~isempty(kv.p) opts.p = kv.p; end pcgopts.maxit = kv.pcgmaxit; pcgopts.tol = kv.pcgtol; % Upper frame bound frameop = @(x) F.frsyn(F.frana(x)); BF = real(eigs(frameop,L,1,'LM',opts)); % Lower frame bound frameop2 = @(x) F.frsyn(F.frana(x)); invfrop = @(x) pcg(frameop2,x,pcgopts.tol,pcgopts.maxit); % Test convergence of pcg test = randn(L,1); if ~F.realinput, test = test +1i*randn(L,1); end [~,flag] = invfrop(test); % If PCG converges, estimate the smallest eigenvalue, otherwise assume % AF = 0; if ~flag AF = real(eigs(invfrop,L,1,'SM',opts)); else AF = 0; end 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 ltfat/inst/frames/framepair.m0000664000175000017500000000446713026262304016153 0ustar susnaksusnakfunction [F1,F2]=framepair(ftype,g1,g2,varargin) %-*- texinfo -*- %@deftypefn {Function} framepair %@verbatim %FRAMEPAIR Construct a new frame % Usage: [F1,F2]=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.github.io/doc/frames/framepair.html} %@seealso{frame, framedual, frametight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,3,'FRAMEPAIR'); 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; ltfat/inst/frames/frsyn.m0000664000175000017500000000355113026262304015337 0ustar susnaksusnakfunction 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. % % Examples: % --------- % % In the following example a signal f is constructed through the frame % synthesis operator using a Gabor frame. The coefficients associated with % this Gabor expansion are contained in an identity matrix. The identity % matrix corresponds to a diagonal in the time-frequency plane, that is, % one atom at each time position with increasing frequency.: % % a = 10; % M = 40; % % F = frame('dgt', 'gauss', a, M); % % c = framenative2coef(F, eye(40)); % % f = frsyn(F, c); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frsyn.html} %@seealso{frame, frana, plotframe} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRSYN'); complainif_notvalidframeobj(F,'FRSYN'); L=framelengthcoef(F,size(insig,1)); F=frameaccel(F,L); outsig=F.frsyn(insig); ltfat/inst/frames/franalasso.m0000664000175000017500000002143413026262304016327 0ustar susnaksusnakfunction [tc,relres,iter,frec,cd] = franalasso(F,f,lambda,varargin) %-*- texinfo -*- %@deftypefn {Function} franalasso %@verbatim %FRANALASSO Frame LASSO regression % Usage: tc = franalasso(F,f,lambda) % tc = franalasso(F,f,lambda,C,tol,maxit) % [tc,relres,iter,frec,cd] = franalasso(...) % % Input parameters: % F : Frame definition % f : Input signal % lambda : Regularisation parameter, controls sparsity of the solution % C : Step size of the algorithm. % tol : Reative error tolerance. % maxit : Maximum number of iterations. % Output parameters: % tc : Thresholded coefficients % relres : Vector of residuals. % iter : Number of iterations done. % frec : Reconstructed signal % cd : The min c||_2 solution using the canonical dual frame. % % 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 such that % % argmin lambda||c||_1 + 1/2||Fc - f||_2^2 % % The solution is obtained via an iterative procedure, called Landweber % iteration, involving iterative soft thresholdings. % % The following flags determining an algorithm to be used are recognized % at the end of the argument list: % % 'ista' % The basic (Iterative Soft Thresholding) algorithm given F and f % and parameters C*>0, lambda >0 acts as follows: % % Initialize c % repeat until stopping criterion is met % c <- soft(c + F*(f - Fc)/C,lambda/C) % end % % 'fista' % The fast version of the previous. This is the default option. % : % % Initialize c(0),z,tau(0)=1,n=1 % repeat until stopping criterion is met % c(n) <- soft(z + F*(f - Fz)/C,lambda/C) % tau(n) <- (1+sqrt(1+4*tau(n-1)^2))/2 % z <- c(n) + (c(n)-c(n-1))(tau(n-1)-1)/tau(n) % n <- n + 1 % end % % [tc,relres,iter] = FRANALASSO(...) returns the residuals relres in % a vector and the number of iteration steps done iter. % % [tc,relres,iter,frec,cd] = FRANALASSO(...) returns the reconstructed % signal from the coefficients, frec and coefficients cd obtained by % analysing using the canonical dual system. % Note that this requires additional computations. % % The relationship between the output coefficients and frec 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. % % Examples: % --------- % % The following example shows how FRANALASSO produces a sparse % representation of a test signal greasy*: % % f = greasy; % % Gabor frame with redundancy 8 % F = frame('dgtreal','gauss',64,512); % % Choosing lambda (weight of the sparse regularization param.) % lambda = 0.1; % % Solve the basis pursuit problem % [c,~,~,frec,cd] = franalasso(F,f,lambda); % % Plot sparse coefficients % figure(1); % plotframe(F,c,'dynrange',50); % % % Plot coefficients obtained by applying an analysis operator of a % % dual Gabor system to f % figure(2); % plotframe(F,cd,'dynrange',50); % % % Check the (NON-ZERO) reconstruction error . % % frec is obtained by applying the synthesis operator of frame F % % to sparse coefficients c. % norm(f-frec) % % % Compare decay of coefficients sorted by absolute values % % (compressibility of coefficients) % figure(3); % semilogx([sort(abs(c),'descend')/max(abs(c)),... % sort(abs(cd),'descend')/max(abs(cd))]); % legend({'sparsified coefficients','dual system coefficients'}); % % % 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.github.io/doc/frames/franalasso.html} %@seealso{frame, frsyn, framebounds, franabp, franagrouplasso} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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) % complainif_notenoughargs(nargin,2,'FRANALASSO'); complainif_notvalidframeobj(F,'FRANALASSO'); 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'}; [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 % Optional reconstruction if nargout>3 frec = postpad(F.frsyn(tc),Ls); end; % Calculate coefficients using the canonical dual system % May be conviniently used for comparison if nargout>4 try Fd = framedual(F); cd = frana(Fd,f); catch warning(sprintf(['%s: Dual frame is not available. Using franaiter'],... upper(mfilename))); cd = franaiter(F,f); end end; ltfat/inst/frames/frame.m0000664000175000017500000005560113026262304015273 0ustar susnaksusnakfunction 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 % 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 orthonormal basis, meaning % that all operators return their input as output, so it is the dummy % operation. % % 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. % % Wrapper frames % -------------- % % Frames types in this section are "virtual". They serve as a wrapper for % a different type of frame. % % FRAME('erbletfb',fs,Ls,...) constructs an Erb-let filterbank frame for % a given samp. frequency fs working with signals of length Ls. See % ERBFILTERS for a description of additional parameters as all % parameters other than the frame type string 'erbletfb' are passed to it. % NOTE: The resulting frame is defined only for a single signal length % Ls. Shorter signals will be zero-padded, signals longer than Ls* % cannot be processed. % The actual frame type is 'filterbank' or 'filterbankreal'. % % FRAME('cqtfb',fs,fmin,fmax,bins,Ls,...) constructs a CQT filterbank % frame for a given samp. frequency fs working with signals of length % Ls. See CQTFILTERS for a description of other parameters. % NOTE: The resulting frame is defined only for a single signal length % Ls. Shorter signals will be zero-padded, signals longer than Ls* % cannot be processed. % The actual frame type is 'filterbank' or 'filterbankreal'. % % 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,'dynrange',60); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frame.html} %@seealso{frana, frsyn, plotframe} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'FRAME'); 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; % True if the frame only works with a fixed length. F.fixedlength = 0; % Handle the windowed transforms switch(ftype) case {'dgt','dwilt','wmdct','filterbank','ufilterbank',... 'nsdgt','unsdgt','wfbt','uwfbt','wpfbt'} F.g=varargin{1}; case {'dgtreal','filterbankreal','ufilterbankreal',... 'nsdgtreal','unsdgtreal'} F.g=varargin{1}; F.realinput=1; case {'fwt','ufwt'} F.g=varargin{1}; F.J=varargin{2}; complainif_notposint(F.J,'J','FRAME'); end; % Input param checking switch(ftype) case 'fusion' wtmp = varargin{1}; % Check w if ~isnumeric(varargin{1}) || ... ~(isscalar(wtmp) || numel(wtmp) == numel(varargin) -1) error('%s: Weights are not in a correct format.',upper(mfilename)); end % Check frame objects for ii=2:numel(varargin) complainif_notvalidframeobj(varargin{ii},'FRAME'); end case 'tensor' % Check frame objects for ii=1:numel(varargin) complainif_notvalidframeobj(varargin{ii},'FRAME'); end 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)); case {'ufwt'} vargs=varargin(3:end); definput.flags.scaling={'sqrt','noscale','scale'}; case {'uwfbt'} vargs=varargin(2:end); definput.flags.scaling={'sqrt','noscale','scale'}; case {'wpfbt'} vargs=varargin(2:end); definput.flags.interscaling={'intsqrt','intnoscale','intscale'}; case {'uwpfbt'} vargs=varargin(2:end); definput.flags.interscaling={'intsqrt','intnoscale','intscale'}; definput.flags.scaling={'sqrt','noscale','scale'}; end; [F.flags,F.kv]=ltfatarghelper({},definput,vargs); F.type=ftype; F.origargs=varargin; F.vargs=vargs; %% ------ 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 '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; F.clength = @(L) floor(L/2)+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 '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; F.clength = @(L) L/F.a*(floor(F.M/2)+1); 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,... round(2*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); F.clength=@(L) sum(floor(F.M/2)+1); 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); F.clength=@(L) numel(F.M)*(floor(F.M(1)/2)+1); case 'fusion' F.w=varargin{1}; F.frames=varargin(2:end); if any(cellfun(@(fEl) fEl.realinput,F.frames)) error(['%s: Real-valued-input-only frames are not currently ',... 'supported in the fusion frame.'],upper(mfilename)); 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','dwt'} % We have to initialize F.g here already [F.g, F.info]=fwtinit({'strict',F.g}); 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) wavcell2pack(comp_fwt(insig,F.g.h,F.g.a,F.J,'per')); F.frsyn=@(insig) comp_ifwt(... wavpack2cell(insig,fwtclength(size(insig,1)/F.red,F.g,F.J)),... F.g.g,F.g.a,F.J,size(insig,1)/F.red,'per'); F.length=@(Ls) fwtlength(Ls,F.g,F.J); case {'wfbt'} [F.g,F.info]=wfbtinit({'strict',F.g}); F.red = sum(1./treeSub(F.g)); % comp_ specific [F.wtPath, F.rangeLoc, F.rangeOut] = treeBFranges(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) comp_iwfbt(F.coef2native(insig,size(insig)),... F.g.nodes(F.wtPath(end:-1:1)),... [nodesInLen(F.wtPath(end:-1:1),size(insig,1)/F.red,1,F.g);size(insig,1)/F.red],... F.rangeLoc(end:-1:1),F.rangeOut(end:-1:1),... 'per'); F.length=@(Ls) wfbtlength(Ls,F.g); case {'wpfbt'} F.g=wfbtinit({'strict',F.g}); F.red = sum(cellfun(@(aEl) sum(1./aEl),nodesSub(nodeBForder(0,F.g),F.g))); % comp_ specific F.wtPath = nodeBForder(0,F.g); F.rangeLoc = nodesLocOutRange(F.wtPath,F.g); [F.pOutIdxs,F.chOutIdxs] = treeWpBFrange(F.g); F.coef2native = @(coef,s) wavpack2cell(coef,... s(1)./cell2mat(cellfun(@(aEl) aEl(:),... reshape(nodesSub(nodeBForder(0,F.g),F.g),[],1),... 'UniformOutput',0))./F.red); F.native2coef = @(coef) wavcell2pack(coef); F.frana=@(insig) F.native2coef(... comp_wpfbt(insig,F.g.nodes(F.wtPath),... F.rangeLoc,'per',F.flags.interscaling)); F.frsyn=@(insig) comp_iwpfbt(F.coef2native(insig,size(insig)),... F.g.nodes(F.wtPath(end:-1:1)),... F.pOutIdxs,F.chOutIdxs,... size(insig,1)/F.red,... 'per',F.flags.interscaling); F.length=@(Ls) wfbtlength(Ls,F.g); case {'ufwt'} F.g=fwtinit({'strict',F.g}); 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(comp_ufwt(insig,F.g.h,F.g.a,F.J,F.flags.scaling)); F.frsyn=@(insig) comp_iufwt(F.coef2native(insig,size(insig)),F.g.g,F.g.a,F.J,F.flags.scaling); F.length=@(Ls) Ls; F.red=(F.J*(numel(F.g.a)-1)+1); case {'uwfbt'} F.g=wfbtinit({'strict',F.g}); % comp_ specific [F.wtPath, F.rangeLoc, F.rangeOut] = treeBFranges(F.g); F.nodesUps = nodesFiltUps(F.wtPath,F.g); F.red = sum(cellfun(@numel,F.rangeOut)); 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(... comp_uwfbt(insig,F.g.nodes(F.wtPath),F.nodesUps,... F.rangeLoc,F.rangeOut,F.flags.scaling)); F.frsyn=@(insig) comp_iuwfbt(F.coef2native(insig,size(insig)),... F.g.nodes(F.wtPath(end:-1:1)),... F.nodesUps(end:-1:1),F.rangeLoc(end:-1:1),... F.rangeOut(end:-1:1),F.flags.scaling); F.length=@(Ls) Ls; case {'uwpfbt'} F.g= wfbtinit({'strict',varargin{1}}); F.red = sum(cellfun(@(fEl) numel(fEl.g),F.g.nodes)); % comp_ specific F.wtPath = nodeBForder(0,F.g); F.nodesUps = nodesFiltUps(F.wtPath,F.g); F.rangeLoc = nodesLocOutRange(F.wtPath,F.g); [F.pOutIdxs,F.chOutIdxs] = treeWpBFrange(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(... comp_uwpfbt(insig,F.g.nodes(F.wtPath),F.rangeLoc,... F.nodesUps,F.flags.scaling,... F.flags.interscaling)); F.frsyn=@(insig) comp_iuwpfbt(F.coef2native(insig,size(insig)),... F.g.nodes(F.wtPath(end:-1:1)),... F.nodesUps(end:-1:1),F.pOutIdxs,F.chOutIdxs,... F.flags.scaling,F.flags.interscaling); F.length=@(Ls) Ls; %%%%%%%%%%%%%%%%%%%% %% WRAPPER FRAMES %% %%%%%%%%%%%%%%%%%%%% case {'erbletfb','cqtfb'} switch(ftype) case 'erbletfb' [g,a,~,L] = erbfilters(varargin{:}); case 'cqtfb' [g,a,~,L] = cqtfilters(varargin{:}); end % Search for the 'complex' flag do_complex = ~isempty(varargin(strcmp('complex',varargin))); if do_complex F = frameaccel(frame('filterbank',g,a,numel(g)),L); else F = frameaccel(frame('filterbankreal',g,a,numel(g)),L); end F.fixedlength = 1; 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; ltfat/inst/frames/frameoperator.m0000664000175000017500000000311713026262304017042 0ustar susnaksusnakfunction h = frameoperator(F, f); %-*- texinfo -*- %@deftypefn {Function} frameoperator %@verbatim %FRAMEOPERATOR Frame Operator % Usage: o=frameoperator(F, f); % % Input parameters: % F : frame % f : input vector % % Output parameter: % h : output vector % % h=FRAMEOPERATOR(F,f) applies the frame operator associated with the frame % F to the input f. % % If the frame F is a tight frame, then h equals f up to the constant % frac{1}{A} where A is the lower frame bound of F. If the frame F* % is an orthonormal basis, or more general a Parseval frame, then h equals % f. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frameoperator.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven complainif_notenoughargs(nargin, 2, 'FRAMEOPERATOR'); h = frsyn(F, (frana(F,f))); ltfat/inst/frames/frameclength.m0000664000175000017500000000415313026262304016634 0ustar susnaksusnakfunction [Ncoef, L]=frameclength(F,Ls) %-*- texinfo -*- %@deftypefn {Function} frameclength %@verbatim %FRAMECLENGTH Number of coefficients from length of signal % Usage: Ncoef=frameclength(F,Ls); % [Ncoef,L]=frameclength(...); % % Ncoef=FRAMECLENGTH(F,Ls) returns the total number of coefficients % obtained by applying the analysis operator of frame F to a signal % of length Ls i.e. size(frana(F,f),1) for Ls=length(f). % % [Ncoef,L]=FRAMECLENGTH(F,Ls) additionally returns L, which is the % same as returned by FRAMELENGTH. % % If the frame length L is longer than the signal length Ls, the % signal will be zero-padded to L by FRANA. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frameclength.html} %@seealso{frame, framelengthcoef} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . callfun = upper(mfilename); complainif_notposint(Ls,'Ls',callfun); complainif_notvalidframeobj(F,callfun); L = F.length(Ls); % Some frames need special function if isfield(F,'clength') Ncoef = F.clength(L); else % Generic, works for any non-realonly frame and for % all representaions not having any extra coefficients Ncoef = L*F.red; if F.realinput Ncoef=Ncoef/2; end assert(abs(Ncoef-round(Ncoef))<1e-3,... sprintf('%s: There is a bug. L=%d should be an integer.',... upper(mfilename),Ncoef)); Ncoef=round(Ncoef); end ltfat/inst/frames/frametight.m0000664000175000017500000001122513026262304016325 0ustar susnaksusnakfunction Ft=frametight(F); %-*- texinfo -*- %@deftypefn {Function} frametight %@verbatim %FRAMETIGHT Construct the canonical tight frame % Usage: Ft=frametight(F); % % 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.github.io/doc/frames/frametight.html} %@seealso{frame, framepair, framedual} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'FRAMETIGHT'); complainif_notvalidframeobj(F,'FRAMETIGHT'); % 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{:}); case 'ufwt' % The canonical tight made from ufwt might not keep the iterated % filterbank structure [g,a] = wfbt2filterbank({F.g,F.J,'dwt'}); g = comp_filterbankscale(g,a,F.flags.scaling); Ft = frametight(frame('filterbank',g,ones(numel(g),1),numel(g))); case 'uwfbt' % The canonical tight made from uwfbt might not keep the iterated % filterbank structure [g,a] = wfbt2filterbank(F.g,F.J); g = comp_filterbankscale(g,a,F.flags.scaling); Ft = frametight(frame('filterbank',g,ones(numel(g),1),numel(g))); case 'uwpfbt' % The canonical tight made from uwpfbt might not keep the iterated % filterbank structure [g, a] = wpfbt2filterbank(F.g,F.flags.interscaling); g = comp_filterbankscale(g,a,F.flags.scaling); Ft = frametight(frame('filterbank',g,ones(numel(g),1),numel(g))); case 'fwt' is_basis = abs(sum(1./F.g.a)-1)<1e-6; is_tight = F.info.istight; if is_basis && is_tight Ft = F; else error(['%s: Cannot create the canonical tight frame with the ',... 'same structure. Consider casting the system to an ',... 'uniform filterbank.'],... upper(mfilename)); end case 'wfbt' is_basis = all(cellfun(@(nEl) abs(sum(1./nEl.a)-1)<1e-6,F.g.nodes)); is_tight = F.info.istight; if is_basis && is_tight Ft = F; else error(['%s: Cannot create the canonical tight frame with the ',... 'same structure. Consider casting the system to an ',... 'uniform filterbank.'],... upper(mfilename)); end case 'wpfbt' % WPFBT is too wierd. error(['%s: Canonical tight frame of wpfbt might not keep the ',... 'same structure. '],upper(mfilename)) end; switch(F.type) case {'ufwt','uwfbt','uwpfbt'} warning(sprintf(['%s: The canonical tight system does not preserve ',... 'the iterated filterbank structure.'],... upper(mfilename))); end % Treat the fixed length frames if isfield(F,'fixedlength') && F.fixedlength && isfield(F,'L') Ft = frameaccel(Ft,F.L); Ft.fixedlength = 1; end ltfat/inst/frames/frana.m0000664000175000017500000000522013026262304015260 0ustar susnaksusnakfunction 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.github.io/doc/frames/frana.html} %@seealso{frame, framepair, frsyn, plotframe} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRANA'); complainif_notvalidframeobj(F,'FRANA'); 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); ltfat/inst/frames/franagrouplasso.m0000664000175000017500000001540013026262304017400 0ustar susnaksusnakfunction [tc,relres,iter,frec] = franagrouplasso(F,f,lambda,varargin) %-*- texinfo -*- %@deftypefn {Function} franagrouplasso %@verbatim %FRANAGROUPLASSO Group LASSO regression in the TF-domain % Usage: tc = franagrouplasso(F,f,lambda) % tc = franagrouplasso(F,f,lambda,C,tol,maxit) % [tc,relres,iter,frec] = franagrouplasso(...) % % Input parameters: % F : Frame definition % f : Input signal % lambda : Regularisation parameter, controls sparsity of the solution % C : Step size of the algorithm. % tol : Reative error tolerance. % maxit : Maximum number of iterations. % Output parameters: % tc : Thresholded coefficients % relres : Vector of residuals. % iter : Number of iterations done. % frec : Reconstructed signal % % FRANAGROUPLASSO(F,f,lambda) 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. % % *Note* the involved frame F must support regular time-frequency % layout of coefficients. % % [tc,relres,iter] = FRANAGROUPLASSO(...) returns the residuals relres in % a vector and the number of iteration steps done, maxit. % % [tc,relres,iter,frec] = FRANAGROUPLASSO(...) returns the reconstructed % signal from the coefficients, frec. 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 : % % frec = 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.github.io/doc/frames/franagrouplasso.html} %@seealso{franalasso, framebounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,3,'FRANAGROUPLASSO'); complainif_notvalidframeobj(F,'FRANAGROUPLASSO'); if ~isvector(f) 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(f)); F=frameaccel(F,L); if isempty(kv.C) [~,kv.C] = framebounds(F,L); end; % Initialization of thresholded coefficients c0 = frana(F,f); % 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 frec = frsyn(F,tc); end; ltfat/inst/frames/framenative2coef.m0000664000175000017500000000265713026262304017424 0ustar susnaksusnakfunction coef=framenative2coef(F,coef); %-*- texinfo -*- %@deftypefn {Function} framenative2coef %@verbatim %FRAMENATIVE2COEF Convert coefficient from native format % Usage: coef=framenative2coef(F,coef); % % FRAMENATIVE2COEF(F,coef) converts the frame coefficients from the % native format of the transform into the common column format. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/framenative2coef.html} %@seealso{frame, framecoef2native} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRAMENATIVE2COEF'); complainif_notvalidframeobj(F,'FRAMENATIVE2COEF'); % .native2coef is not a mandatory field if isfield(F,'native2coef') coef=F.native2coef(coef); end ltfat/inst/frames/framelengthcoef.m0000664000175000017500000000351413026262304017326 0ustar susnaksusnakfunction 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.github.io/doc/frames/framelengthcoef.html} %@seealso{frame, framelength} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . callfun = upper(mfilename); complainif_notenoughargs(nargin,2,callfun); complainif_notposint(Ncoef,'Ncoef',callfun); complainif_notvalidframeobj(F,callfun); 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; ltfat/inst/frames/framedual.m0000664000175000017500000001224613026262304016137 0ustar susnaksusnakfunction Fd=framedual(F) %-*- texinfo -*- %@deftypefn {Function} framedual %@verbatim %FRAMEDUAL Construct the canonical dual frame % Usage: Fd=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.github.io/doc/frames/framedual.html} %@seealso{frame, framepair, frametight} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'FRAMEDUAL'); complainif_notvalidframeobj(F,'FRAMEDUAL'); % 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'} 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{:}); case 'ufwt' % The canonical dual of ufwt might not keep the iterated % filterbank structure [g, a] = wfbt2filterbank({F.g,F.J,'dwt'}); g = comp_filterbankscale(g,a,F.flags.scaling); Fd = framedual(frame('filterbank',g,ones(numel(g),1),numel(g))); % warning(sprintf(['%s: The canonical dual system does not preserve ',... % 'the iterated filterbank structure.'],... % upper(mfilename))); case 'uwfbt' % The canonical dual of uwfbt might not keep the iterated % filterbank structure [g, a] = wfbt2filterbank(F.g); g = comp_filterbankscale(g,a,F.flags.scaling); Fd = framedual(frame('filterbank',g,ones(numel(g),1),numel(g))); % warning(sprintf(['%s: The canonical dual system does not preserve ',... % 'the iterated filterbank structure.'],... % upper(mfilename))); case 'uwpfbt' % The canonical dual of uwfbt might not keep the iterated % filterbank structure [g, a] = wpfbt2filterbank(F.g, F.flags.interscaling); g = comp_filterbankscale(g, a, F.flags.scaling); Fd = framedual(frame('filterbank',g,ones(numel(g),1),numel(g))); % warning(sprintf(['%s: The canonical dual system of frame type %s ',... % 'does not preserve iterated filterbank structure.'],... % upper(mfilename),F.type)); case 'fwt' is_basis = abs(sum(1./F.g.a)-1)<1e-6; is_tight = F.info.istight; % If the frame is a basis, there is only one dual frame. % If the basic filterbank is a parseval tight frame, the overal repr. % is also a tight frame. if is_basis || is_tight Fd = frame('fwt',{'dual',F.g},F.J); else error(['%s: Cannot create the canonical dual frame with the ',... 'same structure. Consider casting the system to an ',... 'uniform filterbank or using franaiter/frsyniter.'],... upper(mfilename)); end case 'wfbt' is_basis = all(cellfun(@(nEl) abs(sum(1./nEl.a)-1)<1e-6,F.g.nodes)); is_tight = F.info.istight; if is_basis || is_tight Fd = frame('wfbt',{'dual',F.g}); else error(['%s: Cannot create the canonical dual frame with the ',... 'same structure. Consider casting the system to an ',... 'uniform filterbank or using franaiter/frsyniter.'],... upper(mfilename)); end case 'wpfbt' % WPFBT is too wierd. error(['%s: Canonical dual frame of wpfbt might not keep the ',... 'same structure. Consider using franaiter/frsyniter.'],upper(mfilename)); end; % Treat the fixed length frames if isfield(F,'fixedlength') && F.fixedlength && isfield(F,'L') Fd = frameaccel(Fd,F.L); Fd.fixedlength = 1; end ltfat/inst/frames/plotframe.m0000664000175000017500000001102213026262304016157 0ustar susnaksusnakfunction outsig=plotframe(F,insig,varargin) %-*- texinfo -*- %@deftypefn {Function} plotframe %@verbatim %PLOTFRAME Plot frame coefficients % Usage: plotframe(F,c,…); % C = plotframe(...); % % PLOTFRAME(F,c) plots the frame coefficients c using the plot % command associated to the frame F. % % C=PLOTFRAME(...) for frames with time-frequency plots returns the % processed image data used in the plotting. The function produces an % error for frames which does not have a time-frequency plot. % % 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.github.io/doc/frames/plotframe.html} %@seealso{frame, frana} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'PLOTFRAME'); complainif_notvalidframeobj(F,'PLOTFRAME'); switch(F.type) case {'dft','dftreal','dcti','dctii','dctiii','dctiv',... 'dsti','dstii','dstiii','dstiv'} if nargout>0 error(['%s: Plot function of %s frame does not produce a ',... 'TF image'],upper(mfilename),F.type); end end; switch(F.type) case {'fwt','ufwt','wfbt','wpfbt','uwfbt','uwpfbt'} info.fname = F.type; info.wt = F.g; end; switch(F.type) case 'dgt' outsig = plotdgt(framecoef2native(F,insig),F.a,varargin{:}); case 'dgtreal' outsig = plotdgtreal(framecoef2native(F,insig),F.a,F.M,varargin{:}); case 'dwilt' outsig = plotdwilt(framecoef2native(F,insig),varargin{:}); case 'wmdct' outsig = 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 'dftreal' plotfftreal(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; outsig = plotwavelets(framecoef2native(F,insig),info,varargin{:}); case {'wfbt','wpfbt'} outsig = plotwavelets(framecoef2native(F,insig),info,varargin{:}); case {'uwfbt','uwpfbt'} outsig = plotwavelets(framecoef2native(F,insig),info,varargin{:}); case {'filterbank','filterbankreal','ufilterbank','ufilterbankreal'} outsig = plotfilterbank(framecoef2native(F,insig),F.a,[],varargin{:}); end; if nargout<1 clear outsig; end ltfat/inst/frames/frametf2coef.m0000664000175000017500000000366113026262304016543 0ustar susnaksusnakfunction coef=frametf2coef(F,coef) %-*- texinfo -*- %@deftypefn {Function} frametf2coef %@verbatim %FRAMETF2COEF Convert coefficients from TF-plane format % Usage: cout=frametf2coef(F,cin); % % FRAMETF2COEF(F,cin) converts the frame coefficients from the % time-frequency plane layout into the common column format. % % Not all types of frames support this coefficient conversion. The supported % types of frames are: 'dgt', 'dgtreal', 'dwilt', 'wmdct', 'ufilterbank', % 'ufwt','uwfbt' and 'uwpfbt'. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frametf2coef.html} %@seealso{frame, framecoef2tf, framecoef2native} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRAMETF2COEF'); complainif_notvalidframeobj(F,'FRAMETF2COEF'); switch(F.type) case {'dgt','dgtreal','wmdct'} [M,N,W]=size(coef); coef=reshape(coef,[M*N,W]); case {'dwilt'} coef=framenative2coef(F,rect2wil(coef)); case {'ufilterbank'} coef=permute(coef,[2,1,3]); [M,N,W]=size(coef); coef=reshape(coef,[M*N,W]); case {'ufwt','uwfbt','uwpfbt'} coef = F.native2coef(permute(coef,[2,1,3])); otherwise error('%s: TF-plane layout not supported for this transform.',upper(mfilename)); end; ltfat/inst/frames/framecoef2tf.m0000664000175000017500000000457413026262304016547 0ustar susnaksusnakfunction coef=framecoef2tf(F,coef) %-*- texinfo -*- %@deftypefn {Function} framecoef2tf %@verbatim %FRAMECOEF2TF Convert coefficients to time-frequency plane % Usage: cout=framecoef2tf(F,cin); % % FRAMECOEF2TF(F,cin) converts the frame coefficients cin 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 types of frames support this coefficient conversion. The supported % types of frames are: 'dgt', 'dgtreal', 'dwilt', 'wmdct', 'ufilterbank', % 'ufwt','uwfbt' and 'uwpfbt'. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/framecoef2tf.html} %@seealso{frame, frametf2coef, framecoef2native} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,2,'FRAMECOEF2TF'); complainif_notvalidframeobj(F,'FRAMECOEF2TF'); 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.g); 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]); otherwise error('%s: TF-plane layout not supported for this transform.',upper(mfilename)); end; ltfat/inst/frames/framediag.m0000664000175000017500000000404113026262304016110 0ustar susnaksusnakfunction 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.github.io/doc/frames/framediag.html} %@seealso{franaiter, frsyniter} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . callfun = upper(mfilename); complainif_notenoughargs(nargin,2,callfun); complainif_notposint(L,'L',callfun); complainif_notvalidframeobj(F,callfun); % 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.vargs{:}); case {'dwilt','wmdct'} d=wilframediag(F.g,F.M,L); case {'filterbank','ufilterbank','filterbankreal','ufilterbankreal'} error('%s: TO DO: Not supported yet',upper(mfilename)); case {'nsdgt','unsdgt','nsdgtreal','unsdgtreal'} d=nsgabframediag(F.g,F.a,F.M); case 'fusion' error('Not implemented yet.'); case {'fwt','ufwt','wfbt','uwfbt','wpfbt','uwpfbt'} error('%s: TO DO: Not supported yet',upper(mfilename)); end; ltfat/inst/frames/franaiter.m0000664000175000017500000001015513026262304016147 0ustar susnaksusnakfunction [c,relres,iter]=franaiter(F,f,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.github.io/doc/frames/franaiter.html} %@seealso{frame, frana, frsyn, frsyniter} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Peter L. Soendergaard complainif_notenoughargs(nargin,2,'FRANAITER'); complainif_notvalidframeobj(F,'FRANAITER'); tolchooser.double=1e-9; tolchooser.single=1e-5; definput.keyvals.Ls=[]; definput.keyvals.tol=tolchooser.(class(f)); 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. [f,~,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],[],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 f=postpad(f,L); if flags.do_pcg d=framediag(F,L); M=spdiags(d,0,L,L); [fout,flag,~,iter,relres]=pcg(A,f,kv.tol,kv.maxit,M); else [fout,flag,~,iter,relres]=pcg(A,f,kv.tol,kv.maxit); end; c=F.frana(fout); if nargout>1 relres=relres/norm(fout(:)); end; %% --- cleanup ----- permutedsize=[size(c,1),permutedsize(2:end)]; c=assert_sigreshape_post(c,dim,permutedsize,order); ltfat/inst/frames/framegram.m0000664000175000017500000000257113026262304016140 0ustar susnaksusnakfunction framegram(F,x,varargin) %-*- texinfo -*- %@deftypefn {Function} framegram %@verbatim %FRAMEGRAM Easy visualization of energy in transform domain % Usage: framegram(F,x,...); % % FRAMEGRAM(F,x) plots the energy of the frame 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.github.io/doc/frames/framegram.html} %@seealso{plotframe} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . plotframe(F,abs(frana(F,x)).^2,varargin{:}); ltfat/inst/frames/frgramian.m0000664000175000017500000000447313026262304016150 0ustar susnaksusnakfunction o = frgramian(c, Fa, Fs) %-*- texinfo -*- %@deftypefn {Function} frgramian %@verbatim %FRGRAMIAN Frame Gramian operator % Usage: o=frgramian(c, F); % o=frgramian(c, Fa, Fs); % % Input parameters: % c : Input coefficients % Fa : Analysis frame % Fs : Synthesis frame % % Output parameters: % o : Output coefficients % % o=FRGRAMIAN(c,F) applies the Gramian operator or Gram matrix of the % frame F. The entries of the Gram matrix are the inner products of the % frame elements of F. The frame must have been created using FRAME. % If the frame F is a Parseval frame, the Gramian operator is a projection % onto the range of the frame analysis operator. % % o=FRGRAMIAN(c, Fa, Fs) applies the (cross) Gramian operator with the % frames Fa and Fs. Here Fs is the frame associated with the frame % synthesis operator and Fa the frame that is associated with the % frame analysis operator. The entries of the matrix that is constructed % through the Gramian operator are the inner products of the frame % elements of Fa and Fs. % If Fa and Fs are canonical dual frames, the Gramian operator is a % projection onto the range of the frame analysis operator. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frgramian.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Jordy van Velthoven complainif_notenoughargs(nargin, 2, 'FRGRAMIAN'); complainif_notvalidframeobj(Fa,'FRGRAMIAN'); if (nargin == 2) Fs = Fa; else complainif_notvalidframeobj(Fs,'FRGRAMIAN'); end; o = frana(Fa, frsyn(Fs, c)); ltfat/inst/frames/Contents.m0000664000175000017500000000535013026262304015772 0ustar susnaksusnak% LTFAT - Frames % % Peter L. Soendergaard, 2012 - 2016. % % 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 % FRGRAMIAN - Frame Gramian operator % FRAMEOPERATOR - Frame operator % 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 % FRAMECLENGTH - Number of coefficients given input signal length % % 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 % FRAMECOEF2TFPLOT - Convert to time-frequency plane layout for plotting % % Non-linear analysis and synthesis % FRANABP - Basis pursuit using the SALSA algorithm. % FRANALASSO - LASSO thresholding using Landweber iterations. % FRANAGROUPLASSO - Group LASSO thresholding. % FRSYNABS - Frame synthesis from magnitude of coefficients % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % Url: http://ltfat.github.io/doc/frames/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/frames/franabp.m0000664000175000017500000002421413026262304015606 0ustar susnaksusnakfunction [c,relres,iter,frec,cd] = franabp(F,f,varargin) %-*- texinfo -*- %@deftypefn {Function} franabp %@verbatim %FRANABP Frame Analysis Basis Pursuit % Usage: c = franabp(F,f) % c = franabp(F,f,lambda,C,tol,maxit) % [c,relres,iter,frec,cd] = franabp(...) % % Input parameters: % F : Frame definition % f : Input signal % lambda : Regularisation parameter. % C : Step size of the algorithm. % tol : Reative error tolerance. % maxit : Maximum number of iterations. % Output parameters: % c : Sparse coefficients. % relres : Last relative error. % iter : Number of iterations done. % frec : Reconstructed signal such that frec = frsyn(F,c) % cd : The min c||_2 solution using the canonical dual frame. % % c = FRANABP(F,f) solves the basis pursuit problem % % argmin ||c||_1 subject to Fc = f % % for a general frame F using SALSA (Split Augmented Lagrangian % Srinkage algorithm) which is an appication of ADMM (Alternating % Direction Method of Multipliers) to the basis pursuit problem. % % The algorithm given F and f and parameters C >0, lambda >0 % (see below) acts as follows: % % Initialize c,d % repeat % v <- soft(c+d,lambda/C) - d % d <- F*(FF*)^(-1)(f - Fv) % c <- d + v % end % % When compared to other algorithms, Fc = f holds exactly (up to a num. % prec) in each iteration. % % For a quick execution, the function requires analysis operator of the % canonical dual frame F*(FF*)^(-1). By default, the function attempts % to call FRAMEDUAL to create the canonical dual frame explicitly. % If it is not available, the conjugate gradient method algorithm is % used for inverting the frame operator in each iteration of the % algorithm. % Optionally, the canonical dual frame object or an anonymous function % acting as the analysis operator of the canonical dual frame can be % passed as a key-value pair 'Fd',Fd see below. % % Optional positional parameters (lambda,C,tol,maxit) % --------------------------------------------------- % % lambda % A parameter for weighting coefficients in the objective % function. For lambda~=1 the basis pursuit problem changes to % % argmin ||lambda c||_1 subject to Fc = f % % lambda can either be a scalar or a vector of the same length % as c (in such case the product is carried out elementwise). % One can obtain length of c from length of f by % FRAMECLENGTH. FRAMECOEF2NATIVE and FRAMENATIVE2COEF will % help with defining weights specific to some regions of % coefficients (e.g. channel-specific weighting can be achieved % this way). % The default value of lambda is 1. % % C % A step parameter of the SALSA algorithm. % The default value of C is the upper frame bound of F. % Depending on the structure of the frame, this can be an expensive % operation. % % tol % Defines tolerance of relres which is a norm or a relative % difference of coefficients obtained in two consecutive iterations % of the algorithm. % The default value 1e-2. % % maxit % Maximum number of iterations to do. % The default value is 100. % % Other optional parameters % ------------------------- % % Key-value pairs: % % 'Fd',Fd % A canonical dual frame object or an anonymous function % acting as the analysis operator of the canonical dual frame. % % 'printstep',printstep % Print current status every printstep iteration. % % Flag groups (first one listed is the default): % % 'print','quiet' % Enables/disables printing of notifications. % % 'zeros','frana' % Starting point of the algorithm. With 'zeros' enabled, the % algorithm starts from coefficients set to zero, with 'frana' % the algorithm starts from c=frana(F,f). % % Returned arguments: % ------------------- % % [c,relres,iter] = FRANABP(...) returns the residuals relres in a % vector and the number of iteration steps done iter. % % [c,relres,iter,frec,cd] = FRANABP(...) returns the reconstructed % signal from the coefficients, frec (this requires additional % computations) and a coefficients cd minimising the c||_2 norm % (this is a byproduct of the algorithm). % % The relationship between the output coefficients frec and c is % given by : % % frec = frsyn(F,c); % % And cd and f by : % % cd = frana(framedual(F),f); % % Examples: % --------- % % The following example shows how FRANABP produces a sparse % representation of a test signal greasy still maintaining a perfect % reconstruction: % % f = greasy; % % Gabor frame with redundancy 8 % F = frame('dgtreal','gauss',64,512); % % Solve the basis pursuit problem % [c,~,~,frec,cd] = franabp(F,f); % % Plot sparse coefficients % figure(1); % plotframe(F,c,'dynrange',50); % % % Plot coefficients obtained by applying an analysis operator of a % % dual Gabor system to f* % figure(2); % plotframe(F,cd,'dynrange',50); % % % Check the reconstruction error (should be close do zero). % % frec is obtained by applying the synthesis operator of frame F* % % to sparse coefficients c. % norm(f-frec) % % % Compare decay of coefficients sorted by absolute values % % (compressibility of coefficients) % figure(3); % semilogx([sort(abs(c),'descend')/max(abs(c)),... % sort(abs(cd),'descend')/max(abs(cd))]); % legend({'sparsified coefficients','dual system coefficients'}); % % % References: % S. Boyd, N. Parikh, E. Chu, B. Peleato, and J. Eckstein. Distributed % optimization and statistical learning via the alternating direction % method of multipliers. Found. Trends Mach. Learn., 3(1):1--122, Jan. % 2011. [1]http ] % % I. Selesnick. L1-Norm Penalized Least Squares with SALSA. OpenStax_CNX, % Jan. 2014. % % References % % 1. http://dx.doi.org/10.1561/2200000016 % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/franabp.html} %@seealso{frame, frana, frsyn, framebounds, franalasso} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHOR: Zdenek Prusa % TO DO: Detect when F is a tight frame and simplify the algorithm. % Maybe add a 'tight' flag to indicate the frame is already tight. complainif_notenoughargs(nargin,2,'FRANABP'); complainif_notvalidframeobj(F,'FRANABP'); % Define initial value for flags and key/value pairs. definput.keyvals.C=[]; definput.keyvals.lambda=[]; definput.keyvals.tol=1e-2; definput.keyvals.maxit=100; definput.keyvals.printstep=10; definput.keyvals.Fd=[]; definput.flags.print={'print','quiet'}; definput.flags.startpoint={'zeros','frana'}; [flags,kv,lambda,C]=ltfatarghelper({'lambda','C','tol','maxit'},definput,varargin); if isempty(lambda) lambda = 1; end if ~isnumeric(lambda) || any(lambda)<0 error('%s: ''lambda'' parameter must be positive.',... upper(mfilename)); end %% ----- step 1 : Verify f and determine its length ------- % Change f to correct shape. [f,~,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],[],upper(mfilename)); if W>1 error('%s: Input signal can be single channel only.',upper(mfilename)); end % Do a correct postpad so that we can call F.frana and F.frsyn % directly. L = framelength(F,Ls); f = postpad(f,L); if isempty(C) % Use the upper framebound as C [~,C] = framebounds(F,L); else if ~isnumeric(C) || C<=0 error('%s: ''C'' parameter must be a positive scalar.',... upper(mfilename)); end end; if isempty(kv.Fd) % If the dual frame was not explicitly passed try creating it try % Try to create and accelerate the dual frame Fd = frameaccel(framedual(F),L); Fdfrana = @(insig) Fd.frana(insig); catch warning(sprintf(['The canonical dual system is not available for a given ',... 'frame.\n Using franaiter.'],upper(mfilename))); % err = lasterror.message; % The dual system cannot be created. % We will use franaiter instead Fdfrana = @(insig) franaiter(F,insig,'tol',1e-14); end else if isstruct(kv.Fd) && isfield(kv.Fd,'frana') % The canonical dual frame was passed explicitly as a frame object Fd = frameaccel(kv.Fd,L); Fdfrana = @(insig) Fd.frana(insig); elseif isa(kv.Fd,'function_handle') % The anonymous function is expected to do F*(FF*)^(-1) Fdfrana = kv.Fd; else error('%s: Invalid format of Fd.',upper(mfielname)); end end % Accelerate the frame F = frameaccel(F,L); % Cache the constant part cd = Fdfrana(f); % Intermediate results d = zeros(size(cd)); % Initial point if flags.do_frana tc0 = F.frana(f); elseif flags.do_zeros tc0 = zeros(size(cd)); end c = tc0; threshold = lambda./C; relres = 1e16; iter = 0; % Main loop while ((iter < kv.maxit)&&(relres >= kv.tol)) % Main part of the algorithm v = thresh(c + d,threshold,'soft') - d; d = cd - Fdfrana(F.frsyn(v)); c = d + v; % Bookkeeping relres = norm(c(:)-tc0(:))/norm(tc0(:)); tc0 = c; 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 if nargout>3 % Do a reconstruction with the original frame frec = postpad(F.frsyn(c),Ls); % Reformat to the original shape frec = assert_sigreshape_post(frec,dim,permutedsize,order); end ltfat/inst/frames/frsynmatrix.m0000664000175000017500000000654513026262304016572 0ustar susnaksusnakfunction 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=frameclength(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 synthesis % 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) % % Show the matrix (real and imaginary parts) % figure(1); imagesc(real(G)); % figure(2); imagesc(imag(G)); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/frsynmatrix.html} %@seealso{frame, frana, frsyn} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . callfun = upper(mfilename); complainif_notenoughargs(nargin,2,callfun); complainif_notposint(L,'L',callfun); complainif_notvalidframeobj(F,callfun); Lcheck=framelength(F,L); if Lcheck~=L error('%s: Incompatible frame length. Next compatible one is %i.',... upper(mfilename),Lcheck); 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 is ' ... 'non-linear and does not have a matrix represenation.'],... upper(mfilename)); %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; ltfat/inst/frames/framered.m0000664000175000017500000000326313026262304015763 0ustar susnaksusnakfunction 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.github.io/doc/frames/framered.html} %@seealso{frame, frana, framebounds} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . complainif_notenoughargs(nargin,1,'FRAMERED'); complainif_notvalidframeobj(F,'FRAMERED'); % .red field is mandatory so no checking here red=F.red; ltfat/inst/frames/framesinit.m0000664000175000017500000000163713026262304016342 0ustar susnaksusnakstatus=1; %-*- texinfo -*- %@deftypefn {Function} framesinit %@verbatim %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/frames/framesinit.html} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/frames/frameaccel.m0000664000175000017500000000762313026262304016264 0ustar susnaksusnakfunction F=frameaccel(F,Ls); %-*- texinfo -*- %@deftypefn {Function} frameaccel %@verbatim %FRAMEACCEL Precompute structures % Usage: F=frameaccel(F,Ls); % % 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, it will be a benefit. % % Notice that you need to input the signal length Ls, so this routines % will only be 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.github.io/doc/frames/frameaccel.html} %@seealso{frame, frana, framelength, framelengthcoef} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . callfun = upper(mfilename); complainif_notenoughargs(nargin,2,callfun); complainif_notposint(Ls,'Ls',callfun); complainif_notvalidframeobj(F,callfun); L=framelength(F,Ls); if isfield(F,'L') if L==F.L % Quick return, we have already accelerated return elseif isfield(F,'fixedlength') && F.fixedlength error(['%s: Incompatible signal length. The frame was specified for ',... 'fixed signal length L=%i.'],upper(mfilename),F.L); end 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, asan, info] = filterbankwin(F.g,F.a,L); g = comp_filterbank_pre(g,asan,L,1000); F = frame(F.type,g,asan,numel(g)); F.g_info = info; F.isfac=F.g_info.isfac; case {'filterbankreal','ufilterbankreal'} [g,asan,info] = filterbankwin(F.g,F.a,L,'real'); g = comp_filterbank_pre(g,asan,L,1000); F = frame(F.type,g,asan,numel(g)); 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','ufwt','wfbt','uwfbt','wpfbt','uwpfbt'} F.isfac = 1; end; end; F.L=L; ltfat/inst/ltfatarghelper.m0000664000175000017500000002307513026262304015730 0ustar susnaksusnakfunction [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. % % Advanced usage % -------------- % % Expansion import was introduced in order to allow sharing common % flags and key/value pairs between functions. % % The following example is taken from PLOTDGT and TFPLOT: % % definput.import={'ltfattranslate','tfplot'}; % [flags,kv,fs]=ltfatarghelper({'fs','dynrange'},definput,varargin); % % This code instructs LTFATARGHELPER to run functions % arg_ltfattranslate and arg_tfplot which define the flags and % the key/value pairs. The arg_ functions must have the following signature: % % function definput=arg_name(definput) % % Moreover, a special flag 'argimport' is used to pass the flags % and the key/value pairs from PLOTDGT to TFPLOT: % % coef=tfplot(...,'argimport',flags,kv); % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/ltfatarghelper.html} %@seealso{ltfatgetdefaults, ltfatsetdefaults} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . 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; ltfat/inst/ltfat_version0000664000175000017500000000000613026262276015345 0ustar susnaksusnak2.2.0 ltfat/inst/ltfatsetdefaults.m0000664000175000017500000000270113026262304016273 0ustar susnaksusnakfunction 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.github.io/doc/ltfatsetdefaults.html} %@seealso{ltfatgetdefaults, ltfatstart} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . if strcmpi(fname,'clearall') ltfatarghelper('clearall'); else ltfatarghelper('set',fname,varargin); end; ltfat/inst/INSTALL-Octave0000664000175000017500000001115213026262276015017 0ustar susnaksusnak-------- Compatibility ---------------------------------- The toolbox should work and compile on all versions of Octave later than version 3.4, but it is generally recommended to upgrade Octave to the latest stable release. For demos etc. to work, you will need to install some of the Octave-forge packages. All versions of LTFAT from 1.4.2 are also itself an Octave-forge package and the easiest way to install the toolbox is by typing the command pkg install -forge ltfat on the Octave prompt, which downloads LTFAT directly from the Octave-forge and compiles everything. This was tested on Linux, on Windows with MXE-Octave and Mac X unsing Octave from Homebrew. 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 libraries and some additional MEX files. Block processing framework (optional, experimental) - 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 ------------------------------------------ The GCC compiler is needed to compile the LTFAT on Mac OS X. When the Xcode Command Line Tools are installed the compilation of the LTFAT should work without any problem. Alternatively, Clang could be used to compile the LTFAT. The BLAS, LAPACK and FFTW libraries are taken directly from the Octave installation and doesn’t have to be installed separately. --------- Compiling on Microsoft Windows ------------------------------ Currently, there is no direct way of compiling ltfat on MXE-Octave. Please use the Octave-forge package. --------- 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 ———------------ --------------------------------------------------------------------------- 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. From Octave 3.8.0 the JAVA package is part of core Octave, so it doesn’t have to be installed separately. 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 ------------ It is recommended to compile PortAudio v19 to use with the block processing framework. PortAudio v19 only compiles on OS X version 10.4 or later. For any version of Octave older than 3.8.0 the JAVA package should be installed which requires the Java Development Kit to be installed. The Java Development Kit could be downloaded through the Apple Developer Downloads. --------- Compiling on Microsoft Windows -------------------------- Currently, there is no direct way of compiling ltfat on MXE-Octave. Please use the Octave-forge package. --------- Compiling on Linux ------------------------------------ - On Redhat / Fedora, TBD - On Debian / Ubuntu, install the packages 'portaudio19-dev', 'openjdk-7-jdk' ltfat/src/0000775000175000017500000000000013026262304012351 5ustar susnaksusnakltfat/src/include/0000775000175000017500000000000013026262276014004 5ustar susnaksusnakltfat/src/include/ltfat/0000775000175000017500000000000013026262276015116 5ustar susnaksusnakltfat/src/include/ltfat/ltfat_blaslapack.h0000664000175000017500000000216513026262276020562 0ustar susnaksusnak#ifndef _ltfat_blaslapack #define _ltfat_blaslapack #include "cblas.h" // 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); #endif ltfat/src/include/ltfat/config.h0000664000175000017500000000310613026262276016534 0ustar susnaksusnak#ifndef CONFIG_H #define CONFIG_H 1 #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif /* defined(M_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 #else // C99 complex header // fftw3.h will define: // typedef double _Complex fftw_complex #include #endif #include #include #include #include //#include // We do not use bool anyway #include #include #endif #ifdef LTFAT_COMPAT32 typedef int ltfatInt; #else typedef ptrdiff_t ltfatInt; #endif /* defined(LTFAT_COMPAT32) */ typedef enum { ltfatUnspecErr = 1, ltfatNoErr = 0 } ltfatStatus; typedef enum { FREQINV = 0, TIMEINV = 1 } dgt_phasetype; 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; typedef enum { PER, PERDEC, PPD, SYM, EVEN, SYMW, ASYM, ODD, ASYMW, SP0, ZPD, ZERO, VALID, BAD_TYPE } ltfatExtType; /* BEGIN_C_DECLS */ #ifdef __cplusplus extern "C" { #endif // First, include headers of type (single, double, or complex versions) inert functions #include "ltfat/ltfat_typeconstant.h" /* -------- Create the single precision routines headers ----- */ #ifndef LTFAT_DOUBLE # ifndef LTFAT_SINGLE # define LTFAT_SINGLE_WASNOTDEFINED # define LTFAT_SINGLE # endif # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typecomplexindependent.h" # ifndef LTFAT_COMPLEXTYPE # define LTFAT_COMPLEXTYPE # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typecomplexindependent.h" # undef LTFAT_COMPLEXTYPE # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typeindependent.h" # else # undef LTFAT_COMPLEXTYPE # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typeindependent.h" # define LTFAT_COMPLEXTYPE # endif # 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/ltfat_types.h" # include "ltfat/ltfat_typecomplexindependent.h" # ifndef LTFAT_COMPLEXTYPE # define LTFAT_COMPLEXTYPE # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typecomplexindependent.h" # undef LTFAT_COMPLEXTYPE # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typeindependent.h" # else # undef LTFAT_COMPLEXTYPE # include "ltfat/ltfat_types.h" # include "ltfat/ltfat_typeindependent.h" # define LTFAT_COMPLEXTYPE # endif # 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 #ifdef __cplusplus } // extern "C" #endif /* END_C_DECLS */ #endif /* !LTFAT_H */ ltfat/src/thirdparty/0000775000175000017500000000000013026262276014553 5ustar susnaksusnakltfat/src/thirdparty/f77-fcn.h0000664000175000017500000001264513026262276016103 0ustar susnaksusnak/* 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 /* 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 and . */ #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: *** */ ltfat/src/thirdparty/cblas.h0000664000175000017500000010214713026262276016015 0ustar susnaksusnak#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 ltfat/src/thirdparty/portaudio.h0000664000175000017500000013141113026262276016733 0ustar susnaksusnak#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.
 set PA_RECOMMENDED_OUTPUT_DEVICE=1
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 */ ltfat/src/thirdparty/fftw3.h0000664000175000017500000003327313026262276015765 0ustar susnaksusnak/* * 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 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* If 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 */ ltfat/src/configure0000775000175000017500000036347213026262304014277 0ustar susnaksusnak#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for LTFAT 2.2.0. # # Report bugs to . # # # 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@gnu.org and $0: http://github.com/ltfat/ltfat/issues about your system, $0: 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 &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='2.2.0' PACKAGE_STRING='LTFAT 2.2.0' PACKAGE_BUGREPORT='http://github.com/ltfat/ltfat/issues' 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 runstatedir 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' runstatedir='${localstatedir}/run' 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 ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -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 runstatedir 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 2.2.0 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] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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 2.2.0:";; esac cat <<\_ACEOF Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory 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 . _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 2.2.0 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 2.2.0, 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 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 #include 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 #include #include #include #include // 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/]) # 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 # 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 have_libportaudio=0 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Portaudio lib not found. Disabling support of the block processing framework." >&5 $as_echo "$as_me: WARNING: Portaudio lib not found. Disabling support of the block processing framework." >&2;} 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 2.2.0, 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 ." _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 2.2.0 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` 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 ' >$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 ltfat/src/README.md0000664000175000017500000000165313026262276013645 0ustar susnaksusnakLIBLTFAT -- Backend library of LTFAT ------------------------------------ This is a standalone backend library of LTFAT. Dependencies ------------ The library depends on FFTW, BLAS and LAPACK. On Ubuntu, just run ``` sudo apt-get install libfftw3-dev libblas-dev liblapack-dev ``` followed by ``` make sudo make install PREFIX=/usr/local ``` You might also need to run ``` sudo ldconfig ``` to make the just installed library accesible. There are three target libraries (static and shared versions) * build/libltfat.a(.so) Contains double and single prec. versions of the functions * build/libltfatd.a(.so) Just double prec. versions of the functions * build/libltfatf.a(.so) Just single prec. versions of the functions The dependency on BLAS and LAPACK can be disabled by calling ``` make NOBLASLAPACK=1 ``` Docuemntation ------------- Doxygen generated documentation is available [here](http://ltfat.github.io/libltfat). ltfat/src/ltfatcompat/0000775000175000017500000000000013026262276014677 5ustar susnaksusnakltfat/src/ltfatcompat/Makefile_crossmingw0000664000175000017500000001426313026262276020620 0ustar susnaksusnak# This makefile cross-compiles the whole LTFAT for Matlab on Windows 32 and 64 bit # # It was tested with M cross environment http://mxe.cc/ # # To cross-compile, one must define paths to Matlab (and other libs) in MATLIBS variable # and a destination directory OUTDIR. The makefile creates a directory structure mirroring # the tree structure of LTFAT i.e. it creates subdirectories mex, thirdparty/Playrec and # thirdparty/PolygonClip # # The MATLIBS dir must contain: # libfftw3-3.dll,libfft3f-3.dll obtainable from http://www.fftw.org/install/windows.html (select correct 32 or 64 bit) # # libmex.dll, libmx.dll libmwblas.dll and libmwlapack.dll from a Windows # Matlab instalation path MATLAB/bin/{arch}, where arch is win64 or win32. # # matrix.h, mex.h, tmwtypes.h from a Windows Matlab installation path # MATLAB/extern/include # # portaudio_x64.dll - I am using a version compiled on Windows, but it should be # possible to cross-compile that too. Change the library name accordingly. # # When cross compiling for 32bin windows, specify EXT=mexw32 in addition to other params. # # !!!!!!!!!!!!!!!!!! NO SPACES IN PATHS !!!!!!!!!!!!!!!!!!!!!!! # # Example 1: Cross compiling for 64 bit # # make -C `pwd`/../libltfat/ltfatcompat -f Makefile_crossmingw CROSS=x86_64-w64-mingw32.shared- MATLIBS=/home/susnak/Dropbox/win64libs OUTDIR=/home/susnak/Dropbox/ltfat_win64 EXT=mexw64 PORTAUDIOLIB=portaudio_x64.dll # # Example 2: Cross compiling for 32 bit # # make -C `pwd`/../libltfat/ltfatcompat -f Makefile_crossmingw CROSS=i686-w64-mingw32.shared- MATLIBS=/home/susnak/Dropbox/win64libs OUTDIR=/home/susnak/Dropbox/ltfat_win64 EXT=mexw64 PORTAUDIOLIB=portaudio_x64.dll # # ifndef MATLIBS MATLIBS=/home/susnak/Dropbox/win64libs endif ifndef OUTDIR OUTDIR=/home/susnak/Dropbox/ltfat_win64 endif ifndef EXT EXT=mexw64 endif ifndef CROSS $(error CROSS variable should be set as a prefix to Mingw tools) endif export CROSS CC=$(CROSS)gcc CXX=$(CROSS)g++ LD=$(CROSS)ld AR=$(CROSS)ar MKDIR_P = mkdir -p ifndef PORTAUDIOLIB = portaudio_x64.dll endif include ../filedefs.mk include ../../mex/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)) MEXBASE = $(MEXBASESAFE) $(MEXBASEMORE) MEXS = $(addsuffix .$(EXT),$(MEXBASE)) MEXCOMPFLAGS=-I$(MATLIBS) -DMATLAB_MEX_FILE MEXLINKFLAGS=-static-libgcc -Wl,--dll -L$(MATLIBS) \ -lmex -lmx -lmwlapack -lmwblas CFLAGS=-O2 -s -Wall -Wextra -std=c99 -I./thirdparty/ -I./ -DDLL_EXPORT_SYMBOLS -DNDEBUG all: clean makedirtree backlib $(MEXS) ltfatarghelper polygonclip playrec copyrest clean backlib: CFLAGS=-O2 -s -Wall -Wextra -std=c99 -I./thirdparty/ -I./ -DMATLABFORTRAN -DDLL_EXPORT_SYMBOLS -DNDEBUG backlib: make -C .. CROSS=$(CROSS) buildprefix=$(OUTDIR)/mex $(OUTDIR)/mex/libltfat.dll FFTWLIBS="-L$(MATLIBS) -lfftw3-3 -lfftw3f-3" BLASLAPACKLIBS="-L$(MATLIBS) -lmwblas -lmwlapack" OPTCFLAGS=-DMATLABFORTRAN # backlib_double: $(DFILES) $(DFILES_BLASLAPACK) Makefile_crossmingw # $(CC) -shared -Wl,--dll -L$(MATLIBS) -lfftw3-3 -lmwlapack -lmwblas $(DFILES) $(DFILES_BLASLAPACK) \ # -o $(OUTDIR)/mex/ltfat.dll -static-libgcc -Wl,--out-implib,$(OUTDIR)/lib/libltfat_dll.a # # backlib_single: $(SFILES) $(SFILES_BLASLAPACK) Makefile_crossmingw # $(CC) -shared -Wl,--dll -L$(MATLIBS) -lfftw3-3 -lfftw3f-3 -lmwlapack -lmwblas -L$(OUTDIR)/mex -lltfat $(SFILES) $(SFILES_BLASLAPACK) \ # -o $(OUTDIR)/mex/ltfatf.dll -static-libgcc -Wl,--out-implib,$(OUTDIR)/lib/libltfatf_dll.a # backlib_noblas: backlib_noblas_double backlib_noblas_single # # backlib_noblas_double: $(DFILES) Makefile_crossmingw # $(CC) -shared -Wl,--dll -L$(MATLIBS) -lfftw3-3 $(DFILES) \ # -o $(OUTDIR)/mex/ltfatnoblas.dll -static-libgcc -Wl,--out-implib,$(OUTDIR)/lib/libltfatnoblas_dll.a # # backlib_noblas_single: $(SFILES) Makefile_crossmingw # $(CC) -shared -Wl,--dll -L$(MATLIBS) -lfftw3-3 -lfftw3f-3 -L$(OUTDIR)/mex -lltfatnoblas $(SFILES) \ # -o $(OUTDIR)/mex/ltfatfnoblas.dll -static-libgcc -Wl,--out-implib,$(OUTDIR)/lib/libltfatfnoblas_dll.a $(MEXS): CFLAGS=-O2 -shared -s -Wall -std=c99 -I../thirdparty -I../include -I../include/ltfat -fvisibility=hidden -DNDEBUG $(MEXS): %.$(EXT): ../../mex/%.c $(CC) $(CFLAGS) $(MEXCOMPFLAGS) $< -o $(OUTDIR)/mex/$@ -L$(OUTDIR)/mex -lfftw3-3 -lfftw3f-3 -lltfat $(MEXLINKFLAGS) polygonclip: CXXFLAGS=-s -O2 -Wall -shared -DMATLAB_MEX_FILE -DNDEBUG polygonclip: $(CXX) $(CXXFLAGS) -I../../thirdparty/polyboolclipper -I$(MATLIBS) \ ../../thirdparty/polyboolclipper/polyboolmex.cpp ../../thirdparty/polyboolclipper/clipper.cpp \ -Wl,--dll -L$(MATLIBS) -lmex -lmx -static-libgcc -static-libstdc++ \ -o $(OUTDIR)/thirdparty/polyboolclipper/polyboolmex.$(EXT) playrec: CFLAGS=-static-libgcc -std=c99 -O2 -Wall -shared -DMATLAB_MEX_FILE -DHAVE_PORTAUDIO -DNDEBUG playrec: $(CC) $(CFLAGS) -I../../thirdparty/Playrec -I../thirdparty -I$(MATLIBS) \ ../../thirdparty/Playrec/mex_dll_core.c ../../thirdparty/Playrec/pa_dll_playrec.c \ ../../thirdparty/Playrec/ltfatresample.c \ -L$(MATLIBS) -l:$(PORTAUDIOLIB) -lmex -lmx -static-libgcc \ -o $(OUTDIR)/thirdparty/Playrec/playrec.$(EXT) ltfatarghelper: CFLAGS=-static-libgcc -std=c99 -O2 -Wall -shared -DMATLAB_MEX_FILE -DNDEBUG -I../utils -I../../mex ltfatarghelper: $(CC) $(CFLAGS) $(MEXCOMPFLAGS) -o $(OUTDIR)/mex/ltfatarghelper.$(EXT) ../../mex/ltfatarghelper.c ../ltfatcompat/utils/list.c $(MEXLINKFLAGS) makedirtree: $(MKDIR_P) $(OUTDIR) $(MKDIR_P) $(OUTDIR)/mex $(MKDIR_P) $(OUTDIR)/lib $(MKDIR_P) $(OUTDIR)/thirdparty $(MKDIR_P) $(OUTDIR)/thirdparty/Playrec $(MKDIR_P) $(OUTDIR)/thirdparty/polyboolclipper copyrest: $(CP) $(MATLIBS)/libfftw3-3.dll $(OUTDIR)/mex $(CP) $(MATLIBS)/libfftw3f-3.dll $(OUTDIR)/mex $(CP) $(MATLIBS)/$(PORTAUDIOLIB) $(OUTDIR)/thirdparty/Playrec s%.o: %.c $(CC) $(CFLAGS) -DLTFAT_SINGLE -c $< -o s$*.o d%.o: %.c $(CC) $(CFLAGS) -DLTFAT_DOUBLE -c $< -o d$*.o %.o: %.c $(CC) $(CFLAGS) -DLTFAT_DOUBLE -c $< clean: $(RM) ../../mex/*.$(EXT) $(RM) *.o $(RM) *.a $(RM) ../../thirdparty/Playrec/*.o $(RM) ../../thirdparty/PolygonClip/*.o .PHONY: all clean makedirtree copyrest ltfat/src/ltfatcompat/Makefile_octpkg.in0000664000175000017500000000330713026262276020316 0ustar susnaksusnak# Only .mex, .oct and .m files from the current directory will be copied # to the target installaction directory targets = oct playrec CC=@CC@ CXX=@CXX@ export CC export CXX ifeq (@have_libportaudio@,1) export HAVE_PORTAUDIO=1 endif # Disables compilation of MEX files. They cause trouble # with missing help. export NOMEX=1 ifeq ($(OS),Windows_NT) # Removes -fPIC from CFLAGS export MINGW=1 # If OS==Windows_NT, the makefiles use Windows commands for # file copy, delete and directory creation. # To avoid that and fallback to posix compatible commands # we temporarily redefine OS. export OS=NotWindows_NT endif .PHONY: oct octpostbuild playrec mulaclab all: oct mulaclab playrec oct: # Compile the backend lib, no dependency is resolved here since we compile # a static library $(MAKE) -f Makefile_libltfat build/libltfat.a # Copy to the common place. mv build/libltfat.a ../lib # Compile oct and mex files $(MAKE) -C ../oct -f Makefile_unix # Do postbuild explicitly so it is not called before # oct files are finished $(MAKE) octpostbuild mulaclab: $(MAKE) -C ../thirdparty/polyboolclipper -f Makefile_unixoct mv ../thirdparty/polyboolclipper/polyboolmex.mex . playrec: $(MAKE) -C ../thirdparty/Playrec -f Makefile_unixoct mv ../thirdparty/Playrec/playrec.mex . octpostbuild: # OCT files here mv ../oct/*.oct . # Compilation of MEX files has been disabled # mv ../oct/*.mex . # Delete corresponding m-files ls -1 *.oct | cut -d . -f 1 | xargs -I {} rm -f ../inst/comp/{}.m # ls -1 *.mex | cut -d . -f 1 | xargs -I {} rm -f ../inst/comp/{}.m # rm -f ../inst/ltfatarghelper.m ## Copy extra help files for mex files # ls -1 *.mex | cut -d . -f 1 | xargs -I {} cp ../oct/mexhelp/{} ./{}.m ltfat/src/ltfatcompat/Makefile_mingw0000664000175000017500000000144313026262276017542 0ustar susnaksusnak# 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. MATLABROOT?=C:\Program Files\MATLAB\R2011b ARCH?=win64 MATLABLINKFLAGS=-L\"$(MATLABROOT)\bin\$(ARCH)\" $(MATLABLIBS) -lmwlapack -lmwblas OPTCFLAGS=-DMATLABFORTRAN -DDLL_EXPORT_SYMBOLS .PHONY: all clean all: mingw32-make -C .. build/libltfat.dll OPTCFLAGS="$(OPTCFLAGS)" BLASLAPACKLIBS="$(MATLABLINKFLAGS)" FFTWLIBS="-L../mex $(DFFTW) $(SFFTW)" MINGW=1 copy /Y ..\build\libltfat.dll ..\..\mex clean: mingw32-make -C .. clean del /Q /F ..\..\mex\libltfat.dll ltfat/src/ltfatcompat/m4/0000775000175000017500000000000013026262276015217 5ustar susnaksusnakltfat/src/ltfatcompat/m4/ax_lapack.m40000664000175000017500000001166013026262276017410 0ustar susnaksusnak# =========================================================================== # 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= in order to use some specific # LAPACK library . 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 # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # 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=], [use LAPACK library ])]) 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 ltfat/src/ltfatcompat/m4/ax_blas.m40000664000175000017500000001513613026262276017100 0ustar susnaksusnak# =========================================================================== # 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= in order to use some specific BLAS # library . 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 # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # 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=], [use BLAS library ])]) 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 ltfat/src/ltfatcompat/README0000664000175000017500000000021413026262276015554 0ustar susnaksusnakThis directory contains the source for the C-library. On Unix, type make to compile the C-library. The library is called libltfat.a ltfat/src/ltfatcompat/configure.ac0000664000175000017500000000225113026262276017165 0ustar susnaksusnakAC_PREREQ([2.62]) AC_INIT([LTFAT], [2.0.0], [http://github.com/ltfat/ltfat/issues], [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], [have_libportaudio=0 AC_MSG_WARN([Portaudio lib not found. Disabling support of the block processing framework.])] ) AC_SUBST(have_libportaudio) AC_OUTPUT(Makefile) ltfat/src/ltfatcompat/utils/0000775000175000017500000000000013026262276016037 5ustar susnaksusnakltfat/src/ltfatcompat/utils/list.c0000664000175000017500000000454513026262276017166 0ustar susnaksusnak#include "lcthw_List.h" #include "dbg.h" List *List_create() { return calloc(1, sizeof(List)); } void List_destroy(List *list) { LIST_FOREACH(list, first, next, cur) { if(cur->prev) { free(cur->prev); } } free(list->last); free(list); } void List_clear(List *list) { LIST_FOREACH(list, first, next, cur) { free(cur->value); } } void List_clear_destroy(List *list) { List_clear(list); List_destroy(list); } void List_push(List *list, void *value) { ListNode *node = calloc(1, sizeof(ListNode)); check_mem(node); node->value = value; if(list->last == NULL) { list->first = node; list->last = node; } else { list->last->next = node; node->prev = list->last; list->last = node; } list->count++; error: return; } void *List_pop(List *list) { ListNode *node = list->last; return node != NULL ? List_remove(list, node) : NULL; } void List_unshift(List *list, void *value) { ListNode *node = calloc(1, sizeof(ListNode)); check_mem(node); node->value = value; if(list->first == NULL) { list->first = node; list->last = node; } else { node->next = list->first; list->first->prev = node; list->first = node; } list->count++; error: return; } void *List_shift(List *list) { ListNode *node = list->first; return node != NULL ? List_remove(list, node) : NULL; } void *List_remove(List *list, ListNode *node) { void *result = NULL; check(list->first && list->last, "List is empty."); check(node, "node can't be NULL"); if(node == list->first && node == list->last) { list->first = NULL; list->last = NULL; } else if(node == list->first) { list->first = node->next; check(list->first != NULL, "Invalid list, somehow got a first that is NULL."); list->first->prev = NULL; } else if (node == list->last) { list->last = node->prev; check(list->last != NULL, "Invalid list, somehow got a next that is NULL."); list->last->next = NULL; } else { ListNode *after = node->next; ListNode *before = node->prev; after->prev = before; before->next = after; } list->count--; result = node->value; free(node); error: return result; } ltfat/src/ltfatcompat/utils/lcthw_List.h0000664000175000017500000000162613026262276020331 0ustar susnaksusnak#ifndef lcthw_List_h #define lcthw_List_h #include struct ListNode; typedef struct ListNode { struct ListNode *next; struct ListNode *prev; void *value; } ListNode; typedef struct List { int count; ListNode *first; ListNode *last; } List; List *List_create(); void List_destroy(List *list); void List_clear(List *list); void List_clear_destroy(List *list); #define List_count(A) ((A)->count) #define List_first(A) ((A)->first != NULL ? (A)->first->value : NULL) #define List_last(A) ((A)->last != NULL ? (A)->last->value : NULL) void List_push(List *list, void *value); void *List_pop(List *list); void List_unshift(List *list, void *value); void *List_shift(List *list); void *List_remove(List *list, ListNode *node); #define LIST_FOREACH(L, S, M, V) ListNode *_node = NULL;\ ListNode *V = NULL;\ for(V = _node = L->S; _node != NULL; V = _node = _node->M) #endif ltfat/src/ltfatcompat/utils/dbg.h0000664000175000017500000000553113026262276016750 0ustar susnaksusnak/* * This file is from http://c.learncodethehardway.org/book/ex20.html * * Zed's Awesome debug macros and therir modified version for MEX files * The MEX version does not have goto error and errno as the memory mnagement in * mex files is automatic. * * */ #ifndef __dbg_h__ #define __dbg_h__ #include #include /* Choose the macro set depending on whether mex.h was already included*/ #if defined(mex_h) || defined(MEX_H) /* * As it is not possible to use mexErrMsgIdAndTxt and continue in MEX, we need to store * the error message first, clean everything and call mexErrMsgIdAndTxt after that. * The following macros relies on having a global variables defined: * static char MEXERRSTRING[500]; * static int MEXERROCCURED = 0; * and * error: * // Tear down logic * print_mexerror(); * */ #ifdef NDEBUG #define debug(M, ...) #else #define debug(M, ...) mexPrintf("DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #endif #define log_err(M, ...) sprintf(MEXERRSTRING,"[ERROR] (%s:%d:) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define log_warn(M, ...) mexWarnMsgIdAndTxt("LTFAT:MEX", "[WARN] (%s:%d:) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define log_info(M, ...) mexPrintf("[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); MEXERROCCURED = 1; goto error; } #define check_keepmessage(A) if(!(A)) { MEXERROCCURED = 1; goto error; } #define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); MEXERROCCURED = 1; goto error; } #define check_mem(A) check((A), "Out of memory.") #define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); MEXERROCCURED = 1; goto error; } #define print_mexerror if(MEXERROCCURED) { mexErrMsgIdAndTxt("LTFAT:MEX", "%s", MEXERRSTRING); } #else #include #ifdef NDEBUG #define debug(M, ...) #else #define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #endif #define clean_errno() (errno == 0 ? "None" : strerror(errno)) #define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) #define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) #define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } #define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } #define check_mem(A) check((A), "Out of memory.") #define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; } #endif #endif ltfat/src/ltfatcompat/bootstrap0000775000175000017500000000002313026262276016635 0ustar susnaksusnak#!/bin/sh autoconf ltfat/src/ltfatcompat/Makefile_mac0000664000175000017500000000002613026262276017155 0ustar susnaksusnakinclude Makefile_unix ltfat/src/ltfatcompat/Makefile_unix0000664000175000017500000000037613026262276017410 0ustar susnaksusnak# To run this makefile, you must provide the ARCH and MATLABROOT # variables on the command line, i.e. as in # .PHONY: all clean all: make -C ../ build/libltfat.a cp ../build/libltfat.a ../../lib clean: make -C ../ clean @rm ../../lib/libltfat.a ltfat/src/configure.ac0000664000175000017500000000225113026262304014637 0ustar susnaksusnakAC_PREREQ([2.62]) AC_INIT([LTFAT], [2.2.0], [http://github.com/ltfat/ltfat/issues], [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], [have_libportaudio=0 AC_MSG_WARN([Portaudio lib not found. Disabling support of the block processing framework.])] ) AC_SUBST(have_libportaudio) AC_OUTPUT(Makefile) ltfat/src/examples/0000775000175000017500000000000013026262276014177 5ustar susnaksusnakltfat/src/examples/example_gabanasyn.c0000664000175000017500000000360213026262276020022 0ustar susnaksusnak#include #include #include #include #include "ltfat.h" int main() { // Number of frequency channels ltfatInt M = 2048; // Hop factor ltfatInt a = 256; // Length of the signal. Must be an integer multiple of both a and M ltfatInt L = 100*2048; // Length of the window, I use a Gauss window here which is possibly // fully supported ltfatInt gl = L; // Number of channels ltfatInt W = 1; // Number of unique channels when the input is a real signal ltfatInt M2 = M / 2 + 1; // Number of time hops ltfatInt N = L / a; // Allocate space for a window double* g = ltfat_malloc(gl * sizeof * g); // Alocate space for the dual window double* gd = ltfat_malloc(gl * sizeof * gd); // Space for input signal double* f = ltfat_malloc(W * L * sizeof * f); // Space for reconstructed signal double* frec = ltfat_malloc(W * L * sizeof * f); // Space for coefficients double _Complex* c = ltfat_malloc(W * M2 * N * sizeof * c); // Generate some input srand(time(NULL)); for (ltfatInt l = 0; l < W * L; ++l) { f[l] = ((double)rand()) / RAND_MAX; } // Compute window. Using a*M/L for w makes the time-frequency support of the // Gaussion window to best fit the time-frequency sampling grid pgauss_d(L, a * M / L, 0, g); // Compute the dual window gabdual_long_d(g,L,1,a,M,gd); // Do the transform dgtreal_long_d(f, g, L, W, a, M, TIMEINV, c); // Do inverse transform idgtreal_long_d(c, gd, L, W, a, M, TIMEINV, frec); // Comute error of the reconstruction double err = 0.0; for (ltfatInt l = 0; l < L * W; ++l) { double dif = fabs( f[l] - frec[l] ); err += dif * dif; } printf("Error of the reconstruction is %e\n", err); LTFAT_SAFEFREEALL(g, gd, f, frec, c); return 0; } ltfat/src/examples/Makefile0000664000175000017500000000026613026262276015643 0ustar susnaksusnakCFLAGS+=-g -Wall -Wextra -std=gnu99 testgab: example_gabanasyn.c $(CC) $(CFLAGS) -I.. example_gabanasyn.c -o example_gabanasyn ../build/libltfat.a -lblas -llapack -lfftw3 -lc -lm ltfat/src/comptarget.mk0000664000175000017500000000014713026262276015061 0ustar susnaksusnakifeq ($(COMPTARGET),debug) # Do debug stuff here CFLAGS += -O0 -g else CFLAGS += -O2 -DNDEBUG endif ltfat/src/Makefile_libltfat0000664000175000017500000001306513026262276015707 0ustar susnaksusnak# This is the main Makefile for libltfat # # Builds three static and three shared libraries (default prefix is build/): # # libltfat.a Contains double, single and common code # libltfatd.a Contains double and common code # libltfatf.a Contains single and common code # # make CROSS=x86_64-w64-mingw32.static- # or # make CROSS=x86_64-w64-mingw32.static- NOBLASLAPACK=1 # # include ostools.mk ifdef CROSS CC=$(CROSS)gcc AR=$(CROSS)ar OBJCOPY=$(CROSS)objcopy RANLIB=$(CROSS)ranlib buildprefix ?= build/$(CROSS) objprefix ?= obj/$(CROSS) MINGW=1 else CC?=gcc AR?=ar OBJCOPY?=objcopy RANLIB?=ranlib buildprefix ?= build objprefix ?= obj endif PREFIX ?= /usr/local LIBDIR = $(PREFIX)/lib INCDIR = $(PREFIX)/include # Base CFLAGS CFLAGS+=-Ithirdparty -Wall -Wextra -pedantic -std=gnu99 -Iinclude -Iinclude/ltfat -Ithirdparty $(OPTCFLAGS) # The following adds parameters to CFLAGS include comptarget.mk # Define source files from src/ include filedefs.mk FFTWLIBS?=-lfftw3 -lfftw3f ifdef MINGW EXTRALFLAGS = -Wl,--out-implib,$@.a -static-libgcc BLASLAPACKLIBS?=-llapack -lblas -lgfortran -lquadmath else CFLAGS += -fPIC BLASLAPACKLIBS?=-llapack -lblas endif LFLAGS = -Wl,--no-undefined $(OPTLPATH) # Dependencies ifndef NOBLASLAPACK LFLAGS += $(BLASLAPACKLIBS) endif LFLAGS += $(FFTWLIBS) -lm $(EXTRALFLAGS) $(OPTLFLAGS) # Convert *.c names to *.o toCompile = $(patsubst %.c,%.o,$(files)) toCompile_complextransp = $(patsubst %.c,%.o,$(files_complextransp)) toCompile_notypechange = $(patsubst %.c,%.o,$(files_notypechange)) ifndef NOBLASLAPACK toCompile += $(patsubst %.c,%.o,$(files_blaslapack)) toCompile_complextransp += $(patsubst %.c,%.o,$(files_blaslapack_complextransp)) endif COMMONFILES = $(addprefix $(objprefix)/common/d,$(toCompile_notypechange)) COMMONFILESFORSFILES = $(addprefix $(objprefix)/common/s,$(toCompile_notypechange)) DFILES = $(addprefix $(objprefix)/double/,$(toCompile) $(toCompile_complextransp)) \ $(addprefix $(objprefix)/complexdouble/,$(toCompile_complextransp)) SFILES = $(addprefix $(objprefix)/single/,$(toCompile) $(toCompile_complextransp)) \ $(addprefix $(objprefix)/complexsingle/,$(toCompile_complextransp)) # Define libraries DSTATIC = libltfatd.a SSTATIC = libltfatf.a DSSTATIC = libltfat.a ifndef MINGW DSHARED = $(patsubst %.a,%.so,$(DSTATIC)) SSHARED = $(patsubst %.a,%.so,$(SSTATIC)) DSSHARED = $(patsubst %.a,%.so,$(DSSTATIC)) else DSHARED = $(patsubst %.a,%.dll,$(DSTATIC)) SSHARED = $(patsubst %.a,%.dll,$(SSTATIC)) DSSHARED = $(patsubst %.a,%.dll,$(DSSTATIC)) endif # Define targets DTARGET=$(buildprefix)/$(DSTATIC) STARGET=$(buildprefix)/$(SSTATIC) DSTARGET=$(buildprefix)/$(DSSTATIC) SO_DTARGET=$(buildprefix)/$(DSHARED) SO_STARGET=$(buildprefix)/$(SSHARED) SO_DSTARGET=$(buildprefix)/$(DSSHARED) DDEP = $(buildprefix) $(objprefix)/double $(objprefix)/complexdouble $(objprefix)/common SDEP = $(buildprefix) $(objprefix)/single $(objprefix)/complexsingle $(objprefix)/common all: static shared $(DSTARGET): $(DDEP) $(SDEP) $(COMMONFILES) $(DFILES) $(SFILES) $(AR) rvu $@ $(COMMONFILES) $(DFILES) $(SFILES) $(RANLIB) $@ $(DTARGET): $(DDEP) $(DFILES) $(COMMONFILES) $(AR) rvu $@ $(DFILES) $(COMMONFILES) $(RANLIB) $@ $(STARGET): $(SDEP) $(SFILES) $(COMMONFILESFORSFILES) $(AR) rvu $@ $(SFILES) $(COMMONFILESFORSFILES) $(RANLIB) $@ $(SO_DSTARGET): $(DDEP) $(SDEP) $(COMMONFILES) $(DFILES) $(SFILES) $(CC) -shared -fPIC -o $@ $(COMMONFILES) $(DFILES) $(SFILES) $(LFLAGS) $(SO_DTARGET): $(DDEP) $(COMMONFILES) $(DFILES) $(CC) -shared -fPIC -o $@ $(COMMONFILES) $(DFILES) $(LFLAGS) $(SO_STARGET): $(SDEP) $(SFILES) $(COMMONFILESFORSFILES) $(CC) -shared -fPIC -o $@ $(COMMONFILESFORSFILES) $(SFILES) $(LFLAGS) $(objprefix)/common/d%.o: src/%.c $(CC) $(CFLAGS) $(OPTCFLAGS) -DLTFAT_DOUBLE -c $< -o $@ $(OPTCFLAGS) $(objprefix)/double/%.o: src/%.c $(CC) $(CFLAGS) $(OPTCFLAGS) -DLTFAT_DOUBLE -c $< -o $@ $(objprefix)/complexdouble/%.o: src/%.c $(CC) $(CFLAGS) $(OPTCFLAGS) -DLTFAT_DOUBLE -DLTFAT_COMPLEXTYPE -c $< -o $@ $(objprefix)/common/s%.o: src/%.c $(CC) $(CFLAGS) $(OPTCFLAGS) -DLTFAT_SINGLE -c $< -o $@ $(objprefix)/single/%.o: src/%.c $(CC) $(CFLAGS) $(OPTCFLAGS) -DLTFAT_SINGLE -c $< -o $@ $(objprefix)/complexsingle/%.o: src/%.c $(CC) $(CFLAGS) $(OPTCFLAGS) -DLTFAT_SINGLE -DLTFAT_COMPLEXTYPE -c $< -o $@ $(buildprefix): @$(MKDIR) $(buildprefix) $(objprefix)/common: @$(MKDIR) $(objprefix)$(PS)common $(objprefix)/double: @$(MKDIR) $(objprefix)$(PS)double $(objprefix)/single: @$(MKDIR) $(objprefix)$(PS)single $(objprefix)/complexdouble: @$(MKDIR) $(objprefix)$(PS)complexdouble $(objprefix)/complexsingle: @$(MKDIR) $(objprefix)$(PS)complexsingle .PHONY: clean help doc static shared static: $(DTARGET) $(STARGET) $(DSTARGET) shared: $(SO_DTARGET) $(SO_STARGET) $(SO_DSTARGET) clean: @$(RMDIR) build @$(RMDIR) obj help: @echo "USAGE: make [target]" @echo "Options:" @echo " make [target] CONFIG=debug Compiles the library in a debug mode" @echo " make [target] NOBLASLAPACK=1 Compiles the library without BLAS and LAPACK dependencies" doc: doxygen doc/doxyconfig cleandoc: @$(RMDIR) html @$(RMDIR) latex build/ltfat.h: $(CC) -E -P -DNOSYSTEMHEADERS -nostdinc include/ltfat.h -o build/ltfat.h install: install -d $(LIBDIR) install $(STARGET) $(DTARGET) $(DSTARGET) $(SO_STARGET) $(SO_DTARGET) $(SO_DSTARGET) $(LIBDIR) mkdir -p $(INCDIR) cp -r include/* $(INCDIR) uninstall: rm -f $(LIBDIR)/$(DSTATIC) $(LIBDIR)/$(SSTATIC) $(LIBDIR)/$(DSSTATIC) rm -f $(LIBDIR)/$(DSHARED) $(LIBDIR)/$(SSHARED) $(LIBDIR)/$(DSSHARED) rm -f $(INCDIR)/ltfat.h rm -rf $(INCDIR)/ltfat ltfat/src/doc/0000775000175000017500000000000013026262276013126 5ustar susnaksusnakltfat/src/doc/texinclude/0000775000175000017500000000000013026262276015272 5ustar susnaksusnakltfat/src/doc/texinclude/macros.tex0000664000175000017500000000243013026262276017277 0ustar susnaksusnak \DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\supp}{supp} \newcommand{\stime}{t} \newcommand{\stimearg}{\tau} \newcommand{\sfreq}{\omega} \newcommand{\sfreqarg}{\xi} \newcommand{\Lspacen}[1]{\ensuremath{L^2\left\mathcal{R}^{#1}\right}} \newcommand{\Lspace}{\Lspacen{}} \newcommand{\Lspacetwod}{\Lspacen{2}} \newcommand{\barg}{\ensuremath{\mathcal{B}}} \newcommand{\dstimearg}{\ensuremath{\, \mathrm{d}\stimearg}} \newcommand{\modop}{\ensuremath{\mathcal{E}}} \newcommand{\tranop}{\ensuremath{\mathcal{T}}} \newcommand{\dilop}{\ensuremath{\mathcal{D}}} \newcommand{\modoparg}[1]{\ensuremath{\modop_{#1}}} \newcommand{\tranoparg}[1]{\ensuremath{\tranop_{#1}}} \newcommand{\diloparg}[1]{\ensuremath{\dilop_{#1}}} \newcommand{\modopsfreq}{\modoparg{\sfreq}} \newcommand{\tranopstime}{\tranoparg{\stime}} \newcommand{\diloplambda}{\diloparg{\lambda}} \newcommand{\stftphase}[2]{\ensuremath{\Phi_{#1}^{#2}}} \newcommand{\stftmodulus}[2]{\ensuremath{M_{#1}^{#2}}} \newcommand{\stftphasefvarphi}{\stftphase{\varphi}{f}} \newcommand{\stftmodulusfvarphi}{\stftmodulus{\varphi}{f}} \newcommand{\stftphasefg}{\stftphase{g}{f}} \newcommand{\stftmodulusfg}{\stftmodulus{g}{f}} \newcommand{\me}{\mathrm{e}} \newcommand{\mi}{\mathrm{i}} % \newcommand{\normm}[1]{\left\lVert#1\right\rVert} ltfat/src/doc/doxymain.md0000664000175000017500000000316013026262276015300 0ustar susnaksusnak\mainpage libltfat - Large Time-Frequency Alalysis Toolbox backend library ================================================================ General conventions ------------------- \anchor stft \f[ (\mathcal{V}_g f) (\sfreq, \stime) = \int_{\mathbb{R}}\! f(\stimearg+\stime) \overline{g(\stimearg)} \me^{-\mi 2\pi \sfreq \stimearg } \, \mathrm{d}\stimearg, \ \ \sfreq, \stime \in\mathbb{R}\\ \f] Papers which use this toolbox \cite ltfatnote014 Compatibility ------------- The library internally uses complex numbers from ISO C99 [complex.h](http://en.cppreference.com/w/c/numeric/complex) and [aligned_malloc](http://en.cppreference.com/w/c/memory/aligned_alloc) defined in ISO C11, therefore it must be compiled with a fairly modern compiler. When linking the library however, none of the above is required. It is not required to supply memory aligned output arrays and the complex data type in the headers will become a length 2 array. Such format is binary compatible with the complex class from C++. One can cast pointers back and forth in the following way: ~~~~~~~~~~~~~~~{.cpp} double ccomp[][2] = {{1.0,2.0},{3.0,4.0},{5.0,6.0}}; std::complex* ccpp = reinterpret_cast*>(ccomp); double (*ccomp2)[2] = reinterpret_cast(ccpp); ~~~~~~~~~~~~~~~ A complete example: > Blockquote > 2nd line - More text for this item. - Further + nested list item. + another nested item. - Prd 1. First item. 2. Second item. This a normal paragraph This is a code block We continue with a normal paragraph again. Code inline `int prd` Cross link to \ref stft "(formula)" ltfat/src/doc/doxyconfig0000664000175000017500000030410113026262276015221 0ustar susnaksusnak# Doxyfile 1.8.6 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "libltfat" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = 0.1.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a # new page for each member. If set to NO, the documentation of a member will be # part of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the # todo list. This list is created by putting \todo commands in the # documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the # test list. This list is created by putting \test commands in the # documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES the list # will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. Do not use file names with spaces, bibtex cannot handle them. See # also \cite for info how to create references. CITE_BIB_FILES = doc/project.bib #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. # Note: If this tag is empty the current directory is searched. INPUT = doc src include examples # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank the # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES, then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = doc/htmltemplate/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = doc/htmltemplate/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = doc/htmltemplate/customdoxygen.css # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler ( hhc.exe). If non-empty # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated ( # YES) or that it should be included in the master .chm file ( NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( # YES) or a normal table of contents ( NO) in the .chm file. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 12 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = doc/mathjaxinclude/macros.js # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /
$projectname  $projectnumber
$projectbrief
$projectbrief
$searchbox
ltfat/src/doc/htmltemplate/footer.html0000664000175000017500000000131313026262276020010 0ustar susnaksusnak
ltfat/src/doc/htmltemplate/customdoxygen.css0000664000175000017500000005657713026262276021274 0ustar susnaksusnak/* The standard CSS for doxygen 1.8.6 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; } /* @group Heading Levels */ h1.groupheader { font-size: 150%; } .title { font: 400 14px/28px Roboto,sans-serif; font-size: 150%; font-weight: bold; margin: 10px 2px; } h2.groupheader { border-bottom: 1px solid #879ECB; color: #354C7B; font-size: 150%; font-weight: normal; margin-top: 1.75em; padding-top: 8px; padding-bottom: 4px; width: 100%; } h3.groupheader { font-size: 100%; } h1, h2, h3, h4, h5, h6 { -webkit-transition: text-shadow 0.5s linear; -moz-transition: text-shadow 0.5s linear; -ms-transition: text-shadow 0.5s linear; -o-transition: text-shadow 0.5s linear; transition: text-shadow 0.5s linear; margin-right: 15px; } h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { text-shadow: 0 0 15px cyan; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd { margin-top: 2px; } p.starttd { margin-top: 0px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #3D578C; font-weight: normal; text-decoration: none; } .contents a:visited { color: #4665A2; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #9CAFD4; color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code, a.code:visited, a.line, a.line:visited { color: #4665A2; } a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; font-family: monospace, fixed; font-size: 105%; } div.fragment { padding: 4px 6px; margin: 4px 8px 4px 2px; background-color: #FBFCFD; border: 1px solid #C4CFE5; } div.line { font-family: monospace, fixed; font-size: 13px; min-height: 13px; line-height: 1.0; text-wrap: unrestricted; white-space: -moz-pre-wrap; /* Moz */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ white-space: pre-wrap; /* CSS3 */ word-wrap: break-word; /* IE 5.5+ */ text-indent: -53px; padding-left: 53px; padding-bottom: 0px; margin: 0px; -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; -moz-transition-duration: 0.5s; -ms-transition-property: background-color, box-shadow; -ms-transition-duration: 0.5s; -o-transition-property: background-color, box-shadow; -o-transition-duration: 0.5s; transition-property: background-color, box-shadow; transition-duration: 0.5s; } div.line.glow { background-color: cyan; box-shadow: 0 0 10px cyan; } span.lineno { padding-right: 4px; text-align: right; border-right: 2px solid #0F0; background-color: #E8E8E8; white-space: pre; } span.lineno a { background-color: #D8D8D8; } span.lineno a:hover { background-color: #C8C8C8; } div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; box-shadow: 2px 2px 3px #999; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); } div.groupHeader { margin-left: 16px; margin-top: 12px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background-color: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 12px; margin-right: 8px; } td.indexkey { background-color: #EBEFF6; font-weight: bold; border: 1px solid #C4CFE5; margin: 2px 0px 2px 0; padding: 2px 10px; white-space: nowrap; vertical-align: top; } td.indexvalue { background-color: #EBEFF6; border: 1px solid #C4CFE5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #EEF1F7; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } blockquote { background-color: #F7F8FB; border-left: 2px solid #9CAFD4; margin: 0 24px 0 4px; padding: 0 12px 0 16px; } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #A3B4D7; } th.dirtab { background: #EBEFF6; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #4A6AAA; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .memberdecls td, .fieldtable tr { -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; -moz-transition-duration: 0.5s; -ms-transition-property: background-color, box-shadow; -ms-transition-duration: 0.5s; -o-transition-property: background-color, box-shadow; -o-transition-duration: 0.5s; transition-property: background-color, box-shadow; transition-duration: 0.5s; } .memberdecls td.glow, .fieldtable tr.glow { background-color: cyan; box-shadow: 0 0 15px cyan; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #F9FAFC; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memSeparator { border-bottom: 1px solid #DEE4F0; line-height: 1px; margin: 0px; padding: 0px; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memItemRight { width: 100%; } .memTemplParams { color: #4665A2; white-space: nowrap; font-size: 80%; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #4665A2; font-weight: normal; margin-left: 9px; } .memnav { background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .mempage { width: 100%; } .memitem { padding: 0; margin-bottom: 10px; margin-right: 5px; -webkit-transition: box-shadow 0.5s linear; -moz-transition: box-shadow 0.5s linear; -ms-transition: box-shadow 0.5s linear; -o-transition: box-shadow 0.5s linear; transition: box-shadow 0.5s linear; display: table !important; width: 100%; } .memitem.glow { box-shadow: 0 0 15px cyan; } .memname { font-weight: bold; margin-left: 6px; } .memname td { vertical-align: bottom; } .memproto, dl.reflist dt { border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 0px 6px 0px; color: #253555; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 4px; border-top-left-radius: 4px; /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 4px; -moz-border-radius-topleft: 4px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 4px; -webkit-border-top-left-radius: 4px; } .memdoc, dl.reflist dd { border-bottom: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 10px 2px 10px; background-color: #FBFCFD; border-top-width: 0; background-image:url('nav_g.png'); background-repeat:repeat-x; background-color: #FFFFFF; /* opera specific markup */ border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* firefox specific markup */ -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; /* webkit specific markup */ -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); } dl.reflist dt { padding: 5px; } dl.reflist dd { margin: 0px 0px 10px 0px; padding: 5px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } .paramname code { line-height: 14px; } .params, .retval, .exception, .tparams { margin-left: 0px; padding-left: 0px; } .params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } .params .paramtype { font-style: italic; vertical-align: top; } .params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } table.mlabels { border-spacing: 0px; } td.mlabels-left { width: 100%; padding: 0px; } td.mlabels-right { vertical-align: bottom; padding: 0px; white-space: nowrap; } span.mlabels { margin-left: 8px; } span.mlabel { background-color: #728DC1; border-top:1px solid #5373B4; border-left:1px solid #5373B4; border-right:1px solid #C4CFE5; border-bottom:1px solid #C4CFE5; text-shadow: none; color: white; margin-right: 4px; padding: 2px 3px; border-radius: 3px; font-size: 7pt; white-space: nowrap; vertical-align: middle; } /* @end */ /* these are for tree view when not used as main index */ div.directory { margin: 10px 0px; border-top: 1px solid #A8B8D9; border-bottom: 1px solid #A8B8D9; width: 100%; } .directory table { border-collapse:collapse; } .directory td { margin: 0px; padding: 0px; vertical-align: top; } .directory td.entry { white-space: nowrap; padding-right: 6px; padding-top: 3px; } .directory td.entry a { outline:none; } .directory td.entry a img { border: none; } .directory td.desc { width: 100%; padding-left: 6px; padding-right: 6px; padding-top: 3px; border-left: 1px solid rgba(0,0,0,0.05); } .directory tr.even { padding-left: 6px; background-color: #F7F8FB; } .directory img { vertical-align: -30%; } .directory .levels { white-space: nowrap; width: 100%; text-align: right; font-size: 9pt; } .directory .levels span { cursor: pointer; padding-left: 2px; padding-right: 2px; color: #3D578C; } div.dynheader { margin-top: 8px; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } address { font-style: normal; color: #2A3D61; } table.doxtable { border-collapse:collapse; margin-top: 4px; margin-bottom: 4px; } table.doxtable td, table.doxtable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.doxtable th { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; } table.fieldtable { /*width: 100%;*/ margin-bottom: 10px; border: 1px solid #A8B8D9; border-spacing: 0px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); } .fieldtable td, .fieldtable th { padding: 3px 7px 2px; } .fieldtable td.fieldtype, .fieldtable td.fieldname { white-space: nowrap; border-right: 1px solid #A8B8D9; border-bottom: 1px solid #A8B8D9; vertical-align: top; } .fieldtable td.fieldname { padding-top: 3px; } .fieldtable td.fielddoc { border-bottom: 1px solid #A8B8D9; /*width: 100%;*/ } .fieldtable td.fielddoc p:first-child { margin-top: 0px; } .fieldtable td.fielddoc p:last-child { margin-bottom: 2px; } .fieldtable tr:last-child td { border-bottom: none; } .fieldtable th { background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; font-size: 90%; color: #253555; padding-bottom: 4px; padding-top: 5px; text-align:left; -moz-border-radius-topleft: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom: 1px solid #A8B8D9; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; background-image:url('tab_b.png'); background-repeat:repeat-x; background-position: 0 -5px; height:30px; line-height:30px; color:#8AA0CC; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right:15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#364D7C; } .navpath li.navelem a { height:32px; display:block; text-decoration: none; outline: none; color: #283A5D; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; } .navpath li.navelem a:hover { color:#6884BD; } .navpath li.footer { list-style-type:none; float:right; padding-left:10px; padding-right:15px; background-image:none; background-repeat:no-repeat; background-position:right; color:#364D7C; font-size: 8pt; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } div.ingroups { font-size: 8pt; width: 50%; text-align: left; } div.ingroups a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; border-bottom: 1px solid #C4CFE5; } div.headertitle { padding: 5px 5px 5px 10px; } dl { padding: 0 0 0 10px; } /* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ dl.section { margin-left: 0px; padding-left: 0px; } dl.note { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #D0C000; } dl.warning, dl.attention { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #FF0000; } dl.pre, dl.post, dl.invariant { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #00D000; } dl.deprecated { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #505050; } dl.todo { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #00C0E0; } dl.test { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #3030E0; } dl.bug { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #C08050; } dl.section dd { margin-bottom: 6px; } #projectlogo { text-align: center; vertical-align: bottom; border-collapse: separate; } #projectlogo img { border: 0px none; } #projectname { font: 300% Tahoma, Arial,sans-serif; margin: 0px; padding: 2px 0px; } #projectbrief { font: 120% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { font: 50% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #titlearea { padding: 0px; margin: 0px; width: 100%; border-bottom: 1px solid #5373B4; } .image { text-align: center; } .dotgraph { text-align: center; } .mscgraph { text-align: center; } .diagraph { text-align: center; } .caption { font-weight: bold; } div.zoom { border: 1px solid #90A5CE; } dl.citelist { margin-bottom:50px; } dl.citelist dt { color:#334975; float:left; font-weight:bold; margin-right:10px; padding:5px; } dl.citelist dd { margin:2px 0; padding:5px 0; } div.toc { padding: 14px 25px; background-color: #F4F6FA; border: 1px solid #D8DFEE; border-radius: 7px 7px 7px 7px; float: right; height: auto; margin: 0 20px 10px 10px; width: 200px; } div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; margin-top: 5px; padding-left: 10px; padding-top: 2px; } div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; border-bottom: 0 none; margin: 0; } div.toc ul { list-style: none outside none; border: medium none; padding: 0px; } div.toc li.level1 { margin-left: 0px; } div.toc li.level2 { margin-left: 15px; } div.toc li.level3 { margin-left: 30px; } div.toc li.level4 { margin-left: 45px; } .inherit_header { font-weight: bold; color: gray; cursor: pointer; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .inherit_header td { padding: 6px 0px 2px 5px; } .inherit { display: none; } tr.heading h2 { margin-top: 12px; margin-bottom: 4px; } /* tooltip related style info */ .ttc { position: absolute; display: none; } #powerTip { cursor: default; white-space: nowrap; background-color: white; border: 1px solid gray; border-radius: 4px 4px 4px 4px; box-shadow: 1px 1px 7px gray; display: none; font-size: smaller; max-width: 80%; opacity: 0.9; padding: 1ex 1em 1em; position: absolute; z-index: 2147483647; } #powerTip div.ttdoc { color: grey; font-style: italic; } #powerTip div.ttname a { font-weight: bold; } #powerTip div.ttname { font-weight: bold; } #powerTip div.ttdeci { color: #006318; } #powerTip div { margin: 0px; padding: 0px; font: 12px/16px Roboto,sans-serif; } #powerTip:before, #powerTip:after { content: ""; position: absolute; margin: 0px; } #powerTip.n:after, #powerTip.n:before, #powerTip.s:after, #powerTip.s:before, #powerTip.w:after, #powerTip.w:before, #powerTip.e:after, #powerTip.e:before, #powerTip.ne:after, #powerTip.ne:before, #powerTip.se:after, #powerTip.se:before, #powerTip.nw:after, #powerTip.nw:before, #powerTip.sw:after, #powerTip.sw:before { border: solid transparent; content: " "; height: 0; width: 0; position: absolute; } #powerTip.n:after, #powerTip.s:after, #powerTip.w:after, #powerTip.e:after, #powerTip.nw:after, #powerTip.ne:after, #powerTip.sw:after, #powerTip.se:after { border-color: rgba(255, 255, 255, 0); } #powerTip.n:before, #powerTip.s:before, #powerTip.w:before, #powerTip.e:before, #powerTip.nw:before, #powerTip.ne:before, #powerTip.sw:before, #powerTip.se:before { border-color: rgba(128, 128, 128, 0); } #powerTip.n:after, #powerTip.n:before, #powerTip.ne:after, #powerTip.ne:before, #powerTip.nw:after, #powerTip.nw:before { top: 100%; } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { border-top-color: #ffffff; border-width: 10px; margin: 0px -10px; } #powerTip.n:before { border-top-color: #808080; border-width: 11px; margin: 0px -11px; } #powerTip.n:after, #powerTip.n:before { left: 50%; } #powerTip.nw:after, #powerTip.nw:before { right: 14px; } #powerTip.ne:after, #powerTip.ne:before { left: 14px; } #powerTip.s:after, #powerTip.s:before, #powerTip.se:after, #powerTip.se:before, #powerTip.sw:after, #powerTip.sw:before { bottom: 100%; } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { border-bottom-color: #ffffff; border-width: 10px; margin: 0px -10px; } #powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { border-bottom-color: #808080; border-width: 11px; margin: 0px -11px; } #powerTip.s:after, #powerTip.s:before { left: 50%; } #powerTip.sw:after, #powerTip.sw:before { right: 14px; } #powerTip.se:after, #powerTip.se:before { left: 14px; } #powerTip.e:after, #powerTip.e:before { left: 100%; } #powerTip.e:after { border-left-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.e:before { border-left-color: #808080; border-width: 11px; top: 50%; margin-top: -11px; } #powerTip.w:after, #powerTip.w:before { right: 100%; } #powerTip.w:after { border-right-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.w:before { border-right-color: #808080; border-width: 11px; top: 50%; margin-top: -11px; } @media print { #top { display: none; } #side-nav { display: none; } #nav-path { display: none; } body { overflow:visible; } h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } .summary { display: none; } .memitem { page-break-inside: avoid; } #doc-content { margin-left:0 !important; height:auto !important; width:auto !important; overflow:inherit; display:inline; } } ltfat/src/doc/mathjaxinclude/0000775000175000017500000000000013026262276016126 5ustar susnaksusnakltfat/src/doc/mathjaxinclude/macros.js0000664000175000017500000000030713026262276017750 0ustar susnaksusnakMathJax.Hub.Config({ TeX: { Macros: { stime: "t", sfreq: "\\omega", sfreqarg: "\\xi", stimearg: "\\tau", me: "\\mathrm{e}", mi: "\\mathrm{i}", } } }); ltfat/src/Makefile.in0000664000175000017500000000330713026262304014421 0ustar susnaksusnak# Only .mex, .oct and .m files from the current directory will be copied # to the target installaction directory targets = oct playrec CC=@CC@ CXX=@CXX@ export CC export CXX ifeq (@have_libportaudio@,1) export HAVE_PORTAUDIO=1 endif # Disables compilation of MEX files. They cause trouble # with missing help. export NOMEX=1 ifeq ($(OS),Windows_NT) # Removes -fPIC from CFLAGS export MINGW=1 # If OS==Windows_NT, the makefiles use Windows commands for # file copy, delete and directory creation. # To avoid that and fallback to posix compatible commands # we temporarily redefine OS. export OS=NotWindows_NT endif .PHONY: oct octpostbuild playrec mulaclab all: oct mulaclab playrec oct: # Compile the backend lib, no dependency is resolved here since we compile # a static library $(MAKE) -f Makefile_libltfat build/libltfat.a # Copy to the common place. mv build/libltfat.a ../lib # Compile oct and mex files $(MAKE) -C ../oct -f Makefile_unix # Do postbuild explicitly so it is not called before # oct files are finished $(MAKE) octpostbuild mulaclab: $(MAKE) -C ../thirdparty/polyboolclipper -f Makefile_unixoct mv ../thirdparty/polyboolclipper/polyboolmex.mex . playrec: $(MAKE) -C ../thirdparty/Playrec -f Makefile_unixoct mv ../thirdparty/Playrec/playrec.mex . octpostbuild: # OCT files here mv ../oct/*.oct . # Compilation of MEX files has been disabled # mv ../oct/*.mex . # Delete corresponding m-files ls -1 *.oct | cut -d . -f 1 | xargs -I {} rm -f ../inst/comp/{}.m # ls -1 *.mex | cut -d . -f 1 | xargs -I {} rm -f ../inst/comp/{}.m # rm -f ../inst/ltfatarghelper.m ## Copy extra help files for mex files # ls -1 *.mex | cut -d . -f 1 | xargs -I {} cp ../oct/mexhelp/{} ./{}.m ltfat/src/ostools.mk0000664000175000017500000000074713026262276014424 0ustar susnaksusnak#This file produces system and environment dependent tools for working with files #It sets the following variables # # RM # CP ifeq ($(OS),Windows_NT) $(info Windows detected) MINGW = 1 RM = del /Q /F CP = copy /Y MKDIR = md RMDIR = rmdir /S /Q PS2 = \\ PS = $(strip $(PS2)) CC = gcc ifndef SHELL ifdef ComSpec SHELL := $(ComSpec) endif ifdef COMSPEC SHELL := $(COMSPEC) endif endif else #If not on Windows RM = rm -rf CP = cp -f PS = / MKDIR = mkdir -p RMDIR = $(RM) endif #CC=gcc ltfat/src/bootstrap0000775000175000017500000000002313026262304014307 0ustar susnaksusnak#!/bin/sh autoconf ltfat/src/filedefs.mk0000664000175000017500000000114413026262276014473 0ustar susnaksusnakfiles = dgt.c dgt_fac.c dgt_fb.c dgt_multi.c dgt_ola.c dgt_shear.c \ dgt_walnut.c dgtreal_fac.c dwilt.c idwilt.c wmdct.c iwmdct.c \ filterbank.c ifilterbank.c heapint.c \ idgt.c idgt_fac.c idgt_fb.c iwfac.c pfilt.c reassign_ti.c \ wfac.c windows.c winmanip.c \ dgt_shearola.c fftreal.c files_complextransp = ciutils.c spread.c wavelets.c goertzel.c dct.c dst.c reassign.c files_notypechange = c-safe-memalloc.c integer_manip.c reassign_typeconstant.c wavelets_typeconstant.c files_blaslapack = ltfat_blaslapack.c gabdual_fac.c gabtight_fac.c files_blaslapack_complextransp = gabdual.c gabtight.c ltfat/src/src/0000775000175000017500000000000013026262276013150 5ustar susnaksusnakltfat/src/src/drivers.c0000664000175000017500000000446513026262276015003 0ustar susnaksusnak#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); } ltfat/src/src/gabtight_fac.c0000664000175000017500000000573513026262276015730 0ustar susnaksusnak#include "ltfat.h" #include "ltfat_types.h" #include "ltfat_blaslapack.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 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(periodize_array)(LTFAT_TYPE* in, const ltfatInt Lin, LTFAT_TYPE* out, const ltfatInt Lout) { /* Do nothing if there is no place where to put periodized samples */ if ( Lout <= Lin ) { if ( in != out ) { memcpy(out, in, Lout * sizeof * in); } return; } ltfatInt periods = floor( Lout / ((double)Lin) ); ltfatInt lastL = Lout - periods * Lin; ltfatInt startPer = in == out ? 1 : 0; for (ltfatInt ii = startPer; ii < periods; ii++) { memcpy(out + ii * Lin, in, Lin * sizeof * in); } memcpy(out + periods * Lin, in, lastL * sizeof * in); } 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 } LTFAT_EXTERN void LTFAT_NAME(dgtphaselockhelper)(LTFAT_TYPE* cin, const ltfatInt L, const ltfatInt W, const ltfatInt a, const ltfatInt M, LTFAT_TYPE* cout) { ltfatInt N = L / a; for (ltfatInt w = 0; w < W; w++) { for (ltfatInt n = 0; n < N; n++) { ltfatInt offset = w * N * M + n * M; LTFAT_TYPE* cintmp = cin + offset; LTFAT_TYPE* couttmp = cout + offset; // circshift takes care of possible inplace operation LTFAT_NAME(circshift)(cintmp, couttmp, M, -a * n); } } } LTFAT_EXTERN void LTFAT_NAME(dgtphaseunlockhelper)(LTFAT_TYPE* cin, const ltfatInt L, const ltfatInt W, const ltfatInt a, const ltfatInt M, LTFAT_TYPE* cout) { ltfatInt N = L / a; for (ltfatInt w = 0; w < W; w++) { for (ltfatInt n = 0; n < N; n++) { ltfatInt offset = w * N * M + n * M; LTFAT_TYPE* cintmp = cin + offset; LTFAT_TYPE* couttmp = cout + offset; // circshift takes care of possible inplace operation LTFAT_NAME(circshift)(cintmp, couttmp, M, a * n); } } } LTFAT_EXTERN void LTFAT_NAME(findmaxinarray)(const LTFAT_TYPE* in, const ltfatInt L, LTFAT_TYPE* max, ltfatInt* idx) { *max = in[0]; *idx = 0; for (ltfatInt ii = 1; ii < L; ++ii) { #ifdef LTFAT_COMPLEXTYPE if (LTFAT_COMPLEXH(cabs)(in[ii]) > LTFAT_COMPLEXH(cabs)(*max) ) #else if (in[ii] > *max) #endif { *max = in[ii]; *idx = ii; } } } LTFAT_EXTERN int LTFAT_NAME(findmaxinarraywrtmask)(const LTFAT_TYPE* in, const int* mask, const ltfatInt L, LTFAT_TYPE* max, ltfatInt* idx) { int found = 0; *max = -1e99; *idx = 0; for (ltfatInt ii = 0; ii < L; ++ii) { #ifdef LTFAT_COMPLEXTYPE if (!mask[ii] && LTFAT_COMPLEXH(cabs)(in[ii]) > LTFAT_COMPLEXH(cabs)(*max)) #else if (!mask[ii] && in[ii] > *max) #endif { *max = in[ii]; *idx = ii; found = 1; } } return found; } ltfat/src/src/wavelets_typeconstant.c0000664000175000017500000000174113026262276017764 0ustar susnaksusnak#include "ltfat.h" LTFAT_EXTERN 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; } } ltfat/src/src/dst.c0000664000175000017500000000506113026262276014110 0ustar susnaksusnak#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 = (LTFAT_FFTW(r2r_kind)) 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; iiL; 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; int bufLen = N>Gl? N: Gl; const LTFAT_FFTW(iodim) dims = {.n = Nint, .is = 1, .os = 1}; const LTFAT_FFTW(iodim) howmany_dims = {.n = W, .is = bufLen, .os = bufLen}; LTFAT_COMPLEX* buf = ltfat_malloc(bufLen * 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 = bufLen }; 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) { ltfatInt Gl = p->Gl; if(!Gl) return; // Bail out if filter has zero bandwidth const ltfatInt bufLen = p->bufLen; const ltfatInt L = p->L; const ltfatInt W = p->W; const double a = p->a; LTFAT_COMPLEX* cbuf = p->buf; ltfatInt N = (ltfatInt) floor(L / a + 0.5); for(ltfatInt w=0;wp_c, cbuf, cbuf); for (ltfatInt w = 0; w < W; w++) { LTFAT_NAME_COMPLEX(circshift)(cbuf + w * bufLen, cbuf + w * bufLen, N, -foff); // This does nothing if bufLen == N LTFAT_NAME_COMPLEX(periodize_array)(cbuf + w * bufLen, N, cbuf + w * bufLen, bufLen); const LTFAT_COMPLEX* GPtrTmp = G; LTFAT_COMPLEX* FPtrTmp = F + w * L; LTFAT_COMPLEX* CPtrTmp = cbuf + w * bufLen; ltfatInt Gltmp = Gl; // Determine range of G ltfatInt foffTmp = foff; ltfatInt over = 0; if (foffTmp + Gltmp > (ltfatInt)L) { over = foffTmp + Gltmp - (ltfatInt)L; } if (foffTmp < 0) { ltfatInt toCopy = (-foffTmp) < Gltmp ? -foffTmp : Gltmp; FPtrTmp = F + (w + 1) * L + foffTmp; for (ltfatInt ii = 0; ii < toCopy; ii++) { LTFAT_COMPLEX tmp = *CPtrTmp++ * LTFAT_COMPLEXH(conj)(*GPtrTmp++); FPtrTmp[ii] += tmp; } Gltmp -= toCopy; foffTmp = 0; } FPtrTmp = F + w * L + foffTmp; for (ltfatInt ii = 0; ii < Gltmp - 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 = -L + 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, 0, 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); if(p->buf) ltfat_free(p->buf); } ltfat/src/src/dgt_shear.c0000664000175000017500000002056213026262276015261 0ustar susnaksusnak#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 * M_PI * idx / L); } /* const LTFAT_REAL LL=2.0*L; */ /* const LTFAT_REAL Lpone=L+1; */ /* for (ltfatInt m=0;m

KT܎y%LC ClkBHdi`voLs;+Q#2NLp! YW"o$57&mp"UA*A U2(K,d]BhuY6ŒIO`T0p5a{.>61*Oa_]Z>bQn690^P t%qGcW 7Ш<x LEd!ZE$]B4 `Z|39(K5nϤHdśu|ѽF TP@TrLrX9ȽӒXrb̬ A)"ɆQz, %J.Ū˽Èl4i$,c,Hl"0XhZ[\u 6#K P[)#y)ۘ~uUrq/sjz@,SCI@yB͔qL/oo?O; oؖk`4Ȩ jmIF3+@\х:1lQݚ7(*Y6%JzkP5!)FSn[;}*>~gXx~F660/G\Dž؛x@S(aU>]J)UV 7Wl' BV2o'?ư%t y8a$nMiwJeѕ1=d9u2]jaJT*ͶRz@9& +r-B5 t \!H!8ToGo6YR`@>zsU:ulc$ {̥v`Xvz Lu1Oɝb  JR۽Y ?)6n,UQYaBGTх2DZ0nA% |;D& ̈́S RL,CNXEBtRܶdBPZ{RU` Rj J65€t1VǞJ"~Swə.i%%Oo|7GLפBLٓI3+gfv^W ̦92ov*;|`!b(v% aFgͱ0} h#N rGs+_@ l\brNBI2Ѭ %N7nvNBq.da *CIZ .t@xO(i&k^@5S c29`Ѧ~_~1f]x~_Yv.7 y*!B4Ho9r?64axC5;)LdԪq cCW շBAonʮ"0/#@W~` ulK&7hS&&` Pr\F1XќsBι=|8Q Yb]R(ULfH/_H3T`_0A5A0My[+ބ1Ȑ6hP}!PzaI2 yR.LL^^< ,h#YLyytD @5bIu*z A ˤ΅ϯSOç#w<k=+W&F`0@B{9׍{:bI_=ģ0(ՙۙ1APxf7#_qІǃ oCÍ Oo{ o4x?xxj.NDr\wB}UGe$`:"BQ%HQՉ͑w:uχog'ȺBٯS.w#e@0~&;!𖝙kIyo| 謫fYJѠ]! F %;{G3dS.: H]OtϺ aìQ+eWqji\m ~ <;yYcNl\+_-|s9Pwk+Z˨bAhXѮyҵʕ}g\Vf >]ܷt/C頠sEeݩǬ0bBhx)D8$J_go~}> |~ïk=>ǟxk3!Vu6"ɝ` HOQf.Fs̖цQIM,3Q )Ly,%\o}_?ɯx3ǫ5/WwLq\ ٣]ܩku c LVm)pa\ig!&4 t(:$H T!%N>AG_}Ϗ_gԋ~כzޣ}xp@nAU{&,J/5šlں4TOg<2lkܜ&!1rj@7Iץh.F,sX=eW\23SCEߪJD{WC^Wz^g/ޕ~dž2Ud+:-fbֶP3)/a#A xq~Rg%D*N|4e# 4Ed߽nI k?oڿz?kׯ~H?5Ǣ~g=l=|owJVRT[+ D WQ/Q?-%{4F6pRju$Y^{D4Sv3; muJ]˜2AFIzC{ ൧/oҷ'?'ևo/]Ԁ G>ג/gHZӖ2qߴ Le]\PLtU/gr}{m]h"f>$ڸP;5qnML'P喰kQ:Ԡ`ܽ N~g_}H|[ PCD_C쵩O[Gs=?'~:~/3.W ߷0Umk7y<]da_`S ͐k32V:("]ʼd5&Ss@ŽSt ɺ|_ٛ IDATy8Kwc'e &WHX:++Sq)&Qt'B֨FJ 4,*,0P+֧!&sgq>dE:*_t?~k{?E77#¤]hnEw$UCq`K) jKB:^ijfP !?u 4}w|xC==sxǛyk@⇿w>x|ן?-̤j΁!ÇB0#2B"övO ־ѹf G,x?X9΅Duz#a0}LQ&*;});}?-_͏9/kw} yc?^3?o|y>y |U=7VznSp~sLj V:Sa ĺsmnthR2}Q:.3ÿa݃-;oosZlY~cg060I%03L&3@  j6lݣfze%DM`% {AVʵG@ 0y?д4mi}xv,?qc9/ =$a6;n &(mM.%DGKeLcrŞ-r-aּ.<*7L٠`ސi\hfp!dQO4(VH@oy3O[h級*ybș9zߚ׽W[+Eͬ6 _Xvb:ǰkP<>48wҟ}e2 v'޳qݾqvx.޺sD@Af M0Le3.  I\ ' s0!9ƹ>[)"$8uE_ݽ{#GOx;+Eohq~%^|kV7^o}A3QcW3YEnM0 DCڒJ2Z԰u SJL1dƔU4frM#c>Zz%"$CGGoɇɝsoz](|5kEx<̻]>]i’>i$@8D$%L ބ,iuw9g2[ntA a4\ygf`i*xOy}#(5/:Fc D{=h9\+WU&b#!6q$C0.EwHLtV,D CQԀ$ U70i(ot r0i0o)Q}W.וild @#< 4g Lkp3=:ֻ_+ex(Y4Y7 TFuk2,d"Z7fj4MxgGNVi0<\FȷGH) 0+E3`[̀b0'7q6yzvG2XlY4uфs RN=#A>EsL +tv?Id9@%IH@ i_~rwN"~5ЭTg;嗞zY>z-R2oNLfT&ʂ>xf kGp4xqdEti.+F{#Җnj0֯?^t bI.sH,@|Ͽx]Ǵ#[Q /Kg;{߿>ڧ Vh5S`O0[3[[iv-*m;s&4D’@$M)=;jLCD(^* @# B\A}8rEk9qxxكfk')5zq TobXH.L $dnisSҗLj+7m|[?iWd F 4LrJe (5 s>u^_Lnݟx Nr+mmT=-W'nlsKn 0&Ai8;(lBE]2d!mܘjcؔy b!5Z?h˙U.-!tL(0BL|n|;9?zۥ`ē + 9 `& hdH1de::! և6 ΄oI|K::0LZwu#Uz*js=ˬ_.gow4<>sS|*Zz9|9{JSwg >z554#a?@( aTf$$df K[,xeꗗ=:kBY^|uR ]*u\Eda0yTE>L3eov2݄eT6)$+`Sz'{?\ZKog^|dw<  8Yٽ -+ M-a^3舖#1WQ4$EK$? [z'JV%@ 1'Ȅvti =';@N_щ)aw0הN$\JV͵- =M^x1iYTn: N%^흳@cv{B,(>R‰x"5'U75.!6m5|}KgD[RsVD[`"3R`lfTL*!ÀHH\M60r`,[B&3h>s*>3#2@*,m[ 3#͒}Zc*9 ov= s?;K҇qD nck dkp[Q2O9x2|t6 ==(kPګ>XziAi;*p,DH2.a$0%ҦGDE}O{西?]+FN}2傸WlQz2)Y&$,ݲWF뜳ʲvToe/Z+]ijކ+0UF cKj' $ CHgV }{_93N1?mJ8d'#M%$2;Q:_!d]LSEH:@#HCI֒,d[veBܣ%K)RBiA*J|\`[$j {N?8S$*t"Uk8.Uc@ *G`+{ L/qL0 aMl0UtCA@01*::¸^Khf%o>Uc p3~ Y\|~sH*3RJfH$'S"E"ZGSjmDu3@Z0T "S Q`-A0 C3#I6+(Q_R!Uā|O/^Y!DPlNB@}k d],6Rspht63Z%2&SöEROip5y.!%X9}G)A-# hi@:h\Ujg H{W[?A|悮etr%duvzE%.n GZ9{-IphP{ϡ:#]*ߢxVfD9"!6[N/h1)Azڛۣ]ю}I B8m0 2&Ŭ/JApGaFCKNe5 3MʖH'c $,A*KuvY7 n^“UBC 7[uӈo`aP;h1}F)Ri\*.7L^d<97zckNVr-cO2iY  +2Ge&$Ybu}{`ܛ0a0pI]kML̿kN=2S#XAxK680mFTbT@fFu ޙ]A[?%Fʚhތhp7s6"W nTcpsv%P<@$qhnhfC+ Ud&N{y1R{}mO AՐ! B Df& ؀)PHD ҩꐘiїfRoPH_odx̼> V_а{ʆUD]!]L$aԝ8zYSN&9*4u&R)Mc2٥ڵA]BPggZ!˫F7hRN\"R2 @s~:i{˧qy n$O|yrիDnf9HVYZUKRzUfdJb)};[uЯ)d,@{~ƿdVhˏ0TgO|9>7[/a2.MPܲRx+O~x{펒 a9!,ΕG_[W@ A x`@-P1Xڿ}  mJQo)a˹ҁ^*$¿)3f OHxTS3 ?q׻\A:fe[†ɦ#HuJ?3=WeCoĨ3j n`m0edeLKLT2 fY!ӡ4H3e 0K?z$; (1A5θ7#$3#`Xɿ1Փ|^π^<<ʵ-$)9"} jG`hY9/CRt5 f"AZOD TmE^pĞ.B^YRcպߠ%Zrtk{Ԭa EwJdX ˄(ĴJ ږV1.ݼY%aQbeW8VFzGDRkv<CzWJ-0%)3O;ޙOFu!.f85* jTɝ n&$)e;K%[gYb @!.JTšܸ$6hó _@'m.vmY$D]N!,$AyfYB2LӛDueȼ'2o$,(ϐ"kE,_tg[~⩥ٵQq=6huVqIʫ@Z|p8 -m3BPl6@dZN!'nLa4!dN PS.79 \ڙJ{iqEPڶ;]z\z<ēp-tM/)W3>FIh13Y I7sIECU됵n(唥5)l-tkXYVΏD q mCZP~dUYi2vN3b giamܻHi=O` IDATRE(Be4;=Y([СZ$i4G`[IiAY‰QEJ%rGZ>4Bm Sj_O_? K|h,&̿c O賃PjSL7-#: `CHr 3%Ҍ`i |tھUA7p8CF6 ?<1lYW c~%EdK03)0lq/W/쓉PI#gML3 KC0yFy؀gk#Z2{*T{ xIǍII )Tm@9a9widc-R.ܧeso^M+_IpϣΩcxǽɁȲVUS봤ϵppXV0HFQq׺fJh&0/(3#%7 (< ٜ޴qnp+#S>Z{ҷz;WZatZ2K7-%R(yHV:*UJ)+}s?ahag-pcgKu%?/@㛠 P>ʽ;neLE> W4㧯xX+:z_,FqHb,h;܀QF* jk]hLSt8F;:1!$' )D&!CB/}p=,Y_;;qEaEf8!}эgnݾS.jpg!GPs!bIp-7xq=ѓ9~y{GXhM+.h(y7PFUhua\ ȓn\ 0:#(GJ(K ͚b+SdCRPS"NVxzoa0O5D#H~&J0 ?Ƕ^ϊ#ΌXr=䴽u%|ud_=Osg,̱>Y/[S~cLt.#A6*wsȕr wҵ-7tCdeB('Y2#* 4HGeE|T~Yؚ_2Jϟ>7fwX1a4 eNO]; 4Gf pHW6&smt#3RFE[72ݭR6y+zYr&,3-Jv󐉖NHdd?| x] PU=GYl+<_eDoߩ[^V<2)1o|F힫|FFl6۹ iJ"ajZN5 v? !VX2/0Z.݆*f64ь$KCQle#ȥn8vʘBql~Ϗ{;>L-]Ѐ_|gS]nKE}.tƹ {\](=s^NRsAxW/oke?Mu/ydv&څ Q_1oK^pi2IРؿr-`MйlG+}}a 8Q8}߽B^`qĢHG=Rj4d 8Wh`(By`è%q$4~L2yW/(*A G&L|ډwq?|+0dr M :ŗ3݃lT\9$)-n]Bi2)Qi =Ƃ0s]*z)a $ k7&6MvNn18#]ۃɄٺ5퀘ih J!| Y۴^BQM1Cfs" P2yz\YtyEX_f˵o\H 5Dv D mԃxt΋>SgtOp9Iд]L>9HFIɡWxwyx,W;1xna} :˴S̨eIukxq~ \> U?/LZZcqś^ӯQs7cn6|w~hj'G1)ʕfnI4lm9K7̲>H&0mbvډq\-%]{Wqga]gY5NZSנkFWP"pnٻB艓peAlRR;^J4F7ev8mN$ [3c:lVt1`}WeD$hJ] dQwzg.9.9v0 kkg'W3O=sG9O4/BdRϊ3"}$Z# k&)]H[kMY|Pك̎ʹj|B ʍ+i;I`3$̈yΖNpW'܇QPi1dfFȆF)9YɢáJ( 5,dRG*]<$t+קlt֗HZygȇ-l'؉l#{a ]lf O!E;tA6mvcv*\JYN]OqZ]0?8<ѯ}1Q.[PZC,waT`~ 4 =ߋgm2̫@׎Mg_qξxVve3튉Lv`L@zfVj'l\ }"Cucgz'\'v;|@S?0E a"/_꼘 VA5nWN76 yҼsjo# Y6:E-*]hLI&A'i] m(o]>9v7(G<--.-|[2R|kvH|oC)oV}r;7N\Cػ^ЃuY"btS?<wb;0VFGzO\;+6Kf>ϟ؞{'{.=xKUs; ,RεvH*e}LzC7f/.{A浣Dmrw2slڬ6AqCЕ#~ll>jl=fnW=Wy;Lgguvyʭ鳳\J,*d˖ H ,J$IJPlK ؁%,#@X6UhQ)Q,.Wݝμ_o{9p,g;yycZzL_$Qƻ :!@(Ú4 a2oUؿiaR p4"9D(]=wƇt! 3!BlcxbsZV$$ZJ "BÍڰ۝NqW/ƍW︫~9ͬ޽ތ*>Zr݀8&E^" Ȁ Q٬w< &͂MdhU2=O?A%/XA%Xj30h5"&"E^X_{WO"?>:w ` }v H 򙤃TE`rRCx_[4 J d)Ĕ3ŒYbM<ζn`u8=`s1#+ fG`?ܝdbO} 0LtY"^6r1p%-? *Ƥ|n%;ǯ}/s?[sw^^V?.&B~Q$N JRE|ML⁸rMMȦ_P/9BtGD '=x:'%<׳#.^i$} bgIVd(I>2d#/7ٛy71 H|իah{hbDzH@iWdEuwQSą5 6 @$=T [Mk)E  >v)d}cQ@0?\lbNg%9S}\=>,ŴQi2/~CϞB/& tꉅiUa`Bb G!A{c W {7 Eɯi!DAA,`;[q) EGo w^{>vs(ς?|P2*IN_B@ _zLt 2Fxp AaVOƢNM %:H$ (`L簮K=QOk!\w7g,%VH&P's 9kB#?Ÿ g@$<=c[hrUH J,&-Q]|^u.BVMViL;]2EO=H(ԷQmZՐ}|F'>Y/h:nP6>PHK°JO%(W^6~f7ja=HDRۥ(}X_DaXqdqfosYG2{ixU}XKת*A賉RM"2ϮBEa K/P=%^-Ƿ"B D"dw|ݝ7^SR@U$Q܈( sTi%¬ڭ*rmN@v&_p"8.g?^$|eVS'~K.nuoɇtFsۛUu6A6d+v!4^%t' 2 QC}ڇ?<KoU9ˑ%Qz R*[ W1ZEͺytG2')1X_M(BGesC2~N>T6{d4m@<^.((_mpyvO˪AFD}{@Po~aovYA ؠ)=tT!es. 7ل$iJ7H lwSYO -SG"q\Ay@ș߼5.997rë;Nn\>@Q KPI`& (-7>_,`tE%GJ 3}l?:9w`1*Y$k?mׇ.A%{`O3"eaݐO'o8d?󰺳Ѩ]/}rM] kItķk55xw?raAMKSΠj1p"nBDz kGqY)* P~ "q qө߳H!^!\BCn/:W3n˭Pg}['/._:w{~["wNQ(24D LmgL~ c/]ӝx7K.@3C (I `VP/ʳ˛aϟWջsv12 pU&+|jl/`].ژj}םF7{.,+aeN Q݅37t0q5,p-L-H,ʄ-W@Za!<=YŷZ Cpuk#iH{_YKx- f cgͿ;-O􉋇 €_qLdwobwzɥZ|>cJNA%4ǸJ[[q5)F#qXA!G[CqH)|iJ/z{PNu;B{0tsnod|r"g[!==s@m\zb"hAa~{~GmO?8{48V]GRcbHN`Ц!$q8艶DP`I(F7.jb:2,gns} O{{]@oQU"Pg],RjQSvaHk>q7?o=O^{4)c "Y kd3w>Da@Bg!: Hb" X(BX)85`PP{.#$+ِ 6(뮎,H(m<ì%!Y]-Mg~/ R}p PY0?/O31 F8>GD!~j! )(P@@ĀbDё@ ޤ=W9.\^A"{uLt3L c;rGs|}pThC ҈ /z{WH<JaDD$@H H,G1 $GǪB)BTD6{]zNg#Bp:%5H B]@y-q i^m> @ ر@-䗾O@!@m#1/OSĄ11 h# F-U,QDA@BTB8hР% &=`ֆO$fhk;J`mسr aӦAD-Inwe-_}ڲ/e9"޾?/?Ѡ1DՆ IDAT2D䝩SǤq C%(1"DapĬMV! FR ^xtU{ah- Ubn'p~*Q1q*>+@Kq1].'cGA{<@" x7yqػdlci2EqDidp\D:u h6gol!`}B }ݩFW:DgB <_P3?HbPF)  D>?+ Щb$"|8*7QI)'As0+Š#V'APGeHq&@jOwqzYDj9Շܵ WyX;% b `<O+{_K_|"x!A};*z FH3|AQԂ5D H@a~gROm{&?u4(ާgP6XQw6nvg^zUfH+ wF1~vR `;o `k%+! XE pزפm@1o9Y?rτ7r?EU[Ps8ƨT|>?H`Cȍp ?뷜BdPFp^} j&M FX)x4Z(*v_aS2zF(TEE/DX#}Y;ݬW 96}1_^f҃G( (Cdɀg@r?zM -QbVNsh"<ok #G r4|>(JCH ELDIT1Z+ˆRCtit]-]Df%J)xEQAt޳)!~Z_n﷮v 0O}c5 + ɂs?]k=!p/,Tp0LN? b !m+FACTu1ZD=.f\O }{#z*ry;'D1JD׹9xUF#fd8'~7( :y3‹͏0#ѡUFU+PlۄBQXSeH#&Dċ$Je ZAwgƀ(vg_!V OhoBӖC SANLN҄Mc&[w@`T ZrjBgm-Q~!iې&-=d} y]81E/~}c]{X@zɛ2)<0 7'.}nrD[SIk `Hb.bktJ(ψ h|Orj*5RRj:-bN^Eع41"6Si(^fWh"384l7/gT\NQye(O}#Rv:Ġf2c*:8.i+j21(?iE§0yY4>Oze6޷@QMA!s&ϽaWQ5!ڰdDD*ѹ A@Z>cֈ8 Pր M3'K3W.8s ,KOZ#C6 iyh,'~N<6@ NqX/jj|oV"2ʌłɇjIqsHE%Y"}3;ϩi H5a$İ%%-GAQ~F6?bol  A|Ďr2*C D:T$FW/?g맾/~Tu>!ĝӕAAB;)( dmH(O A#mͩAc:D:ssFe37kL{; 0"{6@zRe w`~u߹jxvcφBs q`JmU_{;.eRF5Y :Q6 { Η:oHGMLɸ%S2elb0!FNCm+OEbEQ 3Owh-ԟ=Bt6ӾIpFbl; B= ma.KQK$M]bab=o_qN?hjF2ښ6[{5jJl] ;nשW]f&`4su;HD`s^9iH,OEܿ~ʚ_߄kPr~EևdNt k|-\ՅM\m^8.@18h%ꨟ?݇eZ]y6NF,!wA1̈́YؒƉ)FL$IBR]TdK+ULBTmLED:S.O~ʉ ^$!;Uxx,3s4V! ։#! cyXmDe/zׯ|v.ɶkhD!52<&MD! MJ# zr4tD%lq^A)kMPZFzm?2᩠Ai6 zp/0~?*R3oIdaUdX꥕ OjWf-Y%WrϿגR#z\A]RlMh.;SYp$]@`^A!W'U*1joڠj[}N\G*QGSeЕZiݺtp.#+:qm17mbҍ+q9܀7|"1b/_7~{xPIk7*G Ve.lQ+Yu*CB}-t>WNʉdԋoW ҇I€ozۤmҲ_槾ʏ/>AR$vY5R$\T&.7$֏n}̰ f&"֪a[2(A VQµKd"IqlH](H6 bP)aBJc[9iNAqP$B(W+&`)WC5'ŸXsvBk-yfxV1C*.y c۴*J]_;>y/~ ΌZp&.؉_.Vޙb:of#[3uJidq6ei@U۷XZ2(Ekk`zT>v8qI.]WzƟ=?%yPi=#%$PGPElrjFɕ8WyckE|nЀWtshJTֳNE<@g0v 8a:0ew ¦ZPF7B U4 l sitw2a5aXo֗0>2 D I~]ZgޫU`T>GuSxfr8Pu6ؐ!ƕv~苇*xXPA!T-À[39oeTMVbSE'c4i A>YA1tJpI(3޺F Pa_ˈ؇ 5KdRgN _!NueS&K%EJ ԫ& ZmȰsOTdp*Y*w:SM+IJV:Nk~c$SZgD[ʚ27.ns\/n~4Z+ۘhH!:êda".g8:4oi}*Y䣔w3g:uXgn2ܵ#4BD$/mfuom|on+ @jغ :LWS].b7ۉpLvTS9雺ml|'77ԱPK((~MȽJ :>LO4}r&g'owa/[MtLqŨ2x^j6RZA#;Pd@]ݙ"jңdtݦ eJYk2ɨ3ԩ8#Lu֘ƴrUM/K:"aj2PIdDH6%gV=JqpZNٓ{+{4(4"I,i^ZߛWnMvb禫ai}8Vrr^ݐlopS4Aw6F.H;;GzWeeƛhPY$-Ha3aFgp]ib0X6la`.fauYAznVbWW2D|]éஔ,7xLLvocsӧ.5wI}Hd&gF%+;M1oK\s g͙Ý3Ã397+7vu`b[y‚O(}`QON\J6,z5&& 0n_!yt"CQg٥s&iu ޴i?pd +ݼcJա/W2yk9|jyݴxbxK-;}| ^9w9,̓2 eRszeW|4p0_"iۚZ%pJEvf9@`E@CDڕa 1ĒB4[ۭgG]=_`}~ÏL9>rs_4K͋Y1~^A!Uf37]Q=nnn5''Eux|'Ǘi5٘Jwf*g/=o a,n7Z8qk:c5,+CH"JaEௗ_YE J)CH16I~Y[,#1/r='|ۻA 8Սdr< .DdAq2ef[ՙT,%ͽ[/?K߯aL,jWpg p]&PQU7W:,lh:mC; ס[oOΆT! *]4CֈiQeDi-|ZU9|n }k1 jt.ծ\JQ6a"@Ͽlޔ"cZ҉!L*ElPtH!ϦCxX3n[t~n6o,Գb6?=+n;L (ALB"|x_Ye@@0[FJ$]`B|'~/+gs+-{ MIwp,m6>jۨD-ŸzWLIDATb,j0.P\M%hΆQ7qEOp6Q]r:vȈRO"yi9"wݸ]m]톺7¹Q8-޸|R)E*2Qt->JLj D|xg8Aďo,駶>ަ lΕaX`N'YSx*jmR<$`Lhy|fmhm͗ti;Wl^d:݆1Tq^luq1g+^nWwn;pyËt9&PN/2B]Pq֑1*bAݡޚo lKFrUXajzuЃbujdJWWwr\ gnizK_om('LzGB;:ZloLfBz_7uPڝcۓX,Մ3MJ RIƄ t^LujQpH馪=āܙA8:Du_J2+wf纃>CYGٵ L99;Yn#8&= {j:99SZCo_bm&/ZH(qUw7wǓ;8)Lzeм,9R߱X\r}z גdav9wuk鮪gz8P4-ɦHl䡂  "Jg8kOoUյ};p1>~ ^Y*C*@ehTgB/WI+q V ?$} A}Kj%Rm*3(iؘ'yqq631gW&,^AEVxAR#9M6i^'C*F[ J~КL20-;~iDX\iβrn]z656IOf"ϓ\HL@ bT5y|`gшc;kO`X5MOv^-{\$冬^,ʾZwb1R{|0m%^z6xeoy-6Y$%ѮqYǃLׇ HB<Տz`浪3_6BI#4" jerwAe\h 4jMTS!7~Gm.|nB))=n5*  (K9q+ `⧪8vy{|"P/.S&Bՙla-jP LƏ݃fE6#ۈ2LbitVrmck+`g:^Z)4eĿBH3%4 T~W@<4y;eu,U_nx/EȸcEvN:-Fr"+(++#t$qeQ_]r-n^? >idW0ֲI%g݊HT}Tʰ+t m ' nxGS+jP%Z l*>><}C-Hd P`dtJ~?1b3fʊ֜yb1D 'jՑ.y.raF;݂)&d=mIbt<1LiaR73{Mg{ki3$Na*'TLSR@U Z65:oBBH))!;Mf/y8N^b'3¥OsA~9ɑ{'Rd[l.A.Мmx AHul^$kFk'Q!TS8DN+í}EWcr+ 0@Fe竤^;d*hC,j\+?.v-%sNp[30ok� ʸ~`-9/eBFcW榘)7|44F,\?.3 zUt&2om0 n, L}=6ho]TF :σæQP @kcwW¾^c,P5iwEpj"iԶ)@) (+Zmv; j0Cz9tmMV{m-p/n7 &װˀ7`~gOÆ-RSy7j!f~Gf:s,.E-vFDnE|:#yLEr r_pI #`awqLzSB;bv&frSLw R. ^64^$x֡ [X4T#j. a0.ilwoqj?.h%.LE[Mۥ~v+M%`iExwӋ]v_9DS%fpU0Ԃ2B*m\.<6&MS5ࣟqsظI:2oN:UHa?w/۾=vgX-/z(No|/nYIFFĊ!]lfZuC,[xvvm*6+Q v5ۨ{ A8;Wŀ;kZ^YKjj%$zJ΅D&\Os޸Oi V9?<2߬#L{90<|uT osL]qV VnȌAan/!}r lX Gv S6Mvj,\i'NVx+x#_r@)YFO-]h?0JIePBj}Q(?֛޴ȲS} ̾E^Mlu/~ˀ)ou5 &VNq3c_*CzȶfV~mmy9U@A?q}qw}:^VRֻsUlZԙeIĻ/kWk)z?mܴIJ+}<'@(Am- "D 4,|XplEʑZe۷{΁Ko{큨`9 Vie\LqU=ҥUW;..*)+uL):^Ab'-&𾓋"%cd9:mΊk}~ݴ"Ottv SjV#@@׎㏍ _hNMA6_nK_FiMAlWIaWcIcN*G@cewx{xnP^FC턭 kPi~}>2ʲ6wu:/:壖å/mb/l #e.k:/y.uvUe&Ѝ09SlGi5>YAG ͣw{`ݡ'J J\M;?o|Z${rV\a+q,$% F2q96>ZgOK<|̿잢?C(*4X1}v9 ={68FUY)E*ޞ˚7fsQ:3-Π:&8zZ˹d^dKKٓ"(y`ja0;|%>٭svqHV145 8A 'GZM $R5leɫ uMZ.[Td5vF3w1 $?vtj[6ێVd'DF7ɳ\K4&``r ~3R;WYTACZ1k{-g_aਥ)0?_T}*Em3m;R[bJI v;}/bl 7 {kDJLpuɽ] S f[޳;|Xv`eM>Up~uTk`سaYٯq:&[kYԹfMg+Sdx% ݦp֑,G)4_Q^! AslI!IENDB`ltfat/inst/signals/ltfattext.m0000664000175000017500000000323713026262303016400 0ustar susnaksusnakfunction 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.github.io/doc/signals/ltfattext.html} %@seealso{ltfatlogo, dgtreal} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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; ltfat/inst/signals/noise.m0000664000175000017500000000654613026262303015504 0ustar susnaksusnakfunction 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.github.io/doc/signals/noise.html} %@seealso{normalize} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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); ltfat/inst/signals/cocktailparty.wav0000664000175000017500000261271413026262276017614 0ustar susnaksusnakRIFF WAVEfmt DXLISTINFOIART James Hartedata                      #" #0/%& !)-&&))0(/('+)'& !#*%'" "#$"($')*%%#&*&''%!'')+)'&$'''&)+.)*%(")"&32,)(40./*,-,-%07362<38/2.43020/1,.'/1>/2../+.*.,540*631,0*.1*2))3'0'31=435.4.-(-(/+1,3---))775916,612/.3031.-0-./*1,.,.+,0-.,/0.,266,32AC<4/12.*-+,,,-)/2-21,+(',('%)7:+1+100<C29.4.7/202414138:55737;769677;98=6G9E=@AD?AFBLBKNGAF@BD>JEGLSCC>A<E<FBAB<LIDIDCGDHFGFIDHIHKFRa[TZ]RUKMIFDF@GDGCFFHCIFJFIIROOOMQPZRXSZTRQPSXOQPQMMMNLIMJMQKQLSSTe]WYRVS[QY^ea\]W_^`aZha`Zlb_^\]ab\daa\c__bZaZ\[^\ek]i`b``cfac_fabda^^\_Tefe_ca^__Z[XZYV]X]\[g]Zllfch^b^cbfcdc_]e^bca`]_^c`_tvoigg`gb\f`bba`bbhhig`dg`dfndhlgb`a`_]\`Zaa[]\_``gbia_\]^[bc^bVijab_]Y]`]Y]Z_X__`\_XZ]ZZXUW^]VVXSUYVb`c\\]\]Z\ced\h\`YVVS\SWLSKOSKN?DEB@?@::>4:58=A>656:48:9<<:??GFGKLHMKJJJXRMLLQJKROOSUMUNYVSQNQKPKNLNKIJLLNJLMWLNOGQJLIJQPINMNJQQLKKPLMGJFJJLZTMNGJLLBKCLDJXd[WIMILRNNJJFJIORJOGKMNHHHLJMKGGGDI?KFDFGJMPSIJFGHIFIM_QOLKFEHHLKRROKHMMPIOKLNMOPLSOWLWVXVbXYQZTSWSYV]]b]\\]\\V\XYZ_]\aU^Ubaa`a^`_dhg]g^f[ridbe`_^``\af`fWaZb`\ab[`^]^]baahcccdafdahb`hcjvlikgjlkrslifniiehdcecihdyplkenkjiejjponjnkljjgigefbolgejjdiivdmgfghhplwqoooqmjmholkmozlpprsjqmlgjjelvkjejjhh}lrgqpqojnkkflefilgfl_fd`a__[`X[]W\\_b`[a]Z[^W^X]Y]cYhn`h_a`c`]aa_\_`Ub`\T\VZb`Y\\Z\\\[ZZ]W_]^\`[`YaUbU^[[d]ac^[ZSWQUWTaXV[_YVPVRRSORNIRLPIRJRXZPSTcZ`\^[ZZQVMMPILIHJCJHQKQKSNUOYVQLMLRNNJRQLURVPUSRURSQNPMPKPGGGLHNGIJFHNJLEMFPHSJOUOSJNONONOPTLOPLNMPKQLMXUVSTRSRVKTQRLULGJFQONQLUKVNYWW_nf_UWXWVRTQPWR]U\TWOVNWPWM^S[LWHW@QHMJPLTYPYM^V_\YZSZUYXXek_]V[VYSTSTTRXP\Y[RWQRPSOT\[TX[VSSVOSQZSVUS[TWU]SYWSZW[]VVZVTVW[a\Y^Yb`\]]\`]^^^b]_\f[cW]_`[][^[YZ[YZZV[^XZVYUT[pa^[\Z\YYZ[[PXS[S`fc[W[_QZOUSUSSUXRTSWYUXPUUR\[U\TZXW\V^SXSYUS]VRTWVPSRei\XOXZRSOZ\UUSPPMSILTNMGOAQVXMFDFCKBD@@@=E;G<EEB@<GBC??:=:@AEPIB?A@BCI=<?<;=9?>B=>>AGC;:768:?H>:963B@6/405046&0,*+-*135/2.2*+++)'972*0%/*)((*#&#(" "(3:.,.)&*$/)+"+(*(%$$$"1.,'$$(!*'!#$" "/6$"$$$!"#  ( $ #'  !$!%# !&!#'#&&%%*(+(*#((33)-*.0$)!(##$!%%%$"+'%"-+&*&-1(. ,&-,,*3,,02>://*&()%*')+'&(())+&2,*/3:4404./0/-3614343:58:57343312>8;4/513GC584/21;20-/*.*1(,*),$-&6,/*0*0).**10+0/./-0,,..45117-3(548/F;724/34/7545880/5-3-1.A8412-/*1&/2-(+,*)+++)#())%-$)+ '()-(-&-.1/+++))&'$#/&(&)"07-0/.(()11..0'.&*+()'3+(*',")$$#'!"(!%&!(&*&*!&!%"$%)"!+#.!+,*%&$ "((""#,-#%$%*&'"$(*#%!#")!$ &!#"$# "" ! # #,1%#&!##$!""."&"%$%)%#%")($**($+"*)'+'*'+(5)7%-)+-0;8.3,3-00.)11.5+01'/)+++-(+++,'+'.*1.574DE9710020+68975835+9A:45/=6::8858297=:5<84:9<<;8FIB@K]IHD>=8:<9>9:9=E4<;?8>@?=2==?NDA=B@B;AABBFF>B:E:>;=:@;<:>B?KMRMIDGLMGHDHEIPPJJGEHHJJOIMDG@E?HEDCFDDBA=C=@D>AFC<@9;@=A?=<B;<;;;94;4863:38768=;52;27344777797;696774946040151406207-35?620A54-/3,.,2411+273*--,(+'((!+"-"+!'%!'&##$!#" %!!                           "'"%&(" !  $! #,'(+%($$&)#0%-$:5,3832-,..44083190,+/(-1.4/4-+2,14-,)*))).4(0).)*'-++-,-/1*(-+'-.+-/0,..//.2)..*0+-*1--'.((,+/-..,--,/(,))+,/20,,,*+)'+)&)*),*73.*4/+)+6)1+'.)(-%*)/')+,-'&$%& $$+(&!!$%#""!'$#" ""#(#$&! #!! "!#"% "(-%#" "!" ""!#!!&* +,#/*!#&6.&#'%(!& " "!#&, &$$'"%'%(("&-14'*&$') +(%$($,$'%#&*-(&%&'/'-0-1'1.-.,(.,,)*-/*0131/345A:>3;8@GA:=:;:8=4A<8E=F?C<B<DGIIB@>AIGBF?I:J<BCAG=@A@>@?BFAE=B?ABDCEPWLJAEEGI@IFGGFSXNLIKOMKJMMMGJTLKNRJOJJILKNMRRVRVR^dVXSSQOMQO^^VTMMPZOOMNFMLMJJOKRJRJJN`b^RUOMTHTMPOROLPJLILBFJJEGEFICWJLFFIBKSUOMLOPFLJLPXNOEOHKHEHDRFOGFPEERTLKOFAAA>CACFBJMLGGJHCBD??;A==>>>==BA=@:==79;=6<9<=8<BH?CA?<B;B>>D??8@>;667565-:041110415.0+8/173272592203573541/3058856946>A<984:98696@=9B?;:;;?6<;<CA<9?<@8=<AE?<;;;578:3977272:57270505.147653<46:087;>595455529668<9;?>@?IGEFBC?DEKFIDHCABACH@U[RNKOMIGKKGOHJGLPIRDHFIGIHFGOOLOKMeSRPITKQLUQWTMTQXYVTUURSTOZOZQVY[ZXSZUZTSRWTYUUXUWVSYR\[WTVSV_[ZWRR]QYSg[TVSWLMNMQTTHLZSWONJMNPPLSIIGOHJNNKKODSKRLHIJGKFLPLNJLTQMPOVHXNLROLFJMNZUNMNGKOGLFOKILHLBHIEHEMNLKBCABCLFG>D<DFF@FB=?57:95884A<;63725:68?1:?B18102.4,9GC<.9=26.1%.)-+52--.*.+" '0:QPURQDB;<<=96(%#   &,"%%!-5,$%         #"                  #%#%!0/'#(%&$ "*% !        HHN]3"Sd$)" T*$1O\j}+2YKUOYjfi{7|lUyuk@dsQL< }+J snj k                  !%!"+$ !  ,+!! %$#! %$!!##%'#&#!#"$ "%%$&$ )-'! "! ' "#$#$!%' "#", $% "" "# """ $%! "#"#'))$$-%(+)',)00/'-),.,-(*0+./.1240001200.444A;=<<<@=>B;?<?A>C<FDE@JEFIIRKRILHELIIGFHLGHKJPNSMU`\UY[Z^V\]Y^X]S[SVV_hdfajfkcdbdihpjghebfefgjhggjjflgjdjgkhnjvvlwonkqmnnjqppurtsty{zy~}|y{yw{}~}~|~}yww|yx}wuz}y~z|{z|w{y|}|vwxyy|{~~}~~|zxz{yz{w}w~v}s||w|trt|~z~z}|}}~}~{{z~{{~y|wtuv{t{zz{|{|}zz{vytyxxvtzus{{}}v}sy|w|wxvxwyvv_wts|mn|mly|rw{swwstu~utnunrlmmztrsmyppqpvruktioeekijiggldgfiehbgcabdb_a`cg`_Z_U^XY[ZaZY\OYMUKTQUHNELHGN?MBMEJDHHDFDD==E>BEJKAD@?O>B?C@DEEAACA@D=C@@@:?<:9ABE>987:=IC:920,27B72+ !$"$!#/)           | P]6}jhpjA]i#$\EBYpoI><@N[he[KBHKSLILMhirkily%(3,-!"'&((7<D=?6-4<7.11    {spnhbdVacmyz}} "%(-)1.:137935/(  ytqius~|~xyprvluqrsqmtmrqokrnxpuo{v~}x{~{{w{wrsvrtvwqqmoqhrpodobedfbYcU`ZXXSROMMJKDGB@?ILLRWOKNKJKKGIEEVQMEIMNPTUUZXXV_Rhpje`bZ_`exxqspqqmiecf`X\WZTY\Ufb^]]\aW_[]UTOLKMWVOKKLKQUX`ff`\elm^bYcYc_agkeejbkmkrgnad^beuhacX_deejgvpopqf`UQOILJCD@?EPDLHGMMSSRRUPVQUPSLNPW]Zbcacbgifqaokjccnhntxurrtmumqrru}{}z}}x}uyu}y{~wxx|w}wzv|z{y~}~z|}x|~~}v}vwstvwwwyxzzz}~}{|~w~{~}~              %    0/          % #!&0(#)1*--),(,2*.-0(/03,)*'&(&.,/.37@EE[VO9$%"+()++'*0216,0.665/.14/-*.+/43214/63556<=@;932)/-7,4/306454A;:DD?>?B<;8;>D@IR]XTVWTZ]b^d`ecefjmkkjihiiijptouxnuqvtyruuqmvpmkfdf|lrmullsyxqw||}lpdfommiuuotlwntx{urqkogffhdkdhmolkjcjed`fbYYWV^\[\aZc^d`^a\[\Xb^\^ZQQMQBFNKMUVU]\cb]bc}shfdf^a\a_cclhjjt{tqzwvwzrpmogjsqlggckgbkesppvwy|vtvqnqfqce\^WTRNROVNSOQIJGMRDIECAGJ@=7<6:>;;>>@C>BNIHNKGQGXPRNOKQILGG?D>A>?B<GMMGLPPSPTVYXX\WXQXSROQNQZPYXQSQYPUPYPYge\Z[V\TZLX]\Xi`^W^W`^^b]a[\[TQRPUGNLIIFNJHKRPIIKAFGFCEDDGHCLHXVQNPHLFCB>4;8492F<5/94:A>E;CHGFD?>=?>>B=<67>;<:@;INKQEKHHQLUIMLMGKCJEMCWLbf`_aaa`lqppur{y}ypoljgfcaac`bgiminonhgiebbb_Z\Z[VW^]\^[bkeddec]c_ffaeb[eZ_VYYV\Yacddbbnplklghjiklgba_Y\V[\a_aebruuttoqlplddbbX^Ue]lchhoqornqqsywxurlkegrsjkplupustupvwusmpplfl_khqwusonqikkn`d`]c[_WXRNTPVTZTWW^[`^Y]U\VWWW`ahf^aY`achfflphhgdbeekhlplunnlojgzohkka`___\WW\]cY]_ptba]WTWXXRTRLX\XNT[TXU\TXTSYOWTVRUNTWYW]\aa`djcebfa\]ZZURPLGPKRVYZ^bfefc`a_^mhe^nrhjglnplsrruq|ytrknmisgqjlkldrnoonikplyryx{~}{|v}{|v{oxsxzz~sn}zuw|~ww|}u}}{svnt}~}z|yzvrtrtw}~|{xthnsnfca_ao~tdcfofqqupkf^VTVUZYUZJTOV]\[[c_bf_^kZXJQOKGJNEFEOMORYbbY[X][YRRMJLMMUQRQRTMOOQTZOc[]ZPKL\WWSNL@EWE=243*)')'''(*(109<=DABD:4-!'!!&!    "'0.0,C;353984506311048596555-7.2125:278<:::@>B486>>?BH=@<:36/437=;<=IOOIBABCBC<7>A3;::48CC?@:64602.'/*'!!""         )(&&!     x{qtvxu~~}{lniinnvvzqmlmqnz~rtmmp{~|r|urtx{wusru~ymzyrsw~sqgh]][TQKQW_khnzx}vwqlldg_`]bajfnq~~zx}w|svpulplxwom_bXcbwz{qd\RUOTVWZZ[\XWRQRTSNRRMfMNE>D=BBFBE8@=CELP`hrjvmxn|u~~|tyytrnnnruxxxplyxoijaf_eelnttutkja`^_ab][KML>>9BJSZ^`a\\SLNJGHD:6,'$%$"'&6>HLUONTPTMPG@?33+#& & *$"2)98?@HKS]]^^\PNGF?D9>:BIS[fezzzxvjba\_Y]USQJNQYgkrrupofpvsvdd]``f[h[\YYQVOFB>8>?CDKHLS[c`XPB=58,+&$'45>8?AJRML@>3-,%'#$!"02.8:FBOaPJH@>96=@JJ\hrr{}|sk`hibj^[WOLGLBTM`]muz~{vvtxmc[SSOPQUW__bgllqjrnh\ZWNIEC@C9<?=A7++ ($,+/1*2.*"$( '#    ((*&#$!//3/2*) #/9DNP[cbodiacZXOOMINMRQY_]`X\UVZZ`egggbYSLFJGNKRQPMHCCBCAEKIFJIGI>A85937:9:@IGM>FQ_XZT^XX\^vde]^VVLNCD?96396:=GSGLGKLTXW\]SI;.(&%-2:ES]ityz{uo_UWNScirux~{xri`ZQSV[bgb_ighsxxtj_YWRSHKAB>ABKMU`dmdgaaY_`agq{pteXZTZ\gikqqkpeg`gegiorqledU^b`V]RRLPUOTS[Rdfeffa_]]^^X^YddfdbZU^RRNY`PGFHJOWbfrvxvfXTLJLO^Zdhn{vri^a^ccciijnls~vuhhgldYcc\TUUSY[]ehfhnpntyr}z~{zx{quhjec_bio}yplgihrssupsqw}urqi_^UPQWbkq~vvlibgboty}~y~||}{ztqux{ywtx{}wrn^]NMGKGNFNGKKPWWafuspumoqqrnqipdgd``cfkuv}}z~}tikk`ZKIDFINLLLUOPINJTOODVIB6:9:ENYMST[ckkpjlfopqpqrjf`]ac]aX]WWQQLMOLNTchmknsnsqrnkeb_`h_b\Y^ft}zpnfh\[Ua^nu{hcTMGIHUc_or~|shYPGIGFFKIHJWZgelioyzxujb]U]X[YYZ\]didirwzwwpuwoccUWZed|~|qqeaSPB:20,27@GYhnx~ryo{|xoqkmolecknrl{~|yvtxpqkkdba]ZV[Taenlifii^_^^WYc\a]f[[]^^gceac_^TZW[beoytshnihlttykjZZSPSbkze[YSKQQV\_jnotnrlne_SCE6-'%$"!&,8@NQQQWUT\\XVWPQNPQPRZhgsw|}~wjhU[V_^glsvrlptmmipfjinhnvvyr}{~zrrwztm`c`jlpvwnegaeglxnfa\YWXW_^j^_gslemohg^]^]bm_b^hbc_cfligfafcZ]]`e^^`]ims{zywrulxv~tpmkgjvnxw}{zxswwtooionglijo^`UZTPPIKGFHKDF?DILLDPI=904-/++-0(/#/&(&-..47493--#% -#)$!#+19;CFDKFC86576,$'"'(66DIIGUY\SROPORXVUY^VX]`VX[U^UVXT[]]\\_baZd^XSNK?@9<7<97371,+-.,-)"" #-'0((#  -<>??@86/&"  ,@;:840/)%*%*.'&#        !"'# )1BMWb_YOJ=9/,*#*6CILPHA<+(   !''',)(#&&      -'14500$'  &% (%'+!         {yu{|~}x~x~y~{xrmprvsshaX_alzyok_dY^_imqmgi`gdjp|xvrz|}t|wvnkosu|~|wllehefeiyyrvsqxrtrjihshogfb\Z[_YWTONMFFCENY_`dklfts{~umpg^ZPJEMKDC8JEIP^bhr}}zifZYJI@==?7CDKR_r}wqi\`_g`a`cszvzqlebeafjpswmvqpphjd__cjgp{|z|zrlnlcYJIFEDICMTdfosmnkde]WPJEEAIFI0*& "*/;ANUWWY[`]aXXOQLEBA@>:7:>:-44%    )9777--2*4-.''%#$27LSYZ\YUVQC=)  26:7=78& $&8CBIJPQVRQ<4#08>LPWQKI62%$%)*%&)!$#*"((-"-($$+).6/,*')*'"$))$$ %-+3,.//1.( #" !'+(& #--3,389;0*6*  </5&)+!!-+579,539ESTYVMJ><5;;@FLVW\_VSMQOIJJJQKOGLMOOKHKIG<2(#%/.43//-+$  !/1''#28FIEDA>B8=>CCG?BDLMV]hhy|yi_\I=9--(! #$&3;DFDC>ABGBGBBBDB==AGJPcpzztiha__WUNUNZ``bjsuumkeg_`X\ael~xrhghca`_acgjq|~}v|xyssss{vx}}xwu~~z~|xtg`Y^Yjdhllijplv~{xqdb\aaiu{s}|pvp{z|}zmh_[cbgfrru~wtk`YOKE>=;9FCQPger}xqiXSLREO]deryxsh^]YZYUVbaTY[^gn|vuwtzy}zwpimilpsy}|rpjrggfjbhahjsgwsz}ytqmlefehfcTWMSVYY_couu{nmba`dww{~}}txw|~tt{{~x}ojYW^VKAAAFNUTURYUZZT\TXT]WMMFFEBGBLEQUWZTTMMKRPQORZbhcrmsuu|}{xwqkd[RSOOTXdnnlty|{{tqhg][VPYYXYY]^a^efmgm`ea^_\\Y]_muw||xtsnrngc`gfkflmhlficc`X_^PHIH:7.2+()&-(1.0+$&&# *4+20;<;793*0% $+)/35497>@8,1033A=9BJfjgjkpXMC@3=71)(.5=:JDFD9B;86:,6,0)0-1-759867442.&+*)(3(1+5-0103.,.,(      "&"&%-/!'&17A<EB??@L>>951/1*/,4=@CMMRUWYX^]_`^g]\YPXJOC>C8:67:7:EHOXR]d^KG9:,'#" ++6<MFPWKG>842*##(*8:>=A=GLFLFFNUC>9066:>>:B<?>D7AB<9:>>BGN@K@MMHDG<6+((  ! '$%!&#!,042;C8.*% %24==43))         $(/5.," %-15.364:3375%  "#%01'"       &!  !',+2.%     $  '',*,)*)       ",(%("(&.0&+$   %"          $)-/5?>FAA>72,!   ,64555711-($$%$       &+8996:1//0(#&%%,(2<>>CFGDK=D24-/,"-%+./5C@78/1%"   .27@AF8?8+)  !''("  #&6428=@8@7</3*+.8;:9;5;79940*%   $%',&'  #%$'094A8895460,+%#!&-"# ,& "%"2230'*$ " -3,--(44933;@4,%! $#(5,0%0,%&#&%!)*-5:>B7;545.3'$("!'-44AH9?IBAEADEHBDCA80-.++#(%(%  %#&  *+:4A?MLJJHQJPOQMQPUXdp}}~wsng`[TSMKHFJUX^_ifrtrqlk`ja^ZUYSVSTSYifidhhcdXYJIEDNPA>F6>A=>EPCOGHMXXPRNX]kZ^h\SVSRPMJRJSVW[XW\RXOQPLLLGNWf_eekqrx||{nlegZa\[[c_]cdfoznidW^NFE?<BEGOU[alvxywjb]KMF>0379-1368=EGG>=>@CUf`ZX[UWXWSZ\`d`YWUU[[]cdgdekrwvxwzr{qwusvnmddec^Y[b[[ZT\Tdkhnqvvw{zwpf\UNE<991518<FIU__imp|y|}wqme`VZPKFFACA<@>;B;LEEIFJKKLD>892656:BCKQOLLYUYV[XZYURLMPFQLQMSelljidisxuzxtwtqqmoegdijggoovw~y|}}{|zuxtqxvvquvsyxsstww}y~xzwytkrcfe]`SPRLNPWT\_`aikoruvonkoch]\TVOQGNCOIPQNXW`a^b`_db_\]Ya]cedkkkmtovw|~zx|qwpxx|v~vxpnyq{t|xzy{~~yqpvpkbd^eb_`^`cfcljvyzyztsonggkgaa\``ropqopvr|sylmhhhha^e^_Y_a\_XXMJE;62*&##*,+;?VRbiuzuxzxproumnny|z~~qwgpnpuvqypqmpoqqksspxkuhhllilmge^ZVQJEB:?D;/-$"  &,'''%95)" !&-4;BGOQWZX\_\\NQINFVRLLNLJIOQPQOQKJ=>8;?>QbaRSLC>@BFEGMEJD?<;<DGNKOQOQW\Y`_aijdfZXVMK=8:838:>=:;:=;BAIDDC>951*& 1)#!.+=CLMSPRNGE<:*) !!-00;7;//.1.(-6&"*1<BGQV\_c`aXXQUWU_bb_rosmquzyrggd`ag_b_ejr{tzlyuouhqn`XHCC91/+.(($,/0<<BBGJGQTFMLTEMNCINTRU[Wa_aa^XMLBB:=EBDHHMZbcpuqrrpvtrmka_dVcX\^ZY[[_caiwquqjmhe^^`___hhd`cceeljh^d\lmhfcg`dTUII<=A@775:9:>@@FJNLVVWOBD88<184599<9<<59567/+('$%*! #&&,/+6..'%  #$&&%  "*3=;IEKOKME0.(!*!&!-33409;CCECB?C;2/$     !)*18F;>8::49.5#,=?F'()(D(1; S+> #  $& %)# & $  ! %+*&5 #'-.,,9>7'1,' +%!!)"#*1/731+$!!  z{}~}vwrsvtowtpuz{~yzu|vvsvyvvzwymqrsrv~zv{}|r|t{~ux{y{{||~}~|~{{xzy|xyuttvloksrom{vttqrvpnrsrklgmgqffly{}y|||}{z}}}xz{|ztqnnkhnreif\cX^VXVTV]\UTXQ^p`_^]_^_e\`^\`hhb_`h]a]ghdgcmepjhqlsuzzzxwxt~z~}~~}}~}|{ytzpqg{kfegefdeedkjedi]k_ddgfrhdf`abbhmekkhnhgebhbjembdadZ]k_][__WZXV[WYWUSYUVWVYWY\d[_Y]]f^[^`abj^g[cX\W^[ZUUSRWQQUTZYVWPVWWXZUZUXUUY\Z^]bbafha]dbb^hfdaglhb_g\^f`dadb`cbfhmlgm_lfirknkkqx~~uztq~syu|zursrsy~y}u|xytrrz|qovqwtvv~v}zz}z}{}z}{|y|~z~{{sus~xwzuwwuxzwxvqttwustvpokjqrxoprjpbmdmjuglzomihkhninkpjrnrrtqovqtrszotozzxswuxuootksjwltltvpukrijogoirhhehikmrltfmlkt}uqtsouirfhjcfhlrullYzw]NspL.!29S c -5xRy)m$\{LABUqubZRTguxxha^USS`dnnnbVPJHTT\^YOFIGTOWPKIJSV^a`YPNIY\prughZWTVcdif^_`^aa`^^Y^[`Z^S[USR]Wc^aRPRLTYbbl`dT_^dlhnjhhcgqttsqinvvwpu|}|wxur{xzw{|{|v~ysz{z{u}~ztvxqxttqr}uxmrhlgngkrqu{nea^er~vuoqqw~|}mfu|qw~                   '&!"## $%#) * $" "')-#"#'%"%"%%!"""%25')*.22.-*'('',*(-01-+&.0.3146./)2(.)/*0)++-'**)"#! !/0& !#!(!!  "!                                           #-,$)''$1A931$'&%-,%("%#&$%'&-#)#%'#$&<3*1**$--20-9B6752536@428/4.96956>CAIAA<>4@@G;B89<87;8<989;=OLJDKJHQIMKKOJFGIQRMLMLGEHMOSPURX^UYYUONKTPXPb\aafihih_jjb`Z^ZTUQRVSVUR[SXRabd_a_liehdtpqqkxrrqopskr~q|ssnpqwyy~~|{~{z~|x|swx|yuownwnoqrs}{}txpzvnuqzstppvsuw{wxyvwrusxtxvzqxrxquwsspqyxoqlqltqphrkypkohkffjdfjkjkkkdjhmiigjmhlxpnqixwrwkwnwv|vv{vzoxx}r~|}~w|}|}~~z}yrv{stxuvwssnu}y}zw{~w{zzqrnvt{zzwqtru|x|w~v{y{~}wturrtpzzwvwoptopkhiihpflnfdcfmggabbdjokjahgmekpjuqunts{vxtvvs|xuxzx|{~|{z|~pwmpgrjmljormggmfcgchfeadc`b^dUYWSQQUMY[TWNPPOMLKFEIAFBHFYZKPGPMNNTVRYW[[[b_ab`afbmgf`_a`\`X[_X\YVVYRVMVLTNWJPFJERTIDA=950</711/(+-.515/3064755040/.014)3)302/257?6><>=<=DOKDDG>DEESGLGAEBJQGEDGDIFDUWRLHQPKC=>BDK?EA@BHOMIFHHMLEKENGMEHFDFOKGHGIOHZRTIPPN\[SVUQUVP\Z^W]Z^RZX\aac\_[``rynrihjimgidipmlkozolhkcdfd_c^cf\]dWaZ_]beabgaemghdmfnhupumrenvxtvsvoroetjvnyttvuv{y{x}vq|py}twl|su}{uywowosokoopopowpupsmroqutknkhosrqtwyyxv{{stusuyvy{swprmqtsxsoxunuissruprkppusyopmmhhgjghkuqdde^a`c\`\]Waee_`^f^hed`cipfffahhmlhhirumzy|psvzuwstuwtumrinlkrvpjjkdkhjiottmngigedc_\a^jpdd^]_RZVVRSTRRSSTQPOPOOTROTPOSQQNRUNVORTPQNNOOV[VUUYVX]WXRWTXTWQXMRQPXUWTYV[VZ\XcW]XZXPVP]WSUUQZUWVWUWTT\X]^^_\]]_^ec`oyjfaa^bdhlingniqowutonkimknkyprsnquwquqptwyvusuuvhptpvto{uspruporoqqrokrjmjloqjsntstwwwvxrljqihheksiigdghcijklytsqlhokjgebdcrtsilifjkrp||zvw|}{tvpkhfqktozp|s}~}y|}}wu}wswxtv}ykkihlzx{~y|wrkckbcfifigjgjpmps|~uxqvlphcfjkowx|v||{sunrhhkiljejjcbjeggklfbmndjbm]c`ffffade_f^_^id]YZV^kj]]`jdgnbbX[SYMWJRMQV]Z_Yc]_b_^\XWWWORLMHIHMKWXWU[_d_hbd^dX_UWIJDDAFEFDEEGJJSPOPRWWX]RUKJNDEBF@B><><=::8A@>@AB:A<DAD@D>>>:583758758A.434977AF??;@:A@E>;?@>BM=><>@=KQJDA;<;<7:9<;343238764975566;:994675.:5718/+012.?C65/45523727?;78736;654:1*./@>5503)1.3-33/.0*+'%.,*+(/%0*'%)!!,...?E;933286.3.4-;?6712,.+130,/,0)2-16?@186>B@7:541623236521943<=666ED?=CC6E7<882703-0-.-,3)+*$,$-'.(/+0/59;3406524++-,02.*/)0%-&++($+&("'"$+,!!&"!$')("!$!! '&'#$!!(                     !C*"B5ilU 3n{RAk0@A)db05Q8v{+<ec0[&7\c($_Zp, c),"B`3L@Gdte) ?dG5zXZR_|}4`1SI Bf:V>] *Fe ZgaH mC Om"`xgK3#86"|-=;%*jg&Z\f2,.XK|8y%NIz #187X{ IMn\;2A.5Gw|C9|mHId|B<lg8*JVQ[ -)EzXe3PyW'nF(td`I9,+&  !#-54  x  E s>cmEy BG  ; --'f&CY|0St[vD[2Yh0R2R5a vTW!8m_i:L8@Z 8i2+_5bshC_V)& ` 8 / 4 n>8}+$P{n? D * (S3T auP?d2 .^KPP4XorlOo">Ik< . > Yz?f T * FonNB?Dv6SlU&YK7K!.2 ;^KzBd\q@ # D 2{?hXI'uEk 387 y9x`CA]jK<4UuEW3Nt@EA!G,0o}'AY D E h & I L__#:lF?m(`? '_YJ=9n0*ck%  ) Y g < ` w ~  y [  U &  ` ( ,   p <  9 g K + D T u a  S A q #gr.33Qm![2?O)=Ce?cy `V)bq)9|)O|,GV<c24-   (2@Uft9Sl0PZo <Zcu  &.429:A@;5450$& {ywujgaWQJGA8;11'"3%**##&  yytskda`USOFPBCC>9433?C8290400240131:9ABCEMLEIGDCIFFCEE;B73-*+-'.),%&*0,188?@8<7@734734?E@JGNXYaipx|pje^TWMRFLJJFFDWJMBN\ONOPPMOPXVbbbgrstv}vpgfcZUPHLEA?;.* ~svnptrtqpsy}t{| +-*&$%##((-35DB?EJLUMWTYY__^ebhpnuz|}}~{uunorgebf[agfed[^TUUUVSVVTUXYYVPSRPOLcaWNIJGJMFKKKLJKFI>?;>8501,%)'/)++%)+#& ####*3-,/,&)2.+"$#'()*1214<?;:F>A@><4@46@8A<52'001,-%'),*$"  " !&(5357?>=@>?F>FDNGLJNOXTb\nfq}~{{{u|wtustmkhaa`cVVUPOFJCCCELEGAK@MLKJILGTKWNTWWRYSd`^`\c[gbd\]b^\`Y\]bY\YV]XY]bU]UZNQMKBF?A8792-0),6''+)!"!   *&0*'(,07092:<;A>BK@HJTKPPNMLOQNKK?@@B;<96:463.0+0&#((#"# $  ###%,)0=@8779CD;C?H=EBCMJJSKNPM`YUMOFHMHIE@HKKA@<IL@>68-1$$#) ((7!$       %($%#$ "$         %*,*"# #''" ! ""!!      ~|w~zxu{xwowttqwrssvnrnwousrsmrjqlphjrnjqwgpehehojfcgiefepgkdhbfhgdghjjhfaee_fdageqpoklrnulrmvstlv~rxwrwwurxptq|tsqpqqvtpwqyn|zwrwusv~yz{}x~|}}}~~{{{{u{}~|zw}x|{~wxslmhaRE@2]a 5i^gh7>{tZ:u.Nk=P=)|!CJ<iRCT0Q{,7T~};5-|Dh?7 .9Y zNpe'l@rC1+r2@<d_TuU;l%id @ { AuF(]x60m5'v/dNMgkR ]-~Z [9{ Q % "<(uTH =03& 2RQF>,r^t{kO q A s  "  Eg&EZGLO! lz'']bt jm')3fVNxI>7/K '(=HwYmSLE{bfC:./%F=08VNdoLXgB>ON"lkW 1 p0&QGtWmJ"ot2v!zPU'2ml"QY6zgM1QYEPSr2|"<wVg .}7v,/kPPpWC dWrNP@/kB+&<T>U \DGU7|]aH;^C[FUmn> y3pc^c6@l*QL<N 8?9V!f%dyh;[2<XC7o(V%3,][ JeyAs3* ->hZ88lf4G_*."{s0|>TU0 ]l>d|u3F*=_, RPC`}._F\8[ `{-eAVcWz(fP~S0c08iro/<X3l-#=9!o+_)wF i)' VGx }Q/9# nAe^]hG~]=V"z0;m  ;-!D<=S%DD5sY:(8tgu.Wvia+L<:9Bo#^~,JLR<'0,@AHA(~x*cC&}8ts?CXe} zE !byc C1Wq[l*|-C)1 QwlYzsMZ|H  y \<@XGS!igS7\8(]7{$sW]cuL6?S/qUl"c}{u4fy`mhPgCG8 !PM2 Y<dQp ] (  F  2 `  } SE%Qvf^fN :>tsG(`Sf L  31J&:Dcbgc'c wI\2 BJQJn':6 Y?@ b;8 kq?wF{gP #['+w/2441,`'! vKiޱA֍MӲՠٳ!/$. V`jKjtqS b <  \ |=fR%.2߯ 18ЋcӚڦMjFx;C}w `= Z , J "ll" MJSLNP!!#B#"V""!""!"#D$$"!x Lq !!g!.!) ?#4ډPb,ָ֜֙ՠ"2ݪt{}#in d l$n )D7X/44 s }m&UB$Տї.Nlp+nb̠ж=nۿ7 9f+8 {Ma "y^:* 87&F  ["=#m#@#F##$^%%%%%%R$!7;q! iLhV9o\9ܨ(݄7ޣP 1MXi:Le.s    g : M  fK"   D A  G$|Uz@%Y~=i#44LqEj"!s[ p F   ] *Vxc{ahV, "$&'(s)x)($(y'&P%#! t F6Tw Sڎz ӲԘ֑lEP\hV% r { X }d  8 ( f \ R : .  {  ~:m\2 J>UIE^":^i T})@ r_876g/t5 n \ \2Y3"$k&~'''''''&%U$h" {r{S1PWO#Ӧӎ*טھhn+`   =SoJ/~3 HD|b 9h +^ h%wEm9F (}V#2/p+"  ^h$6c} G!S#$g%%&&r&%t$" tFNr% ocw%om_+~.3Fby#Oy ( ^ uO4M+ < \  h ^ p _  E vlb "_1DSTw"lZdNDr0 ]  w  R a _ qy.+s  ] KZiK-\= ~ `_i Xa#L?(ߗN&Usn| w  y u b - ] M t dik0;KP3[(z%a~Q^'NxJD_Uk 8   (5E{  W p^01>]a / Jq; 8 B8ra.sg7`^;JbKD  3 o ,) 3 t aUzE>\B,`^6Nb@:bK  Q: R!08vm<d4/AJ pWQ$z(|}U:Os& uL | '.J  ]<jhc1p9cH47B) ZCvZ C!j!g!P!! ` /J y J!r+%xV+8* LAiP7{uW1 A & X ~ P + Q np\=ZibhBE!BeWzw4T@s r   v 3 2  L WQ"y<pLj`Og9|P!gBY;[@.Zf#Y+,x~ngV98Q|U>8l<wj } f G uQB `kHj E )nl@JRDaLHw%bN8L?Sq~xdlxYV7$JSV1y/\ 9a*3AB8;=1.)*(@;DIFSmvs~njPz#Z[E\`45gaZh|.3s|*m ) k 7Up2}M'Wk$  {  s l Q  |ynDjc(]2s'KoM>Py!Y6+KiGCA?\i/o6SnsiX=- G3.^8j}Z!=TUD'H  yaCP3b=/X $*2#u]:" BvFTu,qZ%Pdfp^Q= xKLX76-O/s- j &mo{vR2kyz~;x.qGi/r=c|u//=XQZWT^^lq~~~~jVNF<6h@`7bD#bR/$&0EUs">d~'/0/8>=C>;<9740353.%#&+7FM]dluzyn]WI>/ 3E^pi[@8  4ERZetxxrgZP7$ b? q[> !)?L[7\~"8Sd (=TctBWj}qP1SpL#wYF3"teTG0& +7Jc}-Lm0Ht/On*Hb#I`q}qY<"]4fHX9{[@%xlVJ4&  4:Q\r~ &.GPSa`hnz|(/LTk~"2<Q\jnuxzjh_ZOJ=.'  wmjWQG6' yljhXRNB4($ '2EH]l1<Lk{#:ATXjmx}udU;,xmJD$ *'44;JJSS`Wcaeoosw~{&8>JSihqv}vqi`YOM?/&yvribZVOD<1/"  &)9AFQZfmx    {k^TOJ<+ ",0@BKO\^bgipsv{{~}{usonnqmsrppkgphljjmuty|{vwjldd][YZZ[X_XYTVST\^[SVJOLSGE>>;5/2,/'$'    !"%),462=>AV_\djku{}|sorfigW]PSDLAUPB@35291,.2,-,-4/1-6-4,:9JNB:;46.=9.1/<0/-8,+$&../5<;>>OGMIKOJROOTQVNVJTRSSR^[[ZceYb^bhaadkghdelinnllnjolughikjhmm|kljfkggkdab]\]WWNONGHAC;7C?:',&(" ' " *2& "    $'$"-"&%#)%+-6<35//*100187<79@<CCCIGKLSSOOMMFLFBBEBD9D?C:?8<4;8736./)+''" "   #*!!$!#(.)" "$'=881;?4=:;>2>3;/7//*.,( !    )))'&,*.235DE:>9E@A<9>9?27203+/,+"'%!&!     "#'**38081<=DFK=@A9?99=5=;97,-)&(#   # (!!!#%'*1(.#/$+.9+4,2-8656282565195:166=430-,(*'%$    '$ "*#($ "            #&             uxopusqzx~~zy{|z|zuooklovs{v}|{ytospofjfY[RRRZZW]Y`bjmumqmmddb]baeehkvu{yxuvzy|}}{~xtpnq~|xzu{~{tqtrqyztutohfad]iaehfkfffbgefeprwm|kphldifegedc]]bnd^VZQZWYPSNPURXO\M^Xa_e_h`^__k`ljpomnjljoqlrqpjldg^[SRSUWRJRILGIEL\XRPMJRNPYUVSYYWZZf[`^c_hhoxvmpplsksmotoiigsjoomqelhhgdba^_bd_\_Yagg^[ZX[\[W]ZU\_dVZ_lb\][bX[VZYZZ^k_^VaW]X_TYZXWR`^\]XWW[R[WVUVTTWZXWVRSST\SSRPSUNSOGGDA@EGGEJFIEE?<<:<;:98:4=3=5?5?;=@AEAB@C?@G:865-))#)//#.'$" #*:EGHNMRXQSORIBGHB9=1>-3--.42ACAOKXTdkxy}~uzonqf\ZQF=::;63/0+#(&%+956GR\^^^chkpxv~~~z~wwv}{~|yx~}|xusrrukmghonomghdc`fbeviicla^YZUQQKSBHDD@JLLGGCFGCH>MKOKNNVRRW`V_j\_YY^_^_Zejcegdfhfg`ffb`c`g[\]adg^XWY^TUYT[UUXSXWVY_\ccZbaabgsmlheolmiikfjeei``dddah`nchfcgnleeebkoeeagda]leb`ccakgkahcnogriijlpilmihllliljjgkmlnktnov}x~n^,rGgAT2Z-q-e4g oS3|=u':PxTdDC[3Q#PW+yC"^,+Q&!X m6H%lHu+Tq|Y~77P-|9wkA6G Eq@IC3w}MX@hU<.tPl@wW'C{dY /& 9VeR"AOQvU7%uTRh ^e:bU,m N`[ia[\=4EmnxB K*rHMBaz)RtV Qsv8U YBP8`Ckt`_gi *;dZl#k~)Bf99fvR0BZo#3 ,qu3@\8Kr[1u i er,N_f5pC`  A%dFrO0;~jjW4irF4u6QU=h7zJW`QsA["+mLu )S{H .B gI5{C6" $&P$G$lQ NU1WhX"50"wzsLTr&N><(Dntw1Kq 1ZWuykt. H ?b.>*b0 ~/a[ 64 ,%I3  )pgz h=?-IB 9`]`f!)QvLP!esK^i\ rl T'6Pd1o*j  am 3 RkeZfz@ 2J 3Y , l WG:31$0_ Nk`poZHL<Bo5Xf9srL?YAtg |  w>6xQ@HGo$K n"g}|g ' g?NV| rw1K`D V}]Lg o,[Kt;K0VN  z AC9x`0r~.O1N\X=SS+m ^932q=3aTr 0[ kEEyp` Fj#+SX:\|& }o X 9n"i_fYW(y"U2A W]%ZAa! s\T]ta^HX87q^y* js' V|=5o&J?w51rzOOlis?pFB &RY[@T!:g` Z9NT$ zLhFEFtNlzcT =..X,\x/iD&'A/RS8U&=T0y$)bnOjh0:V S`h>4; `X QQ,3 +EJNVFFA:4hAep46Sd>% $T$n`wI;whafcP4Z8XHpwi)YG:Va &?=r8G/ :?D&I{}qP+bj@iE nO`S }BP'#M@B= {4fW rU7m';7d4O7Zbxp.iNim?M!J=;= ?7^{d ?G+l!P'BliJY= &u/MT8G'<vK(UEe*9z*Zi 8YuXa)h &@lgd9> [q/lUc0D;(s-8Z!!j5v{P!|_%. z5 >4Wo%XW:#^p 2^'l?-a|&WL*1Es ?uZO/$vMai Q 1 o ] R t 9 G x r D}l >I[5vW[=ja / s9% VIr_ *\k(\'_ZW7?iJi=r z ,EJ:g"Lm)#wi.w{oh,m!qL>}9 :!] { & * S?W?R)+5k "$&&&$@ Wx-qR2w/ ;70~-}B( 8O0jd<UXDOmT 8&Hof}JB]+' S> "0&C`<Mdb 1 ] b ZX7}r ETcqau^Ch&*8Du!|#$%"+7 \ LznXUaN,Lc2VWf /pV K @x d  %Lv" 3Qڢ28"uؒۃIp`pjU'_k\s ]  O_+  # [  Y  >-~ ^^3!*#[$$$# p/ *}N{N| pv/71iipg @ C6 T p , S F  {R1C5ݎړ{t0}s=xcRc{ID.[B. k Q X A m Y \ 0 /  sFv&{b3$^5:i *"~#%&B(,( &";Ci& /)i'y}"C_@S . cO@?!|&ާ;h2eub}];D=Q}AuK#AWo2wHeU 1 a + 6k>~OV"S !"t#!$ %% &%$$%$$"w^H4a Hx-= e` aY { I3 x(  A[@uJD1dMbpSFb4cr1Rw@v[i=Yb}M; 4h !#W&( *+,j-@-,+)W'P%#!^ Y`'TڏSBנ,=ݪn^? \d)[B ; ";$%f&&n$!jF1 G R 7QD0}{R\\o euJ}\|pd 9 L Svl|T#*.85CNt  45 O"$'),-e//e/.-o,*f' %e"9J&Vmߘٛ׸`~2%֟ 8ڲ>GXdۖjnI;m vfUO K"g$&;(i))(&$ 6VI b %%3h;+5ߋ,bކީ)XAdy~1Gw8 . 0 ' ) [ b !rrwORZ]O,GENw { Xifh# #o&),.d01z0\/s.-,*^)(&# g cE(n{1ժ}X"ҝwbԱԁԗԸ[ޭ2 UrVn "#%/'(7**_*(&#!-q( @ L%22tFwށܧ܊z$kPO(0g P^ K S !W)V& 2(\1 @U.a $ ' *,J03y454420.X-n,*(&f#/L %N%&ںհњ)5E͕ ~TҴҩ`ҡӜ}R;'2eL 0 "$'M)y+[-G.-N,)&m#; =b_o C-@kA>ݰ$Jr= ng? C R` X p UwQ7'CYdpv:{yyH3d )YK!%$&),/26577+76_54;2D0.,*'$N sLݚڽSIiȠɷ͜Џ}ԃכQ!"dx_o m;Q!"D$%O'#)+9-..-+)%a" hEa`:ފrjx@kE V 00 \JqW[R3Aca*O 13R "0%c(X,0H4,7q9:!;I:864{2102/-j)5% 's w8- x !VĪʣY͊ε(VqcMl4G KK(G !"#%((*- /)0/:.+(%"`]9zB x\kQݻnL֐ԗyԂy_(EA=; |  ;R n  I Nr} Q [ ;$gGmH bik`!}$q'h*u-04689T:9_869531U0.,)%[!q d4 3RɃjx0ȏɻʱ˹CϽ[+ڃEw  ODJZ!"#Q%&(*+,,Q,*)&1$!i*, V'53vErԳԁVټ.U!1zZQQ$ J [1f :'l^+mgi:'@Q ^6C$"&%=(s+I.02C5=7 8 8765]4H3A2s0X.+(0%g qqzV\ ˽ǸŜ^>š:ɉʿYͯJKL'"5` *N7p3 >!" #&$M%i&'(>)})('&$A" <N n*A0RZ ZHն԰?Oְ#=߽u\u$XXs]g R  rX)F@ A P%b`\8%@i;0hb s-Wp!g$\' *i,.y012(3333k3H32{1/}-*&9"^ &G;܊6g,̻7 ǀͶֽڧjh rW cM !"#$%[%b%I% %$($=#9"N!_ 9?> k  A[_O78}%-܌!@2ؽ ۞ܒ%c&)'/Q`7  ~#@ L   c  3y==0 /ja Q`AB R!R$[&')*+,z-..../.B.,+(&"l ld! w"׀rгʏƛĻƯ?ˍmҁ֗ڽ! *S+ ]. !"$$$$$$?$## "!}~4( I~aL3W$#ޢX8jݰ޳B\h=8QXa,  4  6\,gip> 6S>8 Yf]]!#r$%&x''(%)f))))d)(,( '%}#6!>rV$ h #Q;HխqWˆeo:X؊ߪl H _Zo!"l#$$$$$n$#"!c O v Z=- 2INUI:)Cs NJaiI h;@>L"7To| iOZ& +6?*o!"t#N$!%%u&&T''i''d&Z%#*"9 ^= DIqkiӌӗz("߁ X@n"o;H   a ATpT<+ Q l |l: =rNW_k6Z9bAFO{R G(2X _?2_8%,Y:dh|M   4mOCJ V!G"*##$/%%%6%$#"!je - Pi:*&jv0.dzfޒ^-ZW Gd?e$NNQq%G* n %Pde=]LYr0tjgx9f[ RJ s +> =s[,EP~cm v g`QU:  g!!X"""G"! a 6p y DnT^~$=;ؑ6'ۉ@1RNLLLYrM 3 i;5p%-2 a l![5#se\_{%jYLWgLc!,Pv l3y;+e!V#  [ ~ ] _ [q4^D>'> j 2BH>t +ڌ-,lDޤXAw  & 'Y"C&:{vA&^spZ.x+ x+ifPGJC^%q71~.\Tz@^-d4 ?D3?(RmA 1 Q D;d]%*|,%Vzw R  +3*V6LB14܌%9ۣQ1eyI] {LlO l(y0!xF t } tKkn4jE5Z$+wwzAf0q];i= n5S B V & W7_7= k+OYQ1,7Xx8ZO :zI Z/gV޶ݳ!ބ߷ߠX 2y\S4>( ;PGoNyOW4CSR`K 9 h ]v^@:U:j,{LZE;95CM]u@Rx;a475+7U & 6 /% XWJ"W]=4'wE @ .aN *[6#TIG;\.m%r#2 P V G  pa UL  { 0 ` ,Mm^DSf; 'G4,MYL^  G g yfBm"<zq< ~6m2Yx eY  1 ? D ,n./7FlcyZ[O)$LXQUs[b(itS&NeznQ3 ]]f9] O6P6@n j-&T"lHj54miLYJFw Q A w V & o X A ( b ! m+s"h6]o$7Ftv-[# )Gs 1fpAwO4nU9#fJ$rFrZ?# m]G>":h[p1hPC73,y7F=idO3 2Roz  }tjdG3 UZ{2rJEB\ w6Q- pW=,rX:#b6v\F.! #7>Ym 5V6xjt;[$Rz3 o'^'Eezyq_O:-z^N<3#!  -CLO]ixnP5uR. z^N;cIqS/mBsH!nE!lT=-$7P`+]Hr'Z~ 2X+Js5Qn70;BLLUU]VUPLGIGC>=;E6*'        yoVC-tcN@1,tlkeIE1-"  +/16@B>HGMMVU\bbkpv{"'.577;@HSIUZd\SVNUISIMFJ@CD>621),*   !$%%#'!            (-(-+0-46<I@CLGMWVMNMLYWaTOTIJFCB@9>:95557100/.1.+27/3/4294955?<FD@G@HAA:;594/+1#( !"#),%.*/'120248295/8,409><>;@>8=5696;9<<9=<:9A5>2<812).),12&(+ &!$" %'(,,-5376>>=>BJFJGOVWWe^```cdefehglmpqktpqllmju{ztnthnqlsqptz|wx}~z|z|yzrnonesgnipijhhhhkjioqkhjfjfhehidfdf^b_[^ZYa^b\aZ_XYY][_^]dh_a\aX_ojbZUSVSORITKQJIC@ABI@:=<=<>;999799;;:808133894<;5A6815-14.72529/3,:1/5719<8>B?24<:74?62;51113233:8:?>>AEGGPTPNPRSYXX\[^b\jfbgajenjginmmifkgelflkggoulqjmihbgba_^_]XUUNRNROIHAHEDCDDCCADIJBLEFBMJIIHIBLKIEGKIMDKDHIDLGGGCEF?HB?BC?>?>EEF?E?@C<>?<6;<<?9372=0:786>1;495567:=C:=:69:7?B>:928535>QA;12/44@98;76:79<C@<><762LOIBDT=IGFHKGJIFLLONNXUTJXH][[UXV_SW[Y]Va^[_^b[aaZcXYQQXVNXONIJMNJIEOGGGJFGCJDLJLIJKLKIFEBAC??;=34046=<<;:8723214)2,51*((,*10),&.')*('-,!%&%'()''"''(+,-,.;993168:471117-9+-)-/.-(% $+')"!##  #+5447/-4062-+!##%!-'-"$   #    %      ~q #24BRRKG9/52139<IRPQ<*5N]iDE/;8BZ^TJE6<?:9FSJ1;>!   (   (EGC(2+& 26-%076><UDLVPHJINUZ_Ub_b[VOOHVVYODXGOTV[E[mtnYXYgwmcSP\Za^^]Zbmg^gdirxuq{qwnpnqpl\^]VPZYfYYQ`dVXYdh`bd^L.1;>142*:86  )  -/8<)"02#*>:32;:C;<90AR7&9N]R@-7>RIXC766# 9F&  .0  ,G6! 0&4&  }aYem_PDp|m]>4A^jg{oxaz]zkkf,"bOacx M $R3yij[* I()x=,Yjqyc4*k74pO ~iQ=G].SUcO*o)%&Ecqhx hmaJ(!Q? suKcg_FZux{Y]pv.FfhT:  7TSMT1f!'WupJDCHb;;7>0,,")Pnj\8 CVE)" +?ah? }b *x z~i>'1Npu|hT-7:vjM*X!zCU?M`El;ew86rw@|:ghW AEAoB."&yfixL'-wX]z!t !f=:D%k |i|GIit5lUl44^, P(( xeP%r#k~R:u~9HEbNGNRv'5SzIg]&%Ady>tJ?8_cq; fNd b*}NE=pVy@ ]pga,;Ck$Q!6%ZyjVtIG&T=Cm#V,R%OHar7/QvJWjQE#Q_ EeB4x"%T$~z=Oq.?;or!t;kZ}fO5=w7 's Sl;t4MSvb*(zm l5}8/Zf<,=2KL"41Ys,7_$&O wJ.^XRY6GX#+H?  pq,mG w{?zC%2B;u F](*d2WlN+sn\6:{JuL 9NW'J\/1t>Qz 5&k9X?C7PrYg[ E\P+^ >ihCnz5 i^n[7Z.\ix]'"]<y'd(FvjUk,/<[Ia@ACWik.L{1qbJDA@wgw4j>Gy5e9q}J{ F>K@pM?m i_|F`+pF6S5QaA iJ8O-3#bQs j>oBh/GZamWd$:x"YjAP%w%=:Rc8Lm*@5/_JTDt~@fJTlln9i>s1J`u.V\.>=6@]>'c+rn!! m3eZ$x=K[%qpqP( o, XQ|gx+x+2h +w^ O NJ p. =GdP9Ec`?KIY;q ;ov-iIK;DNT/ nT*zVed]L`pLSF6dE]FyE:m]<~at: IrkzJr/S+Y(b"Wkll p:;(pr zB ,r}h{KoI>cm3H&ZJocV5g,_%$m'3 tF MzHItMpM|U& :c XvNv@fd]i$HW5]lQNF J 4  ( e O  P@(^9[!s.l2߅ߝ>cv+n&vi Fbb8 RLs<t"0GY)T  k P H 2s>-T !."/#"$#%C&x'}((u'a#&dU *d>"Pu,Ӿ;6ѽtHw ` D3%l 1 5v  S _;\Nd6([ y*`q =^% d U E 6 '  e   u " = I u  u' ^p=*T b"*$%'(M&{"X 3x},:<ީL O Iܑ|:/x&e BJ<;kY4EWs 66:|(I:%v'|4i'؍Gc6nFI \[KB_U "  %  ^ '[fjB!$O3!"#r$$$$$#!8 [jK  aahGCјЦЪӸy٥Y| bH0!$$$#"@J 4 ]0gn'*`է҈m]jGE˝Μiv GN4 , jS(!|  P I t A o!lf !Q" #$%X%$"B !U5 b|L4 }wZRړ۩G1^4 D&`na4qTg H  hHnms?i<˰|˲oΌc"@۰id D&.9 Z54% };Y8$UY!"#C$$#[###""! h 0d.չ}0ԋ "א6]%lI& * =z'p Xa ~  F/mS GڼfSx'6o0Yտ׀ڨqnC:6& V3D0o_?YtBM&S 3!!"""!, G_W1 >hW  M*UD~iרՃӭѶІf7Մv =6 50 ~; V>~ $ Oc?'qٹ'}sͰЫ]cקqsmSf  P"nf*17 W!K""=##9$$T%&&''''%J$?" #7f/ I >9w/.8ԈӖ|r$і5v0>7nuW d%DzXKy7&@sw 5 PjݔA֐ѳ лРv 5]wTlNW u bI Rs a"X$!&s'k(Z).**+W,,--d.z.-,*(&k# awLG Y <{(؟ц!-ʷˠYKo)%\& o'IO-* j j p^WCx7zPLڬض)׼byي9ޓ|T<+ OtN? "$& (`)*+p,--.l../..,+5)&#'!z[ T~s?wχͼ(6H\r .e(n . q n!|9& 4 tD8+Hn};x\kg+fbJIڻّ P$ߋ}AID% Z ra!\#%&Y() +9,--+.~....O.-,\+)'%T#| { jFG/sZ͎nfɈ˛ :EZ O9 vJt,h.  C $_JE5f +~ߚݶގޅs<$< o k. "{%')+-/]0@11[2z27210k/-7,n*k(&#[!{@ qlTaױixc"MNͲϟJ٧=M u  z4qEs: MvTj0 f 14BQ|nl#o:8A '{d9-vߜjU|u ?># U p Is4m k oW'(<=RxZ i{|fIU8* n:S - ]o{* ! #$&n()5***|*)(J&$!+ rGVz. W/"1c5q@r "  k ) I + 6ie b;1[j`1MT C5),mF3k- P >_9s(s "#$%&&(''U&2%Q#?! 2 7mCBGS'R(S  E41A6}  |8(l&?:va !4aM*( n  ` c^QyV !"#p$ %x%%%%H%X$#!pG> .cZZjtP&S Hs[(d D .c&t3UX@B޼:8|tCދym]vj zru_ O &*<R d"#%%&''~''O&:%%$"7!U s  TTZ=Z#a <JLqE6#{* P 4i[2 C|N.RއلwَpR܍4:ߵiKT~O6cX M y|ea "$N&'(3)))`)(( '%$"1 vC>-N݌ݸL1^D mav;[IM R ;"t)7U܀ۊc۽O(0mY.,xa< i 4 'NV>!#j%&'(m))R)(\('&&%m#n!Ql MK>O8)PEoX &M5x4 }Y_h} qD )^*c7qܐށ޷߾J22a%IeTOB"( l LLig!$%S'()))))j(v'&)$" ( i;e.p^ߤ#MR\7M(f! 7Wu.qS6:LS 6VzqJPH޹q݀-wޕc߄d^\~ELF? d  ! #$%&i''''&%$#$"5 E/xR !8F ߘU] D^O^ b-L{"(ws O43DPޏޯSߚ@0z;iKMj:5Ti  2z("t$@&'()d)))) (& %%#.!^t5\ i"J$ޣݖhSU'v0Sd]*? :d+*I  "Ps",p57lߔ߲K_' A5i{7q  I"ZM "K%F'()f*v*\*)c)[( 'x%~#^!xT ZB{zލݦ:F1CH39ReW0 /;5[E~n>] a ~>LjkAj Rߋ߆ߜZ'=j`5 ^;7 O$[C !#%') ****o*)(S'%#!Uru :T o&ۆۯoܨ݂ߤ5,FD '(EO,i "@~N[1Uud,;j߃߯Ec`bc{w@ _ qvW!C$&(;*V+,e,P,+*)U(&%#p!P; QiO\w^CܻZۿIܩ݆{Vr<I p z#lXcSMMe%y K >1m;z@kO;eUQz>3h!9QQ@8^D1f  ;4""$'S)#+,---B-8, +)'P&$"? Z '*1^Yۻۣܵe'qm*PM- u |^Rv# s ( RfxH2O YqVMG߁"ItK@~$ 0R}*k F/C!r$'J)@+,A-{-}--V,e+)(:&$" $b m2Y_P߻ݜ1=ܟpݷh "FwUkxfn 2 hF(zyG^ߢ\#n1I~ pS ^zE W%Av #H&(+,../.;.9-+/*(&$)#=!lD ; yR4ۀS۟y8/tdcUH 4 ep&.)N3vP V[M[Xݐs}݆DyEz NOh  ScaJ#!$n'),-s....-,+-*)'%#W!SQ XSJJFۗڑtڶ.Xݼ uU0 y$&BJ#  9+q߫aVX݂ݎ޶:fy+Fw ""%(*,D.#/r/l//.-,+K*(&$Q"v 3 ?Ytمg٫فڨۅݐ'*- , H oF"= G<j)|v8am dݰݩݙ݆dsݲ]ޓ ## nB z"%([+-./3000+0/.-,c+)(%i# CNr :oR ?~<ءبIڇۇ]C#Z p TLEJy_ J h 4WP)MSLݍF܅ݢߐa.]EA$ i m%"%b(*:-,/0E1`1a1]1G10p/%.|,*(9&'# f Vv<08,lH=1Gڶlߩ)B8 _ p.kl_B LWrruMDEsEݙl~2YmOeVmal 22"?%#(*=-\/12v2222Z21k0.,m*'$!qm rc&ڡgUTխtשN>lrOvzd e G|8#DnGk JE+)U&h#; TU 9G9N]ܷsװwnwԿzUޡ%KF" g CAVPrMY b 9`b'[#Z6ۋ:/J1GqG"7]z+r6 T s I#.&(*,.0223m44w43>2X0p.j,)*'$". yRDA7Ԕ֗RIXBfY?; :?Uwq_ p $a`Bfqܚڊ٣ضחpHj~GoA`: XI"q%(N*Q,./i123>444l4?31-0.+n)&#![ jF7HޗJ<W_ ׅݢs cs. cnP+]Xpr6 |,E^bw%Oߐܣڐ@خُlp`Ku3qc(o Q DXc!#%(a*q,q.0L1N2*33443W2q0r.,*A(%#  ?\ 2us`Q%ٲ5ІyW҅ ؿyV <NLa d ,uTn: ݲ};>ؿ`ؼقkݖSG=?O39' +"$&(b*3,-`/0`1X2-3|331&0G.,+%)&#!s\H Vl Eؒ+ҙZѭGҗa`ٽ"e-|( X #mP4eyYO # =>1un9eexajUڂيAإؕmh3cGU%W 2 nAL*"+$ &')+-/k01232620/.-,)&# yn6? GB}c  A!x#%'x)*+,-e....q.-,+R+E*(<'\%R#j!wf }jJqH>11bݴ=g=gݕމXtRf%/xXoAe_ V Y X M " |LVmTD]/1K&+m@[tHPH#1~ P'4IbK> N A  * !  gW  c^dQg7u6tq0^4W0.H^rgHRuG /h37hjRI9lurpy[Y5p|QZ(hl($aL&:eV"DU!FgMi 5 ?  5N \//'k5{;u-[=!fN-@uZs#'9FWm{yn_\NKHH=;8957?HSVgv0>U]o ! mT<$ raD$ wl_]\UF>9:>9JHGJftxcUPV[eg_MMP;!#:A;4*(+68<;JP]`]egekdk]]H>1$'+ !*)/=DPS[dn  }rs`gfj]YY`V\Xg[\eln{s}xrpnlinstr  .+,-..86;627/) ~~suu}t|wwx '/A>DBEJ]aXU\agjrt|ytwhgcZNE:/%" )")#,660-()&&)!%()")3<.,$($ &   $*38NVWkqp}zwsrkjdd_`YVUTQNKMED=:60153)"!&#!,&*.*.?@:=@>FBGEHBE?FDFFHEKMVWQ_c][_datlmhglfjgegabZ^SSNMKDNPIPLKIPKV[uloqxz~xympifgegWabYZYZ`\ccdpgrstsvvxy}{}vyxy{}tsxrpqkqjovq}t|uwwu{t{z{}SoOzY:%bm NO#B+Iy=$-: Mlxg:zgm}Z# n xoL%rK"`&# *]/ sCc|5$ wLSx# a\LD?+_lT/sd&+\|zF`b.)F"c%eBj"^zi])9vPcX qL.*r?4,'Ki9T>GtTk#f[&9 m  /^C=H /fac7R.R4~uNemqQWgdS>,&1 POaG]~j V! n5uk)vU>7TMY^V$W8ilnk f&!.%yI4c'=#^-#s3NO(0 j|I#@;k6 jy.%VoFM*$\VnYhF_l".G l&RDdB9\^Z I:2S@/,l+DCW]|]P R`&) `jjr{  i> "XS4>5=Ip w={~PHr\@$p*vO=r]R)(DW ~?Rv+_wAC 4pbL dS@@I`_ }syt ^ F&,0vbvuO9A=9dF Iah&:xW tNDJgIS0yyr"n?i;;iW7 ":k5oS<-]  92 rWi6oFB/6 a}H[ 4?G UU5Wm|y u!I]&>E x ^U Xq yt2w 6VQ qC{3J+uY4X sehw=&X9fbS e QEfz Wp;9 _"f'^. * xQ[cFhtJchJy)?{-i5N@g r("8BWH` h [b  f/JXj c2v9 e0AucG8F-rVgravkz~-\9)` MR>]>"^A`Qo)rw+v1 L=%W3O#Rfc[A-jCjs(>) ..f|- (xg1-R4*=+3t&i;hW*GNC3 ndV9FH t4`#`h\ (o=3Zf( aMJXD zk[q~}up Ns'EKb|pPGR; "|M6~$-+C4fG8'jD-RE(*bgLJdvO71R5:&%a'0uj] t6iMTo7>FV;/i 1#2Qh#9Hrk%!`N]Pq AsU[F6Oe=*e\p!_2Ev>XJ);SOpQ I/9+l ,~f90>UR!83E3kFY]7>k1MPzS9aaY!5}z@hA!]6k$t;\7>C$:Z~@$XFcdi&20D-g+9ov zkqFA@vs413Q :EVU{.)#g]} 7IN[sz%2\dn,!G "6s yR53R[/a&gxep%BtN+r~P50_\ N%w&=EX8 aG)s d & 2 d 0    ? \ ; E I } ~ i   ] "  !/jxEY2w|`@ x=*0af`$U Q&^4`c=QWf2Knxx;B8~3Q )?]D;c+ %@]-FXMLhU</Fdtjy*<hRa , 8C&><MJ<[c!rB"|aEs E~H| ] U@60>k- } b4U6ZfkXd`7u6d<5Wl1{Y }[ ,  8f9 g   P s2+w ! P  T C &OizW Ur>_MlUDIileZ Jw*\RF'so!o(L+hbj(y.Z ? A A @ g t mN|W]S{}Z'Mzu1gp9>\mC 0 R I  1 6IBJZ95 nn 6YV^a#A]%Clz<F: ;  ##^| I:R<>  G'=V .ElzMkF/Y# +}R^',{TFORgD}f|?~U@KN}O}*! b O/?<^Mpt$| U  BE5:~)Ak% ^!""#$$#9"]B[ &  :DVMKn4oޗ>9ڰrcj_ދ4J5!g(8a ; + E@W'@? `9FHDp.s N m}w f=Z F(\nabL2 -"8r:u9kj3WXUaw<,"~l79[ E V: Agm&_S<#zf)xu - R.=*vU y !!!)"s"" ##C$%%&S''&%# N,%h] R o : D : VADa lsZע؁xZ&5[\4Qob} & OrIxu9GOxAzG G&izbk=}Z,&2PHxDaq1gA6C/ ^ B c L \_:  vp 5h5&95g%Q?2j+ Bm/AM*8  L;<_ ! "E""!O! <r6MX71\[ ` G4KX_62?'޸A\r2Pn8>*Z~JkEG O vgb*6IK)BW#4E-G? ~ =h,E<1 mA/ji*g;V3Ebf_{ @  T j t [ 9    K V /' W 2~/Y?fX63NcWSU(4Qb_('QYi~bAVf( a SzhV0/2|-#J&gKm sm7  Tym%(x)MH\%,msp{# #A \ X,t7 x  ~  C } +E+&<e b  !< -V;`jn*jzR](E9YH V[(. o S   ? iNh#4#cD ,~G>vOZ.z VYd98l!a*wM80f 5 S  $ \6(Yh !g*t Z B u 4B!B xygzjM*AIA`^Nz {U' :l:@rAkJ @ y  K 7 ^ Xr}  b!GFYv2. FR)eC0w>"]T\hwzvN?%#$:/a - " :?|aL!p^9i#o5|)] jV~ ,;yT(N&u A[F=@O}vJ2) &  ;_v~dLPUceL` $Rd1)Un^`\GuG41Ob~Vp\I=|mV<|bV>>kyw>/+l?[pp; ?IY-  LFIEvNo7*S6%Y =Kov [}KR,X7y\d-oj_jddQeF"ws :oh4o{|Z $ >=MMEb@jOv:0u%dTa! ~q([[83kCgZ:j[S.V}qL\>uv2l S|Kq`dyEEijKJ_X/v&+?58mFBUk:9aJ B{-TvoBV;P`dX\zy&oT3W>_p!^<Qw 73p}& dF |NuGWqN9H0}jP'fLw",0\)px~UebB'/uEP X z?@BTO9b"&DzM.40;o_XA/>2 p# 8!(h(ui5p!xT?QrmduZqEf iquxNK0SH 3j8F=HoQ_H&RM^N*./&c.Iz?VwqYKx$l%T_q-dX=7-& \Y:.<(A W_L?;@@@" j_ Zv'f (&ssx-,[x8d y4qf;'F0WFeSvC>hi<y93ZG@k+ncaq0=%)3s-'Ulp-2]ph2@O=4H*r `&k 3I_fJ5s |]qo}xWiDER5a<S& ;):x't:N@oc:G:~vkC`Bj%HI Xj^9$@6O] s^R!*k>He '(t~~hEU[_`9>S|a5J ["r9mej%hmjT^LVWd oC|5 c\w)TW4n>|&pe-TX7[~[e> S]y[ggua_a*\thgBW|X:q# dh#hlfCvqx}aC533bu{TS]x^n\)Ysix hXUK?)$GEl8LwNmoO anP)% +$2rM3#1n[7?p/Fde"jD!oz!s,]Qh~bii 98Q$ 3o :h~1l pW<pKvlah4tVlNJADL9z b1Z)gDI DO^kOV-]f!} 0!bH|b"tB;zVPn|c )\BML*E+:uwMhy(\Gy-'y^HLzeo,4Y;I: lt{S~e(OVqe/>9sw*C:,~A}=+L&]hnwDE Qab>C3 FQ,CRrvM&+QQ93U}^iSs{WUYgQ48 {s$I=bQ~?A} g>8 J k{:K1x_B: E%L9mVvy43rCFql_W4@.s5g58}h'EG.E7-< ,Wu)n_gd 81sLcjJg%1E3(&y$+2$1_u" +m>F#Cs=M IH>RS JEG)sS*5pEsNVzpuTu34`Fx0:(}R#wmld/NiFNUZ2EJb;eW OM&, gf)GBjd/6z:*1iN~zhkcCpS2EnQ?)Jnqm !q\K%u'Z $QfRn'/mx}94l%||c=0|2(L.8vHw5;xRx -wQ> tW<oZTH0FTmy!x!v'.?Gd@Q4w"$EFYE^Z=U9" $.W+2gTi(y!\MQ< LelSr).I0]3Ow";Nfu=] o`Cu+h>7{k!v /=d"( =nP4hJcCRz USkJFy5LpUcup*^xcv3Sda'\)Cbsrtg!-@idx?)W1d2h%0 P.T[liRSRlE#_lF MCn'JtR{p`g8PL^ 4*5rwA.J}QU\fgRqp\2V8enL250(+Xo<2&1iM( '86L7.,u%K1{Vu?"4@Zs[k\~A,)g>Nc\7 kFr^(sO9R}i8 &3*mw-Xs/`T5'o$pC?*:[hlWa'/;}cr;w]k_`u7)a\Ed<*H_uaz:qlG,7)%"!O n9BT'lfJ;F+ rrb_Y7*(x}T![/'+T>iyW4.--a$?JO<_pZU]yP-xaWU6|\C_),r"Ws - d  K R  G c Fi,z H8YU^J l- = L8>^D_}*M#%cDW4RP_} 6Qa/b]i)P_HC]s!UW3v MNz1Of!-)-/g.`n CmC,Ej3 |O3m2(b'onB[["%bQ?t'\U1|(fFu$&yJ  y  b ] wqeN!u=2#hO"! J>m6hZHN')g>HM* < 5/(^_ g hE}@x;ZDAVvmbpMoGV4=fTc c   i P S | . 8 GllRc| bPIr cmihf{mc)Om0h1;FgK(9,H>YbACa*npaIBo*]03,j z  A f _24X p"<qi2W_a !LZQY!j[g/e{&Z4 IM;^./ :>N  g [RM|R"-R '=6.`$~&>> < F3od2eoeM d  0P.V;,j%r:2hF_shbr H>fxxb] &  P-jruc]_D9#1De_4'Kqx!uKLO3b~?L s  _.WS.  0v 8  *  F  7 q $ n J F tE4`z y:%Oh}(f[%g%$=x)g  - reB c . y c!UsZ`i..pSXw p2in;l{7. H 3 @ i5:1  1 T ` Tgo<>)h#'x5,{s)~xvE-V6, !<:3.%*E` mxVS\n%H_'<`iql >zZlH9  3 2 a gGIa  ;    K  ? -dQK3D dTu EbN/eO[WE8w9  | 8u=%0  : T  q c|Gxwvne6W'US:m ' .njJ{ w?i TI.S^ Y@f;_n;^gS~\MLu7dK>Bb}{anW`1#7cT,- @ tW (z5 | C  j lx-,0yhT< tW)4qV pSpc, ):nf(qo1)G  {$uB ) ` 7 $ . d yJ]]*5#EC #": i ABR<No 2 B4jw`d:rB.7Hg5/x=3dxi6]  ^  9-_gJXg@% $3A5x38;Lsh?JP@}3{1~B 0u ;;' < < _ 6!BG:'dj|J*0`_A J\ 3O}uC\4$x).! )'r "3G" "Mye@R%sM$mds2 9 U  <E5n?k G T Cc[AXyeCWz 64 V { Y ( JWMNA""*>hCL]y9,!:a&,Wy=HT<oUa(*Xve~rkIF"'O7aeq R i !WYk3Agv#D4k\ "X@$}xbf!b1m[Hd(6g* ~ ]4Bx7d E &ZWN~%_;3D5EX%^! Lxb W |  F6MVn n H! $k=rfH2M "sWJ[&+|$MP o  g%^c,I*g,x&N fR~Y.)>~6 EvMfl ]ni:a]GDj sD~ aK  ^GQT'@' G3 u`1Wr } (c8*bzLqua!*gALJ QJzp A  %j1.   $*AF@!^N/^?Pp 1'!:s5e |/1@ ->iuGQpiTCo4} Z rmy"y?hO:1~5@y;^y\uU~rG L9@{VzQ^jtj.MT3|'PE0 F &-3!9xl]W/Q|Z :BRA /#2SH@?M~- h YR+:`_@>  l_C@\{z\h>XpZmUvQ{yWC$M a_!'Ot y [eH l + F2Cy(E&h++I>Qboa./eT a}{qkR/fV}F<L2UjAk(I: $1D` zu,{L  PhEoJLV  m },*Q2yLVig v+r.E-I q D4h87P ^ E Z:W$Gpce:nNrXGg>a;lL8I > [ 5 15H/oQ%_K;o1 3Tk>l?Sb}cB@IJ4NWcKNpS qI _Yb|P ߛ܋ݬQ4j" ( 71q1Q  ~ ) ' }UPt (eGmJKPWwc, <-O;l^na0 ) |gN0garHsuno tyA`+     ` F --LPC*! *@av'(.RZX*UciB2%tT < ^ q .WrI|'J([>+E'Q7@e+!F  B1@8W}I +1v ctO-1g7,mߵra!){yD#+l ;7V+$  2n!}">$T>"a{2.,GOn%M:<(> q %  !   g>P,%k[r$?%0:v[gN7(]9~zd:~36ebZgS  ,*' ht o]=IE! _  \ vmI*Bv*$.y/>mzrm AD0(Cw9=T6O.lq!0`DS1;D 39V?ML,PMa%Dj5t:/q&6779HShxrG e:g/q3 8Jh DM +=bzdNHGf2yoZ=.)z`bPKE[q"8OZv"@DP`mvoV>! $+1+9R[hqiS-L'LZz ,0/CsJ&QYd.fM1 8d+=Uz=Ha t+Uv BOk)#(x iNWQ ge%`^ut.Q73kxF1W1]t\IDB]O|9}sizI3uV?1kVMQIH%|< }`LEQb&+/428Jj+^ *>SfvxgC1ugP2" #'(#$ '$$+(3:Pi  yl`V?- ()31DIH]mpmn~wq|)-a":z3QmL4b|[u|b@N]`2>a^='7D$;=  %<>>! 1=WU`PJWft~zurromd`L5534(0"13*...@QRisxrurv|mXWTINA<0<=HTNT^`[S>+  **;HJJ@E>// (5776>GMH[dkhrih`NGHELGW]bbcdlii^WPE?;0--*&'):D?:'++!$ !/%)5874+/<C<=GN>;1:2E;>ACFKJB<.1<54:@6350,87:>55.1, ! &$+0-,16&/$%# $98.%03DE@HF;D=A8D]OP?C<65>;2/=<G7A::==>=@>FO@;85;6BGB:76?>D>CF?AFVJB=><?@@DMRTVXb]`a`]YZYXSMPTQZT[cg\_`_X`ROHEB>7:6=<BEILEPLGFED?8:5****+*3:<7;7=;?<BHCHQS740,0-)1'(&./40BFGKKC?=A?C?E;A?@9;<:BDEIRNIMPQQQRUPJHE>G@LDDFDGGACBA>E@I>C:77759<;@FBEFDHORUQZUb_^\[TXc[TSNWTR[V^Ya`caaY]SOKB@B<===DB;>9A?:<H@@==@8=CHDHLQRXNNEHKFKEFNJLMTQXWSU]ZYV[QHMHED?:?BBEJKUWFF?I<=76:?12-,381/.1..-3/5+9/616:9:::=???=C@BQGA<?;;3<3404,5:9637<7@CA?496<C5?AA9:8D==555:;<7AB:13*'*10.0+(+%6///0,0'. ! "                       ~z{~|{}{z}{{|x{|s{pzu||}~y{yzy}|tzvrvvyz|youy{uvrz~~x|y{{v|wyvzwxzyzrxuv}z~ysx|vwurqmlgnhleppsxy{~}~||}}~~~xuuspoxp{y{z~||}}~~}w{pob]VSQJMFDDCDDJPJKGLHCEA<31/(*! &!! %     $+/:AHRW`dpv|xwrtngoabaa^^d\_X_[YV\XUPTWRYLSFKJIQNGM?HGGFKJIDEI>D>HW-V$L]_n20{aDAB6w /(! s-{o' hoS7?Q.U_<DisT{:X`)d}sk 2^9T3o6.'1w?XA &Cq^$skjDN2A|G+j>/BgFtQS.R/=r|^Rr 3xk^u$s*`J *9  WXO]yj$nFy T>)Sg8=c3HKo=rl,F}7=Fax9#If,xLvF$[b*>gQE]0~Mflxt0yT(R\L$1^X_[2>`Jx bUL[\Xu#q[9Bu aqnM9%t= xwg[_P5c4q)IP2Q Kuz(po&<;mzsdn j lV/?:uSWz7Pfss\=%g~y:s%b/3i-Z#FoH"VjPnfB<(!qK~,T+7tZ.< yv2w]e[u01%Zs* ;iu5`=O+6XK\p]dcd:-OS7zXem-qUK [d|I>y[ >& 7_qa\aT+y.&l(%4rtX|ds lL 5OD3[<@qx2h:o/gJ_"P[SpZ- $&)<Ui~bR=[za^oq<?mS~z)NOV9bf"g"b3W<fJ WVm(UPP~@t'3nd"0{Gt?5-DQXDK?u%P$P-,BOQXbN!qAWy#fM_bZ[LR9$ oyowuC}_ : ,Hcmw~yD M(4Y4'AaW$u@ KkfN/)+*$#$AwxI.6Lci\EcMaOg?/Dj (-H]Y'R|O;`FtT" G'4o9s}pyyow4& ld^V# *.! ("1V~me]_h]hctoR@6Ti#sD0:R<wFNp*5ZgjG*rux  &@VUG?A@A2#  +7*gHHcts~ 3XUZWNB/+)76#~|r}w .)(COUevttznG.#*#-6FY]O4 "03,}sh_X_`u*.0Ebu}|iM, zw{vnnjx~{wbYINXenojegx  ~}xkc_SRHEBACNAQLR\ea[K?8FWp~z"!  ~wniupqspxs}rr[HFHT^egkmw#!0-&oiWOA46+$..22.*  "4:FEEBN[^ow{jUIA<49=KMXVW]ho{}~xs~vy|yjjfgihrvjm`WODB8211-02%  +2<<8=0/( $ ((*'.+*17;@FGLMUZe`geeVLEAAQe]dX\Z]Z^orqyyvwuuqgh`]a^bb`X]agwx|xz|spdbWS\ae^\YSJJ>DIFIFHD@9.+   $)/,+,529)/'&&%35AEFEMCBHLTXXY\UVMIAD<@AFRS^plqp}|yqm`ZRLHFCAJIKYYbZ\W\ghcea_ac]\SQPKPY]qsurbi`XUQ`iox~}{|}oc]YPQHMDJ9?1:9IUJMIQTR\VZRWRUID?6*))+%1/68COTclgqlomh\QTMQMUMONPQWc]_Z^]fbmdjamcihifeh_WJHCJOZYbfnojksfxsofkddZ_\aebmemlkncrsvwrkhheimrsyzsoivpptnsm{vz|yxxsnpnnkilhqnqw{w~rw|qied`[]]Y^Ybboffce^Wa\YRPKICGCIKLS]djvtx|ttrsmgc^VVYMH@A6A7KIQPUPYUXTb^\dhjeYa^XTVSQMMREIEJM^Z[feff`fig`da\^h_\a`dhpqvy|~{stjvomhkgejkllnotsyy}w}z~}wutww}}{uyvvpnuphpstyrwyzs{}{uwokkjfccbabjhjrrwvxxvnmdj_cegilmlnosvyvurllhlikjknqxy|xurpuuurnstx||{|}xy{uw~|wz{y~{zslomrvwzwztokkeebgdijktszv||~yvtqpdb`cW^^^jmy~zxh]TQFLIUUYYdhntxqkieqkmjkipxzzwzz}|vzt~t{{wztv~{uswknintzpvvt          "#                 !$.1%.)*  ")"           2,($%''"-3+%&%(*,%.,/95757>=MIFIVRGCA?F=?<?C?::=41>06314476;6535342234//.D;251>6684857723.092(*"#$&)*+.*;585POK?DJ@?;>B<BA?EG=D>?:=8==<@>A=CKF=EBDC?B@E@G>E;C?>;=;IG?>B?=DEJ@JBAD9<7873;5639>38:<<AFBBECCBKJDB>2.-)&'--3*2*.-/1,/-,+'),$'"" ,/%$&+ &!!(*(+)-(1234>98834;/71330;52.,+.&-**)'10..4..5,.,,2*08/0***+&)*)%)$"%$%#'%"  $ )"*",*)5,69ACKEDDHCG>E?AAB5=,:51;6=6A7;88@>77687425-63-0+(+)+#)%(*,+140745465:33730356296<:79?::::A;A6B<B:BBDG?DDCA>>;@BE:=497:<9<<8?2E8<>9450.2//1--51*(&'$('74-817@;I?OGQQRV_M[OXNVSW]\_U_WZ[]YX[`fdlkkjbg\l^aa]XWYTXTYTYQ[UYX\]]\b[_Z]\Y\UZYUVJRK^[WLNLNLLOPXVPOHTOLKMHNIJPSNZMXPW`^WXWWZYTWN_fV\Vej`XTVPUJVRQPVRXRT[VUMIIJFDC?BAIF?A>C?>FDFBNDCC<@AF<=?;E<BAEAERQCJLGROSQQRPXYN^a[XQUQOWQOJR[ZVS__ZZVYUZWY[[W[_Z\YUUZSPTPQVOTJPOKQLJLJMOIG>K@GD>MF@:8?8AA==;<8;83253453339185;4B9EFHCDDCBRNEC=A;A;CDBCFGFMXUTSW]]UXaf^g\ijhheag^h`hikacikiciijdgfhedbgkjigfcbe_eai_fae_jeihofdiccepsfg]gaa`d[_X]^Y`ddojgc^decjcrgiadfdcchfioqpqsnvott~{xy}wzwxsupx{yuspsrsry{vvquv}|vvsrxt|yxrqlnhnengz}vyz{x{xz~|{yz{|{rzu{q|xy{u{xy|u|qwxvxzyww~{~}y|zptpstnsvvormpyzwzztrsqzwuzqqmmlqqxq}z|w||vwxy|vsyqxoqkurrumowiemifhba[b[f_Y]UWWV]X]bb\`a_bddfbaacf`dddab]]]`_cd]e]edaca_c^bgqofyumhicgn`idqiicgedh`dhfkgidmdkfdlcgddhdgljda_e[^Y[WYZRXRW\T[^_[Y\[\a_X_^]W\W^Tcc_c\aa\X[]]`ZSeX]VUVVX[XTUYSTROTNRTXUUQQLPVf\^VZVY\b^c^hggfacehc`]`bf_a^Z[Z[]ajb]daldjoghdfdehmmlmgijagaoficfdaihkfofvwwltvpxyxxtrvmtzyyrvontiojpmjfjhfcef^fbgdfegoj{vvnnpsjqlpopvkuttlsrnzy}typvvxuptmtsspqqrpqtlzt{o~q~|x~|wuuqqmpqntqpojovxjoijhfgakcmhbjinhad^dddZa^^]UbVb\iWd]b]a\Z[\VaWb^^`YZZ[Y]\`a^cd`facitjeia`adfc^`Wjd^`XaZ_dja_W^\]]^]\ZZ^\[`XYPbU[MXTPLQDPFMHHMPMLNQLSKTP]WVUV`XZY[X_VX[[kg[ZTVQ^TRRRSOWcZYT]USPOLQRPPJOLKPNNYRNOQMHJLMLKSLXRMHKL[OSLILKRMFPJIJOKWVMTOSQRPQTUS_X\\[^`d_ebffoheicfcaefoeplklglbjhiciab`kec^abc`boeihmicodnhlioijkhmhceeaeceekinpolkppvpszzqyuwyw}wo|w|{}y{~~|}~~w{|}zv~y}|{||w|y|xxvysxt{suvsqwjronkljkdiflfkikikhirwupmfgkcibgdqwujofoglipkhlkkhpetpmfnierpohfggk\ca[b[_V^W[ZTUVWlb_^\Y]TYXRTOROURTVUPMGOLOLINRQSVUU`Y`ZZWTYVWZYXOURQTPRPQLRPPOQP[dYZVRRMRLROMNVELTRRTPPPPRKMWQNUOTOLPILJNNLJRUMRONPMPLOSRZOSQLQUXPSLUGUNNKOQMMQORTbRQLMPJSLSSb]NKPJOLFMARRQIGCFCFDF<F=DES@J;HF>D@GDAD;FKDG?M@JCDDHAJHMNNKNVTMKLHZPQQQGMKJKMPTNNTZQQOQJNSVTSSQNXWRSPQLMJOPMXQSNNQNUQMRITDOANIJJOIFIFMGORYSOKJHEDDEAJBHCIJGHEEIFLFMFJFICIFEFBPKDJIGGCCF=HEDAEIEFFIFBCHCLEEFEGEFGCACBF><>?:<771613420949CF856535795/6024,6,4.2,/,1)-0/1,/<+00./4+3.1049@9739,2.@=342-13248;5512712?F943;:212*,.-0*305,5).&/+/+0++0*(%%!%$)&.*-.+/120*.()-,/(*(,-%+(%&'-,(*()&'#*#0-+&-'),/,.3000404551.43<4C?=6781<5;A;>>C=B<A<>>;H5D?BA@?A8D;;C=DJAE:M@?9@8@F?=:>85=<?9<7?6=9:@=8;:=<7@:8:8596?B9>9@9==A=@DGLHDA>D=@@>>A=LKH>I<JIPKILMLJNIGHOQPMKIIAHFIGEGMSMOMQHQKROPOQTSVVX^WRUPOWSTSUTVYXYQ[TXSYXSOUKLNXSOMKJNQNTQOOJRIMKMGLOKKELKMMJKOINHLMNINHOFW]YRPRKRTONKIGFFLGHBLBIDBGDKFJBHDFCEDECF?EBBDCFFGJJEDFAAB?B:?8B>9?8?8=<<:<==>=><7::4838:5:58899?:::;<590:37.734..-/-0--,6<7==D622/-+$%##'!49/$  $                                                                |x{zyr|yrsnghfsjkjmplnigefahflcddaghjbeflhlotvv|x{{   %,.521@;HDOMVT`chmrkvy|~|yncWOJF61& {k[PC:# l]JE.&sl]YPPPKB;<97BA783:;9>GPOWV]_r}~2:?MThm 4MVk !2CScw2Qq:i!7Ne!Ae| 2LgypeRB# {b9d'3KM_F f5N)Z:p]LPA@B777?RZk(IsHu:[%5Ket"4Tc}v[UB>*!{_N9% ys^ZRE-' #1ITaoz >Fd@g}1Ws9hQb>u={Bx!Iu.?APICB9+n;zU!z8\$KC3D_} L\u-Ih| 6Vp+\?d2]*Nu8d:xg"}1.|R 0 U o ~ u l X E  P^Dn t>n$tbu p)K]+U8&!%Kt6"unA hDI4qZ3U 7Sv`7X:Y oz4Bt/o;o-e1Y:5YvDz=k3a;qCy$>k'=h7?I[pO({%y'"e GuP# m = ~ # . ? Q R > % W  L 3$Z"  p1E?v^m$byl3}=g $Fh"8Xc(BYo+e+| F L8m W;Q + ] % h   $  o < I j 8 LI,"i=dw6@U w3I+Jt'g@Ab>1-@Vr g+&o+FcqmaE$['t&9Rz((AX.;mF# +JaYM^SZ 0`!3BPagu}$'1>NXm$?b4V>u?3</]f > s G 9 ] . Z -  C y uJp _ ]57i,l30}\^>cQN:L,L?0hn@EIJr|xxiJV%6X#j|&=hUk+pL+#-Jd(S#[@$X-Pfmj`ccijjcmAh +W)[?xE3lE:y0p ~K ' ^  q 5 w    {  ~ NDYCf9QCb r_[aZ gLOME=8RvI~"t3=y*pe"z5x:O~]MC5%[!KzEg\({H a;8V6-7("8A:*Hj :Uv|uf]m9Kc{`WWVO[7l89VczEES%A^z?{n*GHDJVcmipo} 1+G:T|XDX1S8_,3Bk0-]t4a5cxR_W;6,a t6bJ 6]pPF, a:  0aqzOuZb{[;+ Yaz Iz(w ?F=cb\k{I[Pw'9P"l[rmO|@B\S} X;ym5'PYQ1t9.oXOAG;2f/{[$ =skvt= Z~BJ*{u|orD>6-l) ]v2J/GC9_OtPe3 R uSiz_lgim o4>9e79"3m F(UrWmHZ8r[V8V4T;{gDPC1}v+ I (#GQY_?hNJ;3Q<&%J0nIiw`{L0'FI3&+) )Xcmf00.|g8bb x(*_&l1lF 19:\mt C>Gdw@#ih ?VD;b-]SS#X7TI,%D A}ZWq)MSm m Tj+cye({|8ZY;j(#N$wiYZOA <9zsPk cBVr!uak5|,~ 075H2]-&mO)\]I|9PA(8V|GMF3$2)ri} HCo?qp=mG])y6K }~lFz^c[L]QiB`S]\.I cOHB Lus&'Bx1=5z7Dp;7M;e7YM FWAo)DN8*Yf9MF,ljvry@_P!6M0LT0x oXrdOhlhsG]0/9yf'u6Vv"7psHu 4$m0V]{V?IFkelNiC$8 <YO"}GB`7vi(;w~f5A+< u8*{7;uK [;K WLWws@Qpw4u!Dn 0e wX% @$?#*/xi5<BaXc,fc\K7bl2@nI.^ `@XVLUj|KJ!2|& bU^j]Tdov V5;%ZFw;SaI`t^R*0_ n<m34I6lE(`f'5]kHzK7B[PBw?Loa<Ny(,/ 9h %z  ^J1:n8MoU6",o!~F*NeKk4_J/a$@|'VfifgF3L}W"t -31^]nIqj&-s8|-YuskRJ 8=-emJnzZhi`&D=b 05u :a_^bI-BT3w]]h3FkZggRp&iV.)h2lkO/8T'C^zECNdfH}M5Kyw)J">*lBxl 6 Af5Ay,Q$b@*xAE^~+wxdlK js2L2&j>SmA1h^8]o9m)mB)En#a-Sc~ rK<e*1AL b\5~a~}7af;MW0+F$!Bh-<$5NlqCHM;#L 6lTU #@Dwkg*D}MGcI)tWB.(IYhhN:2u^ vgzzJvva-#Llk3J ~rE~%k>uMf|`z,rb$vFK|c%4WBL#>Iq/cSQj<}YJY9F-8uI"l'tb!9X!4@h }#v"8&zDek-CAML ?r(kCW)!<'?gcyeq vW0S#|h @ a(\Z+~zL(GL2lsZk6KwlW9 gOqy'(@ Res^R'ari>Sl+{VSc oA lS4X;-vSl65BVd;,<%G+m1!;,3?LDA;#'F[(&_5] D6 .ReMVdFyMPEa5[38; (8*O\:_qlq0O)e c-<s<SBt_)3Z|b%IJE@,(`y!73_m-Qy%Uw0%whvj$bSOFy* np #;-SjOa7:"#je<h0(Tk$%iTBz/?(E~;iv@Wiu+AT=z4:WbFabAmB2r:xvO*x8y{5&car#~gmWPJtH:_;0j/kIO$}~9vRb? hksMY\teI_[.?wsmH[~C+?CToF_-X<`}d/s%0_<AT]#q!?k5hxX[T~++;, s>l 8blYM)D{~*t6kKdCDY$"P</C 1}z \aTdua_}yZcp,"%3.< $Ub;uC%Mhi<q~z`Eg Km<<85LxL#10?;$*.'$+RK@OymCxB+ R+R9>PNH=AQ]N>@0L+"wjVA/.<>@<=8&1I+K<, @Z}N?Fs egd s7u^'m ai r   A U s Wh3S @.PsZy2/ e u2|\MV:aoCQTyUz:Z\xz*nUB-NWFB=PlX\C|.=hW<@:nzU* `6#+1hiN 8mWPzy=m75 P I  b  6 ^ 8qf5BRv-8sF) j Jk>&TC\,6dmWw4~fzXr."YI  5 S>RZ>] x A B^ m1T[k(vV:5Z9uG7 Q)UY= \/\L.i ,y |  .Z@:9"Z ~!!d""">"f! 4 H_  tB f'h^M/"K݃&ߩcRKAR.>7)fb " g ~s3]W[O)GR6P  ' }Q1 ffE,p`48V49Z(Qnz=kf:p d}|=T=urU:O9{(T{EK.Xe @ ) `W@U!&#%&()Z**^**v)L($'%$" o_R 3 J=S#aQ=Te'"  h\Z[[czy2NBD)HU3 R&de(&\mP;  1TETN38t+U[uF3u^,vj4"d }{Mq*? YC+a! n  ~ O!#%(*+,.///-7-G,*()' &$"BYxz & hn{p(:dkՙӊqҭmԈ$[Hܨ2 S ye[\^t~,0 93H(f:W<ލ\Pވb`j8CXr/U" #\ f ^ J  n p N  + A/iCA#1[@Tpkd`^#l @:@,k"%(*,M/E123043I3h21/.+*^(j&!$`!W+w nN-@^0ם}0Π-t<_г`:hBߜ| *Z2e!_"}#P$$$$"w! S!/i#[_2 3x<ޙݨOLI!JߏHa>PL69 t PDDx m e I yr@Y:;uNgqSC;~8p^T @f= 7!#&)a,/n13A5V6P777|64~3 200-+}*(&#Ba r8\<9> &,*yvً_|*К/Ʌɭ7xзVg|׹\')_oc , # 1 !d""#^##$&('(w(Q('%#M!N_o j{ZZ?ףOՙmqէ3CTp7nww we;^)x3 o  N, UL'iO) cH<-4'A~ " `=@ O#&7)},V/1<4}6_89":::y:e9 8653P0s-+(%Q!~ @.#>>==<:8642.U+($%N!0' >G,KFչӦr̠ͮˇ,ydz.HdՑٖ`WpX |r #&)+h-.>..---,,,L,E+)f'$!u-Xk O9Y!ޛVH~CжRMͷ`'ϨЮNIݖ^,]\i O>&^eyv&6bs?' vp3~=Eg|*( 9I)$HC([ G!$'s)+H.034685;7=>?@?B?><;97c52-0%-)%T!: +L&et΋̘siw[4ǢiʪWϪ5ܣcjG1.0Td t#&),D/$1X22210/M/.&.I-+M*'$i!;!y 4qM Pd-:sϿH2ԲּFsN,G'NgY XO!oU*pNr) *  FJQ c.6Cl w\ ~ # @!#&T)+.0'3x579;T>@@@@@@z>T<:86u41.m+'.#7Y5 |NBՌ L/E}Ǧǵ:p;W՛خہTMt 6'"%(+.1355543f2a1h0x/+.,*.(R%!QI K*}/w>ݾhJʺǖȞ̄^HGӼv܅(= JTn } oDvDL8:]_} D z7'D}]X+G{%ޠފߩ"`  =9J #9!0$1' *,/P1B305P7O9;=?@}AAvAn@><:87 520{-(*?&! 3v/}Pr΅pʷcIJ?ǘ7Jɝ#MC׋'w<{}  !J$`'\*M-02466676-532!1/-,)>' $d p' %;j3@xطHӰοɕjdɿL4v#q#B}|<   n_R 2D+GEV Xd߆݀O/݉=6T8p9 H 6 M##6&)+S.024U67m9 ;#=@?@@@@?X>GGqڜ0Ђ98',ȌYS҇͠>8ڼ $LZ5? SB_^cr*O* I zvEJx r|j#oZݔ%7܃W+ߠ#Ka0@6 f\!#&}),,.13468z:"<=b?AMBBB6A@J>;8I631%/l,)M&H" x^۲׈ԭxťs(~zKFfp pj dF"z&),.124#6g788z7`6420.,)&# 4 m&ii)r ʚȋ([ lKѐt׬%uNh Dpjo(> p T BBl{\@d +)NO'7]2ܛ!-ۨ7ܚ!CߒfydN3 j !q$9'*,`/13q5w79(;P<=?AAEA@w@?|=:]8_6w42 /, )&."sg }ʒ,ȫƄ9/ŀŴaƕO]˼R+Љ& 99f,5L7"%(+.j02467d8d87642v0I.,)'$ .; 3 I#)Q3ܶ$дγ67.@>ͅѳԂחݽyhZX u+([ [ w?J#4f 5Y=~DJYG۬(ܸܕl2y}.' [R!x$n':*,L/13C578:2<=B?@AAA @>= ;B97420C.+)'"x/ ,r1ׂܼԄ:̮ʺtM>ŵpjt̲Ͳ1&8h(U?) z H"%j(%+-/1 46788w837i5$30J.,)'$!?S5 Y c;oϾ͆F^BǦș1ϒ*$P\UQ, bWZ, v - nbDa:N v %9d,v=Zosۖ;&Eiy=J>W1 0X4v!>$'),/23579;T<=d?@AA A? >2<[:8t6J4:20y.O+'9#}kk1 ]*ӺIn˯Ǟ;H;vcx[Ά ҷ<~5X!tQ/  Wt"%(+d-y/M1C3^5?789M9752g0.+ )&D$! vosg:'k/ۀͻƉZ6o̡Ѿӗ֜ٱ1VOr]'_4 # -2c?c . _#"  ]{#ތݚۆۘq7޿߻S-P%QOXzo 04S-:+"x%(++.0357n9k;=?:AABBBA> =;976b4{2G0,($pF v_*jJ*rv*ɫH:zьԡ%.~%y "%'.*,/1{4689s:97s52}0S.,*(V&#Q LfC [y#Re| ;aدkҸ"ʹ`ȡƝ`ƎǰKС;/۽Pzf{$@ d ug0J !;! :<c- yZX^'L|܊/q ݤ0ލߧg G e 7"! %'*-l0&3}5>79;>?.AAmBCB@>F=;97:6{4(2j/#,($;S ?܋hcFͭ4Ŵ.<ĊƙtIZk̾}. ݙ\<79XI3& #&)+.146O88875310.S-{+H)&#z5J$ ` mX߇/ښ Kҍ3.ȣƅEҒIvTޡ vlQZ 0h2$ N hH @ T6?,'Aߕ݄cݍbR,ta 2!c$'*-0b35f7F9f;i=?@@ASBBp@>=q<[:77643/i+(% Y kWcڮFԺЫ75Ƥ`Iǵ(ȩȎɉ/d6uQ_ {@#&),/2>577765=42D1/.B-+R)y&#GV;  X7W[[6(47>̎ɛƞ/wwqڡ&9R ++o2@6 ! 3 jZ]lZcAWߨߥ.W> n PQ.G"0%(+-0=24"79;=>?#@@|@?>U= <;:98A7p52.*% >( Z7)=,?9ۓBp3ȪriLJ}%ȠnɦʨKωm h/ sU!$'*1.06356O654I3#211/.z-+)' $ W<C] [ }OM \.oc6=ͳʪș8te̒Μ&on/m__( U L 4uT>\izA< ,ko- lCU YX54{ZL(n>j{ z 3>_ #{&`)M, /1'469;Q<<#===c=<8<;};3;5:o863/-,( # N((j ot/{W#ʭɘɄgȐ/@DžAzdӶAox?q3E ye" $<(u+N.]01$211100R0/.U-+) '_$!?W %[z!!Rqݬ sͽ˰60ʗ'6EվޤJ4uZ~ c `2\O7;d @{ vrm!?/v?9#hu"thenq K  #m%:(C+q."1?3D5l709A:::G:::::::39:74W2.e*%[><WWCڹ2Ҩ<̮2Ȫ+LJʗ,iѳx w_I M,G"H&(*,,,,,-|--- -C,+;)'$"!Z {VVs G*QQV_ޟ)ΣS-TͷyΙ0Ӆ؈ڿܣ9 ~V-7UgM k EP{X-|d.* | ?|e niXzkfbTDzh=C=6 , c=!$&(K++.13C4?56677777$8@88763k0g,1(#JO  5@A-fݺ׸hWjVWɹ4xd́iӧ֥.CpQIvjF d "l$%&T''()****)(&%$#"! 9*d Y m[:׋@!Wҟ,RuՀّ6NAp0~>?H^^ 1BuPv 2 `  EZt AqBD' IWwjM= z0u "%(*K,-./0123B44E5#532/-*',#}e M*_yߞAFгoay"͠β1ҧ  af &2 :! "9#L$L%&&%c%$#"l"!c! V )xS_(os@؄֖֒׸סؐٝڱ\/ݿݍ޸+&L^X4Y 4 <C6X: i { ` 7 3Z4KxF[> ^:E } |zdB",$P&`()))+p,-|./1+21o0M.+(%!)o F3w [-C&ٰ݀ۢ$;NЎϧϰ (afEm+s\# &r_t P!("W"i"."""x! adFHP  b /a*ݸb2+R~ܹ :ݗ0C߁fade:<_b]_3S o`- ` e  ^ _@( D x9hDvO A _ !!W#r$.%%&f( *+*.+~+*(&#!sJ 6KQ ^d]YenM9Dד*ԼӉӟ ԠԧnךEs@! | p1mU2PZ-4Z .Yy2q-R5w:A߳qYkށߏhv <LW6c T a @ l `  <LH:X,kI2!XE]w & Q' 4yC u!"#$%'P'E'&%#!SxF  f _1Mއܜئqh{.ؔذٞaq;LydUMp2  ` =y? cl^U . ,llK NxEZLqZ/h ZZ'I3v6^+`@ L K G ;  G!w(r4K\79V}y?! 9 /J\5$ (!!""v"M!9w <6 O}2jXr@ގݖ:ۃ]ڣܐS|~2V~g`1!|L9 c  YIi)aKJ|.P X Z-nD ;kUIGLES3s)~n6 B +G`;.[ UQiR o+ <]Z7 6cF hD1J  } F;L9M,r*!A  qaY< K f ߺߚ߀߳%jx*xDJa p}*E0y( 8]72i a  L%Ah}8wBPiCW'(Ce'U{Q"m[l0\kUF'|/;8pTR2*D m   o  c u  KLz%ER  ~5TmI)+ e  QAE@8m)_ O ck* HNXO5n An|v f \ E 9K F Z 8 A  XEe^ \!^>$C wTlKh9O$4 7G/PK%(dyH ! J :  F  E o  < > ; % p f8DnZ  h H zF.$dNxd9[pYD,$TL?LJ;9jSz/ hk -  oUY|g%?w*$w);/tU0RN_*r1|65< X^I{Mb8rXH$ R Z   W 8  }  M I < o=]Un-+1&0r A]XQc O"Uo. [+Fqa,#X!( o } T D ^rf/i=RG 6rL1( TACG!!O"}o'2t^u';ZD]uD=XtFbj,sQ*0A2tj/ ]v- jTw1ZlU:EL69r5[ R#K  <$1plXPv%T3p]w  Go4]4v<GA|aE*XW=2Z!`2 K?-S7p&XwopKSDP_zR]$mBa%%Bj}_%#d`)*4xWM~/\CB%qR /(U}sq93&vmUT\'Rw?F"Cwqq<bF <0bSf.K*|xF. =b5"uOZjW =\|*e$x7DLE~H'y @%yx]muI*AR/;F,&:(>~O%$UuWSwFI8T.-@Yn.l>KB&+yi*IoA  PK"F:=1!JV:)RF*2SL?06@4 MI 5BB6$6$  + <2bZ4*5?7GVu_6PR2OLaCgvvWt[S]ZBGXZT82:L#dJ */! ,/&  ! $"+6)#)+%'-3-% *:70<H$"BU[;1dg[IMOBBFJ_e_/D[P>:B>94Ibs^M:SlgGB[vKR_icUdmmS; :e{iQ7?DT^aX_]P<F^s_=Lus_Ne\fk^GGj|njas}}zpmj_`fyro\KNSUNEMGPOMP_`H+'IVKALXH.2AR=C9.4>H:)7?>-)1?A887<AG8/4KSL68FQB;?UbM@78CTL@/<V\VA5F`aZNedU<6C\ZL<<DVNB:>KG=7BGYNI:AP^PEHZ_QGHMK>8=FIE6*)0@</42<++::GE15!3>@9,/6<.+*3:?31>KT<@ENX\LSRWVX]di^]a^a]l`rs|q`]r}pdpojfmrxjvohboxf^RhhgHHMVPNJDJH@;:IL?1$'3=9343,**67;I7"176)&(&$(,59) $4/7#--4*3?J@+!'7FA93,0<C;@8:2*,9EF=21KOPAEIQRDDRYL@4;BGIA?@LDKK>;?G7:5:FGEFKQWPRGLNSH<73;;D:911038;<;:4332=?;2&&13/-""(,/3(/+6*03B?=27JJF@?JMMFXT[\RLNYegi^^TYOZ[nffZYRUfp[ZQYUY^XPOPLJEM^QJB=@;910*)"%"$          ~ucJ.tCn -"G/'=M(frE( _1+;L1laGw'a *@yZx!y /Nu>8y12.5/ S]"gwP@<|e<&rhDc_#<\x E*e E_Ksi@'xhK{}vQ`~Z0f8V1{R+`#-`gFm +)z Dx 7Convfw6M@k+;U<g<m~{eH]6-^#FM'czeDt+]QST B1T^#Y3?bh9KMJ? (F+_kks1g>,tt}@Ra@KHX &}x? R#ZYC~vgUx>K8g5LQ0C9N{\JS@R$HNH?RyGS~hg6T'TV_vj<3+*=5AY 5Zc[DoS0Xg:lO9|t_SGs\KeDXY-u 7Qzn`4Y%TdQ9s_HUU!|q^1@SUj)u}7i+~y zMN d.hi,/-,M+% m%5Z@?+<g=n$G@l6h9J 7/S1v G?3odd<K-*z=<a+ ]>qs pDADE Er YJi>3?DW|t{wD4.y7qXiEg$>BeMQ^3 /y[-nG_gRI+_mK D@B}0Y;9gxm{w7kj/}rIG~@Ol3 w =B}Fda9Zgk&\[Vv_!-m88%JTMwPL,7bi#fRxHms%cQ>@"v .=(e$ 9lN7YpZE26f_mM&aDOUQ|sjL7Cyot JhU^3tV!*ZIa0vJ&qyG_"%OH9,X!>4KFJE(9WM*Dx|s .hG_gr>(^!B]J7\BxGl$+9,3';q5+8)+]MRn%MC1 -?ZoV+aQRL1 joe<6!LS?HQ 3.i*+=nfJ A#&0%o7%@/'@=] H+ rw4#C0 *2+L$Dc}.LeSYJOvE.:%je#M *|.94SR5HXX fX_LA)tHxhF$ Um S3+ %/)Bgl-"aVHC11[O=5+F`XA9>ZO@Yk~D Y}o+G=9-%sKA6 Eq#JW]Tw0#FL ?u G4H%EuNT@ OQ"4fy(')-7@- #FmhB1:LkF*-?<Q2Q:0`R!v!KD!''KG$=bH [6u~.J[]T1 /c.=d:EWe5U2;[dw=2ADu</0/!:J'T Ul GwO~LC}XF(/<Od^SL3'QT+[A=U)&)6vY yAg 7~,tKk;3w]%2+.:] 5Vlyvw~i^xKA:8\>6M'Tj92{|R&>T{L 3`+)pza!9}z$IoS,3vV"L~B,-0|E7P.J?$L^HNlqZa Nhd <B ;D >VHvgLU,{ cAOyV%{E&<*5b2fNXP,/ObB2" A& ^a*i+fdE{UYi_EYd#]j>+8Ih`%!4-%67 J8 \EzsJGoiK[ tg.+"n5$[R6Pnd U: <C^Xrt|0p{wD/`{gA0 "n' mua1\2 p`3MMxj^^F+Vn}\  &@?IR"NHOg+~ HAG^? 8]c, &1#GyK4bhzgt}K>3(Knc%NhDQxD@O{bWe Hhom_:5_<otM~H,L;+%Pt8d|}<6CNdX yuM@ZpCcRs|q[2@0p0C>rHO0XD/% 8?<>R_uuntO!cD=uK0euA~z.y.R u f R  @ &JgErclij+$#q   i  & % g  m% Z]%W3twzx%H;h(#wb[f 4b+ u=8%8z!0RLj# d8PztrH@^dbXA9J> @_lp@93)-Pds^mc   F ()evhuS"|$\@=h5!c}ug;L1QG]pH  o @ z F {~1[V)>G}T.uR& 3z cgZs:M|As@f Sy~I7?Q!1f 7*Tjp=5[6 !"F##&$$$$#"# "  y/uo Ur u \#eVzߜgdPZF: !Xhx%XA[^+  f  x 7P R '8 X > & z8lC08< 1H(Cj"d^q6flBN]Op+W2_mtL H, @ # Z /v$/:P A !"$##n#$%%W%$#"n!LL}a?}E 4#nq|-4H]:p$ߛߘVk'yDJU } b ne<j29OK`"_  ] d E*q=\{D|O{#-]g%&#S[hUXd^ [$]yyS !!,""C# $$H%%]%V%1%$5$Q#{"!E v:Fo46p 2 P9'M*B%8h%߳H߭r=/0nߝߖ:2 T!!!!B!!!!"#$&''m(H('a&$" ]t~=7] fTe}Z;Vj7Hۉۧi܅z.Va@`LUKYgQwZa * b } fs$7=E@z:1w  #O9%9)~*+Z=Na7-g&h[^LG2#pPO % x @ hi  n! ">"""#F#B##+$$"&]'0(():)('X&$" !NI/i()@ U XE#Hj9sa \ݙrܢ?l AZ1<r ߎߑ6FbEt9m"2Z1s.,> q `{{99&>y9jYY h  BCv WF_8UdPL-)Go _HG n n+o.E !" $$"%(%$t$o$O$#p"]"#v#F##"K"!v G@I/ $K1]3 /rIߏ,R*GH"#l'Ky'`H$zSf5WcH c 3pF4}( =d]aC & s OJ+Gg 0k}U2^.%R:;+5qT@NhgbdwD#W Z ql 6at$YHq^ Z7{ded*[ Q{)"&%c,ho(E]i  5 n U s B{4^&@ |a Z - e?hCW[CD X A M b 7Xm}/LT?Ak1ܘ܁ݘޖ߃Zߞ=;A(v.GtSb>=KO`t30Hi"Ai\ Cu0f6".:Vi? * *  S'kF"|[h h h$6mKv6 F@V k S _ 1 gUA;\!uPcI[ltQޤ %^kvReo^Dr K j  O".Yl$vT6i!j=8 ` ' .S[W S\: j7_CH53)i7p&~1Q KVZ8+ o " u = j p k J \&C(GnrP!0BN\r1(nX m o  |7V`H_w7>&U2HpAއM;LP >ZW) [ P e gnZ~$>j<J  \AZ |  }|!O[-0>`FI#gJ-(w@ -$OA\r+f %#l+N  B ~  J |N6gb$` 1'%\X#PE8sV4K[7%Nr [5~ I C  8 fB3 D1s,5:3p((! &5>VM0bl?.]9RS: 7  L/;QOOO3$b{(Z u @7Q$WymJR=t8h,bF1a@*\{8RK7Uyq   < n     & -    p  1Ht   48XXZTx~<<-kJu"GX @ 9 $ ShXY qiݽGQ%߿?  ,q:9N3r<2T#i$;WNg1 ; JfN#N mR0' | bQ5x g`%6oAjF?Pi:s?^)#-1Lb} Sh#X@~I O  E R L G i  p -B7/ER5)ga+H;'AKz. #*'(C Q a y  \ #2SH9oL { M:oߣUG<[; h[]Ux+ - 7xf)%B%:Z# n"`8hoW64]%s>F $?>[2PI7(!e3e ! C H  ' 9 N c q i u '=iY5UT qQCu4[K>zv @]+~ 0 i v 0 x2zIa4@0,qBlS'\T.(e zf(1* +Fb ;jWK ~ 3 o ~2"e1[=n Kv{Y@K[M>\KVV82i} `{-[S6{jOWX^ s { f B7>typ_SI.k]T=&*86|* [ n e F 2d&`;i~/d8}jO_2/Z|[+EiQllc2nN!\"EeW(s8g)f0hS2 Z"_D|f\=(yZOI;) xt} $&=EELFIPNQQVQHA>5-/  |}|{ETw&ItM'hSU)sC 6tOw F [ | t Z @  UFdis5R0f'c!t>b$T'sCjU:&|l]RIB;8)();M`v<_yId7Y+R3Rr*8FS]hk{|zqzmnfhie_^][\MPD>3$ zhYH9%tpaSK;91) (=0 k[85 {xtxntq{|(@Xt)@e|?Z5f"B[%>Wn|ynNG2_H1lN3|[>{`D+ _H3o`A/ucYB@0' !&3:JOel'2BRhz4:EK`hs}x~svongfbe^b[Z[TWVTR[\Vaa_fklnnw~#(<HS_r*9Ocr)0BBPW`_hkoyx~}~|{zzqmh]ZMA7/' oVH8& kTJ2.{iUM=4 {qm`\Z\RGDB66/-)*&*',,)121-5/1263A@AGEJKVXa^liorpv|{ %2AHV`it#.4>@GQX^^ehmrtu~ $ &)+/05;:<GMRJTNRLSQPHAJHE><85610..))- ~yxrdSPB<3)|raZKCJ1&wqjc[\UJF=93-!!     #&)43?=LMT_blt 08AQZiq$.36?JPYaevxx~mli^\RMJ?>/5,'sna_VMB@:5,$   $3.4::FIXXfhrz !%(23>DJTSdmsvx|}tuytkkcec_\XWQSKKJTLMCG2    vvo]UQSU`]PPcvohvxyx}s{vuo[MQN@OA&%+:3$ pK#wK=1jQ-9h1+LIB:<6Q 7;4JBo~m-(!~ ) JQ5),{fP*I -c;D}l\SWB'&=g27KXYpSpD}yfO4 E^0X,x>pC&% uR7tQ`:,2L}6HPkJYy6]rP~ D{%eEk_3X U y&]XL ? . w ) \ \ ,  u * w  5 fW@o+B3* P^ Lm:2s)wFxS.S&R D.Ld#v[-F~$f 8SvXtP7.@V$S| 0P}zYKS*=;[Uc> E D G g g%2FFFhxjGkQ"6(&y0 <WQjVE>[7+Zbj;FF^#p(9lq 2 s  @Gs?>x  70di%qSDSJ8(*&JxAU62[rrnhD.nC+s% B - !  W \5SbIYF APC p +!d!t!!"Y"!!!!! \I x*{Dv&ghebf ޠݯs5FDڮڡ۬ݢecIQ ' 85uSo5Ca[#H_ R cmCld- 8h(fBoޔވޞc  :mHbk = s;=B q O }?<$> Q ? r - ]xI&)4F !"[$^%&()W** ,B-.--..6-!+(&N$U .k _2pwAG!P!G;^lҞ4ѿM,ПДшX֠ݥs%sWKxf fs q! "v"","&!>l!  u u%<>Lx#`<3v"C&wT[2YU| far i O  .85q!QZ_j5  i & !?-l}!W$')+^.501A3455555d5w473/21.+($R q~ < bL.>C. &ԳF1ȯCɑɈʿV YߴMM! ; jPn1!"##$%7&&P'''w'&&i$"TlCE1   |GF1si'Jyݔܛ+۫Y}klpr^i#p f#  G \H2e{4CH2 )m@ ]3`? V %`Y!+$')+-,/0W3;5366q7898776530-*{'q"^ bgO,,VVEЗDK4a9˹@ѓՁڟߛV%A7D 8!#$%&:'' (()>*o*7*)](z&#{ S_< F l"xnjd[bM|ۼOlSڜ;#A!Ot(JIO;V6'Yj< Q 5  nJN@#&a/}Q1 V  P1h"%(*,F/p1k34=6O778 877654%30-**<&!I? ~T!?JB ޶۠؞ksMNǽ B3Fɩ]ԐQq[] `%, "$$w%%e&'''((y'=&_$!K 'FV$-^ns^!~yj5\RTJ~_=rۿ݈I;aFqx{V=Per01 u    F wgOP"a%bxasm-vbJ 4  / h ]/*+#-!#%h'&)*+-.../.[.-,+*.)&# I G/8Gk@W/GLny֩|uԗԧnׄ٦'z *++pA\ c - tj -M4h | q'o: DK/$%aOe M.N0Y^F{SaYL}I*(q(w+OW>X I .  :%w%<$wa )!! "H"2"!!!! F\ e s E i b3@&k3N:U}%Mi=?mC~KCU)6`;^tcg7m&-Pd<.aSk%Q"# cy U-<qB : 7nRQNr  . /  I%ur+2t# 6V*'v *]xuHEQ~+Na%"/J[@v< = i $b3y7<~ !"#{$%[%j%m%g%t%%%%%$#!]F+TBZ S{sa siF@7~uZBeNU 16u4 JoRK*Rzu2[v$ P  l #Vls]2 r u r  & LFH+kf!* a4o n+Z t 5et0.d`7 ?E d7O  z T Q5,M6} O"z#d$%t%%%X%=%-%%$$)$#*!{hO@Zu~ | V#| cmI]@|U{7)zH;od["']FH}Y GT@ I $ - Q 9 I  4 / q d 3 u  s  I^~A}@kMLRQF(@%Y%,0?*E  J mf_\\d !"#$|%&3&%5%$#"! //Pd '$ CLV,Q49.m"8#BclW] `3vUW[P{` w ( H  | !  D 7 K ! 4%\8E}80Wv cz9qZ! y\+HetV>2\KHUNdK* I  z ' H J/DCb ,!!"#$V%%$&4&%6%Y$=#! )t_ O c}u[4# N[m[]6܆ڴIܢޚ!T_5Rtv:;T4 I_' v>, f  -'sSj f,6u/0NghB19^} |?U?ONi:W_\D8H.Q^X04p4q$gL 8 = v YQq} nA_M !-"##$$%%i&&3'!'w&Q%#!aX CO8Dpf^x Pސ#ىV׍֯Cխ-׽_G+ L@3a'?6E >\gb/%Tw _ l\ w.K{AEu% !h/C4:AgY# c %{Gng#'P|Y`I`Jp J u7\,!#.&g(<*+3-.F%)[tߣsW%ޱ=fݓކ+3Qg" fd#2%' 2 M N  2 _ MF#x~ TSzos%ENv4- GlG  "#%c( +s-t/J1&34566y787;7p66w531J0.,S*&!p *"!dܨ7Zsɀř.=c.;Y=O^d K Qb"%p(+6./00.,s*(2'& %M$*#q!S8R ?7e _Hs1ְյZbim:ڗgܟV߸'VQ(XmqR# m^8  = ^L21HLpddk4d&f{WYMwVyV<q V"#<&),u.~/02y4'505#6a8:<$<<=<:7$521d.2+'#w x RE4ٵրԵ͔č4(\)$׋ۡk`ItvL !A$b'+.2i45o541.,)'%#" \d{V' Oݴ*ӜP<ҬwUؠM;GS?EOT +`S!$ 6 8$0ytl % LTk[l5s  98<.# &.(f*'-/12357999m: <9=<;997b5U2p/-*O'!<2 HP_xw9-tE+JդJǽh[PǸ̇^&֬Nk'?~s {n!$(=,r/1>33H31.`,*'&Q$Z"D Iq,  ~<eeqL xԒӂQ֏څS߄* KV IztITqA0. : $ *;2T{ 4 w l$<Z J8d}MV#))}= A H , RJ"~%(E+t-/03444P6-77666o664w21/F-)*j'#M  cBd'>tk&X^U8I†XH+ʛ̜Бh~ն׹Kf7Y e"0&b)+-?.-t,|*a(&%#"" x?0uS3   :x/\NgݷV0ߤ1tO+=u R]oD8&1P %Zm}l5OX&$E9uUY.i{&\bi@zZ0.? B i "%y&'J)+,X--.l.r.#..p..../8/.V-+)%!i g <_(ib ,T QY̷0D:rмs{?كFlk 0"[5o 6 Sf/!!!z!! w T R\? iy]3V({fQHD$fnS suz5A PkECB|Q!b\^P1[]:X0; n V  ""#B$N%%%5%J%S&|'(Z(())')'D&Z$!( 5G #sw9Ty-/_ \$iU$^\~<0Hc947 c lN*$BL3[1`xe;T U PY0i. < BJh(]AZWFXtT: \nR=xs\RTnt ,d 8)lL N ATq\* "#$% '!'& %$!r  % jBen 7/3c/7ކ߶2&Gv6U{D| 0 , 0  ! \  )vP,gLkH   Zhjh?4>NV1*Jb/EioRN,?7)*"1SZLi;Uj_]qw 9 -  ` 8   q )   : W e @ D N  D e | v )mH" aUBP/zLRX ;<D]# . 8 J > D oVGo.2<46a0vrcenZ^v/a"R+BfPdHn` Kj <  dvaNo,C Z9`=$n{HlO?WRS m*aupWx 2U$e4tl[5U=[ t  f D;wEGY: ( Z D   {  7/w=  S D V   | i QoWh@*7YJ #0k)i'/RUGYRxgme:G$HKIWKLo]<#*>N8"-Rkt6SYyC('] {jN+sFZLmnbggvXMw> h%maj>k_Y|fQcJ F,m <*~ 6bT'~f> #hY1/l;`~;UPUB*&?s7ST|H&N#fUcK4 "7L'sL,,Tw!9\okxz_C3'@MH)(,?pjCf[J'tf]gh'8I9P[Z\`ePDBNPGJMS_r{}ufQKCH9 $2C>?3)-)  sslhnhry~#2<CKXlx,6GOXV\eYH>* tmYF6/#vxxyqzumofeSSLGIGLP\mz~vrjmbQOHLMTWaipxqz g[QOINSWbanhc`ZWORR^adm||pnfg_c_ebozw    !&-266579;:99:;9=>EKINQQSXcg^`]`]VM`[PG=<43++&*&   %*#)%'+ %*2*5,,1)-(-$!"! !!$%#'(*$-$/%0141-2+50124286:4897460),(***.'*4+7*232/0165A<:>>=:B8E;FC@CAJAHCU]QEUe[YNTWeavrrv}rma^\XSSUPMPPOFGIHTYFPD@<>C:31)&!%''/0$*(  $,9=@:A;@7<2<05-82<A<A9<AEIGJFGJJHAJFAD>?@D><69565425237582620*-,.7366;A@C=F@HDGOPQJMKNOQTWQTMOPLX[VX[\UbVaRWSYNOMTTPHDA==1=0=59>FBCBBAECDEH@FKP@HDB<@>C:8>8>B>CEJK4jg=#FNRSDEJMAHTTPF9@6;23*2B<2(-:71/$##"$          (1BVlXYAWPI$Dj o\yh_CY c# -P .6Ilo<} X0&WQ41\! ]hmY82C-\7-/AG0GCowdh|D? ,3snK ]rIkSw.$ 9t;b| !owf\wuH,~mW8[!Pp)3aT rS1 HYxJ% SJv^T^~ nY}? 0| H)GjL @ptR);5V7 ~19bB~V6\&k, ayM+. Lx*_zf%2x38j[82~VT"5X=DM_|74Q<0k1e;q)_w9au(- e5-wT2<=K")2 oC=88d:]g0 R7}\yVZ vo@+'93==lC~AkOys ^z&3>MwY8IS~}9%y-jQ0*""uv:5Lrx0;cl!,7%2|5>_+:RH4'w3yfj La%cq[ pT kA^q{[d 3 MI2R"QWOOXG:t_4H]~[A->Z==83: V]rOw&y3[|j a3i7! CvJx|NDu(K:"l/(suW]u}oX ;}|f:D.$,pq.X{@wTw)`1h/Q <`.g9tNRR$M)r=]1 H'7iG5af +z7^zLy-)z)Mq5w# aYLM{G =/5h+J|+-)VB_aPQI.(lA8Ko3D+k)|80[+?XX[A(yzDPd:  L5_!?Ab4- X= qs2V$ au;[t)?MC,~>,<=WYS. w&Bh,t,UFYd")* M' n^Eg0gp/xF0MX3mX{Asg;f6v t,!bcdy8W\ 2!R MM D+2h_PcUuw`)8o[$u2QN&mB~hR8 \6T62 n" H ;2!`ymW~Cx6|; :@0)JKJ;\R.3P7  . U e , b m u  " H W + S 1 B < @ A  7 z tw2xU?YjTWI]B0f1XY*^)c$Lu1VGn5TRfyo%GE:-!N"&E^=139X$pj98tY F d I Go,u*`cqg'9{&D}; 0 * j^R|O?PCO~ %xYZgXLYv V68$sC9c.D$bcg\X%H@PYpN! >_]6w*%jf(s%s:&l?vU;8(~jz9+g7i~[B=5 I Q X  [ eQ-~cEI\!vt_c( <-q O l ^hOO?_tw "vhi2Hgv>VI `++89"%1(6%,%RTy#)9V y N 2"EZUZdL3!n4a?0]1/-Y V~%u<:N1 > ^ y D BkG).B|zai4cI)2d O R   |>"~! XT|@>2h- ax^Wf j"i^v]2B5Db&usx d7]u C } /^qZ,8Xg#V0An|4d-=R=De}(~ lX^A$J2k?C 1'DF~J]@5t" 5 !~r ' 1HpjE%yCK- @ygQD0%3" hE:K/4;7! ;HN:sjL 7 1 v[-fcHaq5;{5$MX wq_mT\YT 9 E=awJq>uaTP+whu%3ev _  ) ;  N;hTl(*Wn!qm.|a%s x,Oq /H\8 $-|VW~G{j'g/Id07R6j6 ' jvZX,9LND>tp(k?G7;D'Xwse=w\s{jfu  ) T M 5d{utA.{! XT P   8 Y m6z`8":?F8c,+;$yL}QWiRgvmiEo)jNQ_DGhz|3Ac"U5PxjAJ~l6+6GEC>]y"NeF @_P"e"pTw} k ^ Q ! EI\gqC:cx*I 67r0Z : A h  ZRrmt;R ;bI/15a ` gudgjUAFs#Ov@:g'1zrI-8g+{agQG"HnB*1''* `kUI%nE>tB Im 9]89] w  F , N 8c9PvYWO<%7[pR X 1 w q F g~v['nqeHT',:41k+,7bKj,]>ysZjuAoC+Tkl- 7* [U:${^eR~S!m- 5wW p,u2  & 5u'i[Xs &!B> '   _   a~G5 7<-~pN.I7_jbDtf3vz.l>xJy_`v-htE9UzMItdA]uNBK0]cw.NY k%ENDsiFT '_5Z5h59G7~Hud*I>y=Cc {`jbRm}|t0SbR?>lYw%#HNZ_v < M:FnH_Xm  m K  &O5B[o[^S;,dr@`4"u+,$#: K&Zj~ O!8!2p,B59534<\}~wd9V9 .1SqQ E$\GS/Hc~qc?'n|U Y;PqaYpm=IoG&zltFz&S;6} L  8 x M!\thuT`!<C2 f`!h/e* *ckSFW1GYm{2ug00rojX7?_g>&9Ut8eZ.9;#1WNhdq~PuXfpi[t4r}Z0Jq_=)<pZ!F9q"zu![x{tbRYX3 6$lqo4q`Q_Pz='3Fjm\SHFF/%e< f4['wV5oN8!mg[TG/&~zzrpjf[SVY]RTTh# "#+4K[jmu;Rs twuqjhiad]he\ZNSOPQRU`S]Vgp}&'.:EYn    )<EDQYZX]hpst|z}xnYWPS][YOP:?:>500 #"tsiovcYJ:2/(/*$'     !%)-283810-/5:4:?<IJJLJQUJF?A;41+---0*,-,)%      !               }psmcZ5/#Qz0aCNZg/ZbE_-oBR)8&|tk{pj@3nB/d7! EKOOqP#fn{4|%oZhtL>'#SJ ]Qy`Oh"Amc)" l[p7Bc{za4*c)_ + Rt#>,3CzI  O(&xl9p{ RI#UH&C 1.:I_2BzZ\CnqD8YVdOTwB7c[`bI~ Hf[q~.XIOb`@v\0XhtPjtFU.DT#P`fTo.6u$eSWS,"+3sC PCu.r2'4yObd[WeSBQbP'o-,[.S2If)DN (>`qsx g5-V1;"|^- h~PM1d<|ow1GpR.aKY,<;=uS`-bPFFW;f 9(xv[~uPs- 3iG3-{(l}a6c?Vguflmb,@|6kkK&VoE8DG ygS,Bu,ra:]>Mg71uFOr}] )?e>}jnD=0wJx ~e={W]lxE,6cu~7"i<bWerd~lO PpK]S :{IqS3 52 `XY6|2)-=ev th~@[;8kU~-f  g]G`phSsQ)i;75 -X%KF6F=de  (:|y=U@iFPNvH- c=wrd/O9j*pQ58xR!0R&^wuqV+z(GE}IV^['E/ J 82ckkypy([~FD3.2tiT?) !   # 3  V B < u z C p$?^G#&E@ F{_/zo*b+6GN&i-c6pADO$Sje[,B*MV4vgP I&{`-q x .sY ^  J C 7 C _ d b w *{SHf @sCh .\`y[{-J8|~5nv], *Cz$urw86BQnWead9&j7oT5{GD^ ZVS=42&ZXgsx5Fp53P_Z$  GB}"%Us *Zv>- T)WAB z V + 3 > b79Stx<JpH Z @  fH@Zz9C* d9ydG,'rFdIs!Yl-Qd@O[MTS[~z lbQ3j=>sP2 -"n2 6tAw\Pdsqz=Z-P,zSK#EGJS`I+!Jt9[mcFA J  ? A p \:6(*/#Lx=  ~rRA/>4# | :>'kv449?s~P!my6r^G8ea0> !si,8_l|pf?s.dv@ph,h&aV54*%!.C@86Ih`.72a:@1tLy@ <|c1q#_p}&mZvWDY;  ] N V M '};[S\aU : <.DKnys3j`tX*@4I_fcn~?OINYz;u D>Uksxsebbj!n,8d$U{whUQE^?wP9eYx B G UY`bF.].[ A6.x.  { D  N Q w X # E (8K:  ,hTS[8o)"LybL.> 4y PZP;e#CRDY1!+O9ey^W5V=qSyh+D'e:87>,w F37#e=q 5uL?_$C\ovv;0tH%%  T0ALd4,GU HZC;89peb<FS)n .V kp[E= %g$\V~hC ? Wq('q:N{NR` pH#AJb|b1R1< `DIo:\k8i", Jad<ca=eV 1"4[WH{ c,:^B; 1BgG$qLxr@?*SlZ'Vp W?vB\20T)Q:m(M~\i<`o)>zU2`HySSp ZY9_Hqt* *jXW}&(sO?&#~k/xU,'z1(GcI-pLh0 [Gc| ESP;LwzN`<kv:vb3~>1 qWv0Yw 0\Tq%.*9yT)='SfX[uX3;7o5viB%};Kk& @H=Q.4aV:\oN/8k=/wdEpke^%+5d0b{1M} "]TBA a[k ]f3M-d1JmPqaI / #u`D@O_^'gC5:T: !?A>{- 0GwV{R][>g |"?Wy.."2VrEV8=IFuM aHQ oI/pV1lA rk ?G=ZMfEEmS 1 1T@HgdBwD{/C fWT}u/Sq^+gu:/wh"c6|N'2+9{jV 7z)>}lmdtGLO#7i9Z:6v IcM6[qwBp<(6q4g/7_ ']Yrzs6$,[Q`c)Eoo"XPo'gvfYL{Fr{3m~Dc|X?O^3K y4 X 40UHRy : OuIQz,:y:<7VUbF6+A)ZsT6 \K~:n9QiVx+R/&XMJug*#&v[ Sy y*xCcQf(1fJW9"baDY  UO1pSo>ChH, ;6F'l$: ?u$n^r6'bGpmk%$?bwGebZpq[cqYiTZ#w)RZ7?<BnAA?tOh+kTROV x.v5(~aU}h)(vmX& &t;J >V>eyFGfD|7`>)1!p_0GCZ35|e1quI5&c[ Ml32v`d yp_exvxh^vFaR.->>Y_5;%a#@ E%+r#[Z M^j??zD.3BXwuU9Dxf%kNR4 +cSCH5&"x]7d%tn\xG['/y{fHU:{ {]##OPE2#@[uz,IAbq5I< 9h3274 J'e@CRoteMb|;zqA&uh!LReNvbI|+i#6vA6\+hkyA Ht\i9Z<J68qcB&6#x;{,w kTOcU$<7ohTv|.#O{9< !R2bTpBpW )~3$gDfEzSL1`IF?0AODg'U(/ytFbIKHste79"zu>UzEiJb@bkH[TjpaDX4Rt>0 eaN3tQE_qU)}$-t!Qcu>9xApsbQR89qQU)(E T=@KI:J|oz2/wG.M?c&}fRo| N.Lz0U"E:F5/ d1=#Q8L{0h!0rY/}5Va~8/~bc]uOde__;!'>tZg_KGJRRoxG#tTXk:zQi'0-)III5#&_&a cY +{IGc9t#EN:e9|GYqG@z$ A#~M:Zj3"@n5B~#. 8x&(3s/8s%\}DBWY@S&O(GQYMFWTxRU]d/bIx70id=& :g=_gs Y/Qma -[PrCXS4o"2rH[\Gu4tkjj: 9/.?I6}VL  oXqm~9Ne~ ${ #Ehru5D5G@_A_))E&S`#g.'i bGvfR3_BRPiYF0dW=D|N9w.zZrM-d"7i]Ypa`d3O) MpyMzP7H<'G]C>C.9g>o@/{vnD 6C<^sNF4 $&~h7pj]icC)(Jz)Y*sMjhRo  7Kp#6NF=NYZFQe}iB Ap Nrb>y@i6i"oNbYGNLhd^ Y%,Lo0rq=(p2`W8x '6WOVtm oGjOGBB (X Y  _<uA` X[C3c0H>0VhvnD . s[!G 5T74WI9pRF8U] AV   t?0Z: B"S N n _C=-D{lr;@L/b|*8?Kcam6@NLRn5z/DUdmdHnF gHmxfZSbm 9m>`]Gj?j* A~  |, ^ M !#$%'6(y)*++ ,+*(}&#b d 1  |-g kf]7؎?KڑsJ/B@}|9C\6 OueQ ~!~"i#%$$$#"-!hweEQ{ IYCWU=`G&߭j{v];MT4- Kq1 7(  `^ )`aYzP y1638  y x8f:_;U~ !"#$%+'2())*H+;+*)r(x&# !_0 @m_5NpY֩ֈIݧYVB(iL{G8x* 1? "*#($$$$#" TrY$ l,gS2?DG -9^/!!p""C"!F sy5x T & 8wM$ܖy۾یܾg5^&= Fm=;b2 :8r"juS 1 H= V PQ^C`VWRzV lAet*zA  Um+ Q) Rx>x4Hu" #4X{MQ9*_^> .Z a@ U G >Es;HjU?H,)hDSZ Pc8 I%7diJ߬ލXWoEpV3#c1 F L<(n TlG,0kV. < pd[.F$s74Efnzxb,j;4 EIr  g Ih=<hud2<Y{R%o$+r fw+ߚߑs:% p9 v/%qzS@g  JiXG-+- U'-T >r.sd5i\"G'\C<C # L *z=I,    |HEoB {!u )?fG]^(W/Bx , o 7&<+t=b?7 f 5 <=t 5 m!8BmޖnQޣjߕLa'QC#$@*  cWx? ; 4'! (`O*D<P=H_&mc pW| g 4   s  5 f  5ZK&6Qd|v8Vh |D@q;~ 6*U0 u @U>`LJ u!5""""H"5"!;!A BGn,b0  r NdNF߅:߯|$Wn !B `S;)*`' c[rmEs  -cmW I 7 0_)y|{[VEHgwqJ#@bQ`z Z?  41Yc Vm3] `jo.[m;*x ;X>al3$ y*a /\5tL!O(TpL=/:\*dS@ 8 " G 1e0Ef*Z "J$ &&'2)*++S+%+++*D)p((C'%U$" !:R ',k4zu3ޥ#٧חlT՘ִصٽt!^Wsbx+ -$Y9F`Uo] s4_VL[yv?N  x`%b$RkUv% sO|Qb%Lw4NYb@Gk{X)FlFx$b>fKgWE/u319If<  i <b  R!"#$%&j''o(())((r'&%$-"8 N7 Nr3s?W9k7o v`ۘG ټرEٺdqܢޗ@A#; < [ &ctMH#FB5x'OGW D?~}E@7c+8 }`Z(HZWCeqn!pn9sAegP!lNP! b  } y #34GSq#P89nTU x A 12yt[|y o<}8P(I v;B{o1`.\EKB $Nf6 C r z x d M m   v |Dd<14J-v[ '< K X65t2ts!FYoMq3z b0V$Wt)mPyI  ] 0)* zsd Fm  Ly-z"Pu};L,j isn@ b>$ U_AZ@yR67ffT H z 0 e R #C XTN=d$0R(WP  ^ 5/]rs0"1L4Mf >?v((  1^7veL/7X{zfG0s~ yUR7rH ^a  e E  j S<lY+c R <hI"D fn.~JX[^wZA ; Yx89F)~Q[JTi=>oA|3kE/EY4wAv^tO@@LSes q Q  z<a&e c B G " 3]!Qw`kW`3=SwM|v_?>=k$u3skG<@MFKC62(1a  H  E l 8 r \s+n{%`Qmog+q q q 66}KKniqpd~C>aCShY;0,r>h;jdN;/2R\O8c % p 6 L ] c i ^ ^ L  7 B L = 3<5ioip`"2qO0+O0SwdG-M9#RvN$rZA+ 4! y L G - h - g b/sPCDg#[p+8P ;6n1>; 1 ) # b v%j\ CK(3r8.:1'?z?C$e6'JhbUTZMbAaNx_ 0 1 q a  F  n  'OBe:'U7~6fV!d(u@37%6k_^bMD?j`"i&h5;>W/BD z o - o @ _-y1j|v ryp M Z ' E JUbS \RR?^D=@93+-))'*,*+02979;BBJGUZ\b`urz} 9HQV^hm|~||y~smmliia[XX[S\UUXTOMFBA;9/,' ++0:>NUS[\__fkpkus{n|w}{~}u}iom`ZTQMD922-)% #   )&)+)/439>DDHJSLWKWNQOPROVSXTR\XWNULURW\bd]kegcofktvv|vvvvvsnsjsfh`a^]W\RQPQOMNIOFC@<67+,.&+1(    %(',+-3AF=>8<:ABCFMIMINLLPXdT[MTUQDE@?<97:2908-.)$'')%$"%#%& !!#%%(%691/-1796=5@=<AEG>DADDACGDBFGBC=;A>;::9@?=4836@50(-!$   $$!')'),+2=35,)-%-'*(,'&'%'%&%#)&,#% ! "       "#*+)1159;DDCHOM[LVWVYZXgk`hdfbaU^Y]YTSNMNPILRAD@C4<5:41/)2,+(&'! !%$  %$)*.,.)0*1-0-8062773<;:9:EFFIKMVNY]]aZXTRLKEHAB99:788465& |R0oG( !DiBd' d`DdM-*B\#7bO&7VAD&R[,'|&;WFRNY><4mwis)~R(VfV9*n0~xO<U|Je/V O]7?.ikX#QT*5lb`+h)q? %"}x&Qm+$w"1`7M&Snl2p;.Cvf6 al2SY aA l{w3A@  B E>"alCeET)}xlxY\ c_ Ug9e:3}(df , Y d D R T > ( v #<Ti :J\VNk QG;_D0 +APL.S`ksA>q&m 3 q Q A A ) [J"\t#|,]&IMQcW Q!mmX laF%gcC5UYRi: [v rep~TQ@f6Ae _WQ r*d4 `   S & t#LrKJj#~)y+"AzRoXb$%<--s qm\Y#B$H]7V5g[ X , h ` P h wy|pMaK'sA#  ? $ 4j}bqt!b\V`H -A=nDG=jP+ jg^bHcNc: = W P   U~~c8`y >@tVvJAS1(HnHqv ?";`I4;)h aL8`.g(sE" m  # ( i + ] / \K!rhyVc h?LYbOKpvV^Zzo6LO? UStzl hI!6miMOjjZ$"u(dFYg_TH99 BY*kW]]b](|OKwq'q|>"`$(Tv6ECCSoV;oR / T  P n iE0Na7u uPU87m1 ]D O} 4]V>s)8@g#~f#Ru:hr_ YHDm#$G3T.{V6~y7|upn]`;EyaRKOdMs0rmgItpuod`eu [vJwvL!3?Nct,+FXM v Q 7  x   ~a|% 8+*L52Y: <GlO|blxS^:lJrhPM}om ]?'YZ"Z?#k>~ ]t^TF&)|@V/L3A/y"7'=(Z-J:0{g,`Ul@7>4S :>x>pTFY^[f= 91%s ;!X>1._ ) l 05|T}i?\)!guUb U@ 0} kmYZcvT{}7:K"J=E@Gx2 i_Z$qNq6&t Ds;NA Up'I}J} 9` hn3V9X,NMgo)=Fp)&` FC_!5et {UW~(BIrrrU!3nbhvt%I8/AJzp 4Zh4{zc`psnluPr5 ^O+'InH Q>!cQ WE])TqoJD`vh1 \4IUJcDCc 7QbaJGX?c~k[ix+yr:PX:GL:x+bg* IF<t<S&TC+7#i] (3hi`,;d3cKnt#zq2,Z\~Q-<+%d0w+g,q7b v v~~C}02@Z!p}Bv z@a1t&*+*As$m!-3_1/2!TQL[Tt~j\{P Af3[sz-={%SWrZMw*QorJ`t]_oE=dhxE_h'%5 Lu#}p;$+*3Xf)ONrzcw[>uw^X_.(SqbIGhlPS wZ<~XK/_ A"a>lOK:gu\We79._c|fF<}1;(wE5 oMB<(X4J 3)#[c_xXwrw {mR(O$z44; r& a -d23ycKB-B"q  OeMTwsYm^ VS5H]L:98QxXKF0MBdm`AWTg}!7QNh1F~!1rfJM*u_;?3$WvdykF&,$0#Vh6[l^"7Pu_O3Cp5LP 6ukIVD MzIpLJ:-^;NJdt V k~vDPI )Ie B/>qTF3,>r- \})/s*YBR?Iz{p)-p+> mzx@jBE-G:E~WwzE B"* \+ z/"!DT:M4!*)_#&N`sJ +|"" =UE#\d9e<=3$x  _\rAW.3 - .1=t+Dx MYj\9+*  @w|iwPyCAn X?s+m8UECYD-gu,&Pf#e!_ 1[ {Q im>]wrm "6 *D;:C/7? 1o\|+M2MfR5tmn Q1w ?i` e"U:^RZ{"{0zy0+rq +-N,/TB 'XE[0,V[G^^f;gP,&vQQL*6Tq$O#=)v lc_  UY<S}KJ^s  o&-D@]Atl0|ILhr' yZH&b)_.KbZ:mz0tk9HN*GG}X'Azz&AJSp.$%2.   {v= "ed =t.;g VP;Xy.Yz-)oUs=c9* \ Amh> ?  )b_\63Vn 1g2 9b@/3kHl+hqA>>OFRW.sIV!@$8vhn 7/_ JqH^kXR'7q"| &z~y})UIePX7&HwSE,?\gey)*_{[I+oP=?aAp=B`nge{.9N"\5mDLFkd .:Bso"5b]pYJR &M%a!+s80&>V{Q  BW lz 0o(i=_) = G,#8) vXF1 f"V _(d*U!2dR0Y[ZeO5pEo5"3ZE;N_*';@v%-kY 40bk_{4@F_Oh+dpe`,}8sz`)_B3[>E%<B5_%YF(l+rfR4Ou%e =#o< =K@Y!!;dC9_Ocp\q&)\-e]US9SoR@D1L/`#]Ki\nkRV >k? gf+!yNWW*y2|/k:F V@s&L!O5+w<&N) @2tq8I0{vZ<2hu5pY9 .PR,j,\wRu0Ei~">4RjN$r~"KcO fRiC[%:(uM9'yU3P G{l1vmrwQ|6l3u#b;@n:VXG O2C1f NK)Atkp]L@IO~d7v3KB0\?t 5~ i;tR,uB @ t +  h t V% ak(08Jq\p74DiY#N V_YQs . =N@%n w930$@n8evECYb#DCU}#&R|~JB{,_swpe<c>lAZNHcg\MMkHL!ZGH  1/vtNh e/Ers V4EdV+Q\itl{)2Ec/U':8*$0SfZ}?b Z+wS R / $ J 0 A- N XGq]HQ@X8!6~VH'5%m(p+"&:9@Db>y^D<4$4"JvEq" 6]$Th*l^\8PAG+   3 \ v.R"$I  >}SO,{|Cu=g;nma4IvZ8k{.BE/b(([M27PF!d"lQ72@\M_)}rv # . '  (EgX4eT[Uc {MnTvu1:!je7*LNpZzablYbr/h9 # : T ;#FatXY  tcWo= */2Dc88K{uQ5$4Xhb* f>s4gO;imh&`G8:LZ`,4kI( V W'rCjA#?'}=(m!NBw  VfOfxNMi6fTA5>RxO]w`^i^{bg3oD l 6 7 [c,W'bz=6 ]>v+- X  p1CBv."*UYD_nK=YY4|${\{O)'L31QbZ9>"K*dxc!n +  ZW\&tk!^ZTzE ,Ja:d !)(c(nQ+Z?nV 8a[oR\iF?c!t@ r B .BEX}#t]A`dr&q  ! r|2X0ah?04?^b)X|{A7K238B !=<R= u:U<,i 1^Zs'g1 Y v x ^ ;  cdi)8b<(=tp@ 9b@c\2^s2-V:Cf {K';n.q;%S$X e)fK& c y] )=Vw$E`iP. `Tz~ q  ]qJ4y 6*A:zyV5T*oyf?f'?B]Bt_lUh{Y4"\X ec{ Z C  ? P S > ) c h. L.u\U5j/0|X4SrT9y PxN-n =?[*^o=G*iA38>D4!U/   G qH M|#K],ds ( O h i r<KVyy-s ,[aL)FT'OjjS1+/j%url,m2^)k) y5p{ U_ M % ^ m r ) 1 0nN 53k ;3rCaN m^DmQMH $hqC>xu)j A$31<F5 V c G uY 2/Z|JV[h\:%PbCDO_C] r F % !R}hW1!tLs~ Jp#F ?]pl <=EBG)&4=@"Zuv{,{zSn> vX z ( . . "(3we3J~ P V|,1ANfq~v 52(>btDMgzK?X4X Sv <[4_uZO>' -  w N l : 3a +EfF|(l-M@Wup&+&AJ ; ; L W 6vDE:Y,tpC^Ub]{ug>.q;*HW^ZK.M[ NrHFOj6qYfR*tEkd 9 Q f c N 0  J |c:H`>=]aw FV,K-inU/OYXp%*UdE)2B*{92\"rdZ>D,'' F =  8 F d 5b,Lr]i *0 3A_UDiR  $|}SiK+,-JH61~rH(f3S7ecL'%r,Ux+nG$ 8mEk%Sr75N\k\,;f^QNNGbx9>mI@Px#.psG.q*rcO" >`4f~ y[xA%Jy$o9V` J # J f ) N r $ f GqG v I u , w ? L h n\z}#U{"{y-^P2&+(;Idz?i )DV>g &-:EPak/Ldz"Lt4V|)Pb}eG"t\>.ytUF,}VS j<X5{P*u @a6'!#.% ?l1Ns#[^*m3mLMmV+oCG1hS ~]8 M M % ` N e?ju ~N$M  } q   X|? a4I Y b m7-4pbW'z|yokly.eVL:Y h8yNi f^{0~!jE;u>g+EVfs[7 OTv6Kd\ U ,LT z)EK3V= -LrW:}x6[6/HqpaUZ}Bn$ 5 4 4  s==  r21^g1 N . u dO*J!wUS^\) MIZ/@ :}CkzDwP5' zX)}/."kO-\Dr?].9RUWTNM@3 OW>VGL cA$n+D4>v0x\:|bS908_Qb^)x lM2=['GRF O Q p `|EY :93.d(wTO I $  H  y~"C2(oIdC62_C1q8qBuV<3.2A^ I4v7u H2'(oa#^G[N. gBk%?ax%2KRNNDB5$cE?[C';_YYc}$[51cw{5`z#fB[.dt__0dka[I)N b  E ! h R8.O73')e@(er'e  N v xP}G(%N!zQ)3o/{$WLBI]&)= FzH&=GZ{0i)-&'';GbzNR ,Npe6wfN/o4w/#Mro1<%k Ox\$A bz'J/'J{<|/+d7y],+)7{A d * k X J /=.67L  K / xB5?'*Lu|KF F e hN{3N WZWoO"8>EelEh3k'N^ oiWK,4Co&wkq -Eb {K&Hx7zapcT-yHU\8%5hoL? Q  F Q -d2)=p=w3Oh !tGBe jPLx85{cf!Hu]T_Qgu`; 1Ol;;,8yFY4l"l@4W|-}0Ml6h!q2sIM`arO h^gZSV_|8 &9Y5\|vaJDfO4X&wCTpf8J"M `.z;] S # O >  d M8aiDoJf7 G 9 D ! 38CeU;C%w}*Q:nN=pJ}n1s7}P;%3u2l5CL $Z 4k5i&_`O@;:cykPe!`lr"!?-PVty\NYm%WUJ!^=:dPu Jj>2a / S  Z  6  2 f F / K ` t  v P Z s q T E 7 9  bzSF XS0}vCx i9 FFJI &GR0b= =dt =tT7hrHT=]lhY&T`(,, g Jq@PyX/nJ0$JEp8Mi,MdtJ~TJbJzp$^0e;pR[o B&9Mu8cj{sj}zOZG f5Hb8Y;T#S EG?=Su M-HeiG7c[00bx f  S&xzOj4 g(Zg; 26#Cq]@\MvYU`ZO'b.)CoWO8={'s2Di-q^i57.@hLwk E(yW.(2P zHd'^C>6C^7 I-7 Q koMg?MdW GCY~qR"x$OGF%7@lzJnHd{(  6:rUj%z`C2 !!LdPr&q%L\NP@6},7l"QrHI4~qx-.d^tjsrngBr>[ B E |iOeK-Yi(a1qf ~}~H{M  8Lvwxl4g(8 Ofn^#Ogo-8e[&|U()YCP2Jt8cI*n~ALH/:pUZgO MmExl2'Tkjbl_xj#(]%/(Cei@SgA(OU[E}}*`Eu[^(snTtT{0WY1H}'Kb "DIR_7mY{7pZW`vExT5R+^%0B^vKtH (F,yWWl3-^gR8 g so/y$HS.xXZb~]S";N?V65p\(8qG e+KR Pe:G =&i<D @+=xwwLal$ M".S)qVDg.~_ Qz2FI9rDp@d#{3U&N[Wo3 {1xQKGh1 I5}4FaE<P&n>4e%T}PhA@ z4WPFQ~[<#dao =.>M@b:uF7lBrO<;`7xHcc7{Q&~@W1njF- Kp 51}X9xAyoi0M+^}LJh'(Js"W[>|=y zI!iTBl<bSx-5";Lr}71t"kpl0PWu8  K]( 3vQ77y!s&DGW Q)3+Wa rm LJ^WACP# ^-}'i)>]1C\OARwscSG +K`w*Dt,Ye^,.4EUqEbDpQ MbS%VN*yt y"1 ( z8H^! iidZ Q 7y P ((`# _1xBYm%K>F^bprCps &d'/lEH X`^Dc}'4o{z!%>^wGv^V? X5YB5ZV  GO WiPp_Y,f`y<JB7^l^"c(?- BI[zoCO/xYzx\A9iAGF)3\-s!9[,d96Nkfrj82<9)oTr$y]J c2y Ama@ _ (w%qM qZjBr)v=s@6}j&%lBcNntuSD#UJO\Q-/ Pg6el _ >BN$ GGVy(FfmSve^.-m_6 02"xp7(Y% =w] ;qOc \` b>%H\cC6A ko UtM]Yx !T w[Ip]F2i^z+O ;%onAtl9sPu M)P=)c(e?UDnlX)UX K8uLB G16m n #) * I[KY+S\ w9kMY7r',pyQI#2dHGz 9F([b r&,&AL  [9mYC3 @H: im, X8 Fc\;'M.fz7E<(v>=o+H Nj"QN0<`e8jrNh,We_Owp)q_\Ve B9[WE.xZ&\XSB\8EhT)~=`34kpi:~d!Hb6@1i?/@ e:x&]  w ; ALdy  +  X)-n 5 ?h>A% " "0Ru VX,"D VA e=t E?|}uSd u @/hUQ+   "Tu9}T {qat@%3F;G4rvld  }B h7 @  =M@ mb*t &1w >FW {[htP:kB8pp($&.Ud(=]/Xm.5R:(i/C!Lxv9U1^!D  f%b/ {ZtFl/t ,3; QtQe O/= I*n9.\+JY7  +EU)n. }Vpe\  Dy$ .ii Vy-7)W{P}6IbM9vXN Sx#_]ZpNO/FhM2M6=WewvtD<A &aw F%yjw\wFs/t}9CPR`_RBS@-}wiNzq%\Ua 7 ! Jn8+Lo- 1W&UuDV[EI#yzPSO PcU ? 4qs~>Dd^p  3 6 |Z!{m Y;? SCxZq41?W[I3 Rg=kr=k 'X$,s 0L;pky6oEZ\[l*])yC7a [/~9 &?X#8xSz ) g9?]#XO*6(8,nxC},h  )<4@B fXI@rR/;~*C l*Te;;p n<Js{pir_]'Ul$aP({z8+oB+i>!iDDw ?9x%tD:[?1 B1e%Qhn^&VH[Pi, \=U*Hl Re!`, R a= Mz?k -c6)rLd<EH=GTiK j 7/(*,@,iP%]{Wa,F["J BLK>Y _GO@Y'F/y$-^[ yW: k`%, m1GU  O 7JoIiF - 7D8YL|O> O 5:Wqa|Go(XZhqov@\TN| @j  jrU$Z#m |R3Rs`& G{ul:&_Bc>WnC5if[ -S@4 ) f  _r{Z  w),7GxP^H b +twLA@bzzH}6 Q nB:z,[ ,;? W /CSY ?J?vIpK}C. `~2'Jee  sW | 1M Vb]#e.si #{~ m cw4)O'i6T#q_.l?7 6Z  -YH Dv B   =:-n7T9h>I_l #x' ' #j \|_bTa  ZAC\) (q~ GJ ) ]np" c CSA[?lvuy ns@{ G LDK-\uSA2##%O 25C l -@.:6}2 $q#NdKZb !@ gqXdS88W^Q4`8L ~QQo^|fR#@ 4  Jdd"1\j %&z (C e  fA_p W & 9 .\o^t+', V2F?\gQ}*W!'0U'9XV 9~o0CQX,(q!B & =l/_k3O\6O ' 6C  [Y .q }G\ [Y'U V f fZIJOif.$/ I3x *-d*}J:  =dlSb %!W2%;wk[  S R =Hc;H~w, qw@'t BWdmI[ *Dg"A.ZhwQ Lnihya Bz1S3:6*l{\ $7u#l o}B{WV ^7FfkiCF%0H` UuJ3d?%#7Ng^ISkSG]7ND{IDe#^aQ]VuOG` m'<0V{Z#y0?>,z!  ~imz~RS5 0[Kc?c^` n9 1|7a,}-uNa og.b qz7. 2}A%~.3gY<f4=m5},R  a zNy).Rb fmdk5 NF [^=nQ+mv@o#BP[9|WR8O$*:@@r4N\%HF"V% }Ow ^*K>.aOw<b^vc(I%$7M"_zH90ve8OQtFF%\~?H YSJ'VEJ<+5HJ=\Y/ziZed~- n F0+FizLLwn"bZ 8Z5;r-1p<"U![ @ <'& W Z @m 5 o urDo.`{82:m%e@kbv|SjfP$DloRQPivt/O>K"UIk YuTn'%AS. 3 R  ! F PudRH!h T M l;D\m&`tGd1brwTz%PBu"[0SS9<2U{i L c :  u Q>YuNa^,('I[EbRG:{2C7B= kA.2 A 9J^{#! $&i)D+,C-'-|,+*R*m**r* *A)'%$"`!R _EE&<Z   -z @(,pvSݮڬ9rVu 2ҧcgԖqڕmݬM7vt)T:=e e I!$d]u4!?^t` iL =" 8nn6ZT(DxImi[V'=] kY#&)+0+s*6)'& &&x'+(j(K('&%##k!@ j !Y##^#!om* y &%Lj Gu_IxգC׍؊l-$>1"Nr  -V0={ K   I ; * - %UvEZG8e!"XUvE"B (Upf#:#%')*U,.z1 456p64z1-*e&M# A9iV&J w jDx%9=Vۢڔ++ܯpc3t<ܬۖI(ۍd~au@EWh{g)&m "   y;44^_ ] mG.$v=HL;w*pX7~p'NWzX!/ MLzMs6 y #^&C(c)U*+?-a/13494P2.*6&y!6CU AXyTz߰߷+PIZ"G\UHc@%W3 DCd_k 2Kc  e7jE4JwxrOFq`p O M@h 2Kk<[b 8"#F$A%&(*p,-->,x)% T?h } l1ZFT]uUP92.Q;,GFb\?ap1(gp3v\ Vw=-*//Yh%ve[/; =)6XA fZcK\!"k$%/'4(m('&I%">A P ( E | ^ v  T++U?[fQleP+MBo"=,x9 _%g:Pw vXRr *]OwfH\nl?@'[C~Pyx_ q[=hiW!#o%&' ('d'&-$!g ; Y qp3|(k pUxUle!+>`7nq'A\FZA7g_eryrl5 r)W&WdT:[i;xu9 fC{G 6 "%?'(P))j)q(&$c!Y)"1X%";0 yeZOK=hWv F<2UvNKF@U%EDe Kw}<4!CvPp-6nwd<;BQkcM<_xa 5UT#gnRU #t&(*++*{)o'5%"L4|DhZH"w rs@1_h@alE i#1 dFHgM$&uY3wmy]pFY(Ft^m4 .>k{#*l!$'*+,,,*(&$Y!}g j  K;EC4iHj33) GHrOP5Yu?;.p4\@=j3|gpe5> *qln:o sq AUP"m%.(h*+,g,+5*j(&$" y^y/;Cw|< % xo g2!MC"vJq:f!^{@0|\YV*? P. % b2Md-o$r$YF< bybA\b }#%i'(Q)b)( ($'&$#""H! 0!a!b!!!N! wc ` I  &QO<dmL0z$\ no@9)TS";T [0Z".7L,,7CHw) #~B /Yh9 ' 1 S  f[>n 0!!"Z"""""" ##"##'##""T"! 5 @zundgwf'p 0 %6dEA+,Zue.$9gC {tzZ@\'aj_I5>|9#nP4a&%xyPum x  rM"f>!#$&&c'u(a)$**L++,V,,,,,,{,D, ,+++*)&)('%f$"o!B%iBct  PI^1+.amp$W Y @}0zF&DG8k x Ljg[G-n. BFb,0 O#t=!9#_%a'+)*,,]-\.A//y00=111111}1l1^1711060/.-,I+)'(&$#C!t,XYUO5 L.^0FA^/ߡoG&޷ޔޘ޴Rߢ*kG~;z$ [L3%9Qz*y1;߉w ݮj9۷ێv`QKlۤ.܍.xWޣ/߃K1OK%DWqJ_ACSN] = qN0!B#$a&')*++,,-t.-//c0061m111111|1*10 0D/H.G-!,*})(&$:#q!zh @  wS_Hnwvek ۍ\2 6qۻ i+݅+k޷Bߟ#p2Uf#L"mtk$rlxs{  B`#~9!"m$%5'l()*l+8,--Z..v///0t000000p00//F.\-_,Q+*(w'%h$"!Bir l J &OjQ\O"+\ߝX܇ ۈ\8% =|voP޾%߉2l6Y+|;m_VOr(vZRC4 > ETDG !f#$&U'm(t)`*1++,B--[.. /@/^/}//x/Y/,/.u.-C-k,z+*h)7(&%%$"!f'FXz bR<0$2Iv @bfE8ߥޡ3ܪkK*ۼ۳AܖJݷ_޵ߖsE,1eJ_f1pSS^ s@_I)  \W?][P !#F$|%&y']("))[*++,b,, -#-:-G-%-,,,=,+>+{*)('x&6%#"?!L<2g @ WcVNe`fy0@s ޹݁dLFD;.NY݁uPߜ; zGX{"qJ?p:|bpo5 b a&`y!"+#,$%%&I''D((8)))+*d*n*n*p*X**)w))('A'Z&j%}$`#0"!*AU?  Y  =5qD7GCx%r22a߆Po eR6J.r5^&J\; d[  U @k6) !e",##Q$$$r%%T&&&&&&&&&t&&%!%$#+#\"! 83A [ * ?od\dha'%VUOr iD5'4NRd&xh{cg BL~EGf2l?iUF9$07B]z   " '.=Jcva& K!! "c""""""""{"G" "!a! q  I 2u]  $c8x`fVO[n{?eu N *S H+xB\rFwg|5t41jjrR m B |<nX0NT;jSGP.O>HJ# P  D,w@b._:)G%V}FYQoSI>UWif_ ]]JPe )IN`wl'BDIw hx`PdYniB  ABP]|d.} (Vke@|lD?Nk %  K 8 I v&%>6 Cki7[$rs_$O5  {(dzsxJGeCUOAz C~rK 4!n@w@6`bbA+=N^ <  Q C05i }v:;f]sW's?98FqBZ{-W|X46]?u?NP$:`  + Bv({ J"$%'()0))((j(N(4(U(c(('%#!9qpR Ag:fTm7oJg O2ScFiP% 3kA;"f0D~$FqUXMVm;4,[EhGq W K0Xc N"]$&(*,R-....///D00u0;0/.-+)'%m#!V1H  O8T0xk zdwu߶Xݶ&u$p\ߙD_p~)W,O|oB7()O1pb@ WI$&!p`_ 8V yC` !#$&(*,.:/0o0m0b001i1k1(10V0/1.),)&$" ) / |*+UjN&:Oأش(ڹ\OݓݛG&)YBr_]Thl!S }T2cK_N4v2_AE0 C-jLG W @0u0!"#Y%'(*,.f0y15222222V221 1G0.-`*'$"' IQ> x Q(Cvt'!Eu= Dڣۅ:ݷ ޭތߟ I<5>f%K>CW_sk<Wirm# %nMH@Kvr&=0K 4 ktU~\!u !B#$&(*,.////////x/:/..,*9(Q%"v d6 ON " sKY8$-P@kS,vޚݫܲe;nڭu1VީT;,I4X S{|S'%ZmSBl" 0/%-a'iAY  { ?7 "}#$&[(:*+--4.T.E... .--R-,j,+*'!%"W 0d ] jA}lf" 6JNu}ޗݳE7۪K݁G߲&vlDkUW% (GpQi NH[mHzQD$7iLwy1'n7YN 3  6+!"$&U()*j++3,E,C,d,,,+,+*)V(]&$!q UxTf&^:D;ߍޏݶ"*܁ܝYޏޘ[@W$yaMJ /ZM xN)]2{7B&ZvoXJ*}8G28&TGtݠ"[ޒ߻߮%8.pj &F%LwDygC`%7Xr-c1F^b|M &Dy 23&TiZUZ C 0n)"qb !#%'6((,)>)N)l)))p)1)(=(Y'% $" 2/:>XzU8 ^ j "2e<ߘ޾6&݂zcj{nz{6`^g qR06503[^$lT[]Ql46u>|z#- 5A "  W\_jf!:#$%&9'''&((;))O)(:(o'0&$"+! 2J+ C p% u.U=gݞݠݭݽ/ށ_ߣzh;dO+!++&2A]ZXo2A<b$bv94v7o!W@3Jvn g Ln!f#$9%%%C&&'U((((R({'G&$"!G |$eQ  ktn_. !"# $$%%&-'V(\)*%*)(Q'%$Z#a"!! aB + jv'MCF߮;ߊAmUޭ8Gl<;Kp`3\Z<fN#87  k R N PX/S\bn$*Ln'a># v V p*$m ""#]$%%'d()H**g*)t('%$$U#"! `}pj".  T9dh>PiNA#8>tB0bvg~'ܐ/݉ N`B5g߸b#?{]-'? .9w  h  ) { m     w {Iw;#qO>w{{n*?Q,a)| UuU)!##Z$$%%8'(U*}+, ,:+)'<&%$#8#"!` 'a*}y Cc[[~!-:O2%8it܍GQrV(K߬G^O:"C&s  Me-4=M] b d I t 9  L + 1 2/?T});F1.R5wc_e:? u B5x "#$W$$W%&'l)*q++*)'+&$#Y#"r"!3 (va  8 ayod/1Q=j/Uf߃ݗݴb66ߏOGJ^S5 3-Ptl wy IT 4 P " )  i 0`}@)1!'X1s=@Vh)z@- I L|s;!)#,$$N%%&'(s)))~)('J&T%$#+##" cq  PS,JA*4f-LwPF(l =P@YH^"yWa e o  ; a 6  Y opq6y~/r<4A5@ak]. % |j{g!j")##$ &('>((L)G)(L(m'l&V%j$#*#`"&!o}\8w o  zMY}$XaeE1`3+ymW#$%>Vd#B$)l?qJ  w P j  r % D:|?}/x=8Tip}sG8(*)KF /;o !"##$$%&'?((n'i&-%#"! E [ " ? *< z-x4c-j,0[hR=u7:};#]}n"{a(t,7 X wET"D\vsjsW,_&]H$ib x(`zhr,f C z/s "!B!Y!q!!q!!_  BTf<Z2 D ` PP 3T8!FP}x2g< 3/+? ?+f{F?QA7y-kdcq~KL[ 9MR$@=PtG Kxd- T -<i)oCN-#2j/$\k&? . Fbvz6P CC)6XB5d*9PKG[ I6j5>S&{8@cN!Gss$){b.*G~nH_6g'RX9|I3F54](;m O  g   u  F U T c @#:Ff Z$u/0hC17Klh)icyH0Ba|I49S:~,k$qdd/|iVj e47&15bw`&y4Q/'5O12~gV,85d Ie|QXk"cpLSQXbP%hQXrmZ_(,#M-9 \x}n_7mp^vA W z`-e pl{H#!gpen K2MD5+ ""-62@DN\N]inxq|qwksgnkhcQHB<4,+(( }ysywz}ttyz ,/06!#  "#%    %1*+*%(.)/,121**!&#           "    !     (+$+(0/98<=@BE?HISONNQTSOGBCEELJMHGLHLAM=>@==?9<:3>6947633289?:<5:237>7>7523/5703(1(0'./)5/D=A9BFAEDCFFFTULRJUYYPNLLHIGDIJHD@AA<?6??5337,*( "    "# %%**(+,)0/1211345468999;9=<598567:3-)(.+),(3-!!  "  !(&#$#"#&"!# $"! #$(             "!&&$                      4})1?<%P,5Ti`SyHkq'q 9' 8>cA;9JDo09 x9#= Q!@4s#TL,>:I-%LSP.@#LgQU+6^zL]ts[ZtV*n[Vu\;5w Z:#  %5U,Idx -[>zi45 < r$DI  %DG`'%W]O 6fy`ZOWE{/VgZU45:eK^HBI$ KI<tLT ;PiDI).3pR:}<p<}m 7zqWVW(b'^tS[VRs!d>j K P @xLfkA+yug>il3s783)VmE*c N;.<LE% dL>S!t +k2&<nD`I]}Dip( ?^l@p}t49W4}HeH.tz9ucYJl sYY z`_?*j"k-O[bX g^#:[!Yp<Y_hryha Rp8eOJ v[f+ITiSq yb yEHs{}f2%.EH- 5 3zr cF1 4Kj4J" AoNq+1I#ZS\k]9!%bl!> KHy1Lh /?1Z@|  jqiJEur v40|!N @:}  '*I=t $ T1[0U #q 9" R} 6 :{b ! l@{c6%I}iX# Q\y'V'/ 3!  JP 2Gx^blM|2w% R #Y%OFYz {  AyuBG*oN\dIx+6kqcp\GI~L-(#vlab zV0w>%'~`Ak^e<g 1;5O?hw4bh::F 6K5P[2]l(j*5w'*'i|O&=BTs31 !U."  ;-F-hz~6KU5js[)=0X=bhPdTgJ, 4w|ta}?0O!|6I,'hfv"L/m0>mRbQF0RFnaevhf]8v?gTR*:Ha(0Td {}s2>=M"3X-Y Q $-_* :3zscZT~#R_&pob\wBJ1JIG%q!8@x"su1AKNbG<Ox ]:QX^a{$,IC.AS.Apfp^YAA)\C{d>klm;%qv_$3c).P1I?HZ-]fK#4_ o q/Sd%+UVqg `yTne@3zwBiDVc`Y!"x'Qy$TUP`'85F&Shr6=^UuS~WWu"{mSOT mQUAbOJiK Cca6,A-,0)`4uz00"X-@Q^uPTWyt_^iBIL/N(P.M\O(0~[(aRcH>m>&x[f41 4iY|6OAA k`0<u>pb g-J&V0<nvW8dH-kU*42 /;- ,4 El,@clYxqo@'Gl)MzxfD@`ftBQ }8L#^]BN_T)="3>OlN/O;;x'5j`>`,zF.@fiMV,4!17WEkpFUc y~_EVzcfHY;mhc#ich!D {gdn&np\$A\gLqy b9 ^X@".(v0F!m OnRB8U?2c%j}*+sFSy<Qjl&W}X4Q?@L3z'/u^%Mt.~.p?S$AUfqRWg;" C><}f5Fl4(``P} &fGiN  VEH3!jJgX6f>r91KF~L@ ]0~oI4R4;xxg>0 &I &hT|]?.l':,W] bCVbVXO*>nrt+4"GyPPy~@i&r6V`k @  ~   'uiO9Ao*SO X:+ ! }%!zt}.-yl ,, 2vv'Dc&E> w  m  D _ ` h \ % { . f }5use2Z h9)C1?s4sfq/B=C[twVD-1Ywt}rQ.lP>]WLyR42"K$l78i1   5Clu  { !! r N*LcvN *0x43Z8ߌ-l޹"߷U%(T{KSf7p0o&R  #s/{a!amL|^ - )*Hi4 4Fk RJ?N|s6qQi7V((mV(%c~{orLY bK8Ec\ U"!.J^k?  upd5#DFJ^zm0 ![!!!!"!!Y! B $ '&=SGuYe4ܓۑں١jKL؇gڼ6ަ v+hKBXr{dP T B*RX@_.&.*Jtx:G a +Gc8!/d;nrm"E_=#*2F]xe&uuH>xRuRww9ZNRzD"A=6{N|>x8r ? R ` o 7D6\#U q !K!!!!"""!"!!l! h 5+ }Gh.ArTQwtN@q\/S\BJ؟۳tuw!tkm q7xwS%5ۥZYׁՆWMbՖg#sۭ݌ߛDy}r*x f: HT:p5d/Znb@lu) 3 SBKt FyL>29Wu='L'q-#f- CyRKH*Tka: X    f 6 .`vwe(w&}UccSuY=+I h$s'}9  d=XL4uIL4 t 3!!"J"Y"P"/""!L! 1 ~ s`["F q _"Z fo4xV02s׼"}XSxԣr#"i٬۞-w`tA&R xD [k}Wqe<yhxB3< + VLX_7_*2s}/Tk[e#c.U[L-C~ W  ] J @ z [JeH a&45V[}S/,*@c<4FWZKF _ iEh@=/e * ` !6!Y!l!:! x " Nh !geZ/?pS Y bJcoO ߤݣ($Ո.1ԸeX֞8'^^'m@" { [nT !  !~.4Gt y   XJ:0"5>XX?=B\v/\ Ix?J0KuI sNE,yb@ W R = }m(M _ "ZON]? (]&\{Q *3Vd`\Q@,KV8C]ajTZ3_4M  NjJA5y)^ fpSm42eh@MuCK~EKo](b s < j%  0#Hy|y  :{cG| \GcTrim* V( 9y Yy3F$ Q [ ` @ !61Tz k 9 Y:g+ D )0a]'i/fKAk   kMymrN+J+Ys!fK.$8GN+ N  ((ueimC: b٘j\u8ڿ ޢM7l8B) v GC5"%*0Vg`;7On  - c{s<'R}Q vYh^E?@a;ONnH:/2BY`;AS W Q .  u{/, 6@=*4d2S (3Gh);R*~n"?K+ F DjQ2>bo^@wHq'ORF<B+2x> B +4*jjFF &yba܄tEEv~G3;ފ[\n{W Z 8x X}96JA 1~ $ iUL u{7aOGyaR\isx>dZ+t$4|!: 6 OM> Qi0cQs$R[S] 2k+[~ ~ _ = . x& CQOA?@O{^(A^rݶ7@܎_ݹޙߺ4x+ }F |0Uqe.;D T]UAf$% ' ;Y&k$wyk+7kV@wR}]\d)D]~ x % G Gu~o4L  F o t q @F8Y7bE ag"9!hRQxX"rHE[M$ Al{Tq{=g Aft86lnqwE = HT v ~Atj 9mGs/L WݾݷM޳2߸L3wu@ 9 B "Oz%H! CD 0 g%\6#3U>.@cq7 %[c"+`sH+##5N]`o| r 1 ` =A . r Vu2xrVmM|D!b9SHKz;m<"!7q_VW.gM  S { tC jPl^1+{*2^4YGdaf -  " 6 $=yY3(Dcfi!l7.W 5#+"N  +iw[LG|V% p < QybgjrR0e5~1{c]`uQ>M}*4wN*,;@@H>#p : m   D j n'C}X`y+ f!:E3x1KrFlz ~ 3DfjO?j~}y{}Fh)`?|>mW6}0v  , a H " GPY"`0~L/!K("S#Eo%aFHnpb % JB r^$\*4B1 _ 3 tNit!>f1gJ+ ,F]|4Q2OEv3FJ = ; T  1 * DUv|&i&v]{,~VqeVI3)1NtG~V I z  . X] kZ9auS6|aQ+vV%paKH7f' E 4  .TzX<:a3d)X fW,Ay7m.Jg%0 6 y s c bK M #x auf$QnP(x]H! NHM!FZGv9x#E$7,+_BqkN7fN8%E~L}9zoy HD\'j? m2p9CIX` z @ V  T$Hdp O{l}g9 =in|jE=QLDL+ s \ | $)I7_>d45?o1q/8{@}2FX l  0JTS'  Q 9 8}+&uc=`N wY6](Nu'oGl?*Ri{Esfk=P{ qV+i3Pp: ReA{#S,':\lB/j0OY+qX&\= s " d : f  \ x R ; /  d 5 !  ' o 1 b : V _7&D>968]  1 ;  aqOSqoX*([~*dXrM(,CFIMe}V Qxjw%EL>RnB=]y__depqhm8nmC d'J lnzMHK$!-V~+SE5jaBhvtY:hiHh g LHN$s)!s7o-i3dBiX,iQ]\]9rN3Wv~}k:hJJGdc  Iny K ; P i  L q c " J  O E[z:sAkP_" %u!j[F?tL2}=Nd^'&m?nGeyNM7}R[C@h#rZ; ;_!^0gBe?~Q'AXRF7-&(+88B1$ikkzw~ss=jIi 7Xjkc  (.&'KOO` #28>_r 'BB??75GFW]oZ:+|lmHvsr}{ov{} 203-waiZO><DCW7[0Eet]4 A^PzX:%rtr~`B#jP-|$DeBa 5E]lzv_F*kS1}cW;7% *5EapoaM: "/`y8b(DohV@(|~'BZp (-CGLLFMD<5"wgYRKEIDNNQXao{&,18570.,{kka]RNQHCE@HPUYc_wu{h\UGA3/*!(("'&209LF^]nx|vvaZNI?<3.*)&'#'#))15>AFHOOVXX`jhjipn|n`[YQJD=5+$ z~{||{xutzuy~    '%%#! "#  "&0389777-/)' +401,51<69.56,$ $'1/3>5=<@E:UB?72($#   |{z}y|w{y|zvv{|wopfjYWUJ=/*&pCqjX5EHse1]"& Lcsc-x %|_w`B:$BjXy(-{# #$,DT U33^uDkYRO5WijeHAH,8VU0ga="!oaF^]0C:UmEUXBdD(lG6i?qx V ;;imvo)T\J{&Uxb PUs^zGs.NW" D]a!$jFIZR]+Uu9 +Z*>h`.gQ-@ 8f+^n &o`iA2Egb@ >=#w_.:. >1qlYOt+Maqs"Z/Gu$jKa0&c djh VMe T2:*3svkl<F %+"6IXS; 0IXf &?Uaop_MGVzc~<}4 r& UiD{Rr]^ S - G 7 @ \ Xj6 6Sehi/q}q^ B :Ph)4"?yT t `;*{  >1JL67YMxU{ . x  F l q ; - n-HSYq)pG:sC-' j=JY-]vzjYQLRfz5hnv!x9!e]0)oizf6F|vK<mF$} d [ H :>Q23KKS}.E{ G  ;K|Wg.MwZTZy~`s{KOa}& A e %  1 M .bA U # F i OcI R4762XMdm7L[hn/| "<^LsFj]3du[@8\1:0 l7A.`7,ZSrx Y  , U  I _ JZu2I-m~iaSxSR B M OQ^Q{(7 HZ,]3/o|R:/3~}:sqi} Ds+ ^   ^9 tu5m-R#(yo_3_2K]C|K$ qjf6U_ZD~ 9 L Y R [   ! :{z tv? / L.DD|ghV5}xP @s""W=( t @3*,IdH'Yv U  :  E^5WnS` VglX1"UKsWoo1Zi   ? $pHhc)'7BNa${2o C/lSnYNz\k$<ccL0'8CTx}cJ xd E w d C gT[{3`g k Tqg>n,.tOc(|'D*<* >+l>%*\ y  ~}%e*#!7 7 _ z z C d9O~%]7 4gg\|)GY.fo2  u 4 i v f J u V > l1> 3Bd^e7r3u20/0=3 OO}27Z0N4v7   5VUoYlS'632<z x axP7/^!T_Y&V+QO= P |Y5aD[TRR_  z;H"l_]fHEji^ n> oF~ @ *BD% ;  0 Q u 16+Bq!R%?;cqsiNCH;^>gJw~vF2+VH"EiZ0iTp ;J![ 7  % #YGfpC B4J>r~L  vbuwh,vxd/*O!hMxR4-bZ^ q  &*/8ED 9 \1 9)tZUf&$)tW#Ln 7 ` u X]rZ& ) k u _E<' ?jGlQ}r=xnl@O oBSA'=P Lb0`~3&^'uY]q-r b 0 .`sgFYrgamqOG^ % q\>29w~v5 'aop ! IZv\}  P 75-+%*\vF>a| -O0 gW-gX[ M ) 1s}BU(  _A1#r/4X8 D>"bOOmbp'XN=v5p/HxPZ S & :Dtr& 5 / *  ;UgtxlSV}pO'mm2_1T nE]sh,IBdoDgR:0$ 3]&B7Qm0*e]0\5cT^UGkuX :?o C z@4lvx>l$9  YF4M s+suKg -*@J=  ZD@M.Hj .n2|3w"Qe, 2n9Tv^mt[[; a T 0 s \ Ztfx%W&1^[} Sz Ps2WjW~ _*cZ'vEVCxC3 D | `8 #eEH  9 " Xu?8 D%b&{g_6`Sh+;nWH>, xKdI[sP , uzQ ,zA87xS12Jx~"pK d [   % ]o'eW~.yQ^oM6+9Q3m7TP}j+OM1\$D9eo$&jluA%QnDc/C N 1 : K & S!y^FQ(X  J P&dPJK W64mREJf:F5 V .   Lj zGmjb4 1yi[X_Wb[p@\=+0:Jk3aD. "Be2ar#vS)?T  y O l!1V<YX1r G ,I UMYAa0zgP @4 m W z ` i ' v 1NJ2N]crk&wH59a uT1/6nyS:9T./u ^\`'$q+laZ _4K~,=2UPa7MheM+NoP9T1apbGj,(n j?L })+PuS-zl  [  ,  } 6, f jlK %EXhT8F9w&~*R~!y;g9\ {!vH>IdEJm9Ywk79"BZ'V) dK~UQU]d6>:!Zb!X[R~I0x?=2RC d;]{hGL#$  *l=U2hx0d W n l   P I/%  z 4 (B{! #)#BO_r/ "9 /\Y Tg<`Adl8 vc;mEhac`h>t=s_>pE%3Caay Hp*DMYQU=/ \8 ~mR4?P;|-(st KxM;rBjEk(:DeM KhU2<m P   H ; P H  z / zLZf4~n40|*WbJN\[.gQW?}YBHpx&\Rk@'W# 4Tn|~!j%   xS1rX2+39;Qety D :r6X~&4^w~}"Gu%@@:-L{%Oi F3!cU Y m "  2"F KPXtuQ)Nu9'TmF*[y4^HQbiuOQ^P'Td]F-1e)M$7U]lVzl;$ #0CU"R| &5?Zglu"2DJ[t 2Tw @TWq#1GSQFVZY>6Qkv ,7LE4&22%aS3P#z<1~En%lYLAFTcqjxmX4eL ~j]E/w-`(4uZpc(O/ 'AOKVWUL=?148EG^hI9_5FQQOLG:4*"*02ESZdieQ;*fJ" 0[ DbxrfZVPIR\mqt}&*96>FNJG2 *(-7>B.&%2-2OeyhCjBr\C' `SC-dT:" !.-(;JKSC>73',     .@Z~0[u,>H_iy),?KS[UM@.%g7(Q{27=1+t^OEH@S\dmu~~eQ8" &:C_o &+"# 0@hxjM'fT@CKB:=ENeabWQDA'~|cSC-   .3KSfm !/JTfcxz|mnkkmmptopjeRQKG=76./'$#!',02@9@?FNROMC;4()!(26Jiru}}ml`QQI:/,',8=OSft|,+/38AGKSZ[WFC620 womhbXKGBJEFFTSfgxv~~{xsia\MH=;2:.98D?GLQ]`ht}rnjb\`aURRLPIQVW`dmo|}wrnjinrrmsst~ymfRVEB;(        $) !!& ((,1.4346@F>JDMIPKNOR\Q]]i]ggffbiccbXZPMF??39;411/6/:49364197C18,A3*!/""$ !&"'&&%%$)/-*948A><:53..0/*)%!'"&(/'&&(+(%46145866;@9B<BBCKLFNMKGRLQMPROLSKH?GAD?;@77:;7784>2+()"'5,"    *0*$)-102#        ~{xz|vyrtvqrlokmmhiheg`giaihpilmltotrpolpjjkimnlphkfjjcfecd`ebicnjebiecitqb_`Y][WWUTVZ]]]Ybf[ZXWZVVV^UQPKRCVPEDAHWRLKKMNPQ^hchjbgmd`\\VZTQVWPVRPOPPSK\ZYZVWWVVWWXZX^c_TWQUU`cqbWTMZUOSRTNVOQU]Yc]a]\e_a^a``_`mrlbd_a^`^cackqplov|mnos`j^\UXS[UbYSVRWU^XZXV^`lelkpv{w|xx{|}wyx~}xyx}v{t{~vvuxsrz{~t{~}z{~}|z|uunkqknmpstxrnuqkkkhkhfghfjrrzz~|}yvpp{tmmsqsmvtnqx}|~|qtfZRNIGLRWcdou{y~y{vq}}{z~ zvu{('!   (&   $%*))(       $)4=HWYRMDD:AGEDPF3.  (DN\ek^[II?)   %%()"$  #%0<;;;8=BA?<6+ 7GJMGJEDBDBJ@:<0$ "&)*,-9<:-."  %,7Lewyrb^R= /P^jx~se]UH6 /?Tiuzx~pxlg]WIA0,+ &;GTan}`O6"&/296DNY\a`P8/'AQa_npjtwdI;114;JOX`kknmbX\\listl[H-$(=DMHQMLZiwuziP:#  '2=I\]gd^]RJ?8-'!"!$!+<JLOb^fVK?134688+/ 3VpveVNRU_^d\SLHD@EBBC@9--)2=MTXbhonm^VYWHC5- %+7@CBA/0?P]dhbcjVO:(+AM`dlx~|tgbTD.( !87CDOPYkpt|vn]^4  "(1=KO[k}|niZNOQVWLH?<5;068AHRcrrrnf[UF4+%$/0' */6-//05K_jmdcJ=<@@AACB@>@VYjfnljmaWWMWPOOKK<521-/3Jnz]K=33,46IVr~|z`USSRG=;+ .9M[tw|yq[VSYkrrvyx}f`[YLRVt~rkxuppzeaa_rpcG6-26BWbljf[`jttppvxxmss{}{zyl]LOH`kwtxsmr1KVOA+'"!#rfQOO]ksx}woZSQ]][HDLPQ\belaP;6*(#7<Mc})%(9FJTTK' {~|vfXSTUvn_RQV^hn&;DXUVF9*lTEDJ[p [7 ";araS?9!*7Af$&' }gQ70-6KmuuePLW`PK<1*6<J[vpX2& 'Ehxz`I:HOTZQNKMF2, $89?AT`rgcHF<13%& &1FWh{vvszyl^TM>.")& "!$/=AH=7/-+'/-3:4**   %'IYkp}stjYA7 $=U |gYYQF0.7;Je| *#&wV5 ,VzmU1  (,5DGPSLVMJ7% -@Pbb__aq{wfNIFB9E983 !,<IVgiv~iaP@=98850,) #&39SklyiaQLB<</12'+DFPZRB2  6P`bK2 /0/#  >bwj? $AUns[L.'$zn`M54@Ob,5651'(Jhnvwpp_C-'%!{|*LUd^^NC.nHD*5:W /?DA]cmr{g]B:,5 -P]xneK=0/(/00!)" ",/rWYWr&-;4DEHE8*|yy'AEDI+#xW9))%0FU[m~tS5')3ANVduubC9,68SMVLKUaa_cnvmebXWNG@68EJ?1",F_qT>1IQVYPMCKH<@FS[ynF*:WixztWJ'!-0>MVWZQL7*+5SfrrY0 /RowQ!$.&$AHD7  ::1-Hv\+@e~qP8" . "*1FQRZVZbqsqg_]UYge]K@)&%3M_quxnQ<3D6(" % 6G\acgYZZ]S\auxntkqkhYMHVVhmmP/ /AQRZZ_gvuN-#8Pm}5 7acR. (2EJN^g]fp{r`WMLQlx}qZD0!-B\cq}mpeeblp~d9 %/29GFNMfp~mS8  +C^xzbI: 'Jv}pma^aRLHRYgqwxxtlpnlgWF;0RZeLC5331:D[jx|rh__P5&(;b$$zups_ZS_ds~tlm} $1+ qTE3+,7=RvkXF8(+Be~x} |X>.4Hk o<( $=n#Y|x]-ss\VDMSg}#4(( sriqz}(68BC1<[m}iG=, ,,)mX^w'=YYVbu{dB.  "6BE:>27*,)5Il~wbG0  (4QdX3)%7;4( 7Nj{rX<8N_l{}~ndMHIJF<2% !OizoH*)BUfnn^UQOfyvU=?S_uujL+>M]TSL@/28N^~{xeP@/?XpeB64f~gbg_\[caC/4CDKTg_]NJ^z~vQ;;G=0AIHC3/,2973&Lr.-("# &"++txjhdYVC?2,+86ARm}}ieXTIPW`[^jufeepju}|rormqe`mmmwzVL31#%,05CP]_]RG9?HYhop^_bdrw}}|zsor}K-1DXl~ 2693/(kc^e[ddmlaM=>P]quK!)K[`d^ZRD?0<L^mn^D2&/?Qmvnsoo\J-"":OliVNP\|~wgVH=B7)+0F1/)8GKRWi{~saps'9" ~V(8HaiqxxF$?9?+'+QorN:5,/AY2IZSR=:4# {\8Jj||stln~t]`}aWR[ctr_UWetzXC.0AMO^g 2A.#mVINSlv| )"p[MQk{ul^ZU`u}pgiozaG! %@WUMIj}nR3 ?Vaj? 2ATVWi~V;%5HhlegqaD"3Vt|}vdOG531,BTa_fr_HBHD@=2.0CIioXAB=@=95;@OnaB:Smv~vnm[J5% *AW`aXULA 7\y`G2#<IRPFB/<@Wqpy~m[9'1<E@>9:CBO\gaD5)3*'(@LTE5)! 3TicdO3 -35. >u~rbI4" 1N^x4,&ta_oxsi{|`:+   /Usu~tttuo^ZryL.&!'<Ws~|`38_xQ1 +2}jjx 5bqlcWSafnaF. +"(1@[sypjN8K61;] !$#%*,v  #AXX829+  7ewg^TYV1  1F`sO{`QRm$2#AP]aJsx 6\qX; B^bQ.~qePRIP[p} !51 !3=DOLT?(oYdgwnht<ez}vW<-=ZhyxiXOOZa_P>#'*60<AQRPC>5/# &%.15::8}tk~'Id}j//6FID856?I@0t\VRG]eksuv 3PYKDAONF>5( 4][`RK6($)&( #2NH2yD$9Pt /G\Z9U3,0DIIZj}   nPBOOg7GH0v}wppnal~|tcQHCOXs?`lM84_V`CERf|gXSZa{iF 9OjBYR6c;&"0K.64B[d_SH8)l5-?g !@n!_d /HP0# 6q=u_D2# zF/+;dtl]]D9+OCHWrzjx$@Yen}qdDtB-/,7hp[\_luzbT\q*7IUntwcLT3IgX $4\ =K7|XGEPjtcp )CYVVL<.)cD0'#(4R6yqXL(tD*h jcPRIN>HWo/LK<_A&'Hw&2(hcwyji-Jjwsj^L,~rty~}^R`~|  nTLLLYdpv+&y 'EQZh|a%kI=Bi}plv!28.o~7Jcm|`@M Agz<qhN.]v}@$MszjY&' !8,48CBLK8;RaedU@@CHKJI7* 0;DANSO8 #  !"  #1HDPI5!t{1Ojwzr\C"ymlr5FRC6 AcuyucO3Kksned\O3( gI@Vw "&/!,CTZbblprf_N9$";9Zax{vokhZRMD>4 AWhcpu|zmR3&;KZWWD<,LaxxiaWRTQJA8Bi}qwkln~zR-zK6@Ff-Io  ~J&0UlxfG< ;MpV6 .PZhivtunib?+/<5) '(% $7EYeps_N1  ",=27OiyVA8443-%%& 4Pmu{wcE.%$<HMS\]^`^ghdfVD-.:?Uk~n7&3380 .QouN-.Wvs> GchA&1Eidtr~wtppnkn]I32*$#-=GKOE1-8RUXUI?98<8:3457:FZdmlyw[O6($/&3Npsg]VL:'  !<GNFDM5"ykjpy#BXuk[-fVN`q.9F_\hsj< 7\n]B1 $JVuyjO8$ )7APKLME;/ )/'#*16EIXZyuhO;*%!)@Vcz~iD-CR[a[F8!   &<?DYakuvxk^PFMLH@;1?2:(0,:=FELXKD.'#0?WWWK<1/2VbskupeM5 ! ( .?L_cfb\PHG<3' 4?PWh|gJ%=`vjaK<6YtqI!:@JLD&uelp1PiozkK?)"(;IWi{nP+*;YvkO9,@KPFE@@, -.5( }q{ }).')o`SSXz3Tmpkf_Y?0[lz\6&)//>EPNJ6uXV]l2DSP?%y,Jo{|aI/y*ZoxvbZD7,'  #'5PQZPE70&  #  ;;HB:310.8-jjn  &525/*#  phj}s ,04-$}t|| ,IZpeJ1 yqe_MFKWbmiL;,*.@]mvs^UWbpuuticagr}|`Tdt(6:;1obJB8FVx 44.#rS@;>GXc~ naPRf|eK5.0?IXk{meWXWds~~tmgcaXSF<2$+St~ypbTLVfzxwqkh]QQVZn{yaH%+D]s|jU@% -IkxcVQUFQKT]_m|~}u}ml_ZUWLKGKPRJFMZev|tmjiswuo]H8*&#,7May|aB*&JayeTA5338AFO\muvz+AKE7' kP9!).Rq{qiaZWMLP[h}bWSOY]t $(zv`][Vejz~j]YPZ[eVXMWU\ew!{wswz~|yu{y !!"  {|| oxy ! v{|w|xz#8GHI@'qgZdhx<IZ_ZYE9! +18772//)!%28BJQU\P?1*%!%(*2$!$1?BSRUF?+ &76<?-* ',1565>;FEJG@@<1( !&"-/4075=;?73  &.;NOFLGJBR@7( !&.:DJHDA3)$.+',%    ),2CLOU[]XZVMF<=.( '.024:429,1'""(--4BUM]bmosu}tlc]\TGE/)    "06),,//5-.-348:;;.(( -)1;;B=./&''$).<?LXXY\c`qrtg\WED-  !/=HWZ]Y]VWNbSP=@<:<<?GPU_hmqgmlryzrvlrjfOE8.,&#())./-(6>G^sv~rqb]WVOPGHLGUQ^`ku~sdYUNNQNIUUivoa\MW]RY[ebpv{{|tl^PFG:B7=9@>@CJQQUbnhsrsniaYWPNB9532-022;@CUof{~}~rnkaZYVPRQPP\W_ijkl{vuvuvwtzkpfaY^X``s{|~|~ujbZONNPJAFIJSSehum[TID>13*&*-0=A=>A@FFDGFDHABC>@<EBJOPVSUc[cenqooovtsmnfi^e`_RHN?;>.@HGRY\hfsmrtnke[[X`adhr|qi[VTQUdjwxurj`]UXY`q|        %4++.)$&   y}xv}$    ~y}}yzoqtjljjpjqtw~urlhb]YYXZ[[b`kiy|vu}|~zyqpltsvvlsorrw~z|}|{~}{xztvkloriggdeefb`fmhkgdfnlqmgea]\_ZaX^QTDH@=6661/---42>8:?>=>A?=;8D>;B<@9@778;7=8=5899@:DNFDHMSCMA?B==>;A7=>7<@EDEONNKIMJPHKHFB?B<>490:/9624/+*"'!$%"*$)#!&(%,!#'#!$$&*'! +# !%(    )$                        !!&.'/'"&((-3.2/@<87D:<;@??BBHFFO@@=:<?968/7485==B:B:=CCGFKFFIGKHEJFFAFKFMHIKKHKNQSKSPTSUY[V]^_bdcgcggpjpomsuoptp{x|{y{vtorwztrnqtprwz|}}~~~~y~zy~xtq~p{mkbe_Z]_]\WUUX_ejkslnpss~|{w}w{}yvtuvl}rllnlkglhjjmlonlkztrsuljgmg]dc\V`_aZbc]achbbXYOJL;C<925.#&"%!%!"!$" +)"$!#"" vljfYcY`WZTMHMNQMQUZ`jpvr}{vpsnyx{nlhmkhhf\Y]K\Y\OMO[]a]\a_]mckcgjcZJPDG;717:15%+ !#.09EQMKLLFGHIHIIC<;=4(%( &(.*./::BDHGB0) "%),.97HHG@:,+) ! "   ! $!   ' )(604:=3AGGB:7,.&% "!#23173A=273;-,/:/*$*4.18;BDSRYUWUTMgc\TN]WSIFM=724.#$)!)'8=Q\[``dckjgbmin^IGAE8AE@>6?IXPTPYXVTSYabYZ`UNP^]`X\c]WCMIOJILFEJS_e_fhinz{pfcf[]RknlZLGH26;F<37JSGJghd_Xgdml~g_jlkb_phkei`edmjfony~~~xjhoo|{yzrvt|v~wqlromyzyz}z~}wprulm|xngmkqlgddc\eantnkhhjgluvnuuvqjv|}e^\aZWUmopbfuhaRdmgYUcodXWf^NEZg`CHTZTLWT]Ybb`XUZ^QSMGAK`PN4HRXW]^`f`[OQQd\[[fiWYfrlSWjkQ?PbmXORWJ@BRD@.4%   !/194632>GG@FUWSCGWgdk-Ho6LbDg5mmFt/z\M.pO5B>5hB    (Pbk8`xc2k9^FtV4+&!>X{ 9VjrdK+l= a? |1@s,F{H)=T_r 1Hf!&#,.7FW4bm0Rvh\`w-Ya\U>5j N?n,j;Z@%Wg* s<8! Oz;i)cH2F]yE*;k@ms!dLX~V?o}qeV@,  #!qAt_C-":`:b`K+*sR(gB yvinyquwjN7-iHK3)j//fz;m9t'jhl uQJx=H]W#"&WE5p+Du>I#GX%~sgbi-q:CG] }%oQVQKJE;(-j!eT"tn?#4YT# / v (tPyi Um@[&#5FEn=x[ B ( 8 4 ;UmGy~39;I:ANFvLV_\MO'i>v*@08Rk,pX93RdshJ:YDuF     AXbXHA W Jz u"A-z;:7f6o[eu1Q=qE    s+1k7'WYGb$Fn-E7 >&7y~UAjl did :+SnG7~?%&5xuFAx(JfIHLdf]K UfR9ZVfXF"|X#Hwj)32B:W,lBhm:~-nB1T8N5+8S|[17 ].~(o)fG826@Z Q N R _ iYW 61-\O]  d | X fpsJQX?W04|$va; 8>NY\i\qnuoypt`dC1;]2zM5 gQT6 B~G\sv|xfZE"Rx#K 8t@U-tgSYTgt%8Xo2\T=KjN14ATgx9f ( 9 4 :z>t.rn<r:x 2 [  Gisvy1n6@^>>jFE`4aRMDA7=JYu:FqqI2|]-M`N cBfyiV /BQoo|zxX;D X ^ mKQNZ AtV>% "V?N[0~8cxR| 0 D ( %l@`1X`@C"^ 7 J Ut{wwuor Dq39'XL_m-ScK4# #=_ mOfy<%)& h$b7Ph&Rx$v^%DRk}j9OYX4eF*{-A\3wia\Zai&T/l[=(K,gQ2Y  v  l _!fFHmFzvS fp&\+It u?m$N9ApmoCp/uN3."5FRpjGWkh!=7KxoR3cEblh ,:Sh|X#dL)|DH%pnk 9m-~oYF5/xwF<.\id 8I|7cG ? " >kZJ?4@s]GT)uY]Gh wxa]r3UAq;b6%Z;g:)Eh&Zzkq#+ rH.%xe,h-lqm:u':`vnJ a,S |BRLZ w*@m'kN1u^KF:cy %EmFBvWRz(vJmi^ZUWVg0=]3 ;r 9 wcTO9,p?%TvHV>~8BXcdngO0]uN Wu!y*@P`n+b.|{vo{vwA{0mf2*M*N;{ ( |   hO?7|qW O&8&1F|>j( &   IcR8V|'v(Mxo[QGK:3?Qz-~CsNBU~$UqnfM>-+# uGn8l+*w0^v~oJ$> a.l-^ai!>RX lE ".8Pdy=t0;_IzW}B  : P `zafg<oHh^'_ .2\ vgkc_px)Aj](v/V`=TCr[W\clnq]R!8t;UnqrqoX<dE7[m fMxrK3U'sF b#+}%sm _Z8 1Qp4QEcj,{N Q % N i&f6(c|_hX~?uJx} _PHCOz1Lu 2d#boKT=DV#iTXR=%&.Be({P0,7X@~(" wdK(R8$iN+k&EY[\F"yO&R,JEmw^@Z#ojpsrw?pggB?q'jL ] : a[.K:D[f73/N_M rN#53b^ T /))*/75&/]x"{ 'XOSrtf* S   Gf"t93TySj#[  $ToH]oXO9Jq4 /d`s^\dK5M!SW9!5%]c eygf^@1*?=Je nQGGdL$8}lK:`_0+PynF Zjuj@n*F-L:It2w v I{Dbr "$& ) ,.1246 89_98876]531.+'" ?NqtSCd9gMIݣn/@k peF:'1iH:9s4wR}߷>4\=8d~3 =[b' "$x&'''&X%#="V KB- 77| k;vlM:%Gi/$Sj!uPd+JXVi_%t 7I "^% (*V-/258H;=o@ALCCCXC@Ab?<96 3A/*%3%k82-֡ӃѸ}ˡζЋ+}ވ}Ia$v&ߗܭ<֐ֶ<^#ڌ-NJ_4 4"&(*-. 01m161;0u.+G(V$ x;( J|X P(.W=X,d]-9.'E),.whXsX#Lt&[=}!WA_ 5p!e~` K EFq`!.#_%N(*-/147<9f:<>P???=;5951-(#aMZ2ـһ?eM7TޗEM Z^T>N R ; C #uHxqSf-Jk޻SIQ`9c_ )AG#'')+)--M.`.--+)*'# ak 0XNW!=IHJOVit2v1c%C^X>{]2 ݅ݲ݈ol`$R ' ExnTcDhOy!#)&(+,T/13579:";:97940%-)%!pyi =֢.Xk׎~-"Evb ;hNtEV <CIe.U/',[8އaxۢmO;Ac k#&)*++}++*(&w$!5$ p&`vt{*E^{~]w/(Uu/=A]6)P߆C Ba!U5+--"$'*-D0T24-6Z7(8877530c.V+'#xE u2،׀1_יp3ݭj@|nD- q]HQvk+ 1eon$mryYߠY &(n @y> j"@ b#%'(d)e)&)(c'%D# :UF dz=i`x0G?#LOnN.E> 8y_0i"PN!"VtCZ& Lo .+ _ZH' !T$v'*e-/24566%7653H1/,7)$ V Q8e-,ؠV/۷W X ~FH w _=t5Exd (O=pb !`R|!,e3LpWxs!@ zd5u#}\ggx-jK}nS{ 4 I>yKA:&& #Y%'2*,/0]23555423z1/+n($! $܌ ܦS#M8QT u2oNceJT ) hHFWLC$M'oI;t\߆ߩM?tT:\1-e 2!"8$$-%%$#Q"$ N kW k @]'WTr8FM(sJ=i {+l(YBe|C{n+\VJF`DLRD^:  { bYsU&Ft "$N')u,.02T4O555z420%/-'*'#_ V ^"ZJWߏ۹?s4; p?+0#g X :*3&(8 $ddfV݌*Pf% 1DI{; Im'l9i^!"#$$$#" J^>/KC)[(\Tgv6IE"T,+W$$#r>3dl6AvDKfd f nSH "%O'K)=+e-/r13p45r6642R0-A*r&"  pAy8\ (NF1~. r ? ^[omIZ CHL0JFcn')YIDEo+ݹیڮNo%[߀SisAUJ 0J !!P! ! lc  .`7Bn,ANV..R4`Ci-/$z>dR/XT!Ba&C@[* z M`J S7R}!$&)R,.035677a6431.+(k%Z" 0s |rI* NLzmxf[V + x G uRlRka4Sc+uw}؁ז ud׊ ۃަ?Arb8 8`YmUk 6  R.F'(Rb(;(WC1yZC!b:FxM{C\0B'wg}HY *FF#ng5~N | - 7 G!^$I'*".h14689f::y8753%1P.+;(J$eWm ^I>Ds@\~bY0Zf0Mqv`U}0T`6kkE # ݭfگ7٥*tqv3z[.S z  R ) 8 2 $u K *!G-O[mf k4)TuSbUWyxX13Us7QVta<Dga E+5o#r&)-/13445S43v2`1/l-+1($0 $U I  dI7\EGBG sDMva1p9 Rc4J ^=ZIpCb}!!k/A @ r9 p -7 I qv7;6AA$| 0E&=RfKR?AP]Q %4nZ @tf|> " #dc9j !##h$s$$##"["!U!  uI c\]Ok6[H K?e^kY*t y}:WX9"KeI/enK)eIcAp\7q 2g05 xs{>s{|qaTUhCWW-dY2)zVYFIo$1 ,Ltf^otIe!.q$>T $ ICWS&EQ`LS#&-.(t,vGp[1rX C ]R1Phbal0u;Xzy!CE3d t?-fUmP*1M=hG 8d(DMXbi'Pjs Ed~iG4}[GRu;Nu:ODFqXpO*sM6 @ : O A \tw Yr97yr,* awK%X3 k ,U#^= Cq#mYf6@jY_8kQRb]rdweC0j6e3?di`BhlY,ku#e%@Tm UE w2iW\ew MyohC:2x z ~ Gnwc0U)VP3<UB%m A p3%G>I 8^1$v+ Du_.c.Pa.#zgFmipC:E*^:g.a5T 2CC0#yKa7{DZBx/`U[kE6,=Fez"sI:^`Hm\DA? O b z *Qsq`J994XSCt>[/ G  |WbU$'Jt"p9e `: $Ix6Es6~`RGCd9^~cX;S"b&tHY"P>v8axnL+]*i.p,V6[{8FK?yK Ni0WKM_ BZulmF$|&d+ndKo[^\1 w 0 3LJ5cJJWo6 5tRp\RHCB:Ag2?5O,o N&Jz5]tqY7z8ey)\|={>Sb#J% AcWBYStZ7/ D B V c sj*1kHMYg  P  o49=LuTKPyh\&G[QyWUL^ix#q8b+_0 AvKc* IVshin x 6F9:)Q_,vHD^i=H I  _OY7 #7_IDl+ 0h57 9QhvvfG"f,Z"GY4y XT R7Z {N$KG(@9h ^ ' PObEW\r>t ['V ?tnT~?x}x`Ai0_.[zb$m#X{:[# ",.+!`1=JR>0o=SrZ+tX&mHNj7|u{$t a a J/2()R!!!!!!!8! 6dv5S" L K B [:JA_:$3s(>;zm-! Pk / zd*K>8bbC"Ct|1z.Z?$KSK$8JWG>BO`y(Ar%d^EG=XZ1vU;DHHNZfvv+YD{ JIMQHP 9 S_ a# !c"d##$/$-$#n#"T"!.!< M 3m#xW/)M=gEzm?84vDNQwW#8_'gP:N5a)p! l ) 9:WnF {4wB}@04Vpx: &\ ^'F[qU+s".gn _s  W Qoz9 "#Q%&'E)M* +:+-+3+*)((5'%u$+"Z5 ! _ P^@rAkZypn5b faL(+S)Fy>4YS}r.<\&P\!esT ] \ l V  M k ~v}^8@{Bj*nikcW5&BRgmQYP F%+UN Q5d e![#%&'O)_*<++++++*)('2&H$!L( m ~~h!oa9F^6A-&?b >A$aN^G|cMyQ"# ]U~a[l.4@E7dI 1 ~  u Z gZAVV1]ur/g8bKaA"7fZ>/BeB'6w/mUGFT y > [ o|9 j!!*"""""k"! Ue%)N r z S  ye:uL`vc27zDTa91=^Cf:'(/-Cu{)dd5zoHbNQ).-%e_r(X2^dTv9Lk9zL)l-mG"7[@-v{=8Ln! X D -  q-g Z-#`ep9K<, P  &o mP|E# tbOWp='\qg^X\hy[ M5O2\HYw|q`N)d(w2FY`1q6N]1$El#n m3dGcIvT x[= I? A2x LxV*7o )85 q ! I|"lF #,?MXVh]o}yO6})M0[T n(O?R:]Sbr&X{ x]uGx!x4DWlpW&}? T'c;|FlGmC-)#4rD3_K*Al)@G90 ` |Nf\WRTPM=8F-sF[I9u5.^ MG2%\eJ;l$^*xkt6?Y{+k,80(mL S}\6`;_< %4Tc.Di _8/U(jb P * c@GX(|k$aeg;]/AC6 J S ranty~xsSF( \DSs| 1~)l kU NKFm^7;(:mb a /Tq$]&o TvzX#vArQ7 ~c- 1Px*`3ay'5 V z;;rr0O*=V}/=N_q2. | Eb_Ziw}i[8S2m==MwH}^Uo0pWGSo&{(*9Ts:8H-p+HKQ 5Qdwyx||c7~6rbP>2pum>Xs$q 3y 0 a j2P~K gH^@v_ ^;| q 7 jFZ\>zGHr$BjF1?`KFBoA"YLHlWPK`a`i]3,N3i m,&-5GWq{Q"lK7(Ez+eAULD X ! U &<i~}@AEmR67D  ,1PlobY @  SJ( h9DZkJKaLx1@cy9=S>b( =<`bf^|e { ?{=0XR\yr+ReHU 3eKPE;BPjxV<  n?Y4t-k Js9 }WG_nE:Xo$n+V9Q aC036{ "s=8yvuL*g8IWrztjv|s.f *54C<]q;b9Q * ~ ? l2l+vz!~%{/W >h U(LrW  G |6R z ~4wXLNrN+%@~Ci"4T0#JN-VP`Wf{=X~HMz!0(^%Sy7Yt#`$n+Ws}Ba[: P : YtBahG?<'q *lA | 1 Z E R w8J %6G=|Hzw0Uk_t<T4!Nkz/|),7 A5k6+h-8Puz Y#/Q|2Zz 6f4sZT ' ? a  ` > ^ Y)x7n2r3J3Lk_L/7 !P!x!v!0! K V# }P g y LWWz X#S9d c/^?=@d|eb3Z8B:e X|s30XXZjFkJ>+Y1Y:X*r/7; " 5  h  Me'7`f`AM !V!!!U""""""""E"! !6 YMH%}g%d  3ur9 gox`b6};t<"|t(r(>}'];@xE/M@FP^:&; X b |  'DMq^A/g-:E b (!!!B""*##$$%T%%%%%D%$u$#,#Q"@!% Y)Hd { E<=8Wx@ Ww4)+1nEobfkqU mD3ezy EF| {\=K`z$Cj)wYtp,VG'M*ua7 B < b R!Z,vZI! *!!!9""""N##$$ %%&&&R''''@'&"&n%~$k#9" )AxH> g Hez&DFNsN ;[Y#I ]77f/nB4T 8?8n3+ JlU + ^ @ sh(!!"\##C$$$5%%%0&&g'((f)**4+++++V+*`*))('%$`#! l*[a K5mi*oTߘr[Q91^hG4r g93yRB5bQ _f/m B  W2 &X cl A!"$&% &&C'''("('(Z((^))*w+?,,-`......{-,+*N)(&%#;" kG"t jc   d7r 5/kQC[iߪ(|.lKۼ?ڽF؞ؼg4ڷ$ۢ ܎8݅ݴDv3߁f`]N9'_/dscW@|5@k@x d X U T _szQB$ "# %8&"''8((7)w))***Q++y,--Y../F-6h(2 n #&2'!'M&%#y"""/$'z*,.d27;@SEVIM.PRSRPoMXHA:2+% B.!#I$#!?  ^ޅLϽɯŏìLωZkEխ2?}y»!4j;ϡgݱcC?#m&15ElNv ~xN_^} K)+*GN9` Q|5޷ 2܉)zPX`2x[wNG6 \I P5!%a(1)(!'%G$##%'s+P/2#69=A E>HQKMiNMI EK?U8/&qF1Ki%x; I|ҩ[[j3ȇ/δй<\]DɼƦcekyȆ̕ѴX]O@jSR ?. \"#$#!-{ 1 *x ,zӊ8s[hbe Vr s!! `c. T#'-C26:=@"CJEFLHeIvIH+E@Y;D5.'!lS a4ގغӢη!OP+).Y9O{΅0ɝhκ8r+s!caam  o?L S!QhQk#{/Irޏn^/&ki xh C#$%%N%$#%&(,049=ADF2HIAIH0HuFC?;6z0)#JS_pKN-/_ \}aHӊЃΙU!ܤ.Sߔ;زӇˑͻۼMzd__?V#v X x ^R{vg<i;nzj"Y݌/ؙ:br;vgY3C} M2!#$0&a'>(J)*],.03"7B;?TCF3I1KpLLQKIGED@B<60*%n!,(Ae'  A EGIJJIGEA=g83.*x&"7 -gcw f'@ sПnэӏւصw_L_ƴ<͋VՆ(ޭ^*8 '=-OCce ]Xy "  `wG]g >01?Y"$.'j(H))))('%# }  f ! IU 0 }_d ׭6z *WK\T\2.!AmLnq3.oB4ZEx O1OO( R# /~zj!###b$$f%%$$\$c#3 d0n]j2 G!b|C@^VٍfߏJkA?#}s_N$cP'|&oaQ|:@V!<|7  Nd ? T X e Zd!&k{T&t f 4 (!!|!!"o d+|q )W w =>T5}&$Q}]^4n gAe/iEt>F!:_wx}+ dMIimi /]%7O i o eJLUc_)QJ>-`-&j ^*Fxi $<=oj(b'1V=en#8w: .QLCeTi;M`GVk%5(` &6BX&%:/I M |8p ']#N&R>Y3[  ^  q NB: ~ i3N#(goCI ;-m.P3?`ShN7O6M1|V(Pt9r_-R`7  1 ZIRjg'iU: ?' > \ T & 5 / B = ]4LR gj0e7H{5&E>'\[l|snqhrM&b"vP* 4Tu6<3YQ^ Z '  @ I p -  hxv A'W^C > 6 + RY>mmImah4h&*g7ZWY) )Z;Nubb#' e] %MFC dQ>J#Gw5V8N"h`*W 'na /'CpfQ"mK6>[{ erz;u6^*zo%=EI00g '.3|D<vAT[XE2 !6Lsy]RHSSVgnlP7oN,rTC% }Y.~wsraUNM$  +Hl&4FTu+Mn2Gk}3Rn*/0%{iK,}`O2l[5! sj_J1'ud]NK?>9/.)2 '-?DQUZWjw +H^};Vq$&/37EJgz{      |cZ?+}n]M3"s]S@91%&{hdYXMPR[gmn|z~tomhvrz-:QYjmxt $.AKYbghibhchuzr^YD>, {t`RD2 {jd]]agt{,=[n   uoedZRSONH86,  #,3CFHIFPOIWWjewvy|vzw{}z|vsea\[PEDABFGILLPFG6=?3)""" '+/4/613*1(:=7.55;85736DDAJECHPORKOGKJIKIJKS\NYZYY`dhdkjfdgaf[ghoop}}zt~whoddlusgnkgjldg^f]YVVQNBL@DA8<588A@GOJPJLNKIHFEBE=@=:@ECCB=>4/1"*#'+$'#-.('#.#,$#!#     '            $#&+/1=BBD?E>DBECJNM_V`Ydrugkcc^^ZTUSTNVOOMOONNEHBC<>642:00-*) !&(     "!$!$' +''+%$!&,.%!$1<91&+%(," "!)/0@BJDKGGJ?JFCEHKOOX__fhjpjngkmmphcg`^`aWd`\ZZOSHKGLO?C9=02*$#.,,36+2)'!$%.<=:9^mqO:8GKgra]U@6;Lbp}vvk_XRPUkmokg\]SUYakq~{syvv}yxuux}{{~}{qrmjendor}~~|wzu{||}{zuoqlnonrmu}zy}rruurqonqhrqpsrx}|~|y}}{z{rvplmnuv{~xg[SJ@/ x->OLpmyX@Y2SCY9eDBsU}X.juP o!:P\n2|E_N|pYo' Y;S?Qbr9p$&4 W[hJ<`h #4  \8T-<U0:YD`a{`tHv*0]I^x t]tWx*f&8-> /Kbs5g(8tp%)I>/OaBU~ACeQ,O|R)Bu6UB  ?PPm~cZZ:bt)v!"(0>j%%b K9Uf[R c{h||b2i\(DMThD`>HBvY@eo=UfI?  4FoSG&N[5iV9*n!V~jtf}4 Q@ #= F6", ]( #] #dn}+gX < &' 8Ouv@  Q-|Rv p~d4n x]1V   zUu!3 l }V?   . x@"2j,,  U #Y~ a0`n^?-h#.   YT~c< Y$x !^{I _Tc95-QV) V0  & \\QaF :sK_Z pX /|L Rt . Tr=n^aA5 (,H.W B m##KW  Vg9:wU|z$ @U 3 ?Y^kU=E?L 561)t u %py|((iZ| B Rr6 S q/ ]~ *h%e -Q| yy&{mY&[|cbIP 7 gL p h / ' <=t.zO 6>iB=1f)hIq" L= F(; ;%o+v8K ^3 -oQ jO ooPmvg8czK Wx21(_] 6 :"46b59c  jyG tc \ L+#|P 7d> w [J 78^5 eLu18rSc}&=.~5nYgf - q !SK G# }5 H ~LLAjod|~!(#JS( vq\V6{ / xcztJ  _Z Gh2;c6~ v 9m8(GO ? Y\>TRu@}a.i#jzI^ >40$ xX QD,@gR  ?K\ .cO2U; 7=X1 {&q0 bn \F\k Y w9n:  $!2$'r^ds8 'v =& ]t)9pm=& cTd  b"r4X2 _GN!jP ]{: mDqX  gd6 , j ;A O)kWLtE:hv*-g D D<} 1ZH+-$  o1{n [~ED[L#$ 7)`@9.uo TiL J VmB1Cwg| Z`5p<O\W # 4M70,E% 4qdPs^^IwHWtR$k9 T;( |_/U!RpfZ'3) {Hi  vOJ,&VEC2-\'Mmr"0~xlMZ ~Og~]Phm( 2\u|l ;}o^GM m#Q 02jBO":U0 h L\'*` n : u #K . 7 E5  vlK9 Z:sgZM ' * \67N^ " Q y D 6d2 Y:@ z\  H"&,wO|;\[ @z o nzZ V 3~O!jxQboop/+D:y : 1rm}=r* L3pfYX-!n2Qha():ba *)r9. BH~9G~SPL& +dA>3_8`e/y7*Q|*oA~\5"D+ 06!|2xv2  @? % &@RJ RfB(* 3PcB%GXL!8t];-8\eR;R<*(+"7]D )s`.$ KS- #%9AN\TT(3[vtS4. $N&Sl4(9.$9awc3 /gwo7 ,fDAoH!Lzk1or/5ND& 1u8_ l|1!ZdW>DZI,3K_T]je:5VfggQ3!OqvaHAKQ:@8@P_migfaM:36E[cQ>JbgVQfskM@ASXJ4)=i|m`ZPKMK?=Sfj; <_|lb_jorj^D;=Xv_RT_XX`r}h_aVZquLQnjflWKQsj[`sY8V|LQf{}z`Uuv]]ry  !% #" %)" ,.)(.'=IT3 9A>7)#! #2;<.!+A:=9<6841)'*3<C/.*+67;0%.,1,.--0+52C<D>8*-/7@=;>GD7;30-8:BFF3-&.:DA?=:.159@?LA:BC>=,,&3EYRF0&)*4=ONUQHH5426;=EJHM>9/(0ASMRIILLTA7#!'>[lhWC6-/55@K]TUHH;5;=JOJMNM_QI897?GVZ\cF?+.=FHC;@GWZXTB7==JRZ\\NL96->OXZ[TMSU^MYEFGMSTWTWOC83EN^l^dIOD?88GOXSJRTMSLJ@BHJUXV`YOEG=CDRVY\TTW]VKIFRdpm`Q><O[d_X[elh_KIGLS][`]d]ZRSMQVY^pnwq_R@=\`z{wmga`_di|zjb`anrtf^\_nu}~}vqopq|xckkolqoe`VOD//$&+8Idl'AE^nJGrzm_lu{~|ty||utsQRc wmco ,ZK!dM%C 5@)fJ@sLU<&\pn5M T`r(R)f'C\+x3;~9rE'G7 -6';y>x.#?Zma1dredjRJ%;9ED.p<?^k !8Ko!=I}) ( 5kO)q I(@Oo]'x5,6LfDO&,=.Oixt%_L?W>GAky(nV4%[`-_Vy .P l NUyg(/vP|e'd r CAM,y&t<( $M|y@9e3S$^N[q+.]THD9:X-Y[7i4&~Je{KaSfe 85LM"C_q0E'?cBzw.G7a*2K5ZAHtNCV!2eX(r35g9/O`wo].y)RMn{c'tx`/}CL[lQC\V_m6%}z8?o~E/ZH+ M2IwJ%"zKM:\ZwQX81M\@)0,L*nC=@QQ'ku+m0N2U{5VLKjU8F}.#,0R=w<wo:h? <`FnxH'#Z9&+l1*oC*d4KeTP?,ASm{NA.rBAaw"{%ij~?_lE6(%  {_#*wL>[zdPvlq};.}y 7~~~xy Ig $dWp k@f0^{qci?q;oq9"Vz eetRg[ jq0XvSpv-uk>Ss"jzT,8:?335p#?:^6w]6[")OJ,ivsoW"O@}MAC!c_%n/cd[.-*#Un,^[8nP{n?2;)Pi)I%6!\4*a5,j;6W9>$q Lannb,#MKYfj'd#+b83 H$iB8Gtup!(j4U}TGyfcNmatp?Z(f2QHgsh327UihA f(8fsT"W9{zI'+5>od'q?GJq PP(# V@&hLh.KI  = U ]YZ.UIi E$%CX:m*( > S S H VMTyI4@7s$LNE>01)Q }[:|L:(Sk3}, X r | g O K Y f P $  +r '^N]eE0e#%ed]rI|Q{b8-Hs& KJs.? H v 2 i K \ l xRw& !*69#_Mu\ " * c?=9f2ATN2FLnH$P:BG n5^|QAC  c ;"(->R js,)nNH[BY`wQ$ #Go wr^^V_ye'T Gw'Wd [U'N)/&N- e   ] _ c 0/,06 se I D & Zq$?; ~Q3;Z:PfzG7A 5h&$cQYFXtKUx&5,nta #o r S S & ? nL  E} hld TM5N")[wC;rVD/0f`Mh]0|6 YD2<\ (\k B \ r9_NJA !p!!!!~![!! QQ  tLB?t{tU6\QH<rA)]JKqE/7y4\Zt p   - l U6y reGXA3 , H X D  n3{ 1]bF?{y]DAVh=X(}pdO)I/SztM|@i O!7TW_\WRF=Na.7j8N4 ? EpC9` !!""i##$${$N$$##! +pnZY ` v9D= ~nNRo JIz. silD<8|Wu^m # 8El:|st&ET>S1y r -C2Wx9;w0~*m~%pEAFh`MD>C:&G%k1vN),8JNA2)i=^q/IuW $   K$rC9!Q""##|$$n%%%(&$&,&%%T%$#;" OxB(,2 - 9iB Yz? hL܆XIܪ8ݰsPNv N"}}[w kE[76uR7/.p@v{Z32 P `mawT^wWOUPJ__Gt!d[eD:-k%\W5&$sY HR weYA6Xf*d< u6 }Wk"d !#F$t%T&&q''D(((((_(''&%$" $^Cj0 g1MZ;W)qEtnAhڃTaڭC$)I߉u IQKWr  (U[ q< 3Ut Ip 3uUGOUyr" Hi/S+u4^-  /D y]4cwGFfJTlmnzrzekdG' @v`wbd 7]z 'h(}]! !"#%N&=''(=)))**))t)(7(q'{&%;#!TTa $aP,=~/h)F߮\x2(SٴPH}%ߕ$~ir5 NZ  fzA  oaFYPo8r a <uiITombz)k0j(qZw#/AxD~+WzyjCy.$@dGN`E835-#"CE61GYU] b ;h+n,t Q"#$%&'(B))*T***[**)) )K(O'5&$" k9Q )JP4)~5݁2Iנ׶vޠsIGN]{x>l? FTzQ$B6p%}9#ch?Dnv h ?oXL]|nwa`dZP]JNbJX"2R&^b;a1a-o%LM.K\hrS{&t_NKl8C},JDq K 2[? T!"#$O%,&''W((-))*D*A*F*<*1**)")i('e&$s"I #i ZJeB++HDx?܍F&Dؕ3F׾וةیA7J T kdEnm :!W!&! 3XU\v`#4cd;b k6qN47Lv~"V235cEy#cDnLwH|T46O\k(c$WPmxSBZjq|smL)eDMWREr=   H zg%nG>q "I#+$$%&'(y())*H*_*v***p*)z)((&b%#H!#aoV izMYBpJގ=Z}փ֗׀؜ ۡY2 "j+jOaq /TACy 1!!!m!!g d<4}{x x?Wsyv/\\g 'sPMne!oFEY?M#Kt:K6LA l^\H\Tw4/!^hd$NWx 'xY[?$27# !"Q##$T% &&'I((T))F*{**T*)})(('%#!md<A< 84X$: =apFٝ تtבc-j:޶c3!#~$ ] m9z\3 $ rN&{Vl D=(P '2\y-MLv|[we'3g?{%::UlD5Cj([f<W~n&!(%"}L8>l*  l v4 _-+^6XD?:Mc z  Su&$Eg !!}""#`$3% &&'z'''''H'&&%#d" C{  --'tFp~ DݝW|hqڮۦ_GJfߟNrsZV^e~ n c(mofY1=smH % 8 [!P y}3r T-jm ??x\F."g>)eY:>/-Gy o.W2b#FlPC/+"|V?84$( G 0F,d :yMH y!!/"C"u"""E"!~! ' ngY XWI# e$?}7r}R 2hk)")JߑߐZwz(8n\ \ kB0NpT  8 V x XYL |e@ 7}JjOehL=v\zYFS_7x'u{Av} #D`-_C Saoj 1'NF%zs nR^   + S}FW 0p -Hf 3F0iu0^  sBZQ3j7:@by5P(_WKvFN;H`k;~/h%wK>vJ,\<xrCV^/~jF1 $0JkY7:x!*% {fciqX$BncnX1!T:2{k<}A[dWm!L_#nx0Rl+D,t' F 9 ^ & "[3Tuz,K~  \ ^ b;'vE,H J<_?Opl.s+]$oZL,Cy 0,M3rT/u:~u?j}2o4(3WynM1: 8YBof4 !`jp|kaFA1~%J1'o"_a^'/ 3!frshfR6`oIC /$rBry?ieR7 i v r ~ t g 1 s %>Db6z/ ! P   ,  h "}!9\L+v .cV ]7zlY6 !<@Uu&e-< -EBAN9\*i4[-K6PXsYA4"FW\GVRPGg?r][\,x_$pa[np7RQo|s>Q o'9r65!z k]sva$rA6ZtN21V/4uOaV( qq+{HQ;,Ri]f$}kv>41AZRLplV okw[>u ,WJhoF';x8n?/zoalQU@#HGn{drPQ:c S n# Gdm b A: > IK9tPVHKHe? = &NP@}Nr66ja;9Qg{;Q"qs*LMT R;cE"?Y Er\,9Hx%?yEW1X " Okt=e)C\"p;k?`kdiqro8:}zSVa:}B?p 3.5BN<( kx"E8:*.rTc")+Q7)>_53yik&[:tx8 "^>0|;)tK3KD/ L^}O=de7>E{7LYBk!9%Z2`V)'x3 `WjMf%]Ql\*xbxPaIq:1[83pg\ri0!1\rsB8_+8<Le0ACDq%8K $Xa^ XKV2_X@ (sx$ B@<?dh$'{2'I[QIo+ $AGu=B<f:-3 s9.sH^d='}LW~j_\% @m7eHi`kMYi &Qz4<]:~xBuL#1Pl1fp2)=:KuZQtR]N-9Dh "S?L(U}MZ-M..ATbpw/4BHUW] )=4#DdxrQ`}O!]~yaC:_rm= !1iqpWOJN.$'"*Umut_mxlqzSPgm\I:( 4^qzD' ';?Rahnsc=";NH5IE+ *5?KDCTebYhmo^NE<.  #*-0.0"%#0570'0;;E>5, #"  ).%%.'6I]Z\VPI=4 3CNF@EGKRQIHHJA=9;EA>@3,+""   kEQcsw9_mH) !31'$4LTidng\PH- -/,-46%  ,! -!# $#,-4         ! %" }|y|wvywtzwrvpsl{wifgehhdeajchhulgmlossmpkgicpkpnvmtwuvty|ywwtqqonihcgda[^bYXSTKWQ\KPUUQTLQOTHONMRUVZS]VU]Y]`__dc_chfcc\]Y`Zc]\[]ph_^\W[`Y\XSZV[Z_[UWSWWY^XXWSTSUWQWNWX^QLLLCMHHDMIFAC@CSGB@@A:C:ABCCC;?@:=;==<=?:?7<8674A<7<::>;>>=8?A7DYHMCDYJOONXZZQRTZ__XY\Z[\__b^d`^^XYZSXZ[UYTSTMLWNHIFJCKFDFIAC8MJE=IMKJFFCGBHJHLPGCMJPV\SRRMNLVOVNVJQIIKLIOHJHREHEFKRLEKCOISKKFKHMDF==;<:89B<3730/5423929-820/1&-,3275416::=DFLGJGJKGDO^\QUGNNTRSSHVRONHLGMDM\LOSOOJZNNFGOFKMDKGIBOCMHGBFEGGGOLODFDHJQKLPOPPOIJMGCACFDB8==5=<:>>::C@?@BGDAECHCJHHIDHGELCMKHLKKLEGDGCGAIKBD@?HLEAGVTWNRLSNSTWPTZU\V]WXYYWUWT^U[\Z]```aeikppoupsstuvutu|~|~yz{||u{w|~uywxu{{w}{|x{yz~z~{}|xjjcdh\NB80)k*4TQOyDw N x^D\x^*pF{\jq*e`}=El|`yGtg{l]YHu6Nx#~% Ey-Hu8#vJ|\#y%"Fu#  ( + Viz\wo3>D(aqGhC_f`n7r Dh]1r`=J`B*S=VOcU? {}IM;?|mY8PZ*9hIg9'X]S.~156L6 c|\e"8\35fR+'K;Em!qWX)7o_YfG3t.+{C7o=0#D2oGs{!li#|I,?Y/ dI>s+x; :V ~$Nj)H6fej#i\&VQ8J"/?@ <s.2WUUSbVrG&fVCN C  ;v,V(GFC> xX)[(%AEg+Dj@,8'+i@{>$%5w4@0:P{HI_h ua m:t&. &{Wcn4//(N_ID/WDdd|TyuGGjY08G9*<)"3z.*8;I&D_H He})vV!YF"AK<)kTeL6Os31320&qu|?6R1<Rzxg1Q\NC"w SoLz46>YX0=PQh<GSE\hmkF0)o/CCB8 g^|dmK~ `H;C/ %s b5K;F|-Rn \}49kpJZIr.SXB2{9jD\cNyh)9!]"Fd^HQ3V  KL&'1b "znG;0q (kc;Q)#z+%RO3Wt%9(H^ K2C-]bK^F|*b, (U$9k7 ?6]oy&8)|5713PO`Xb#sp*rRmr{f G.& P)j9|@gkF [^-Rk|d8 MQi0X./pmbeV"Yqk{?BwE4ZM-!\?@*mGIDQ 1 C|}]9 bPqmRKX\j#v+q7Tvsfa~v5 tLS/]70^4L}.A;s5s9I 2fk?eU &0&$E" + j (  % > :  S ; c  8 & O n " 7; $ D % w]qS3ECKCUHl!@X o~.Pt$%68_Zq!p;M,5Z, DQ": >)Bfl{~u}w/U[ q X J s >0@src@yZb?3|'Cewa=,5^ h _( <7_Hb()`V:;OketoU'{=yPC#fO6bVM% RM>Zc1PB^ch{0(K^+d{)]CS/f wuoRT6 9{@cN|s   c " < R H0?oK+94y`vz l - 5q 81Y: IlyvF @ e']?$8}|FzZ#*incM^A/*jn9b*T MkPbq?r5mf!MT0r;?%7Fw` i W  ! ]/{%y6NtNYgRLSm ! #$M&()+U,o+(:% .^S a Uw \wYK9lH0l"6  @ J=\BC  A &psH/cgr{IW+;iYLx9+  K_]Zh" <(=Z޳߶yKVj<8xK77%$O36s\E:(O  7i/iOjG \!"$%*'(*+H-/0233+31V/+!'" = W z8}2<ݮu ى+ nU6 >I l6H f{b0Gd[|&ugYMms 1 .QiZ ic M v!]>މ&kA? -HOr m F a|+u fH90.~7i(\$ b X|Ks5!`#`%'F*,./1N2M3333321M0,.*& .#K GT?+& A54ߠ2|hA} ~b#V R q0qhDn5?cwߩp8rjs}~G$:+BH] o wCH ` ETMU,rs%C$ 4ywp i Opj= %la4@&f]:9}O8`V 8  K"VFQD6 !=# % '),.0245_5<543210.,)f&U" 'xlSCߢmRG> X^{c0  kM9߷cm3 \exK 1 K EJdE w8NX:`f.a{sfG 1X^" #k 6UXG/ _ |mE=Q Wm!#y%'("*c+@,,o-----k,+>*Y( &5#MM 4k!OGKv.W| }"n9 ^  -mc_} H ^OL)~Pk Zot%OLu[ $2,c i RWsC3E&0 Fne&uzH5bqC-m0K|up2Z`P+ {X&N$!A'RlE H< !#%d&'v(l)7***7*)>)N(7'%#W! ,7im{#?^YO8 _aW|r`  >zm'psFqP%3 -S!A<LCuM8=W _ [ C < $kx } C m*CQdtz* 1` =mM4'1`1>95?x<IP9xbCFT%HR]90)': j fGN@ !"#i$>%%&C&&%r%$#" QuQ .3Y_TH383?3.mdH`" cY{[H6f8S aiJ,TCh1 Z  '  U } q- +8Bj tr(Zt8>lZ-6I}3 .iH#q3o-oVYaz = l { Yw4G\@(v`rJnS aWT8  # @ ` ,Szwsforx.It uLtDM"FV`pC[#> ~+^x#r&lCj|tr)g #>VtvolruZH#V!yZI'" &7b{ 1s{aA<8`X e F ! 1/q2#DN.#0-2Htj1IUW9-I,N(n@d  (+0~`bgt 4`|Y8,#{L# ~padfy,l+rmSTy[K8~-j\[i`=%<9$|O*b??Q1a.0<AD<4+I[ O,~$x1zcRIF@7 $UK H#Q,>m+ s 9    r$h: eJj)<-.e  0 X [&9L_q?9lUj]h*ej'p4{U.MV>*0dE"yK*h,D ])8wF%$ z@OXu:\Oo7tSOE:&:Nb T56q<DnU9 H i h * Bl T'Mb]N<^sb i  ; n `KT{ VzPFA+)KX+Uy0\@mI.AW0~cLETm%q!}K.fl cMG1xLgpwxmbQJ:#vPpz4_"EfyO( wdWKKMZZvGo"jow zf&CD] Y '  d $ { wW(*( |*T  f  ^  g$YlOYePERaq @Fp&S~7a {AzgdVao4})a/QcJ7,V h)xN,O a `5mC|/]x]F6  \IIUg.tP(hV?)SfpBs(&Af2V)_kb` I , m " h > v  *,!  p 6 i  H O 3 gBZwN% @z%tr'$|1TGr+o;#YL80~)5=]9=7*AIH8v*g,>5, xK$sL#r6k*tDQkN2 &Rz"IzdZ+h7S h0O:) \ " q  Q  K w T 8  W q h nlar{sljn7hPJN^cn);]M]/ &>Sz =h4 MZ0kK0!eN r _CG A}-9K[m}|g\QJ3*tC*hx;R&bc#oFFN@'()H.*CdG9?Oi CRO5V-(5E ^I4 W  Z  ? O b i l \ ^ P 4 Y 6 _ # .`$QG;.sR-x"~/G2w#AY/wN)Hh|)J V4^/|G(u"f1Y:Ik B|jX>d7Z%<;)teWr+_alcL*)'7dknlDGBxV_%\<%vd / > B @ I T l s ^ D C - f:!}NvT N1c|+ho+a'Ae/{Sw[+/zLAU5Y\1/M@CI/X=R^xxR%J\#IeWE/E}n+Q.="lpY~][vnX()*7'=]# 0 U2$'Rafx] {T 1PrX uXD[s{$ Zn"M/ ^WN)O&bf'tPDH~7JF73AA;]U+ffXN^-eyB:xb7h8j61dQ1;}! { 9 U m;wOb9}mY Q H[~&$/Da&tAl@m[;kr(twlcX;"|I/xH<q#? O ) Z \ " m   WGg:_^Y^0tfks@qQ|.m*nF * # 7 H l > F G [ k z $ 'H%+ 'T< ?!"#%%v&Y&%%# 3T$ 9 " ]!8O,,M^RHb ,aXO~&rW *g=TS } ~ H ATzZ' I \i6R~W e3%HP0T6 B6vH"[v^Q3-3[x= % @   u " Q ] P j q k CEu'V_:{ N  *pz<bY3gK~V&iv&R/33-:ZMxk$~n.d )[%5;0"|D-rLLj~oQ*#7Yyp!I.LG61Z`Z8!Lr}9B [yY\CXlZ L? t t? v  zd F " k v 3 1 b M Q | d     } V   zd q LM5l 1 jmJ?&OYiB(A`]a{VC:e*3!))5%TS"nC:XQv?ST59WUe' =T/'bfubc)LL-q> =='1m_pz$6t@833)URa<5>MCw6^DC&LW^> o|.#AS[X eN? >:*]5ATZ7l 0$b?QVqypDO9X0vLg('u_pW4O1OZo\vE_+wCFs<6 -9jsh.$!f ] =T Ri pRZ4 T3  E e-Z}  s Gk.wJJRH2<[(U3bw x8  77^ sQNGtsY\'e#F :9_a>I&$.nr*-! vppe}khvX)&9|! 'Hn$lXL vx=PeFKB- e0 }  ], e77)yt<-w c go > BdL$lu u=szXJu @e=@' Y 7x->UHi)a2B|Nw9Uw 6mwhZunVULE65uXd.M(Fiw; M~=e JW b;DuV"|716K6;aL`tee mn/JT>g1-M I3c nl  S]>+xHh\<  lhZ{.P "@YU$ *BK&^Q8JvA/bqcFC%OGh Q! &dVaF'O)h kg>Se_ <vX4'_ypS8- `P NM0(]P G\ 7! WOt\PiZ Jp E. be5M$,Yp"xvC'   6%P 0GP GKz=^xB c op  I 7^XXB(^<Qk R*3 cr x@%dcz y(g<6 -CUAJ s|S{f  P,LQ+-5M9VQZK\Ql uZk[! ~$Yi40Yp ojZ&7Ae7; S$q1Ms ]W'y>Cknuw`zpY &< X  0 - MMufC@I9 jS}J& JyHlUV+nTA "hH1( Az!{Ea(Cs+nX' \o Z<'K vXcp *{f8$b5zMwRq#=X,VY!5'uWJc+b5D%L$ c7p8Ex !5JYgbSi^-| Cvg6LSv8q:gBhjzZ`sF 7',zXnQYvT``nH'%*^X]]lsc1glUP*k1+}ynq^cO_%W7N({)y9Z*n#0 Cz7-|?"Pl{!4F :o-E3?=lHAk |0Bt(Katc\d4 Zvt_deT}CFg;x v[&p/fr16f{3 TNm@2W%AnbXxX FxY|Teg@fF;=aGZMre> fJ'5y8B RP@9jQ_1sa8>P8_? lMa %|!;'jBau ObwQ )-  S`3$OvyVU}_mslX"icu7(JEJB0`n{+{!kK'Cs+? {dP-JuuT9T.$%=mN/^8W3]fw%#**SV8`|['65[+&qgP &syymvg0n'8fHXxYIJaZ/aPI!94izj;Yseu7j2"~vdBZ sE+#/m{ yK Es!*7X | MkP| T - w^"{E /@OxnA%pXW%T kB&iZ,db7YwSL9DL&46,z @ ~d)E'h ,yh dbv3B?TYsX!Iz{D5W;vqHC;aS"$VDGAsr !Kyje^ dg&DGa MyvR 1iBD05A<vr6.tIO* WlzX.1Q5%R\vX8c_aGq J\,&7%Sy {p5 H*oFRvi}$m04m@]=~j]c20D;Slg'm: ~v $gImy, 45i6}ad~ }5B/@ 1g5O~wK[7@C).P)Imw~y  ^ ^,l4aI?Smj JaA+uo%Azm 0@[hf"xV"Iimv/%99GEs -4@A #HCN{Pj;5l\2Jm qv x[+b'b|n1m/w g_dM@uAL1mw\ 72jU:H|`{D<1D^B2# Odcbo Kn 1qvFcCv8_0z1/\OK_}ksK8(d1 SePWEa)hX  j?E/L 1 /@lN j psZ!_%[.x't{$c<qk9w\W K  hbo"  cjAVTOrSE ~YQU~Ytapc/VV`nc< >G{ [ 0Y^XXro/C;aWi Pm\7 4 ) ,1 ? 0 "+20 Fxe<<_q< Od##J :RS ]s*Z Aq}, j Gh|Qx626*i>)T4fWwk-=;$JJh>ey9g}YH 1^o1y_4@q x  , AU.5%Pa2~U 6+}1B\!Ms)#u  7 h;c%tJ Y)>sQ qjQr>\IA+!dcHK70[lU 6fykv P 4>D 5 ]F" _ m sQA4h,G,8  5W>=n 1 I 3@5UH) *NI*` 6 B9X !f64 !ed 7F\HP$s6Rn 7Ix. /MRi  IIoBERg~`^R{by ~i76f Zb wj!m!z ~ 'C DG8|Kh 7QJr*Dc_`{ $- OE7k@arvzt7g :,3"_Aq Wz X50D;65 w nXY=/]8U `M[X($c< xr6@Y 4gRuG0Bw-] (50t20sVY7.>?es*:Ih\fzxX`XKVk5&L;;w,*%524fWEw 8=TxH5uwgY pC$L&[  3X==G^F~I* B=PNqDeS?T{#m.`ux%o?t^h wGCWO7]R$^$ . )} 3y!Cdhm?^~vLqq5O2LB3h|y\KId^-kv9{}^>4LR@-> )~In WX3IP},9>3}]^ [TAsb:l [??Uztbey@8($ *5wg4{rBr[+d#8E}[-tj45n~>9";MllV?,&Rog:=;CZ*n  e G ^qWP&:ft#bh )! -/ 'zA`H>9P&߃m6I%NYA`T?1!|X/X#U' N Z U Y^@ o P g]/GFxwz k2I*{6 t3bV#]WBoNuca4=mj`\h$Pt)A:3 " ~  %_ !"#$a%>&'''&%}$L#!%r` W X&bH:xݎUՅq֖د2Zڸڂޞ +e.h[-L L t$ S?^=  U r,e+S0^j}1iS{E>Lr{qh\j|r?'DIV\M[LM}5oFgar}wJ&JxpKeS? ,!%""""3 (e7  4i"PdK4Ds;)cܕݪ 8| !n j [ pbf/9% YbhY'j p[/.5c-J^^}>IVu H { t y ] c  ^&32sA8LFsnsM)2q"  au;Vv\8 x # [ `  *HS?.] q7nU!]#1$1$@#"< SV9# - OQuI]-;ygGRnlՇؕh*)AlZ `"!  ) m HK%O|@ n"##" )v ? ' & #3 TlJ'{%:ETQSi^; o ^&Eq " @L4F\so4zC$~2Zax\CL,R>Y _r ? H k 2P7a8;b>g-;FWG' icbv;H !0=zOh|SԙpgV7MYxbF[ % jT ! S,{{bP)/ H ^)hJM=fi B^a7,v=*. E ~ q / `  + $b.F$`B/ xnd&`)s>L  Dn96uh.*9Bj#ڊWbΩ:ϝPݦ6 hojq O [ !;#%&(F('%"6^  E Dm5XRg(d>߽Z:m %\~[=0 jOC% Xm O3PqwX   n _ ~kx&)={3-ߡއݎ܋ۢtp[ ylHu_,4,9J  N o Z  L;APwc]R!p&ZqW; }KeyNO W { b fobg:^+)ܿآԎϸo<ע5%5D\ _& ?VS '"#$% &T&=&%#q!k$s42- tlfUB>Rq^_"K"t_FBn' i4si/0 Jg/tXXKGf e'xrC9/U %Gxߕ߳ Hޛޱ޸L|MA *pWTd G tBgft-WuitVu6t~y.S1ty+xoKYRx)B[XOBޣۚf(ى.f Yus5iu @asMgkty$\~ Ma'3xOf|b0+>9vaDZf>I= B } Y `#x"0r߮߸SaWvHO&C4Rf5 ? gTq,o"$iKm[d, bC5D/v|  3LRJ4DoݑآֵԁӀӡM߲UIex@,9]V>\[  !|}sH|T{s twI&-,,sV,}vOk6INo'qE9~Pnn } M i { CfAnjJ0m(=$y UI[G qp Y oU@ !!!! q I : !"1$%/'v(+)u)m)1)('&&G%:$""O! .XykF IgTbhZbN!GҴ-'δϒҽ֣d^gnޢݍݑކ@h; WQ O7Pg!TS "$%-&%%Q# 7/ : ` t   F Pd#'uTF_KzdBc5KI6r%P4 G v @ 5m5CIT{<hvTMpn^4=h%.gq*nP[Hp0th= ? 8{,t !# $_%:'t);+,U."//D/-,-+)('T'o&v&[&%%$$#"t!Y Q)IY jgވ6фЕZ۫#ܺQG2Bװu|g>p2mgvS B dFhK!#%%%%$"!6  <pE@`ou.K;b N b]8;): -4)PI4R&0K1`l#;TOD7b"\fK (}4i#-.7t N Wl jqH'-f 4"#$%O&&'o'''(((h(t(4('''7(((('e&e#hgj )O t,]BO?&ݔܽ܃gVWaJލې՟bt1R3ՀT`ؾټeET^VCp  ,%>TVHGj !I"a"")!  >u@u9$: ( Q L # #"cZ(~.':xJ}mAMQh&aW/2 rhGZ| wR:l~ TZRjhnR~rK"'W&?|ii/ &NdF$ ;"#%%=&&%]%#$D#C": \N< I_]u4T`@t*"޺ڱ7~y}V"mXݺq AR33 Qe7D> Wz*` {)CI /jl^)EBxH!zwKb%n ipNB#m >-]=SPh/lD Y DnYkMK W s t n T R k : { # r %Goz/TG/1W !U! M} ;ODR> i7\& uX2;(vw!F:E%o6ZDJ +bo+-gu  l`&<i^E7#tSxhNSe8; v Q z , c t+9Gw+~_\CoVqVJxVga"%z3iL\vfQ$ \L'. C ITWz/8E5T7CBbe[L Eb%)I\s5b8  M L4^7 P   4 f c 9 H % 5HqSoa)J6f115|VLJa]W2wuCa&0k)]Aua!   R >\bYp9aNQoy_l}q=WOtPe K S f >%pp_:i"[d^o\A77_tImIit1+p 3, F w x [ : 4 -  u  * { Dug-{9Xy?Yh#L#LZ?B4zoP U+3,!5w|C3-p 4E.m^G `15~cis>QL L  $ [ r J ? <  " > Z S_: / i 2 JI rFl^l; i ] ( " nB,Wtrj>'X-o|d OWy /).P b{T{#=hcBnW z+^&bNftm0AkV*I n;`w|~YF HMeN;DH (>Te(W\KzA-U6W.#Fn0hQC,H8R.cH^<@k[*JUQ[gFX@4K},HY}Z^: W 8Chi D @W W QXK%dqM~h k6I90oRvtxdFmeK>k`kqqXA"9Nf/?]?EarA ;|Yqc 10\ZE+|71X.\*rc.4W[/^[Rk{)8 j~ij}.rIh\.y"P d~S^  [* , /a/v > p ' wm j L ? o )j 5t_&HR~z{ . b s b z'sR |  5qg!{(.;*%WdO2FfHg Uz!v]tu sgeD O|dvs$Un2HrPLA!?NKZ<+a;!f XQiUs s0yZkcr5A}qe?Xi>yBt z`y)ZY*O3M D[:.]   %e >+G KA|y_ ] O P<) s ^dR  5 ; ;CU2hh C c(xg ~ t.PB$*e % qKKY` @s biy  >x~ )Lf!E)  $OzrAOxa ew G"z &lA, 7$mI MA^Pe+,8]Lx~  WF_&9 s ~D N#k~ z@w){ r 9C V  Zp`f ]  &W):m{#W?hS9 N^~M:Y ?y!CX UD< = 0 Zm EXh#HQr_Ey?%6  .o s Sqa$%!<(DH< wS\uk  j "@dS*It8K&4t#9Z#,|=>kiO\3R4v  ZF  Ow7 6 )G }IaeOb;X5vw[ \vi nCu A 9!  Ov6&TMT- 8TV6K. >F uM , [i\7 k* U  779 E69c>/e9AD(sf!tlH@}RX^;lOeJ% ? }DDd,/T[n]jGP2\c   f?m{\M" e<KG}t$(V  aXH 8V9F$EN[P=9\#qOD S oUw Y Q{s\z`m wg6# ~ kG@1HfbuYqRF 6J;IM@eFst~ > vB!|&1  t4a  aFJ6r EC K 'P-kX =$ I > 5y j puWp 'p../h#:E%VQx%LEqD ] 8vv ed.zd8`$ # a]  i c V nuI i Voc.Sb*=MvPX y i -J|IQ yozqd?X.J`;!>ifA2|4h1Quv2  "J'9Jv c l-_2GK* V6+qtY.Iy2 ^ D H,m9 ZYLx1DYs<YM7UekZREYq4|E3  0 _CGu@ = l!(_V.R*g,V $ `H  O[{yMr  2W&&.s 8 -= o*;TB1  ?ci?T ] -C$VbRM#De~C((7!E} IH1x:V/h's.`2MiY m}sE1H 4d?EUfP. tVj8cce@a;~`u$O NmG\^$240iRx`fU/ud)jM Us:Nlhkr(ffyaX% d3Y| {)#c2#fM}f;1]e=XJT3bX&&{nBze- ({.yN1~F|8GC2xAGdx^|M6t?8M d/ ` % - f,{F 5 S | yz >  5  g x { _ o | < |,|K7yGlPSC~s>pbHI[,+I:%;yt!$YBSk *+Y 65"Iy5im(NAtunTF@oGmxU3*zUAS~5g_NoI1D*A  J j b s47z3pLm,,C>j i ; # l }N@C]p!\4HE5t*)& hYk=bqh T&*r+*s 1H3oX9t;tG)za0sQ>3GN }Qc= Um(}fJ5 Y%t*r7%5G=Cw|%9ME>T?}{@0v,V{"%=O / ' ( h+ja| m9 8JA@Z K u  "N&?|, K]v9b6y",xHiCB/Bq3ZP!'B1_Z<>5Wryb>%QkH!fU$kTVV1~Y s?KG 9/vfH~n]fw:a(wZ5J L3Z! `0P) fM$p& mH/.W\>A22KPP2 X f C ) .46 .T*e=;op_IITkIIN_@XQ9Cl.u1[:]bhA[@r #;IQ^`bXVNE/ _,IN/s&>IH5uZ32I:}pNPPj<`~'cJ A{S(U]# f ?  f./_ ~2(IOxyR!d;KU [{uT9 wOpI#/CBU}6x-}AZ}hXT^yA4rR]I5/GjhK,F]# |]1GM8g9Ga{xsllaN4vD SavpKD3\W*GzAq&lL5Mh2d95t?p 7yU G 6 *  @[2 ]w#${rQ%f6\R7HC- s V I ; !g<T@r*jAwy>o`fr;wlhei;N@&T d,fJl3(k(k -RzmM :u)dF(nDj+Ro?r@x){Q(;^|Gu5dql*_m1W! o ` U :i(V 3IK/:._g? P4Y) a, sX& Dh,^nGUP'6Z>{UNiF*#Q]k} u>j*\1i=QN:V (40# f-Q"!:l_:q 6Qd%i]^V+3h :n> qB g Db9 @ m:?=2t8yCJY MsvuS- o Z / zY) +A[2|+"i*sd^]n G-g{^by%_+@YskBdn[Dj^'O1>]d~ua9# IG8=7eKh(^=`0StW%r-|T. ,Fg!P8y sm?ww-<N pL@  l ?oBQ*).3 `::%9F_zZ/yh a I 2  yZ?rAzb9jO /@\ \WA H*Wy *_&U5,*.`)Jy .RnjG*s? M54*By:Rr?w%Y%>| IS d?#;Yw0kXjk MGRH|E ON  b &Y!)orI7WulN+o,F6)" iW9% sdYVjjz{X*Xo_62S5~d)~9Fq =wI^^k\TKQN?!}.x0b$,79L8( hJ"j.:0+Ow.&(u;\L@6;}aK)8Ws%p E&sp;f <.u$;c~. M  j &k%1KA!nJUHmsoI%y4h_Jc   ! xs)\8>'Sc+JReM;*:l:v>3G_i|}s]?2\66>7?.r@!@W?X_j AY}B`(`9.}&P}K) ]us`BCEF"?< b v "%'7GXcsH|"u k@U^-4ggt&^>7QJb'>CHJHEH8 lOO91Nk|~cHb#a P;Sy =j5qB,m()@a)k\I) ( yH(iZ_4 wH*sY^%naG<3FJ^pQ M/6 uQ0b<X9 vc%]};Hb'MncJ* p>]r#p W)kWTPY\eQ"~U$rcS_Ueku ,W f5|;br6\@Sm`6lS7   : j ! L 9 q Psf9 j 8  k  8 a   I9"tR^geVsFphC tT>dgBS7b6-:^n}?j| o>9wB G;#EtH]rD;JbJjG, K2= cifG W:t=y o.9lv(;f] s@jPR;<Tbud:L8G 7VCnXyZ'v]= t n L g @ * * 3  ? 0 - 1 5 oi,d3 \Ct4{1Ix.Ib$q1W6VoZ?vTX%[^~LU\/0"7{!_})EhNQ)M% oSv ,sxMH7EL[: iQ9o|~o  &M"k/K^B`muwjMREt~1K@m/Hj1)(1BH=@h+T{}/ b?EI-,}GlZ'f{ [_3s)u9GzY  L5kgDV).H*u'wb">;[\| EZmcn u"dKP"+zl9RDAn'`QAgS bVnj?cS_"]!FNG0'ol Bj0rfH'QvaKQNg=rCwEe-dIZK?TB?`Ffi{Fr<XI 16L Gff_rxtnfD^xDrSdnQ=1/l K)T{gSaHygpGAKc\qH8[gB,?OCV]}GUWC 2lnL DP$v/5)d p"XSJr)\Np vEDT"^AB _F>#8XmZ^$%q&C&TiW$[U[Vh<cOWvRz8swx;'|wf[\D+)$H;Qci8@~$2 jw/A cD<;l,I#z- _R 9C+["%W]I'Am!jwpPlGl6{x5IW/Um;2RMJ=ro RmW(y|1Wk)2Jr3(P(YR `IN} R*M&^ 8 U4:d4AxTx> Fr;_k{j\e`NO   R a9A{p:uB)*Q| .L:N%udkGO'L#!zI`0~I-B_i5H1* 9@iGikB" Yz4+17J=JhyoA\Ja}q /(->p9%hWWbFgm^0k{ b"S * /GX pSgrTp7pJ B;4u >L =j  *]yq3~O eg{66)$,1Z w,ORzseX= Fd~P_Qf)]Q *%^%}M%qTgCFkpgrTn=*7 AEa(Y] [wY-+hVgjb "Z (Fx"|[JA;e#cAUu  A\{K#8 hyO|x/'yd./x)**_>g0nBy| nP\BuBMJml{SA!r+3/~9E/ G{4{lijw/B'|V).G>[ W{S[Q7^ PO6MK9$ & 6e_ > 0 ~  3 D  5 @   W\^TXS(_ ; xe=:g\Y)Ew: (AlG? ? eh"CX+#n>Qbaa^QVF,R851/zMe*#_w/5=Kt:XwK'",oYOex@PE$z4n9z\^e2W!sQ8TGW^ J $ V *R6W3 sd]\$W) a B L J leSJq^::I H2`{mZ0t@$FazN4Wn *51q@&86 b22/ I~ f(<B>f0(5MbY#7@-+&3q,8o!z h`;Yo$1`b&ZZ <}sUy  Y  W j t >AMO_r)[$ 0l   (] qUNy{R";!,=W!0s+%NiJR=P3(p5QD" Y > D A      ` .+[RA`Z'Km}'hEXFD_D"1Cs\+_wK"YBQ}VJlw f 1 Ex C f ~ i ' mIf"^`7u}4ztt 9 Q qm@ENE2$Rriv[W_MF^5Mbtu:&Fup3iZ | > = k  9-X_:[ O A d9dNe@Uoqm >@pY3 1RJ$@BHv$Ss$zSuLw\82Y+a H a;39V{u7>X)R{   . w:ytJ'3MQ:GV0@~8uZk{'*rrF. D  m 0 z * X =Y^%n X ( 9 Rx"~6D :j u]j0:j A0.P/Yt1k8O(3N;6(ir:G.  ? vD=[LG:.9kMT\ ? - rJG|)lCY$ /_cw; |-d_(, x%72".|%n#_-%MK c  z - H I ! E q  :C Bg"H rWN*>i:F d. $a$eF9-{!@$_j1G\O(i<X2N  s  Q  T B*z[ 1)-,Ktt [   g |  # =  $  T pA7p8/6 s[sJgiU`6';i9i [!dYK%mT J*Hm&,;L_xs_E0yqaWP?5iF{F mIx]K)f[HA0.6=P\v(1@Lh?j<{ ]v>`B2%=Vu  ) > ] }p;Zn}2Omx~|t]<j4!% k  l -\2]`5, f U*5[/-Tz#W9Gs1u6W{-b%lQ7 (4?J_|8^L+? *;Y}"e1 [ x  5 TqbHm5(p(]fKY[)W >  K  M_M8G aWhJ:R~p_bPTRT\bk-a,}I*"B]?*t\G0  | d  ~ 7 1m;{<s#IWZKB2g c' 0  d - hQ58AOLNXap 2ah s&zB&qXJ6)5PiF{cPAD BK[_S7d /6=E@?0&zgB#yM)vIpEzI'pA+qYA  !HjP,h8yo({)M l5Y#Mm ,  g - n  Y )Quf3 x + 0 }  F _ o<_!U&_/c:tt Ey@Y.kF% waA0 -@^v :f+^H+lWUY A9Z +Hbvh]?'pL"zQ+v]5h=tN,nS=&&;Up(Mm2l(m$gJ/zsi \I7-yd9 v 0 b , S / E g t  z p ` \ @ # M  ? S >}[$h [C<<R_;v6Z*wR6pdNB;.+,  &4AHYl|=[}Lw X >k%N}Ls)F]v  gT0Z:z]M&vZ7${UC(|!9Nj 6 A = G ; B 9 +    zS,t5q*Gk=a]!n1l5 zLoM*nR8"  -IXq Hg}*Oe7Ng,@Vk  *-00..-) p]L9#oT=' tW>% ugSF@8,#!  ('*36EMWbs"NUjgsy}{whbXJ=, hG1hJ(fC&sL:t\@%s_G6 |q\YEE75+)# $+1<;MJYjlx+6=TZdn| -/579=AD@AG:A>=642*,"  wl`UOC91:4  $(24CMYljr|")6<LTXdiz{    }|xronjhf[[RMLDHH?87;1.1). "    &      #/-*)).-<15625@=<:6@:BAHLDLJLLLVWQSQTTRYUZaddf^ZY[WTZY]\WUZVYWT`X^PUJOPQPMMPMOFKKJMQFMIJHIMEEHCFBFGAAC@C=@GDIFAC@BE??@?8@9?E>A<<>8?6AMND?<;:=873.4*2+020./.0,.*,.-)+1&+,/',)+/%&!''!+;G55/,+(*(-(,0+.3-1/<89A>@>E@?>DBE@CDBDHJKSMUOPMXRVUUXXUVZUaW\^[`a\^Z_cb]^ZVXVZRVWWZSXYTXUXUTVWVSUPWea\YXVSZNXQVRQSXPWVW\[Ya``^`\`ffgeecnhegjgdfcfedddae]ed`g]hgbe\`[\]TZRTQTURNPMONZPQFKHGCAH>H?INLA@B=DB@:;:<?9>DB9<874?B@86521366KF<97/5//--/$(#+$,")%).)((9,)&%#!$+4++&$#"$!#!! &!##  #01')&(%+"&-+*.+.+/021:4:498<8?<@?>C@CJEHDFHIIKRUY[W\^]Z]^b\iafaipyojljenjmhnqwpvruuswvwwswx{y{}~~~ywyuqtxyunuooeicieflqf`a`_b^[[TTSYPUKMMIPHNKFLJHFMELEIKIDFI@JIDG>CNIIGCIGFAEBEPHFHDGEEIDFFEAEKNHIGPLOHLMBIEHG@E>C;@;AAB>E?D=CBDCA>BIKAF?=9@AE9B:=B9;7;7364;<A:9;:9@7@;?;>>;>A??A@EKLIBBFBKNMHIGCCBA@FVTJMFEGGGJLJJUQWW]kg`cddhiljnkirgqktsrvz{w~}{|~y}v|wtuvutyw~|x|zzvt{{sxqqoppsiqoqikeriliiknhidfldh]b]g\bib_a^\^`^^\[T[RWPSSONTVMWIRHOIHIFHBG@FCCKHEBG>@>?BAF@A>;BCD=;;9>;UHC::36;/;5><17.002*3394/),.).(,$")#'!,$   !" !,%&&%#'',$**334.11625677<;KVNG=GBLJLLKLHJJIEPLNIOPNKUUeb]WUUZP]V\^^bWa]_^Xfaa`fe^d`ieceheunvqqmmrktfsnomyzvr{vzz}}}|~zz}y}|||}~}v|wwztx|wtussqsqvxkrgmcqifichefisdg`dojhhb\jzogc_\`\`X[_]\Z_\VaWXTVWTVQSRRRQRPROOOPSVJNMGILERSRFMGHIHHBIDHDHHFEEDHDD@BB<@?BFEDK[_XKIBD?EBHIWIR@IGFICI<JDEHGAKQUIHEUHNCEDDBEBBCAE?H@FDJNNCK@BCA@ABCA@<=A=B>B>:BBHEEGKLHOLIHCE@KAIDFMKVRQLMRKOJOOMOV[MSTLQMPMLQRSQW_VRTTSQSSPSSZWUYUXV^RVQQNRNWd`RLOXLLIDH?ECE@?KHE=DIKBI>C;A;>=B>AAE<@:?6=4<;9<D:<DDE?>;B8E>><>=C<6996314.1505+1.306HEA8640+(.-.&.%+.-12++"(%0'#$-'+$*$" #"$ $!$#$+%% !"!!! +)"   ! !!-*(.(-++#&(**-*-.+.*''&&&-'-*'+$**%&$1*.(+&$!$ $#!        q1qC)(*ec,]AL("3TmzdJ!&j I`_9Z#zll=I8M.#c,AlnCpV .6rn 3DaIB_:o =q J`z< -Nh.;QccoF *5>RK56IF*,PKK9<Zrmsvcz;"|*Nx'Rc?lA s~[,HytSs~}[K@?A6v!-l%Y=ZN=W3m!"TS*5EGfD]0`")CR_mwy{jYRc|vuF^%tJ  ) 0 .drJ<=JQ9y3yCM^vOz -  .)rN\8'x #=tGBy4 d  /G0 : x H # ==>iw#]"> )mt%6 { ( y : w   ~ rbQ;* dy699[EZVRV/^ , p DCoD`3!W]'bD#YO"JM58E:cq|+qNzD&?jJGeOGLH2 H~E $ M X i m m 1 0 #  1,g!:V#yw n>JDrOۗ KMܰ}du2 ! k ">qa<H{KY h Z r{ 40$W| w B>x2,o \  @ C b-Ga^uw|tsfaJ@qX3ty0M? 0 &&WAnI h R,;vLv2o2q5W*6"qUF(<.%u.e|eyOVPl(>j-0FOG0%_D}`cwr'9|~, ' p  l  :=oJB4 d5=<^'@J9yu  ? F > g  a 0 mK P|XvqF v +Y K  0 KQh>w>Z^ i}b!4ey?C i ; e w:d^Bc#o&|T%c;CN ?nLREUc`J8K[pgc\Epb$luo>4}] vYk:7.7rTh &jRX5gPj^|6  F e 0 A Wrh+uD SdQlN0np6tMFL"; C B  r Z U  nYv  Q ;m[&VMr 1 ? 0 $ F^%&.**Gr:H 6ADv$ A 4 d <{L<GK,Yj{XWo151xA`S!s 3m0>e? N e;S~o,:zH@[1ZW:K.7`Ga6t+`Ta5^X 0HM W vuY `-%0< -(a`ݧ($cN`#ae3M 5  8': " W\ymuU9^;ud|W L%T  gq'{@ '|->>Aib}faHmD}!=WwH]?s(5/>F7:R(3mtK/Kw$|x!t=? U@Qh &B Zp@?kyzmtPHLw) -zxP)XPoCtE3uyhsWMiJJ0~%wY-oIzsY=/N`[\DMPV4B r;Xo1Y&T*)+3k~NOH}WY Q%Del,C[uKpz3a,+X'-4)% &FBOf%y5*8<,5!d R -2@HQH'(uP@7F?cL~a9vTFMEeGwyS$1lC[~R$5&LW6][h[.lz4kNq> !1X= ~_U(9479Q0m TIst^<@4h eyH{tEuRDA>ALQl|Cls;f3)S*Cx:y;?UYTE:t7h3'ERQM6% *a5k{jM;+  eB ,Ru(5=PQ\fwkR/~Y7)$(%  4AOV_iq"g9YgefYJ(yiejyr~hi[OF77gLA9+ )T*')!.:J_jjeXJ8+,3+-0-" xn_PDGUgl')-    spruvmkWSW\]w)>LPSPNCHB6/     ,P]incH%-IU8yhecefls}6K\M?# *.( s_[dqr ~~uqib[UOU^urhb^Wdgjrsxy|{{zxsmd]aYZdg~  urny|{snigdilluwontwx"%,(/,170<49DLRWX\`]^`jmghmiqkdaYRQE=2&( o`XRBF?CDKGWV^bkcmrta]NK>8/0%$' &(-(/.4*($'"!"+19@ELPX]bcegcfff_d`cgjxw}|~|pqd]abadeooxooim^^^Z_m^`R[V]ansx '):6<ACKSR[Uabq{y}~|wyqukjfgg_X]SVJH@?2&{nfRU<:3/,,*,-3.6.4($!    #54CFNY^\aabqhpp{z~   " &#*)/,.*(! wpjhfW\^^OMG=1/!# "'24>Ja^tt (@KIR_k~wqi^\ZLE80%$~{mf^VNH9-'" ~xxqyqsx"*9GPbl| '/;E\fvytqhhZTHG;9<;'' |yxwtssnkc_[d\MPC920#(  %2.9CLO[^eos{ !*25IJV_jqy}tz|saWQVODK:=66540,.0*.+,.+5!$ z|zxzw{}z)++85<BPRkchhx{}}{vxwrmkndd`dba\aZ[a^WZQSUQROGMPLGFAB<211/'*%-)/-,,,9,+$%! '       ! %)(",&0642:8:<<EFNIGHHL?B>@EHBIQIA;<A@BHB@?CB=BAJAB<@999530(#00)**(%",-('#*&$+%'%4+","*# !''*',),$'+)'+*+%*.&*1D81/%'-10,0<58/15@72.-*&+-*')#'&'',)0-,-%*+##$<33'/-10:4628**)+ !'",",(1-,-.,$&!!#!  $*',.*%*!(%.'')'-,07>856=:78<Q@@8B=?>=B=BCBA;FWQEECIHBGGELQTRRU[PYQSGQLOOOQRU\RXV]Ubck`gaf]j^g^d`ie_e`gkjfckhdidfbmspqmtmttxy{yzuywp||{}twpyuvxz|u|styuus|svovsrqr~wpmipnltnvysvpssqgljekghflbjihgjhkidehnioktytzmrkvnoknnlvormmz~rtgpqqwtv{uztsxsrwupvuqolplreqofrnpoou|qqkngjjmmlegeh_hbkgnsprmuqupos{{yxuxorlvptyu}y~v~}x||zwv|sstnoutrrmtnlropprsqjqgvimegiehjjjkfhljohkmkvwumiikinfomtfgilkmhpmmqv~wrrwuxz|{x|vtwpwss{{~|y||~z|{zv{txuolqroojikvq}qy}|x}~x}}}~}|uuxsr|t{yuz~xzy}~}|}{~}x|z}~|{|z|y}~x{{{}||}}}~|x~|~||x{|zw}vuuwnyv|x|q}twzxsvs|uttorkogoejilcdhcchanmrsqrompmjmkiecdg`a`cb`__aahaa`a_\\]YZ^Yqdd\`_]d[a\\\]^[]_`YX[VbYY\W_TUOLPMNOOQVOSKTNUUTSSSORORMTOOMELAGKDHBIKEHNKIHIIMKKSNMINJISMQR]NLKKNJQKOALEFIGMKKJID?A>=<D@FA@=8D?A=?D89RQEG?8GH=FB;4?C;CD@IHRU_WQVJCDKKQD96>>/<>;D9A?@@MDF5@@@=@B>D898939E2728/3,100.*/533/:144587:;;:@A>@=<88:9:5867:;@@<AHHDBDJDEMWNRILGRLNGGCCIABLMIIOSHMBQPKMPUKJFFLLDGCKJKLJIKKGIFMMJMJFLJEKETOLSNLOL^[SPJI@GEUIKKPDIJBRCMGGHFDKRERCLCQPbXYWWOMQONLMCOIM@JCDAFFCFBHIBH@B>ICCAI@GCKHTXQVLSQPSQRTLMUNNLLJLJKKKKIPJKJIJLODLBLDOFNELKELDGEMOCGDEAE:GIC@>9<E:?6<8995:98675945/36-61;A>98@;99@CC:CE=?855=495503=?981948429:28=?8>:;420020.63326HC=85+.2043*+!("&'#""% %-/(+%)-)63310,-+,)+'( !"""%"$&$$$"$!$'%#$!!   #&%!&,# '(!'#&/'+"%!%# " /44./#&"&0 "%$ %-)%"%)!$ "()$% !"!%&%&"#&) !# -1+#'$%*'*')34179/-*.%+")+%&&$(%"&!+% &!" """$! $$#%               naRDA1L7; ?Ds $Zu|RH\@qh@qsUC2Ys~57aaekP{3Zf%d 7U<O%s$&`[#TcbqKl^YYOZ>@ ~|Zeq`@4GP4  "Kdq $\"^(&5K6&3aDpN# qkW7''${'~O"8Y>Uz%n&{nYyme>h"uyke^miT=#qc[\bRXSNC,Cc IY~:\z_>#f=#pPK(-"$";MScs/?LVclr`ZUB, ysm[QK[VNR`]bp;XgwwiYIB+ $.FTTZhourZI<1! '-.8:<47761....((/-& $!"0-,1-9.)%"(  &#( -:6-,.323-/;30'.0 #)63BGPPPTTWRUU\a^`ihvq{|k^[n\TQXQHV\WS9JP?0MXTFTlmv{{~ovwwx{vxskYZKD-/)'!!    """*'*?56.<${vquiTQ>;( !  xv{fOHN;*"!  "3HSTr7COYt&Cp2r],c>Y*L *QLGg 1A_:}# <    k ~0npH&W'}rhuDq%z}$a;3X9 oMnvQCjhT*p'v)Udr-_+a@vl`NNCADAIL_]ko{=\}*Nt!,qhUH,%rVB g^M.(UA bMIR\/IS'_NK(| O ? 5 | 3 ; !v <D> x a  C G s *;+7jDlC.ay 7Ju7UeVhN\ f - h y [   ] 1Fq\.0:5Glw/T1_ERfq |!LtkQ&b,H .%9kn2yS^r4KZN8FJn!Z+P)Qm#&0<13AHO[t.yO1mhE'%q@we W ' K z ( P 8 _w>S2( * a  , f  JUX_vpnS=SY2 K u G!>p-h&I3C  % Y ) Z   r@u@;7zJ9QV=-n/w;Ga!:Oc-> J9cW,ak,1ZpuXjJ6Ij>}W/_VSo3u j(.QqMXzBZA~X@<e(el~4+ l m w Z    j  P % " } k~  {  k G S ySJ;:DbBOhfGlIm{XVaR @en-fczBDz5^>.?Um`!W"-{LcxsZ>0' yV CtBt/r][?4 Ev0 y.*j LsAd$^1jF's@ 8tkYB:"4Sq~    # i   ! 9 W L i a ) 9 9 v  c  rW:j  CfQEcAHu:9p\[Y= ( { Z U viZ9M/h,i:Id"$UvewZ$ l y  ,  O  x z 6 [  W ) % x   b + ({;L^/6v$Vh-75d5G v;u{Hx0^<""=j!s1n1~/( $Dl+f@N4 Z]* )dg%b 5 T r " N y d Bb  " g x w Q 7P6oX2*bKK5!$aNy7S^Ap|Ls%Kl!zA35F1gF(r+1Z Hu?XkaBzTgZ v_x \\oz:lb8jJ) M"Cq=Z~_%5pU1t9NOD(VU. u58V@$I3Wk| (Bcmdo<e;74=dk}6 q S O 9 c x l`]61efa cNi5%R2nS93xj_E>?mg)pgc9"8>{ ]3fAKhQu_<H6txnagjkhbbWQ3kb[89b3i{T{X$U BnQ/ Mif3bY`f5m)I\hlgJ*m|( &'8gn| /IWm|R_C_V| $!GUYMRcqwYSi;/NUxipvT\D @  h W YM c  H 9 z cO,0+gc+ IJ)k+5[Vio V~M xY~plQ*&J'+Tt.mc( \{n>Fm4Kf0c8a41Ta#r#\yxj5h=`k{e,M-&.D\x{ss}oU&FQ{w bBrPcVzY>"jI62D_{63WrbXF>5*$0gd<j?8 p r G optvK\ X   J F'>   g ]6).K  69%CHhH#',/]<-f[HZZBZ|7No(]C) ^jc? \<lyjO_*b9,;JCI>9+$"((,8Nt(_3m8W}q :;4\>" #AfH>NMN5Y4$iO, .Kqtx~vhT[Vz\ S(-% kYm5bBp ?;$.DH>DL;8H]G -h' _ { b  oHJB[ h  V  k u ` t " g < v R^n)('g@m@>XM$J-vHT!A_9"*`kT*;}=%T]'`KEFTX!kE_K2.^]ykdu+p c^I%25D6B;=/NF\#r6Qr=}Nre'; <`x 7_ *g$_Fp0`uQ*TPdxqWp;e'J /i fK:UJmcE.8Kax: y N d b  & , dE;.8a$,0! 20bf4/G)WxrK (](sd9o1L)),F!Fou0ncRd0 (7ag%Biy)X*Fs@Yq k]QBBFXvL dix"W /3EOTD2nCs?8QlB)a#P/s+[^(p$~l!/]g>*".-,+0-6:Ok8G]u0N`z 8_v 8Zo!6OvCzH~6SXdv1~ f M.U~ T!\ G 9 y p  A Gy6N48< Z}m{5@z m="@aVFp}wN( {.NtIBSLbm1rNkK/p;~'s >kj\U:%\"2{D9xB zrv 8mL4s"V\foX6oQ|C% k]LJVnAnTU4Tc *Lb|&Ag 1;IIQhyES,X!0:HQ_w~voyjv)b?1rh+n4 :  - b p H  o {1bHO 'Io >q1 +h w[)Y{(zj-U+(*C9U1 -JQVO%r2{8r$EcfjifV; xP%z0I3~CQi]Ybfw =lTP*F_soqY; icy<pojrn (Xmt0U"!E 4pW/hab @}2OP7CmF"Dv/U\9&w>[}-2 v  F m  6 U C " l  R [#h ,BjuWgO?Bk-y~qbVj}K1R^9jKv@QcB@N L+g2h63{ij4bE{AYWR9A{N;$ *IS8e#Yvw`AiL]}F ;zV5'qgmr7a]#x1&rr7t%R ##75@D80 #,33?NPXi2C`J0k d47x :l( w  _  M n v B ( E J &d w9c0]xy)W!3jbP7 \4X ':CC.#c*,ay3zBS.,Rq/k:?C?0Bz $!HKgny0MJ"sTC9+4:BQWtz06?70$!yL+pR2 rH'q~$Dn*^0kPk(u6r4q2JN_fy "6^E9pY7x0O}+ 2  7 / (    '  h  \  T6R yqhw7%Zl-3m Y6=%uY"K}BbnQ- OvP$IrZ>$,6Y{SKRO$Hny^@&b:V!vMxC |M_4 zgF?* $ '1;>CAE:DN_;IbwE%Q%OEz'Vv,K&1JJN``~LxAXeh`%d$E`f> o   1 3 9 C H P 8 . $ x O &  F)i"#5~,}d3eN_6" "Y7a9#k7eQ&=^qy^6eR=#  '>]z #1F`n~sU<`4o9g8j8 oD+|`=wwkkea^MOSjJb7a)HfP 8^(Y-_.Ru!(-2=P\p)&*<?ECGXg3Y <n2c#Hh,9VbowX2 @pV>H}T:N"sghFV-5Vt =e #Jk #C_(Sf-BRho{  $%)(,()117=KC71'" |`C"\<nU2|L'f<g5xQ zeL3$4Pm2^ =oM3l,b8v5`![1a'ZC|Hv$UmI/R$ V > Y n y     "  *  e H . a ) j(}d J+xR?5t"CvRTm0e.oaF;0$   ,AHXvY3aT LAC?(a Dt7j?_%=Ran}zi[J:.iN1iBU$Qe*b(tELh/Cn<yiWJ86+*$"3GQm0Pm%^0j[`'tB/l,a8{ U/o3o?o>Sv M(X = `  7 X o   . 7 ) 6 G ^ ` g ^ R > > F B @ 2 /  m ;  T  +2E8tP*D K`fojpmddQB8!kC,j9h$t=Tl,j(o0@ T^%}M{[0zvtfd]cmov:Uu7hS Q(d6 a<mL8h<hK<pH.f % F o  & N p  7 H L V [ _ c m t v |  j Q J /  O  g ' l5@/`H)P~Mdi~ 4bLx3v9 j=+IcYd1w Q%gV d5xB9B)]-Po2DKKX_lyuuknXdPE5-y]7 OJ\b^dg&=xKW\%mL*zmWSFMQW_jtjl{3T'O~m1GC_NAXQ?:5C+q[#f E e $ N m  7 m   0 @ G ? M L D 3 ( - / . 1 , +     j : E  i # K^2p7m]/T~ *0;LrTMt:uF6Z%_?Z<2Y0{L ><~=|0g0[{(=XiddenniWTJ>8"oT0 a&N FP?j!h87o4u1e*m, |jQ@)!+    n J # h  | ; 8;rf:kRFc&&0`=oYXX: 6Z~8pR9{dJ$iN^*m4s3u4l%S}*?QctyytwsttnupXE3$}]-I!d+\]OG@q4|=jZ IcN@ .ER[d,Z.i6nNX)zicNV_3|+_X Q(`H , T  C j  A  5 V }      1 3 '  v \ H 6 -  u <  K B QSyO8b:t9c"0e ] w:pQ, JyI{I=&w_X4wS1rC B K3_ 4gcK3 hBm:~9d}.h W}?*K1f$ b  P 0 `  P % S _ r u ^ R * } S  2 K  ^ 3tg"Mz B\QBKp'^q1m/mR06e8d3`XjO74ggKeE J%W"BRo{}kj\X=2! P)a!b$AP{2Mg(JT2S }8GrO.CTnGtX(pZUr5OR|37R hgt30  i  X 3 e  L { +LRg  ~aM+  i = S  l %  1 {  Ef2HFB\aX>ekdPV)U*]"l#gM,"1*:QuBw^U8#644F@GZ4yb0X6g +B\nkI5qB t<e#FX q$DPS]PaHz1wE{ZB'2J^I|'mM>:Fg.\#]6Y[%^#T | 2 1 h  `  C | I&Eep]L>) C M  u % = C ` p9'&,D+ }y rm9]aLW0}RRygDZs)Hmj%UB.|U;s!Su-3CBNGOZUPC:*wIOc}-Jdm fbKJEU|-Gp>]4y{~ ,W3gS*w|D f*\2rU#b:wI-M  Z \  i  T 0}Qw Ms(8NJ,#|Ep2O X 7 [ |  1 C- }zd'`P&A &fiIY9 waVPYRFB@Id9m _XFU0=f=y4 ~Sk}G:aEsDs,-0nINIm!9jjH\6xkojx6D|_B"$DmNY<=o<wL' xaP?6- C  e  s 3  d Z"hFp#BgW: GR1 b  : t l azc4N._ vN n!  =?4Lj@+*$6H^i ZVBH_* t@u_GZ4k)HN9O'Py.8DCKHHC.pP'k*[%yo!e4\-g$dG2}-:@~? }_A 0Px1egSe%{iR.39CPghr+ #  h # w # ~ fCy5e %@j9TgTM;5+(M+Y$rg$ A H J 0  i+wA7*~&p U%S0#$g^|F ,UCt(H!fL-cG"{X?Zp_2oNn  o7~>q1@+n<U$@Ro "Dl3d JEasFxfUO@I[_p2hDBeK70 +Fm0_Pn8_   b F ( K9qi?dz}mB z'}Jf *.  N  d  bhg]U#`Lk?rw4B[$xpptFt&fc7~WC-,*HL] b a{oYD6Kunz Dg@#lBE1[m}D~<l"Iv(BEMKEI3tT6w]RN?2%"_0 Z"70$ ~c=k>"%-Nz _"\6 LgnZCXi6{#kW>r`y;q.n  s " 3 .98OI}KxXwIc*<t_'B d  <zm*NA8]$) Qvi&O=#%_$g n\LYPOmSFx>u/a~A8g.S~mjP8o#_ ~z])9U|8D B1&[6@;KZw GPOx;r)Hr 2 < "  k K~Mw&AKfV 3x,Ell}6_` 7s 1 $   Q@l<n.7A-OATf.(d,h<0z4^qCn~/VcJBAy3; aO[OWh$h? Aa P"r?0]".5;C@8-!]+LFJ)G?A6xe\{}J  1{<s3+$J9';Bp?lJUK T 5 oZ'Z4a>d~0qW5]O7g4V{J*8 >   a XQmd)*dq3* 1gc)CaoX>G91<XoJFlpIh;Z}:S8p_gT/_'HQPE9,/%:>Qjm@/h9o#KrI M^/+\1uGa2o&ky<LnO ~ H  =L5^I~=igEYJ s,]hw - o!Fy4vS/ " !8{n)Esj`3 wC9qT,2{ F(]w=Q X03pDCnr&[=08Bu*Z1xgPB!pFc|Sy5MSs Qh'I%g%S717?LuT uAV  p U$y]q*!vI}?^So_E &:V)M. Grr 8$ToplPKxwEgB nQYIh.FewygA9HG2`f1>AGgx^Iz/red| cSB?v`nihH3Kr5|~G|PNg8|)x"x"Y y29], 2GY Q|t0GJA'\#8&fg(yE@Ye4u )O xojp$*C\^|s[WWJ<NOB"v6 e =eX|88twtt@!9sh'U}\Y_jv3~'H`P X u  sadjlXWOdiJ9z,pU}3Cy449j!Tm-6i-IIY`N5yr$ pQ2,(@e8js!vRxX' <GS|lDKfC/:x&hl{9Dp![(*+ c/Kkp^Gs@vLWY~3ed? -;R9.rf03O`z'K6 2 T [ 5 ? &s`?vth0wjzJ'OU~e=Yz F6_rumiP03$ z C AZ2H>X,dGc 23@hX +9 XT_d6Lizj! >WX!VeB5h|yhߣ@3Ow,4s=M> 0Gg" R w A  ?JBM%c7r]JJrliN8.&a Y 9 c t.;nazEM"buwW%.rߗޝ ۟y|Vݤޗ߹>|94=3uPm) F 3 g0bJ&\Z.IuQ22Q?0XJtW=-S o )kM>I\1%K5ۏCRj*`RLGa:S"l6t\%9 a  - n b >  q  0 /D{?yr<'csT5,Qmd"h~lR$Kz 2 o j D   R  ]GOi"@{>d53\ۻQ(<ք. [՚֥dVPy\ ;]%>X t Pz~ZU]sa5-H qX eoO{ "g"m"J"""!E!  8@Hl` %a+ =FJJ~SU3bC(^mIH aH>GNG% n #f{ = s2h%6]-jjn5;_*k"bA<Q{ n# z `g6 0 38k,kKJltuamqܚۣ:ؽ؇G)e ۛܘݳވ70 !Ql@AwrHL7,U . X [ c sQ"xF+Y/qM6ufWPZV, P , ] 2 / sB}_Xr  'YZB|5h,޻ފv;%%2Wr<9R / w h]GsB<#  IT%QfF+d=g8 0vcy@'?e` R C  y!zS X Q ndToBUs3ajpdm -SvU :ضۃ++jYG*[*Az}n=  c X d z I / m  I T - U!vj:s+TpT/JP K0lMW[.|H a=G2p Bޟޜޢ*>N>p/Kw[OWlt`&aU0rQQQwgE# YnS Ie4qqO5Q| / [ k ` % }Zu>Y\a޻݀܁vֱu2ԝկivPZB{$d$* }F7 O U b ORBRWQo T 3  8 N   " ` x 'vz{kd  @xDf @5ko+ q;K4C_?G xvjs e> %jqZBv $ i Z # L*HTb] _8wY;!bp[-) &Q{ " 8 EC$DNO1e w 3 y&TjS?4c6Hu߄ܓ؋׍ _ֈ#ہ܍ݼ~%:kO=!p C[^<WK( V Z M ) GJrg02 HZ  7   > N 5 5 d^ I J ( A .I.G -C-Q  ^hHYf IU = v sOZ(Auk[$"ysd) 4yIGrAZTa ' 1 " M~c-&t o ^ Z > &rNh:};2|[ \K Lx`d&v b  t Ab k ` E ? Hi_5"~$C9APO#P7E3` ܏ݪhw~j |lR 4>\IK9r]MG 2?|O ] 7 3 ?r-tZ()LnA1SuQVt)W8!f0HwnkX"S +  q E _  7XqrR=l2aL0e)7vNeyl{{;wt"9 H"uk7': E | Y 2+3ZQ~=g%5vxo17TXq"O.RA8h\p56 ?C m c[o%$@T::=gmnx[MF[Aw8^ .  7 =XlYF+| N 243_M.vT/wkHe)a/<i|~oW0CFmG@QK+9 iGc3I ;4EpUR| /L="-YqhN4z s h . S Q`xM3CP#9TGRe{zUBI_wO &i p 6=kQ-g53eJ1jXMR'Xjw;COV09S PpVo   u + ; & / C > O q X2'c2IYZq#-)-ux/t.i_P'QG4y%$D }`\"_thT6*_MY|kYxN?m5c|39  _ 7  x'~>v:}%{W:_94-b#=  h y H% ~Pdqn/._~PmoyaBNBa?/lA#BM0%X m 6 p ~ @ n s q >  e = +G~`ORj Ds}%we9 Z<'Mnyu +#j+\04NBJZim}o`B`,"[&&%& "M<R#l(g6gL_T9MSp L ! L ^&w%A 0==d_uaa`e| -D,f2 .g  q  n S ":,E^ai=~2< ed=RNuWUb  v U  q ^ N B | ^n,WU'i/A_&w"j 9Ib>*<;I_yu(O"e Y?a L Er *?YmynaXXYu,m(;~9JnM4PQ@#O6H?F Y U  &  ' o ` + x *-hwiKa: $gV M / 1 Z 8 > ~?KDiV.zm0.Y;/Uk<^Zd0ku2_Mc+3YN`V'7=7@>=)-d B!eJtD0yfN p] ++81:57"tZUQI;9f r(Y mth;!*B?~,bsC+(& Mz(:"+aqJ3, Y\9ZpE`A5lEf! J,o(2cJ_wGsv0!xVRD?D@ ey!YcU/ Hg(8Tk:5,eMY!}hHT m ~`[ca]i=#!kn\:*9TO5A/->W? 2VIhzq"Z?&|d cW b"?cH~q]&[APgoW >Nd#TrnM([jzrQ VIB^Y!V=x1a JpkyZ`2 y('wp !(Lw3+xNuQ-W?8W30#y:3 {iC [,,(^{F.DUWNR1JUT0D>mCv+jh[n: #~VkaIALi,Lx7t@F1(q%c9u+@rhuQT "]v=lD1!fQ\eikqbx23CM>S_fw[j!z?jAy^,QQ Tsy? f(|ZJov2q}cOrpmFny->_,$~/Hiz c9;h]E.u,ZCNfrT(?mXh.TM%8 C6iR'BJNaf4(='.mZKdq"~:q0n]~\Rn0,sTO_CB4L;\"QH|~$&la>Xk@`X@&iEu uW0jI@G2C_V!= a8xl ~",nye>!X#(`)]\=LD yx8(`*H,$Fcu o C&pzBL,q0,AS|)=+~PwL[2/n(5A_~{@kW2ZK:jWA#IJrPv+\L$ D6.0{pquRB5>phO \U,Mf+:xEZXBOB$`_}*YT|#_I4Bjt\wy"kQM.R)CG :vj3bpJa_u\V^M{W1"V-r"PR%x?~:/ +&Nab ojP}'\kW9pgnfN wo58xg,*K|v/2[Jq2Rm>n4`*Sae w^`nt~D\aDtYB$T)Aamoeu]K[tR.{;#RNY`R__!KPH.RtH*TZ]DY*`)*@ rh!/I&P77<pCr*shJt[sb G $@]TL'1*<=5"0 A)<UPH(}UemPXi[pQj0 Q\:pi uWY~> GqOe&^BvxRE>gjR/$4wR|tYdggyu!]NV kQlNeb W_~|xnDR9Ye\B7;Q*Bf ")0 %9FSOZC, <fpCoREPV>kVRN.x5ZMMjuT%4- ,2 &3"&Fh-;@"'T^^>+"(9GVH4iPIG=lXCh< c8|e>jJlY?#   ;Zol CZ&Or8b#4S%::EGShdljqvp A}16!/d &[=Ua+VwgMN auPtvF`."CR"ZiUf p $ W t R R-?cbU^m{~tu`_xO zP<9l/jd c'MF j(gov}6k K}+fk5SM6J$} f z I m] yo~vwx>._MFgC#D?TtBu`<]Y?R#{'0* +]K!Z-I M*Ml6WsWC)u:y<dEZ'QVY1nE0 2KnkW<(*JnmyupW:54ES\tk\>8Dy>z > /g#P[-s)~n/q#*9Ly'My1D_bQ6mAwD qfN#l3]!a!x\K"xnd_VRH8' %1Bj'/,-($ !0VbgS1|aL* ,GPRCDIGHGXhli\c^co~In*Ts 7OavFv)Is*Y;dq >]+` (6/'%-Nd/Jg$1HvKmpjmbN=.{MM;r\-QXA6uE`-)Y=z+\z#yKXC9Jg,\&&38RVNG,j=l7_2tO$Ij8b1ywjcXXQE;9A40%$!&) ->b~0Dbw^I<2DtLj9 $4N\ZN72c =o2V2e8y#Tu'Z4V~.b9Cx V$1 4ncAM `|MF@IL~oE5KF1%zN'Xt6Oe9I*^)ycfmm (S!YmYMPcBu 3!b_2FP=x\D^1 yGrV1 T$vbTG<( .Jd|n^g^YBD=@51EZq}zhH!|lsdfbs %!!%">SqIw;Yw@Oai:Z~)S{FXz0AWz1S`vpqu`^T\ev<h/OkyhI@Ql h xmZUccY$mv3'aUd&!T!eiAp8-mq{>cgZ7#6cEy63';UIw; y|n^;mD`J'pD- }mR>6//$-4EM\cnn{qbWN< ,GZbfm{lf[ZG= *BJ_s#+U]l{txth\U]m&Rk'17.-:OmLo+6Jdwxee|  /Zpxd/~Hq`?_!^'-n_j4CJ+=A^!9RkgW&Qn||b(;d6m6^ Fcy}kQ2$p_A. }nsmrngmkcaYN;#%}umkbijrxqjf`ULA@7;/*  ()/6>I^01/JUikz%;i (!-=Ohs$,.;E[YS\v0Ibu+>>63Cs-A?32>CETz <akZB, " 7D#v{inc= [GHC >|d_SMONK7[: [o`djRH2CE<- yihu@Pfmvmgefgy4Oszzsl\J>j[HM>9*%! koknhpordcVS`dk{~zra^Zacxy|usy%35>Pd}%:9ITdp *BIitxjWUK[y  7A1&3>Umzz 08.IXUa  Pl[* .UTA4R|T82)%$}fLD8: P=4 ]) e:wF"/NhcUH=832/>PwucT-$(AZohXPe !(+&!1>GC5%,.@HLRD92   pkikyqysujcghbtznG   !%$ #>HRRSPZbpit 8DD6v^{QM# <}p0V8'-"7*|iW7(!RunKG @g1V!9.:Li~cE*TX/#vu/ 5NH$;$6Z],:yO91=90"):;&qifsr]Wpu '1/%,* %eg`Yhx}\5zuP4=drz]^^de`MJ]jAJc{l5:/eN.B<9&;kUCkue ?sa&9)T`_QeRYYyt8$[{AFQ4,xLW1gBRtO=i~xi%0g}B 0u@AZ%mvphg[CBPWe'XjJ;%>F K$Z!"3AK?>99K@ 19dB{}d$?#sW{at] aWT"~Z9-cT'Q "?\jgEq%`T_v3z%-nweQ~Np ]*~$B_lFFO*E:J#xa6>/.t~twkt093&te{Ln!kcaAYn7I9)DwW UA'%~&LR~vr0X7p~m{ O1~DWNp*? s!iXsO*ZK)f6zG$Hm bUd>b<r)peIR\;nj} fAl_FKzEgbNf]Fwq>zE)4Fp8#X}[eHS$!s4 b o5qaPz6`=nki}z>tAZP"1*$PB|Pw f ";2f^.G ?E(n.: U4l-Z,Ve 7AP~pRBEo98%&.V'E \tJQ@?(U"h^vC%qGJe[+BJgc"CodY7z[ Osjd|4w%AaYF"?], Myo**$ Z+l[(#x$ 2xY)bW{9L(=rPh]u!]_:-1.M`>3^.{D" ooG zO8Y%F]H4PeS+Tv;{ + FdsDSe-R?Cxb|)BAO&[bDoH[:Tgo0O8c:o$i>Nrjt{1A>v T5~G6!'Ic TH|lnhQ<nJQL 7k^@LW'[6J:RA*ub:dt+ok W]7>k L$p*;!e@fD}I7(K?u-|PZP VT]EJK}E6+%+5+AL34kk1]{ 8v7DnmegM(;^ Bch+;"ZC.tPZwIou. oV!FEr%. V<z$a<g%3<%|Rv1cXw8i3_h w[+hKb3:f c7-##M&!F0OzQJG9YENX-A$O'/ ^+:Se/:[I gsQlnHbd[CB 6q xy-%p~E[d `$d,dx&B*Vi4-sR Rng`Z0YX>F}VFPxyneB//E nCgr<z6HY/x d@ %~p^ iIptRR~ CfQJ:P_ATm,#3Q5[<| <5ID6Y6FT\?hfI!r SOni1d}JP^d*_(]Yh"`*ks=`}`JBJ_R$NCs_ 30wP 30>q)c[ -DSli2Ym/w0" chfNX;$"?NN acE<6c(A54F2E}B.\U6'4SU$CY`!vq @ +>*<e*PLrOpgr\(k $? T1A[9>*7Vu3[ cp"lTL)PjI!H$.>a'"D Y@aV7Tm3bm?&xXeFK[XA$J=)'~u A ^;zUoH];YN;0^.{m`'17m%J! ~$]Sd`71K{I5f5CLzbqoZ71j)atj@*W9l.9 F[ ^hx'52Cc|e% `pi7N+5?~\!sz{$>jqkjHVN~BkZpc"K%Q  =4 wGp1TlCUyMM"nG\X [H3oiM,|O37Dm(4ZE%RgA7r_Ypb CTer^T4n|:Xs9Af;Jh:]1gYkCXQBL"NRBmf:?~tb;78P*xj;.I#?$cd-qC{\G';^o8F(fKv j*(E. !T3UE 2e4V N(3<TkE6Mc= g\9c FEV7:CLT3,<ysDlR.W}2|,2":VzIeITm:<&1$*hv<n{+$gyUL%f ETns %s3rsgHldkp.wVmX5] n:?@c' *!1`?Q;1 6 Wv'?o2!'g5j.JU4VlY%-sKUnkrSnNRoNvDZ;@H'&Np%[ ] ZVmdEG/H(za' &4Q&B:wJ7~c?aiNN ~EO^"Zjjn')(|n)vX\^ll5eb$kX_~U(B04/G[Kxy~$4TH4sole09f}9*[ .6x(S.C%DPeWV/j oY 3=*"ZwheR1oZQgOW[J^ :uV* NmyYKDN)x)kcg8'Y9H1/Um{\I|HRG Ts=RN,!DeRF.'n/6 y}O e9/5Xcfo:;Xv`|q`M?w54?MK 1*olB,J5q: /C| 4pd<>7^;Q&TKQq=4="(D!=IdyN^;Ke bAc`{sWS#GJ;Zo'A{QX`Zlst3J DPPzR7LT-{e5T@mF+sM4*H< ,=*zOktOA!L\i6 #05dQ&*i>di,^v[?sICj+o 2_7 QZiF3Dc zp>NMdwmyz ;PBws],\;oeDZz p<70 Zy`{75sH^(m7G*p:1)B)o* &`5|p:)bvgp.7 2glb9EO^"52JJxJ8O,"qifO<@am#.0>o^ bwex[H%x^!(Q/szJXQS<:u~/q QIns nxL~^OEU5bD4?V|?9HZB9$w_mR1PAj&xw4874ytP,$].o= /(Xf Dhfsc;}8"##B8B&_K2ZTk> 6M; q QrPZ >s*y>P#|Gk Qx/Gx>N#dAp5F5@<]YY7e Vj y(|^"K)UBqiH4@' 6X,fACmm!kW| wUy5:p^W$<+2Q*+v`NEei86_*"O-yCD_h09*!(DWQW/aIZ_NB`w} &<sV"ep'{.GAg>}Qj>ky<kwcU5,rq~iYVVs^4&FU'(CZE q1g{>{uA'9&-"3FjkjVK24iqI4\wyuWCCWN+-6A[ sZSQf  E>mPA?\|LY|Q63Edy], (d}kblkuvspcZW^b`g|P-%.\rak\M7A^|zZY^u<%%Da{mmpy}aD*9Gbtu}vul[X_mquvsp[C:/8FOadhS;$(-EZp{taZKQH\gkommqhg\T\bQ?7?hs]`h^QW`ivqaNLKOR`dpvzdi\]VUAJ;,&'.6CJTYPTR]eaicmoiUG2% &?Pgwuscakt}}}}wowqvzzvkeUSKRZfdtw{ztqjhjhjkkmqiWRKNGJLYkn|qolopq~|}~tqlbcgop{~}xxwxxztnrpwmwqyu{}|~|wy|zzsuptlpokfjgqu{wzmgjlqpqoqpfgknqtzy}{{xwvyprlhciheimkhfd^bicdcf]a[`^^a`b]fbbb_``atvtqptttqxquzz{twvt{y~xspaifcgcfbghpd^[``a`gj[^WTUNOQIJHIMMIKLIGDJEJKINMIGA@=B=>@GDG@F=C???B@K=IDD@>>=:1,402275-30598842/3-,*)#(*($*#&&#)')$#"2.1./0,4.//(3.1/02088=6372<278>><@9BDC77222-0).,-'*'&,&$,(()#'& '"!! "#$.%'")%&!$'#$##&' (&#&"%#%'':8611,-.0-++++)*,+'-',+$*-+&%"')*!$!$%"&&(,-+++$&")3,0+.-/,+*++.-0*-('(12&,.1*/3//)1,*)(+'-,&/),'&%*)'*1**$"" !## ! " "  '%%'"                  (*#%#$#       !&%$*#$''+%'%/&0'*(-'+(*)(-'/.,/*-1$0$1')(.),*,&,$(,,')((*.++/0..+*)/+3)2<951075;0;4833630/-.-2(1/6-5269295100328-01*5*<MRL:<392=3;6E?<78:8=5795A4<767:8A:EDC=AFBA@=A@<>:>;;5:;77A?98C:;49547:<<996:735@7839587:8:;7=1@?7000<7.,-&&%%%$*'(++!& $$+*'+.1'3 0!) $,.%/,8'-$+$%$&&(#.)*,+(2:**-'%-4)0-'&!#!!#!*!       ("                    ' " # &.%   "#%!$%$*,))'''&+$("$'&&)%)%"'&%$$"'&).),+%(,1,+*)'(+#.#.$,%&#*$#$$$!$&('+6/(.$-/&,%-$($0!'!(&$ $$ '!&"!$ *(# %"$$*#                                             "((  !$$"!!(2'#'%'$,++(!*()99&+*#% $###"!-*"! '.#!'%!#('%*,-.//=47-<;@:84<?<8<737646:6646:42616A;5.50.020000//-**.$&!#$'6** *-(&% (%#  #%$'''# "!!#!$'#               #        '!%#$%''"%),34112043471554:<;C?KILLUVSSXRSZ\PXHLIGK@HEDF@GGEDDCCHIEGAEFAE;>@E:AJ<B3:5;6<072/9<H9D:?=B>@<;;8;:>9??;=<><>BCFBMDLOSSOU_W[PVNXWRQGHFBA@>??>>>>EDMHLIPKIPHMDGLELLMHLIKNHRRMOUOSFOMNHLEJGLOMQPMLWVQMHJQLLE49%2#'"&(,/,,20/-*'**.--.+-,4/=A4837,0")!$! "$',)1?A>>:FDB6:30-1'*.,3875;79:I=?8@;>?;?B8<<>;;5@GC@=;?=<A=;@B;>:C?CE@F@HMQUMIELGMJKD@H<978457173-3-9A624--.*)(#&#!!% )(*038595<::99>G:;54377<@=?EQHHDDFCHMA?=<;;:89:A:D<G<C=<:3:678NWPHB>@@@:A;=EA@;F@@:::99=;?D>CAB:G@EDNSNKLNJKLSZWNLLI?HBLF?CB?C@@E@GB@BHLGMIDBC>ACBB=<=?9BL;=3:.9244299>AEBFHLHQUOPIMLKMJFGFJGEMGLOKNWaWSOONOLOIYLTN]RUTPVNONQKN\`_TTPTTVVXXUba]Z\VYRUSPTVQQNQUQKQHVIOWOWUXTRUT`\PSKCE@>=;6=<<4:A99785567451677/51156?9=0:64-/2;1432519=<>?A?FGFD>BHB?566:81/3'.*/$.&&,.1*0100-,&,!"$"'$%!",$#$ #,$$! $!- %$#",%)&-+ ##$!  $#%'$# !%"!  !! %"*!#$,"%'#&%%% !! ,'0'.,42CGC>ACFB<4+/0*.(0,1%()&'0+&&%-"+)2%0',(%*'(11,+,)4/.&*%.*,/049887>:=CFDGIJKIGIDJ=EBE7D<AEEHAIGJLKPUOQVMRLGHBD9<>682??A<<:6CG:=881807.203-332?94>4<3543.3/.&!  (,13;;:=>E>BAB:EC@?AOCK9I;IGKLMMNKMLMKIGGIHILJNGRGSKPLTVKKNPMGCEBD=BDE>CBA??73-5+,%)$$%!*(&,%*+$&#'"#")%(% !&'%('1.'#(%$$%"(#")$'%3*(%(" #%""'!%  !!"!*-((#$   !$%)($)%&$,((%!)&172,&&&$           #                  #$&&*,(:.13028..934/,(*,)) $ ~w{xr~vtzuqsqpvz{{}}~yvomqspq{vyzpufueprx{~yzs{yz{|~xyqrwwzu||}{xysswt{}~|z|uulolqs~u{|koigfefamo}z}w{xu{{  !#+0++-)+")" vre^WVfcTTTQMTTg`Zed\ZU`[VYZ]hkp #(%#"&$*!#(",",:?;::AJKNIHFCC>@<<909188;=@<9;722=68@8=33662/(#     "  )"))/232/1../326136.363,-0+223>?EHLPTO[fc\SRHHH=B@7?2;7:@CHHVGH9;02)(+&" % '#$)+1" &!()//64??@MEHAD7FC;A?J@HDEA=;?9<:;8?:?<994621'&,$%$(%+6962-(,     +007A753662.7/=/539:==?:><DGFOKICF?IDFLHPIMFHVGNJPKNMLLDKDFJC?970*(#('  )$-,13?:8,' !+(3:CHTT]Y`\_SVOSILNMSShba_chlnonrnuorowmqtrsppsqqsnphf^c^h^_Z`chaljquqqmlfb`W[QRJP@C;;@JE:8C>DEPW]bjfi_c^`[WXOMFIHJMIPQOVW]dcoekkiy}uvxuhofqpx|z~~{}~}{zvz}~rqjbafgpxppsqqrvy~}|}goc]i_]_X^XZ]ht{x|~}wsumxnurvyxvsrsqlnffgoenmnbgdaa`c[XRTMTSU`bfjjomyxwvntgphjkeiionpourxszjyoruyvsqkvt}~w~qtsvsspi^^X_atckfdfiiruvy|v~ywrrnxy{zxssvr~|rupvt~{y|~tvll]adthmhcjjfhjjws~{tohje`[aZ_^ahkkrrmvlupqrylvhnfjeorlpxwqyoq|}{~{|y{~pt{~~{|}{{uttv}z|{|~}wy{{{nkfZYZZdhqsy}}~x}{xupkjjjosmvrjss{{zyv|tkha\`]hgvlsprrpttuutrilehbebmiyru||}uvxpn`enhfddac[ecltfat/inst/signals/otoclick.asc0000664000175000017500000011027513026262276016514 0ustar susnaksusnak -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 ltfat/inst/signals/expchirp.m0000664000175000017500000000460513026262303016203 0ustar susnaksusnakfunction [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 frequency fstart and ending at frequency fend. The % freqencies are assumed to be normalized to the Nyquist frequency. % % 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. % % 'fc',fc Shift the chirp by fc in frequency. Default values is 0. % %@end verbatim %@strong{Url}: @url{http://ltfat.github.io/doc/signals/expchirp.html} %@seealso{pchirp} %@end deftypefn % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % AUTHORS: Piotr Majdak, Peter L. Soendergaard. if nargin<3 error('%s: Too few input parameters.',upper(mfilename)); end; thismfilename = upper(mfilename); complainif_notposint(L,'L',thismfilename); if ~all(cellfun(@isscalar,{fstart,fend})) || ... any(cellfun(@(el) el<=0,{fstart,fend})) error('%s: fstart and fend must be scalars strictly greater than 0.',... thismfilename); end definput.keyvals.phi=0; definput.keyvals.fs=[]; definput.keyvals.fc=0; [~,kv]=ltfatarghelper({},definput,varargin); if ~isempty(kv.fs) fstart=fstart/kv.fs*2; fend = fend/kv.fs*2; kv.fc = kv.fc/kv.fs*2; end; w1=pi*fstart*L; w2=pi*fend*L; ratio = w2/w1; A=w1/log(ratio); tau=1/log(ratio); l = 0:L-1; l = l(:); t= l./L; outsig=exp(1i*A*(exp(t/tau)-1)+kv.phi + 1i*pi*l*kv.fc); ltfat/inst/signals/linus.wav0000664000175000017500000024206613026262276016072 0ustar susnaksusnakRIFF.DWAVEfmt @>dataC|\ ||\DthhX(Lt|L 8 l ,$T4 t\ Lptp|,< l\0 `PH|,\lL 8@4t|t4t\$Dl|ll|4t@|U|}|}|q|U|2섾|&|.݄ۄللӄ˄ۄلɄۄ< |(|E|m|}|}|]|U|,ńńÄ< |,|2|4|>|"LՄɄ݄l|<|u|}|i|}|}|IDŽ׼|.|i|Y|&Lلۄ |(D脾< |e|]|8|}|}|i< фۄɄ<|E|M|><ӄф߄ \$$ <|}|Y|]|M|E$τɄ< |$|$|&dфׄۄτɄDՄфDŽ̈́|q|}|e|u|q|AӼ|:|E|>|.|:|"߄DŽ̈́Մׄӄ۴<DDDD||:|a|.|6|E|8| DՄÄ, ل$τ|E|}|Y|Q|}|y|]<ل|4| |4|6ɄۄӄdDD\D|$|*|<|.|0|0<$D\\D߄߄لՄ݄ |:|Y|:|(|m|.|<< ׄфф߄D< ۄ߄ՄDŽ̈́|$|I|&|e|i|M|8|4 ф̈́τӄDŽ< lۄ߄݄|&|I|&|<|}|Q|U|*|.|,ӄDŽτ݄L<  Մńń|( |M| |<|}|U|]|(|*|,фɄӄ݄\|$ < ݄Մ߄фń|(|2|>|*|}|m|Y|8|,lńńɄׄ|$|"<tلфDŽۼ |(|E|A|m|}|Y|Q|,|" τÄ˄DŽ4|,|&<Ʉ|8|M|A|y|}|Y|M|0фDŽӄ< |(|$| ՄՄń |"|6|Q|Q|y|}|]|]|4|$ фɄ |&|.|"|,|" Dׄ˄Ä|0|(|]|Y|u|}|]|a|2|.< < ݄ń|$|0|,|*|.фτ< |>|.|]|}|}|}|}|e|8|$\߄ń|Q|M|Q|U|4|Q|"Մ˄ׄф| |q|}|}|m|}|m|u|a< |(|,|,|,|Y|e|e|ID݄DD|.|A|}|u|}|}|}|}|a|*|A|]|M|I|"턲$|"|& ń̈́|$|}|}|}|}|}|i|Y|0|q|e|E|Q|q|A< ˄DŽ|*|,| 񄮄ń|(|}|}|}|}|}|m|Y|M|}|}|}|Q|A|2ׄ|2|Y|U|IՄф |I|i|}|}|}|}|}|]|0˄|*|I|q|A<ՄD|,|.|6|E|A|*DŽ˄݄˄ׄلׄ|2|Y|}|}|}|}|u|a|4ӄ|$|e|}|Q|A|*|2􄾄|>|E|8DDӄÄD|Y|}|}|}|}|}|i|Y|(|*|q|u|Q|6|(ۄ$D|A|Q|<ӄӄфx |a|}|}|}|}|}|a|Q| |6|a|m|I|(|,섲D < |<|Q|M|&D݄˄ۄ8 |]|}|}|}|}|}|]|M|,|U|i|I|Q|A|.ńX|6|E|U|>Lń̈́D< < |]|}|}|}|}|q|]|]|,ׄ|<|q|E|0|8|*|E фɄ|0|M\$l߄ń˄D$|Y|}|}|}|}|}|a|M|,Մ|,|i|]|U|A|*|2脪D< | |E|>|.\$لD< |A|y|}|}|}|}|q|U|A Ŵ|<|U|Y|Q|8|6|&\ׄt|<|E|E|.DɄ$ \|:|e|}|}|}|}|}|]|I|"τ|>|Q|I|*Ä| |& |*|E|A|$DӄلՄńDD |6|m|}|}|}|}|}|a|I|(Մ|*|A|M|<|0|*لd |&|>|A|M|8|(,ӄD< |A|i|}|}|}|}|q|Y|6\Մ|:|M|:|4|(|"τݴ<|,|<|A|6ׄӄ̈́ńD|Q|}|}|}|}|}|i|I| 򄶄H|"|A|A|4|&τ |(|8|6|0,݄لτń˄D|M|}|}|}|}|}|a|M|"ÄD|:|A|<|,D߄DŽݤ|$|*|0|6|,لτ˄˄|8|e|}|}|}|}|i|M|.˄D|8|E|>|0<lDɄ<|"|&|2|2|0| ݄ՄɄÄ|2|U|}|}|}|}|e|E|,˄τ< |&|<|A|:|&d߄фɄ|$|$|$|$|&|"ل̈́˄ɄńÄÄ˄<|"|A|i|}|}|}|u|Y|8ÄD<|&|8|A|:|&\D݄ׄՄ<|"|"| | <LDՄττф̈́˄˄˄|A|m|}|}|}|y|a|A|$L݄|.|>|E|A|2|"݄ׄل߄фɄɄɄфӄՄՄ|(|Y|}|}|}|y|i|M|>|$ل$|2|E|I|A|0 لׄl <<tՄɄń˄Մׄلل|2|e|}|}|}|i|Q|<|2hׄńф|$|:|I|E|4< \ltldۄфՄلۄD|M|m|}|}|i|Q|<|0|"ττ |"|8|E|A|.<\D4 < T߄ՄӄD< |4|U|q|u|i|Q|:|2|$\DŽDŽՄD< |"|4|>|:|.|"< \L4dD$dD|.|E|]|]|Y|M|>|2|$\ل˄ӄ<|"|2|:|:|0|$ @DD$DD< |$|>|Q|]|]|U|I|A|4|(dۄɄT|"|2|:|<|6|.|$< L$DD$D߄T|6|Q|a|e|a|Y|M|>|.ɄÄф\|*|4|8|6|0|*|"< |DDDD$$$DD|4|I|U|Q|M|A|:|2|(˄Ä̈́|*|2|4|2|,|*|&|"< 4DD< DDDDd|(|<|I|M|M|I|E|A|4|"ӄÄ<|(|4|8|<|>|8|.| < ߄\< < \$Dd|(|:|I|M|I|I|E|>|,߄̈́ńP<|&|0|8|8|4|(<DׄՄ\< < DD|"|6|:|<|>|I|M|A|4݄фɄ|*|2|6|2|*|$߄݄݄<DD\|0|>|A|I|M|M|E|8|"\D߄фÄ\|&|.|2|4|0|*,Dۄلل$< | |&|*|(|& \߄لՄ,|0|4|4|:|E|A|6|,< DׄɄÄÄ̈́ӄ|"|(|(|&<t,| < L߄ۄ|0|6|8|A|I|E|8|,ׄ̈́ɄDŽф|$|(|&|  d<< TDDDDD$$,<  \DD$L<< < < < <\\dddDDDDD$`,L\<<<< < <<l4dDDDDDD\ < \h4$d$d4TDL\< < < < < < \$T$$DDDD$Tx << <  D$$t|Q|U|E|>|2|(ۄՄńÄ̈́ߴ|"|<|A|2|(|(Մτۄ߄D@|(|:|2|E|Y|]|Q|I|4|*ׄфńфD| | |6|E|2|,|&|"߄ׄDŽDŽфلфDDp < |0|A|A|I|]|]|M|E|2|" ӄ̈́ń|$|0|,|<|2|,| $ׄՄ˄τ˄لՄDd< |2|:|A|Q|Y|]|M|I|2|&ۄτÄ<|"|2|4|4|,|4|"لфτӄ̈́ՄD|(|2|<|M|Y|Y|M|M|<|,XلDŽӄD|"|*|,|0|8|$ۄلׄфτфՄ߄DDD\|"|,|:|M|U|Q|Q|M|E|*DۄɄ˄|&|0|<|2|"d݄τɄɄ̈́ӄӄDd< < |,|2|,|>|I|E|<|:|0|*߄̈́τɄńDŽӄD4 |(|"|&|"< pD߄ՄфτӄՄ4< << |*|0|"|<|6|"|$|,| < $Մӄ<  $Dd< << | | |  Ddd\dDDDDT< < < < \TDDDDDD$\< < \\L\ < \DDDDDdddl\,\\<,,,\L T\Lt$dDDD\\L $d@D\\l\TT$Dd$L<\\l|,$dH4TLLl4hT4d$$dd\0d$$$htt88TT |xH dTl Ll$tLLthd|,<TxLd\$\,l4<,|$ d,d4@T\ 0d$\dl\\t dt4$4`LD t$$\\t$< @<,ldL$ $$$TL\4 dl$l$Hl\$Hd4$LP\0tLlTd$ lL8\HDdT dt$$dDDDT\ | |$|$߄\ pd݄DD |&|.|4|A|M|Q|I|8|,|&݄τń̈́ӄD |$|(|&|(|&< D߄DDDd\|$|4|>|I|A|A|<|.< ۄɄÄÄÄ˄<|&|"|"|&|( < \݄D|$|:|E|M|A|E|>|4< لńÄ˄<|$|"|&|$|" DD|(|2|A|U|Y|U|Q|A|6|$τńD |(|*|(|&| <tDDTT\d< |&|4|A|I|U|]|U|A|2|*D݄τDŽ< |$|*|2|.|*|&| <DDDttD |(|:|E|I|M|Q|M|>|*< ۄɄτ|(|.|2|2|*|"D`dDDD<| |$|,|6|<|<|6|0|( dՄ˄ńÄńɄτ<< L4DDD$$$L\\|&|$|$|0|8|2|.|& Dل̈́ɄɄDŽ̈́фDd< < 4DDDDD< < < < << L< \d$DDlddd$ t< < \D\l\\\DDDDd,tL\t$T\L0  tL,p<<  ddDDd$ll\TLXd4|<TT@ Ldl4$,t\$L  \$tTtdt,`TL4$,\lHd\4  0$, LXdll\t,dl|tHX@\T8$t,L ,dlld4LT44tdthl@d\plTXtt\4$4Dt(,tl l, Td DT< $$< t$dtl $< dlDD $dll `$ XD,t `$,ttlt$xTtp 4d$ ,\< DDDDDT< < <lp$4@0\ 44tLTd$tLldD$D4 < <Ld,$T@PL\,L$t$$dtd\tdTlTLl,04dP(dTxd4lDH$hl|\\t\T\|A|I|e|}|m|Q|Y|Q|2\ẗ́Մp|,|2|*|"|& <D݄ۄ| |6|0|Q|m|q|]|]|a|A|& ߄DŽۤ| |.|2|0|4|2|,|"| < D<|*|8|8|U|i|]|U|U|Q|2 ߄ÄDŽD |(|.|2|8|8|.|(|.| < Dلل߄߄ׄ|8|>|A|]|i|a|Q|Q|I|* фt| |*|.|2|8|6|0|.|0 D݄݄ׄۄՄ݄߄݄ |0|:|<|M|e|a|U|Q|M|8<4ɄD|$|,|4|>|A|>|A|6|(|$ DۄՄӄӄττՄՄׄD,|&|6|I|I|Y|i|]|U|M|E|(ф˄L|&|0|6|:|>|:|0|,|*| < DلׄۄلׄՄ݄݄|6|E|M|U|m|m|Y|Y|I|4(τ|(|6|:|>|>|:|0|$D$\|,|.|A|i|Q|]|e|Y|M|0|*Մф|,|2|A|>|<|2|,|$@D$D߄d|.|A|Q|]|a|q|a|U|A|0߄ÄτD<|.|4|>|<|4|,|"dDD$D< l$ׄττׄۄd|$|&|U|]|I|a|q|Y|A|8|$̈́ÄÄ|$|.|0|6|6|* dd<߄Մ˄˄DŽτL< <| | |,|4|I|<|<|U|I|.|"| Lۄ˄ÄD< | | |  dDD< <  $߄݄للل$<  < ,<|,|,|(|>|E|8|$| \ۄׄɄń̈́̈́< <TddL D݄݄D\ < < < l |$|(|(|&|"< LDۄׄՄׄلDl< < < < < < < < < < < < < <  DD$dd | |&|*|0|2|2|0|,|&4Dۄӄ̈́˄DŽDŽ̈́фׄL| < <݄݄ۄۄD$< <| |"|&|&|(|&|  Dۄӄτ̈́̈́фՄD < HDDD\< <|"|(|,|,|,|*|&| d݄Մτ̈́̈́τфׄT\ <<  $DDd < |$|(|*|,|*|&| \$߄ׄӄффӄՄلD <  @TDDDDDDD\< | |"< 4Dt < <  $DDd,T\< | |"<DDP, < <<<  `dDt4DD<| |"|&|*|(|"< DDD$l\ < <<< T$dD4dDdd$\t$DD$\< |$|,|.|,|*|&<T$Dd\< < < < \$DD\LtDDd  |,|0|2|2|0|(4DDTt<  < Dd4DT| |(|,|.|0|0|( Tdt\ \ DdL\ << < |"|"| < ld݄ۄۄ݄Ddt  < < \T<d$DDDDD$ <   << \DDDDDdtLD$lL< l< \  < < dLDD4dLd$d<,< `D< DlDdDDD,Dd  D< dDd$< XD< D  | | $|$D< D|$|&|6|,|0T$|0|*< \|"tl<< D< $< D $< DT`D| |*|$|4|4| |,|&<< ,| |&\D $\T <$ D< $D < D < D<  <   DLdd<  < < < d < \ td$DD< < <TD$dt< D< D DD< lltt,\4,ddl |l\$l4Td,tpHdlh,hdx`84Dt8X@4 4TtT4l ,l8p4|*߄ׄׄل݄߄݄݄Մф|>|i|}|}|}|}|U|.< ӄńÄ\|$|<|M|M|E|.ۄ݄߄ۄՄ̈́Ʉ|2|a|}|}|}|}|a|4ۄ̈́ńÄ|"|>|U|U|M|>|$ D߄݄߄݄݄لՄ̈́DŽÄ|4|a|}|}|}|}|e|<фń|*|E|Y|]|U|E|,T߄لׄӄτ˄˄ɄɄ˄̈́|8|a|}|}|}|}|i|A߄̈́ |2|M|a|e|]|I|0߄ӄ̈́ɄÄÄɄӄۄ|0|Y|}|}|}|}|m|E݄τÄ|:|Q|a|e|Y|I|2 τ˄D|8|i|}|}|}|u|Q| T݄ׄτÄ|2|E|M|M|I|A|8|.τ̈́DDh|"|A|i|}|}|y|a|I|(\߄ń|,|6|8|A|E|E|A|0Dل̈́D ӄ|I|}|}|}|}|]|>|&< ׄD< |"|0|A|U|e|Y|I| Dӄ˄̈́˄τDńh|:|i|}|}|y|i|a|U|E|0ń˄4| |E|a|i|a|E|&< ׄ˄ńD<  ˄|A|}|}|}|}|u|u|i|M|2ꄚD| |M|i|i|U|:| <$ÄD|$Lń|<|q|}|}|}|}|}|a|I|4􄖄,|6|Y|i|a|Q|E|.|" ̈́˄| |$< ۄӄ|U|}|}|}|}|}|q|U|A|"ń|0|]|u|u|e|U|I|8| d̈́˄Մ|*|,|" l݄|&|u|q|}|}|}|}|m|U|6߄|8|A|:|0|*|(| <DdxDd< D<Dd| |(|,|,|,|*|(|  $DDDDDD$< <\D$L<<\\\\\ <  \Dd\ < < td$d,< < < ,4$$<DdD\l <\< DDD D| < < < DdD$ XDDDD |0|Y|a|U|M|E|A|8|&߄ńT  D$X<  DDdD,Ld|.|4|6|6|*|"< 4للׄDt<l\ dTT($T<$d< |.|:|6|.|$< L߄ۄ$HTl\< < < < < <0tTt$dDD\|(|,|&|"| | |"| <$߄D<\ < < \L$DD |(|*|&|"|"|  D$ < \dDDL| |$|$|$|$|$|" D߄ۄللۄD$  < < LD݄ۄل | |(|,|,|,|,|*|&\D߄݄لׄׄلdL << < TdD݄للׄل< |&|*|*|.|2|6|2|.|*|&|  tD߄݄݄ۄلׄׄلDd< | |"<< 4$D|,|,|&|&|(|,|*|(|&|&|"߄ۄلׄՄфӄׄ\ << TD߄߄݄|"|6|A|A|:|:|6|2|,|$<DՄффՄׄل݄D|A|A|>|6|*DۄτDŽÄńɄτׄDd< |"|(|,|.|,|*|&| <\D߄ۄׄՄՄلDd< |(|0|6|<|A|A|<|4|*ل̈́ńÄɄф< |"|&|*|*|(|&|"< $ۄׄׄׄلD< |$|,|2|8|<|>|:|4|,| $݄ӄɄÄDŽ̈́Dt< |"|(|(|*|*|(|"<\t߄ۄׄՄՄׄۄ< |$|*|.|2|6|8|6|2|,|$tׄ̈́ńń̈́Մ\<|"|$|(|(|&|$| <D$Dلׄ߄ۄ݄L|*|:|E|E|I|E|A|6|" $ۄф˄˄˄̈́ӄل$< <| |  dDD$< < \ |"|0|A|M|M|A|6| لDŽ˄фՄDd< < d$DDDd\\|(|<|Q|M|<|* DфɄD< D$\<< lDDD$D | |4|M|Y|I|24ۄф,< \݄لD< $4\< << LDDDDdp DDDD| |4|M|]|A|$dׄфD<\ׄՄT\D \< <LdDDD,0$dD$| |A|]|U|2< ݄˄DŽ߄Մ <4  @dDD< DD|E|Y|I|*݄τ ۄӄT<<D<< L$DDD$\tl<Dd|4|U|U|A|&DŽD<ӄτxD$t < dD$d l\D|]|]|E|*\Մ\< D߄τ<  $0  tDDDDdlT$LdD|:|i|E|.|$<ńX< ׄӄDD|$\DD(<< ,D$4L$|8|Y|<|0|,|$ńD$(< D DD < L<dDd4t\|Q|8|(|0|,| Մ<D< < < < $Dt,d@< $ Dd,DDD|E|:|*|.|.|"߄τۄ<DD << d<$$L|6|4|0|(D݄݄<l4DDdT  $dTTtdDd`8|,|,|*|,|,|(لdDD\< \ DtdDDDDDl< |"|*|,|.|.|, ݄ۄDd4dDDd<<d$dt,DDD< | |(|0|*|&|$ $D݄DD htDd4 < \,TT$D$Th,< < < < \ DD<|$< $d< < \DDDl<<$| |,|6|>|:|.| Մфӄӄ,<  $< << \dDDD$$| < << 04$D$ll<< \ $DDDD$4tT$p,< <  <$dDDD$|:|0|*|$< lD߄݄݄ۄۄDd\  (DDDDDDDDD< |0|U|i|]|<|&ׄ˄<< D߄ۄ ,DDDll < < << $$TT<  <DDD|6|I|E|2ل < < d$pLT$T\ < \\\ < \$<`DDT| |"| | <<tddDDDDDd$@L\< < \\dDDDDDDDDDDD|"|(|,|.|,|& ߄D$L< <  \ddDDDDd4< |"|(|,|0|2|.|&<D߄݄݄݄DDd< <4DDdd |&|.|2|2|2|0|* $߄ۄׄׄلۄDtL <DDdd|$|2|6|6|8|8|2|(< \DلՄՄׄׄلۄd  < $D߄߄D$t4|(|8|<|8|8|:|:|0<D݄ՄτττфՄׄD< ߄ۄׄׄۄ߄dHt\|"|4|A|A|>|>|>|<|0 4ׄτ˄˄˄˄̈́ӄ< |"|&|$| لՄӄՄل|0|A|I|E|A|A|E|<|&DۄτɄńńӄd<|$|.|0|*|$݄لׄӄфττՄ$t< |(|>|]|}|}|U|,\< фDŽɄT|"|"|"\$Dۄ< Dd|$|>|m|}|a|*d߄̈́ <|"xD ,Ll<$|0|U|u|u|E D ˄d\  < $< D,T$44|.|Q|u|y|I <T̈́ddd< dD< t$ < D\dddDd|M|}|}|Q TۄL<T< < tDDD$$ |6|y|}|m|,<D< ɄD\  $D|$|$< D\݄DDD\\XD|0|u|}|u|2< D\τ< (<< | |,| < t  < (ۄD@tdDT|I|}|}|YD\ Dτ< TT\\|$\  d$t4dD$<D|E|m|m|U|$ d$ׄńń < <l DD4< < < < TdDDd4ddD< |.|Y|i|]|6D| < D < $D߄DdDD< < < T$D<< HdDDDD |.|A|E|8|"<  ߄D DD, < dDL,TDDDDH|2|>|>|6|&$dL$4< \TdDD\L$DDDD<|"|0|0|,|$d$DT4$,<  \@DDDDDh$DDD|&|.|,|(|"< < Ddddd  < $DDD$4\LDDD\< DDL\< < << DDDddP|<|0|$dۄՄӄׄDDl < < < < < ,$D߄߄D\|(|4|<|E|I|E|A|<|0|$Dلф̈́̈́˄˄˄̈́фׄ< | |"|"|"|"|  < ,dD߄݄݄݄݄DDD|"|,|4|<|E|A|<|8|2|$< ߄ׄӄффτ̈́τӄׄ$L | | < \ ddDDDD$ddDDD$< |"|.|0|.|0|.|(|  ,߄߄ۄللۄD$L < LDDD$. % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % 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=wavload([f,'.wav']); fs=8000; ltfat/inst/signals/ltfatlogo.wav0000664000175000017500000002265413026262276016732 0ustar susnaksusnakRIFF%WAVEfmt @>data%  ! G'/j@dubiBaG,5Q&+  K\Q (&>' ^YSFF_ V4 ,((n/QhN_RwCK6уK%elS`< huR9` { Lo ?(Z GPS ~5ZE ' / $% I [&UH2KN b|t D Mt` jl!r*5, uu t Apu& fM C `_&- .7s, 0H 9rS Nq> H7 &I' I DO3;  s# #p'f;* 3 J{yb P o MDB("7|J ] f vz-g.tG * 7 /oTb!hYzZ.yftO6pe& /dG3>h~4wL~hY/ 7  6B`Z|z%r"(R{n9xL OC|T8SaLMPv3$UJ #  /E * >J Pq F +Ug  C =8 B+ d,4X- 4+X  5#/ +^[ d' D!Y  S|U =D l~ !kzC d  F{) "_  yOW( ] hH OpX Ky  - @% AB q" A ?0LCVy 9L%X$\̑\;As(7VĠ@@yQ 6 |C 41 |' < u2 A . A EF H ,Y zA d $ AR ! bO [) }O j,f Z- 10 %Z 5 `%B 5 ~ |1 bgS F] !*B 9o t #D |4Y(q iQy &ue Q/ =Ch e K ] p2 &lsPR qa1rwysN.qlaGDF>bE,Cm/TB %'L3BOS{ 6jTSNK7SSpQ?zbu,cߩd%޾_߸~(ldP$K%}q>w >0B*DUIEk@Fs :J.u><%!\ EGBe8|PXW Zv A qu Y"2k|*}]&1pbYK9 R R1{ I S$FW],|}dD)P1}2  ;n& bIl5? 6  @s ~R7 bc/ $~b [$,= LyU$ - + `Tw<?,J$q [pdz rf 2.R 71VT10gp5 IYC1xgz*gyZCff;.  &6,JHao{VcA ;\%#cP4|>E 9!*V&! h  _TOO  % g Zp Q 41^ 1 ZeF [= .Loiy H h: {\ zzo h޵$ +o7[ F /,߉ j _zYctcfPNIe #Jq J .(# 7') d'`ُ"'xG+ yE)a# ؑ)<t+#g + 6D9&ف!26K y 5]}qb|]H&%{ޯVp`2*G(fBU N, 9C &^ B'M]p[y *MqE"S$ ݩ 0-CF/ %=<@5 b" ݎQ o8){c  O= eQe n(  & >( k i?HpAJ(2']H@|@o\#~F%i9jifSB?).    %LS)"PuS%motPn`^)a;i95+4YGS_ "#D u[ )\_  rW eU m@c rs T& myZ^ Qo / 5 an{R 7K ?&Z G0 10 `-v ?j B5$ y JTQ `b u0 W],#  dIu x5* t! et^ g S WZ q6   s6c Odd~x 0^f4<x c H/.]Gjx:K:L|r'~ <*0iHCL+n{ Y'" % ol 7}I% lM DR$,o 7. c /  ; [ 97b  p kM T h` " 3g -:T :: |0kW   m u4kH ~(# i /tJ 7-o aD UD{ DM bdy c Ow0U )6  %x= m> ][dSu?0N`HV5>r-bN%,LyI.A-ltfat/inst/signals/Contents.m0000664000175000017500000000343113026262303016152 0ustar susnaksusnak% 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'. % % For help, bug reports, suggestions etc. please visit % http://github.com/ltfat/ltfat/issues % % % Url: http://ltfat.github.io/doc/signals/Contents.html % Copyright (C) 2005-2016 Peter L. Soendergaard . % This file is part of LTFAT version 2.2.0 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . ltfat/inst/signals/gspi.wav0000664000175000017500000200005413026262276015671 0ustar susnaksusnakRIFF$WAVEfmt DXdata  !##%&'&''''''('((((()()()()))***++***+++++++*+++++----,.,,----,-,---.-.----,-,,+,,+,*,,+++++*++)))*)()'(('&''&'&'%&&%%%$$$$#$$###"#"$!""!!!!!!!!!!  *Ry$Ar& a+ B ZO3T I L   u:  f. FW-d p3 p p?c u E x  B"7w F{% $ EN? fx/ c 6HeH*~" o9R N g!lT;vk-GY r!V > uC Ti(x t A M <  }"7 J g  5s 'W L  9LoL c$t< K OZ ! X!" K TD , J \@ [  ^ lw  E/(- z  s| DN 0  9F fit} .q$ g e57; G-j Q jE # GRn :+5 t, }x3E bh2 " g(( # Z IB8 * 'cF  4dA u h.I CH HyBt E )  7QH < D 6g|P C ,R-1R up_A '7 H^ qG s pr* r c r @P  KIQmvHq Qak]: Ho  [N^e>Y Zc?vOEq{ HMsy#  5o s R x f?P- i>J V 5(  8_p c { C}E< 5g H r cn F 1x13? q4zr ezc d[ N% LsF" UK  kiXa c 7/7aePr6>M@c Fqm " f J &X )'#s @zK [qj@ Yu <{ aE6 *f^ {  w  I]? l+z'Pn * _X H1 _=f_v-7r#p\{`x _  mk \)H(c': j#;| ks x 4 G GmCQuj~U`L-  } % VkAG 6 ,7C!d~ FoWw ;*} ! ziT @U3<Q @ p%H  `Tn K |Z2Yj+Y(;8 A ! Y#=b [nCq_nz8Bh C McN. ]98`SY)Kw<TB k] R ^\1  \`m"mmUs>`1 (qA d96 Pt{Jz`{jX/<N  5 W)  P\\`*DI9D@K| %U8H5X z%/tSg_6AHwR R F *0Ty8Jm9BZoR(9( xZe7G6Y0D+R20BR E P]1 ,lF0e^4ltshq iC15t@3Bct>5F 3)C= sM6r|0"["?vN/OhEB&F^(,;~e5"(8FBoJ<>}u D1_%p mD'/K8:g-1p n[f0$uV,#wnp>VA$o~&-:g{%15-[]BA6/3;9^0WC03#L/K(,]r/$;D kjpMC nUgc ( ,wX2V0K-Z9J8t~ljR4&]4;ILTL)#|2f.wa, [&4,F:-A9?Pb=1nkw[G'|&L5A%M?`x3PS5*T7eiDbn f^c%)kFU0 I6<'^vHN(4 tHC=On`S!W5376ov9 N7HUP(oX'W `~ddJ p\``e{).Qs}173 0I@S.zz>104*-/sn"j R&+"xg/l,[] soCcr\VLp'x%k@d'T+a &7`% s/rO /18UcIc0)xGsM~q`I9]8A 91:\q3ac|;1M?Hhb,pV`}Qc' L2K0fsBEJPf*TNSQ~+{Q2NJ}6A )c+;;@"8E5yWB/_{0|by 9Yz%o5ld`vI"iV[?T42&cYu<eHtW2vpWQn<4/l.^mmiy'k( HV]&req!/ zxV5..PvQYM]Z^quRb9j'%a2<T] fsa6=oNwUt1!#9X/;v X3,^sXZFYYDg ,"4uJ+s9Apa%2Rm9`yI1 NN''"{SN_Pd!3Q;< 9n9z8B:B.0\MD8ld{9;Ly]H1 g +|_NQv"d ;q9TAm<~h@CK`O$`_1q$:Wdl|dKAZ(i\7,v]huZepv3MOCM=0LQw x,Lzsu$_L\Sa)\PZ8L.3)G55@l1$MMPM"WP^;yuDi+DK:f5mh WjMR;^"WJKN,TmL+E8EZV" J|Jo,{`~oR>5Cm[xG XLu2Xd!A,-[gD=rHyu)3-h@(p3s7Uj `cK9~i$wdG,Z|Q'##Ft]s W`R^ g\(&gyeRRTM~/2Ka}=tdLm&N\3F-J>Ux{(:pmGdao.y30PG`T@? i2[58:Z2?"Kz4!Gz:+dvC6"9 FgL<ATLLn'9o1S{Mj jq}AH#=T&t>|Zy(i("/Z0$nf=ksE5A(E;$/93 d,:v_Afj m>=ruHE=T#\T's.w{0=AD&"Jd H79Dvpf[sAI+]",*<I2qDl*&k*]<M V3u'<wG) yV{jbM20?Pka>+bmDa/Z *?)|O*6O[(y94 lXfgk&XIH%v d*2 vk)zHn|o/. s#-l9e.fP&!JMd0ncjYG$U\h!M6v] _CS tD|!f}DG9#"+C5_x(%;$\xg21( lxfA7Ht'd4gm+Z8'R eC2"Z_Y'v_iD66 %%4b=Hy'^h 0Rh^ !B44>dN^-n`?d-z_46={ShuScZd [ wvh{~ x_|!1&]x;q)vzi17N`CT:?ego .uYdl"Y G^.G"[" 9\[Ydt-[NbS1LS]/BXn,#HI!$?m%'F!@L>(@q7pE<F@i7O#lsJB yp0L8MaEXdptyI'G?#U> i1 -7h[&Y Bif~qYFK&1*?k^vr_sjwy/6-jy;*{946v0o7ik#3 n'LWIL>qz $.g%&Ns@l;{[yRMG as%lXo(`l2g`75 t4YBCwrb5[DWc8_ojuW ` $(lj\F)[.C]u\@ +RC`\f5/>29l!-+I5F3L\};t{'3y6Ay\KgXdLj-u7LZ\d-j$DlG/]9iZ*wi ">`LMW%~U VTBmrw 0^HI78M?M[umR<,yqPWMn$-?WA`)I|RWz.XK&DndS cBG9>wn3xy5>ry`;)GtB'12H"cJO] p*Jrr)z4hw^L%H":fCFF7c-"8ePrD} []p&jF3:{qo+ _Ebklq%X<xcQ7]hxRlDA sZm_8-/F .RqZce nqwR>K/1_3xNZFN>r]^uYj;n\E h;C|2^%2OgPTciPX`uRbWp<9$ZMB K97f1x^K "-*U]RDV)::7`y>JJO_+L*I/iS\c^'_G Ll5 W_VinV3_8. 0HH+VJu_=%?r^{avH)K\Hz( c]q|xlx&f\t0|B'AVu)V   @@:H~7s| QYt`k D%=yLG},] @?\~u HF2 f '^?;\Ec,s:~=JDZ0mON-F2~r_4hti5E|p!jT Nl7]{>0>1K|nTZ.$=8 :" xs|U)4d>1fb=k{6}!sVZ6O+0IV*oHM;vx%y|)+4+1446u=C  (W9KQ=FKx 0Hr40m$4 $Cw>I9~ogm{Qx[= p1d\dB>M7^C|,}m">Bso :`]|9L*yY*w%w.m]RYvU=hV9 J:!SC"Yh^(.p3RZ' xJEMU~t&8oaqxb1H[M.Ayig?%IRr-O|+-fK;+.uCu&5l+9) D?m g;~x S FzF3Rh\ 2:buUd$tJf)_Wn :4 %zwj T%78z?B92yaHmdGSBx)q2C   ZG =:@65!hV3Qjw|xr?a.GJkk:|U^y\2D)~?vC:'j+*\?kZPR&{($z]9q7@T(;{7;WL]AAd+l'v:p,PTw:~X8Z|Au  25g X5Q ]R<A/}h"0B,5`n^E=bRJ`lh5, &X7_'!%2;tu%2!ozUKEs0tcI^9gY!&2n_ ^ 8_2v?WP5 Cga^lS*j?X#  `1LqV~e;nv_&J/NgCr%giJ yUm,k)}e^"7OK _Cvw?+R8>&w7+[[[[V+p+mG=SAr&\H3U`%l55`ZOmw5h{)s>4 m K,;whb7sJ0k4tD< Ch\ `q `pdRD 0j7h DfpUv)(fZ>N@UA(UlM9JrJc},vC)ZE Y4f]qNN@v_XR0s:@{j|-Mjx$k WZrwE!?2i/aUhxa{~E1"$3{)AYpc5e/\mr4m,al06usg iFIl@,<'<|c2n3e;20Q+\f{PW-ZO>w)c80ek1$6r# ::A^!-r ]!j(<YRnKfCku$p]_iC'<uA2(V\hXX~i r)D\XKNWTckauw Bq ;m5ogUV:V6oVk4Sz&uarYq1 v+2Hyo w:@x23(m]iwlPL!D/%U*` XqwrCOt#~[[eS `6,z $r'sSL!c.3(APi@ _nG8myUbdF=@0i`lbpRjO, lzl?)9  A*h<&^AiWNi$Lf,({\5KjMs2JliLRw.'|tu% }#0[W! H$ xLM}:9fc@suGBb`\Ap)o~+Zi3GY3W0|sjL1C`&mSC{BJnRsAv(41=Rl,{\/j YMzPF.k!oC+$^7wx $UvWK t Y }6r[3uT]'yI 5q?Z<C=hXsXK@wK|j+a # 1 /1(TVV)J.6l^+ Jci9Dvke@?9AAmtwo*Xa2Q=kTW,jUm70y~.<D`'Qe5MWYb;i1X 13X%:Bu%NW6q0+saGr{(tc6zth4)k^q8V.YSd50DHP[R4xy.tWLb\-Y/tS$.ZYK'jhkp=]l$JuUk<|}? m\xLe6}yv#v: 2@7RDa1 mh ;(B[TEHto0b*':nW:x:sLN5RlkbiAelP1B7taM0\VNe'7%%K33\e8,Uw_L",PV'@ >4 2xp:dzb6he'5zfuQaYl x?rXU&lZR,6&Oxl1R]A&6;$G#tiY7>!@:l!Z[:S"SU%Hi:%]ZT',]m 5m ! P >ngQ)4 O7( Eqv2? RHb/,/#B'XnG%n\wCMXwi9?nw +Zk^cTN@VpmJkc`&5(A.* Efa*P%3 4A%(Imr9aUK410`Q_7/ki{vf}h!]z`.KnktY,`oOMc}r3vL6\&"=qk&SHrw<WFT6 [(zs>2WB*&7Wf<7"W@_;E:nuH[ X!=XO. c8'?QQ2{HT;E%9=3+P`Kv^+>123miXRu}[%-dnL[tqp5TM' (* .tlA!tpf>?x(/'I\P ,3;l! AX\B!&WTo](oooj>UQCPxsUk= ,",4wheVEdbVeeM@q LdR8)# Tn$O  O+M"b/6"+ e( JS%c KjcKDS|^Mxi- Lg]GETsdg63 xpn}(:MVlGz0:Cg^K8' z"8Y)!C=eb<QIL!jFMjnFvZm]Zk28zs2E@6mtI,*Et|zt SgLx+ N"@Tn/7iEytU2 L6"_ #KM=28b$5) HYj;vt~|X LnLOm|#9SJ7` 2; 2 <  5[%, 7R` h\R Bjl7p s+~ m g9 Wrm%KyMiwb{{ ]n6G>{/% S7[,I{Y+" ( FN5Q[=q_/QRZ   S = nMPu%qj ,>z :  #_W @2%/^dF!: .  s.Y pO^Ao$5 yC=>g a^ =z2yENp(7<+UP  4|{K QW)(bEwK  CEj k @b -{4Bm * Y q4; 2SrZ:jq<]OX\  qJQ@SoTbn+/-  JY:{%d$2E4hA  D6 ' G5V{UL7> ]5i,j  ^!: Y9_d,D,:E isu7 WO k'@*Fx EB> oU F xZ   ]N / I: -K &ow2,dJb X1 x V\ } a4;Dhn|N==] A (-dLhGxa 6&}3 Qr v H N+sgBE[+C{ H JdG 7P. He F?  ;]E  , p8sYmlM){$ lwGd4a k D,Bry^SK2> b D  #pY Ko =Ig_IKQs6 r 4i ^dO* [!b[^im~ ]rqSo 3 [sDP<l `$> Rc #@_E D G&0dA ZR aV }r */'sxGf WI 3h{p?/Q<[Y[V| !/V5eb~&0Hi<))C6  ]@uUG\ZL c Kd s  /. B NB49f=v[;i%  n%T_b Uqwktf:Y|;3omtSB)o5x  b + O& ,  N&:9B:teL: q 0hB IJ[vEX,`![*Z * *a WLMx [Bsn-.  " 4yEmgUCG![ # u *oWX 2AbI=[7B6 Fj ]@`PK yu`)  !X| Z*xwFXUpnS? - yE1zN uSHc v-'b@Q,) 0F  7u0  5^ lW%PDym\ f  y ~r#<1~b2s J z % 3 9}0J>9$T&f< )   nXInW?2c YPh< 1 Fh8z\%VrU @Q  1e<5#+  H~  [ ,$upi}SE h]x_& V :m R>Hz g[2 16E8"k;P ~*2/QdA}Bqu{ . , e2"s.Sg w K s5+>xD  KmD   [ C  i 1"f1bRYJ7pg_ k Gjw"%3KGS_k+E 6H" <bs mb\ c xl<~]`6BZ X l] Jo`?5y cT_o p#V k %)Y(  \5( |9 l ` K PhZers kBh @  klIbCK3n/q,v`c M  |~5QY[%afkV& t  ="Bu%S*zAVM'  :%" a$p@8{{r  S5$#F_b5Sk7<hW > )Rd61Y#qa 9y0L } M Sh(^ <vtikD+75* a dK/ i T{!:2jR 3+  `&kg|CCU9 :%_O  Pz,EW i. :8iII7s^ytn{qy; s jj}  Z`mU "_/W G C  j;3uxI`L 5 S Hres^*<1|rx  . a C[WDT@E?J` = P6ZKJh Y3#wU`*i )k!tM&6K}ZEG9q8pb  pcW\yq$#.%(\0MHt X  :)mJ4'%2e + Ru 8DTla2t uz0@;IV'%X R=>'i#7tF>O$  %K26L-Sdd$- mT9 %wAptP 8 c` $D .f= a.JJ t a(?-C@{,]BQ"a l { s A:U!(\jV X XZ8~2oto:yK (K8w e o [JpP7T1: PtGf5? 8 Ql/ ) # ?53%Yu-0WJN7 LbSu,0]e1W%+eYHpoZ0Y,7 hGM;  pMmq-Zp>R .&7  6/vUf2H!{Y4 8 j 1]Snx aq5V >PzQ"'lx\-z/P8=b 7uX9[Y6qhxx?[ ([E;X+tP>Y' @tZT*-Q{X M - l)KaEtl S w9!k]K;9 ICp9  &8?R"x).q^2d#@m * |RyQ68;k| B q9$;'FIg|~^)`|&*,n<;> W h,nm4@c,4r / 'sqO nXQT(5@~cVLrM N 5 wH=P7?Q*M-V =r_9up2o [ I N'?Yi  z6/Dk nu>m v< lO S?m+?[4{2 5uRtv-hiZ ikqeyAHhk. GL@W a N  i[-9Ll|O!| &~\  K'&/*@Qr8U}8- }8*9"hmW'V^`-/=y6Q.x #u})! w BKj 5lTc 07" } y'H1DW:L_"u0XJmJ /~?fjUWw o\(ybz*8fmy l?^ 'A+S .z7-RUA0B  8p}!5,:CCq1 Zp5,H/ PN JHSsSZhF y1Cag0S!"SK;R g;.- s s 1*6'wVB5EQsK Sl  y !K !],q${/4 d R5 )g=5 eO!BP 732>%Apsz}xSw3 r LUy/r&'BFI"QCNkLeU/ ;Hz8 O =(7'o<.5  k Q r?yeE`A4);a  L ?C/-'F=-8qZ6B\u;OLY U<6$q4Fs;|59  hh-Fy`jp&A_ b.  wCXRqf|Lq:C5JuSC s q - "X{(>5: &MG5 %b84J~k&}<$L) t%&xS Ro P~{V   8)nHe>rg_ew1\R0W a N&Q:TVNs:-}QC '0W~\anfUo?gY{ N ] " %}X,4i3{%jj: +Hzpx!w2gd!Y e ok RyVC6442;{lG2Fs&hfqEF  / ZSW(m+~5:' 7@rn3.*laAew7VJYV_Now <o`{9; !b~^%FI~'L&'^~ 9 ~ S {1 ~q&" tu, 0 m6WuZqnt8Do[J,m- 1/1NPi58= X R?t]{[lxZT' + l ZgxgQ8oL"|*'9 b Gg[wVH6Z*me=-FKQB? jww<,Ar[("%/ ( b!N;_zKRTT6?{ p{5 tOcf8j _ KRG"+yoSZiH"8z[e++ \w5Olpc O-Q;?y}^ #b ,tB t / d3r9 vdsP8xk tNi4jJWwUo?op0 f_* r_LSVB"G$D 3 ]c8[lX-|\Eg4 gWr : Yz{4.D'5="yq7bex-Ji~59>0sg  0q|W%Mw ;\ 1 Y _6U)DL O1.FED%E -  K[E1 iVt_F @)7XK,K?`SQB ^ 1 >7;N;tym ("O0hcEJB%z}d4>9G-Mh`ST8\!zu) y Bt%k"eU-7oOJ^ S B R # N=n"KvO>jMqP`a mg/`hZOT;LD= e&  4e,Tq5{NYS C< +}{r/2   3 U7gt+F~=0/<y^%b!J`-Up 3#5cr>W~.RQL/V-wr4  c <k`bv_i7W^C~fX[-(0}nV!k2xns cpD!eKldnJE@MeAaL &  |pjb(G,Q fLW  Q -c4jAI-R.+ 5M@=~p1ZeP7^HN<IxG4ar^ f3:[3THvTuv :K^ N:?xI_ hNLya&?4[F0|#nzwS 8h)rvZrl|_XO ! 06z`'jMy:1~#YC(p)jAI}f;M?;e.tGd  I(T6`3 W`+ZW_7tyawk?Y S*WGjCg ,5scNxa^GPp*r $SDM]tjh@Z} mn"cxk*V[MNT U7T.l-Eq0Br&Z3<@6mP%22#%,pp.]xdNtS1CypCmB nIS`z(+SdG %BEA## [ 3Ztuw%&s)qC | S t6SMh` CTGBNO 7B ^@Dj rX SxP$ /_$G3a%=Y.+ZI;VH$%=6tZ)T}&gI|5-?V. #=GIfS_L= ElS[]""whx.${K$ 7"%X? @ml w| P wY\nvuWfUvs,.\\a-kxn ^N\ErKP^ PsMKW2G;! )uSZ6be'0^_N;)YOd , (~7FgDn=Wv?G;%E o%}94V<1"i %U&bhQLc`os@Wg$:D^(- H ;i{lS7 IRSG4q/#uqlQI8d- ==[rV(Ff+o+kTK oDwO 6&;a4P{(.8r"g(c-kwYJ*jN{xPS>rX=U&&MkyC]d*5BH[ Gp"MJ b#,g%s^xcu=4_i,H` }ah1o _/2}Y7 R6Am$p=pmIoKYq,E7y,5:z(gd{p `] quKH,tK|Vl WB_dr@=[]YV'JX Q1mrfLuSQRFhk N1%H[wb\; 4 6fP#e=YdXfaqwY&<vYrF~L~ oX(4 G 7hTgov 5uVKDd]& '-Dpvq'(,hfjp qupm)h!3C=fWiplzeJlmPSoJ_Nxn1O~}P5Rsv?%+mbA6LFyG|<`h^~K5!Hzm: N@ywJo1uqesR.tA46$'j%]5d{[J^;XXd */e(L?Gn\s$IfojEJ 8m63jF(r"j h~!GQ6THT,0,Xf.4YkWTWs3`7f0_OPRZ5<]BZKv5E ;)H \Oomcr:>h`(>C7i($v/0mWfE}8;S_@~P4g#H }_%@ Z ,V`4(C8R T8 D@M; @cd"W<GKSByx`(ss-9_nQspcWK4'0V!,FE<8|f]=f@0XG VcNj`tT]CJ@v`9YR %$%/E' Y/2j7OvHQrF)!|n [n$h"6.1u0-KlhI7D?mhp?}),^${^fj|rW,d`!2D0@|b]T!lF6!0+&}gQx yon$f \2#Xe$b?4>*BEuv\k b@T0^RmWkm  q ?B'bEo 4f}s zJfIw2#'Ft3c$WNljE-O G}7RDI{(Mp /&` nzpD4Z'q-g&w\~>gO}sd0Qh1)qKJb <\7B.hs.CDj`f,zA@pCT831Q5* bYWQ Rr~pln/i}qrSl5*?+ 8{<"Cq5.!>ufAJc1+$O4RtB/#eL9weB:$cOtj=.Lx^eaoO0d @xIrb4-*cF_~G@Bt47 :MR_CRM!9%dH, TM 2Ym2[,MPOs:b;KiezO7V7`smgEaFV' D9(g^Wt>& bGu d``^Y>V` [v?vS c3qx&A?h:r3lBxV)*J:[cIhHdoTKb!Igs>:;gvuE}Ll$]7mO%Gv`B{N(O_y^xS / `DPS) "!0~%k]k3+m`L ]w*J 3$G=+.o-E!I o[cXgl)lbHYk[V uuJ;cm@'UW91mhQm(_B> ]loO~|Ho\ 7_%Es{ekIa%44]L@M$( Wl&Z))vFGo K"w;K6:r+ZpW7!A>vt2.uFh/sf:~RV%ZQ4bHDPI1Mg8skF]jfu5uGAr3:P +Yrke?kA#]i|O-ebHFLCtaEx3klzP Im.6\ `8k=G;)k|&6L*=CkEEVQ<_uAR 3'J{&PN]ZAZ/f{bB!4O@DzG:-D7J;~e) KrO7g F&SJf%hR 2STT>g(oFq-\X-[1L?:'[B]6Kw/"LxP^VQBr"{Sy<w!<|]L}CH#27n5|~l49j=d3 .~zFIaCp!l]4'tcF(G@ThL 8 uJXgOm\d{EKA=TZa!.R!&qdf$^BG2,Lp,*5tC+mJ(J6mCy b$^M#6idlQ"HsZA_ 0'UT(qM/IET4KsD:=p'\m~$!-~8SuJq0@Tc'ta"E4nE_Dncg?!]t!:Pp"5,1O=B'vM (}\aUc6V!{@+An[tS.iU%ak_W"N^q:J;hAdBb.{.SHS^vo]cAR,QZUD; fw7r70r1]e3?/ >;kDkIm}[}y# (g<k @m=W)O>4TNGtxyR!VJ5yKgAf}WFw+<;W 4d>k lh6oHl"4Fo o Dx u N+4HT H=oSN|R EBIT s `>I>{Oq|9 x sba S KO~z KEq    #Y;/23))  J Q t\av`#6 ;1 5 7_i>"{  i4  \Y 3*1g XJY!WJFo}H[j D r n , O97 TI  6 } deenD :=5  !AlISU  )+AM HY%l <$ d$ J _+9 + "   tjk x48  r,8D)'I F G Q 8} \< =Vi6) [@n 7 ZQ@88>7]L H`m ; #9Piux v ,  GnW,wvv\I1   Wv \en n!hFA U6qqlr3 g u  S**5_ MLb =9 pZS` vRjt V[dlE|eR|- . b = j 4=eXuQ  A ; 6 p(au!_$bbl 9R m m4Mjh;-{BI ]S'< ,r 1\_ S$qC ,+C?ne$/) :+ r l8N 0z < y ;O  ae vFw&Jk4|Pfq  Q JE? K=) ^ RS@ %i)z?T\s ] ,. >hD>^ "h cL 3k Y2FM mX %} % TV C  (q J6K#m K 2 0~+n#iTT 5 Y8J ( Cw-c  X:yf/ 2_ 7z  0>W]_T]J *py  ]Hnv;FOhA h 3 3!gZ[AgpD[ nh A B3_U |}r fVp < [s9 %|3w 9 5kx#/p,T WD l _ A~FHI90 y tB J; U[O;,(U | 1 ' @\2 0ax_ I M  |rr+MA(db  ; nVD`z*  b W ?NGg'ICi Oc "  ?j J@8woUWA bWym"'+f|  w H7]8D5u   0=* ;N@14wF{ ux`~:<] m d sF QYorB   , dYihy? d6 %L}j G  ` E@k_3y  aq N:>v  W9)OrHRcQGN >E  +o, Aqy\ V&=@?D= Vxh   p _qG#W@Y=6Kv2  c yp+@ sL 4U9v;epR  \ [ q@Mr A` R !_b9w;t4 z r =$ mdwvR/z` N|MyyIv+b>Pr  P  ~ G$z\pTG| ]C a suqpCl@bChW[ ,kx;a8n& ) \ [X v % "G m4=}\rY :38D1  2 P ?jp p 0 6 F Ic0#/8a q-Y65 -"rQH8!FZ  z  ol yi$a>@EqQ BSlF*Q Hw fi"7N3xnU(  W \  /}ZUx`4&e  Mx!L 9urqW R X Q j &MsE c9J'K p_z%hn Ib Nw[n>?< 4) * h 6Ej|6 w + L `/>|*- -; <  ojO>_HM@@ - e n Am6`X $rC( 9 I  Ve[)MAG JC l w29+E_ Y yAG2 ^0pf/bM i o I { "FrNUE841a  p c^O4.{J. g8V BN,feHc ##V v" RgVK,Gru l I  &zvjCzA.5h P 'T||m  eL7 :oDWI~hLv ! vj a q&eXA7 \R  $ rjZfey40 &v w}&-A[_\Xt60ON 1 l }f_m   e`}7z;kA ) ~ > L &  HUWR14 < $ Fj&8E abSD4Kk'%fR )  ) 9 :Lsk`>k= Pj 7[3/g/R ! xT FHpg3C B ) *'/K3D " o^xd*tQT U^ i S \WeapGFh3 BY"($+ul6v bJ<  bp 8fd = H@Np?z  "URnrg r3 h y  hk c&:Y  Er: 5(-p{T6 M { ()  @|{@i&]B8 | [ 4 ,mA?RUQ#5.+hgeqg bi >cs?: Y  ,qb$e*Q  b dMI<5F  ~V d U !{Jot=7 6 YE52p[~x E k w @:Y3;v^K4VV IdC :7GvVQP p & :F:? G T dddCv$ lokR +]me b@k;i C Tog29{}'  k L, 2h:o+*$=T K-$l z8l>] [R6oM\ 0Q | X W % o{O8 d280F*;C+ l_t] L ]V y 6v6R%+"ih [  W s:gzv%= Y!vl K<:b7YWeg,: , p &? @}6 [! + >3W8pUlh[  5 ^  i S6{jqzn`ty  Ui/4Z # 0U@;^^>" D|Va  4% "bSZ% oeA9R  Y3Y"R`z2}  F 7 iH[7 aA 6Ym nm| M |   (.:Ub:$M r 93i]Z@<{5; *Y  S$HiR;1  R H 6 )n$=3k aH  sG?W[$5NfR ? y @ K_R. Lz41a*AcQ 8Xmpa S t |E*gQop^oZ U#  <#-Z\;4 9 h Wn_K` @ & !  PxlE9Wp]L 0 Dgd77\`P|p 4 ?   w\ :tI"U #9K @[8oa-+~ ;6. | + - W@( l  u d+ \_ia4H~- K\ E)o?7 1 r } | 2*FsipYJ< SB5 @t2v>?* 6 : |  }mvtJs $  & i?'XRP'e_P`dO{vEkF? ` Z q c hIh=_`{xv" ~ O|S Z XP2iZJzLo#: s^ : "+g=ho ' l : q ;e?Yq1@tAvL 2 'F|}< _  h  Z?% p!"e^$ Gq}[P3 sz E DE}R}i!KsEs| { $wK*g~.O 9{v N \h0U1CZx  B +PO97?aa EnF> W9tdxsm  w % ) }'d=m"[45 DR92Kb%}I q  I3SU9v_U` n1 \ M_8!;I0N .Ki1 n*/J.H- p  ( m%3<7JKc)ru% g*oJM(e e h{35; d$ If E [bG1_)2M -_N & YvEK1,_ ! j < 8Xm7r.>ZW5mUCyt  8 r ; tQ1_Jz_X   1-2 J }vUdf^ 5 cT fg8G 5   s  #  2{ r+trbq; i _  ^t/l*< 6DQsiwu2V*x [V k  c9ERg(Zv"< B:  J,ptVW H ^} - V9U,xCx q~ } % = K2?L ~j* c=E5j2% P  R j Jc"PC7V3mj ~;_P ,jBBs #7B +"w0 ; YK < ( N5UI?%@7H0  :vfsng wVYj `  3 k A`mvJ{0  y4 OaFcc_xI@w D7 m2IlFA*" 7 q + lr*1stFQA`rwopS"sh?]  x Z 1 \}v*#]!-d Lcju' d_' 8w V > D  eRvc#y G * "LY (Q"ABSu)v  v K3 (KJ V +n_ z~?>Xep m M jO\ HE  /&'iHQ J+ " 0)lS0q\Q > U oil2&F |Q e$/ e f90$l Y u w a }2:f[  W= R DvI=1d7)]Tr  n LYq'bO4l M1 b RUu [ f;q_i5S?TU\ , Q M Hw`T2Fb|yh 9  +(X$F#jl;uRQyBVOV3 N~S ) ?Pp  D " w I=;L{-k <& &x?XG% M oD`Q 6> 2^'\A ]X9 ^ ( &  o @P3K,QPV N+2?w} g+7o)i ?d ~ VI)/ i mX+|AFd~t2 x' { = z'px.oE-O e 3w6rDZl\ X | B L h UHh<35] 1 3 H=58Hs4=w, [t v1Zn1  4#GV, */O 9C`;Sty:t1! | * D *  r? lnfc"A~ \ 0 'LlW|.^c N yh5 c838DJ  , AV}T3~\KGr,!T|0 O  `Moj>C 6 b G`bu xC9`u*I[J  p 0 a ,v#@ h4c eh}! ZDZS;~'+A  ymh [JbgoI~ y ' FBp0 8Q Z fQ ! vL!EixK]k p N "  U =idPf:L  ?7 >`H H N ~ 2 bSIz@4& `| R%:JX& _PSy u hg- Z r= b(q) V  A*ivy"?%Q_-nz)E8vE5$; m ! ; . T(*nGR . 2  y g t_{R,n~*KP 63l [# #>p_ ~  - H1 >Va%\  t,$jY \ u  U H=me>saz  e ` 7b1:*_-wd;% Dy t 6q %UDoh    C ~ nxI uh8:|55q . ycq>zN: ` + ! ! *>(8KA,GUboo{gCt[q#G/gl L cvJTI[ zd  :" O Q(E3Bn)^1A Q n 88S6>OJV{Z r{g*K KA7S/t^:KDh W   b s f JNds8PUB52 pR \ k$.4L$+ ?R; * =yx7sIN{6 bg dq/qD:w(QkQ  3wUs: ( \ {0?If;x5E ! a   1jt@uC  < XX?J7?p6Le,qK{]  }da`4*T/9o9<|Y i /7@6vHF7Jj  K m q  U.yi _  L l 8 Im&1/_h c  bjv9gTE('g.y{$8<j s  $ R~x5XQ: r@ T) # 2 > (! Gv j = X:<{j:=  {{PE\MHhd(*CaJV!i0 9   L 4*N qg| &)?  fS_\kD!1 G K  A ]};66M/2 F:[~rg!&yQUQ:~M[w] M s@D^'9_n a 3 Cw(xgr  C ~ q#t.%q "COu2xx,Yj%rWY"%*wCAPxf Y x g 7 r  %AF t^od C   #kK`0Tb F HJ 8 VRe8S e E VSR>f[ [CK/,ZL=P~t 9  h <R- ymvCBA n B v([),S1J p D L vdgGIK8^d75cb%}  leS TE}MBQ)^L  C  PlE_m : 3 |zc, ,18;`/f Y A  CHN%n)se{P>|5@Ud'&PT^k  8N2b`  B z Dok$0[ ` # eEJJW\RfofM$m &-J^ oxf}FA?2qd]c + f.jG !GQ  }" S5=T^c{Ybky .9 5;z @5=6 _   e@!{T 6o|sV\YPK3gg^ib8h , p  K j 6 )]shtfq t _  br?0 :S i  ,OpK@:u E Y  Z(IR n65v x'dib]H\w ]  t _ B % ;f=LhjigvTqM 5 m {{IWC  9) [ + xqWKY@z1x4@&}bupa@p]  + (%G "DmZ g % ^&b( _{yic(> !  B KJ=" C b # D, S~(T  NHF-x=3}N(M4eKL+[(_B D 2RP y TUo (SG]_S Ei x F FMl3=5:^  9 y_M5 8[(  D>Ch>v ^'6 UD e_J A^4! f/n  aobKk c?6a)t , 9NQi  }x:2p 0 r   RP[}}>t}2lH!MoM=v 1 @ =RhNo$a'  )@ )i* d>ma   9tUuIehuB N [ }C[x:- DG(+c# ` BmCn^u6YM= [ B pic)uXv a  h U 6 Tp 8q wQMT v @Wuwb,eH~F1+Ioi ?  P98KPz o2PHT!j : 'l  2z rj2,M"   LE|'xewW=kFO1p$8F=Av6t*)/(tX5l*H? I  _ 3 -rHv6MQU}/ QpnI8bUq] : wBOaF(!QXufNZ5i\ EfJ#lkTdEKH:fzp  KkF:%N { s 6 8s2JW/Q;cuU i . ?0.@Ig06gV^5%LO"V3Al  XMWf=cC{N D ) .} H{5m@K  t QoWvF:)zS _ R R .A- 7ycT4;;mv|Q'iC:_ ! ( R|l-CA5eL ; *' ih%f+b 1  [ c -IK/@cTNl m -Yd1ehTRjVhY"@Yn45 M @J2VoPlT%A h  ivvl0Re5  x ? n u ZqXZO/(b"RjVnU7LmPL:L6WBl C $ / [  zvb)y;cre Z # 5I w )1I=AV94= c z 0 g . jjIcS{9PjZF6i C# ?#tZN+hm  G X DvU_:P+vn6  G E N ,KJ3q[:OS> $ w "r,K8e,2bn|&l7Vj% 7cx6+V}$}4f{  G J  pwU  ( J .' n  ^T'y!y$)iM c#&WFc^X6+MT*+Q*L<X  p : 1 TVq5^@_%B ~ T M T 1ox;: z # z Y sA0VcqQF5U5;N U  ='k`8xvHW8A\  U /  ` ?B]l$A}- / X=k g# $w]OMi ]=X 4   Ne.M>(C9&bMIMJG<h}$02 ]A#$x6!4=   pH>\R" N X C{:RSOKuO ] RQk<N{XZO-}FoQ?E 60Hf > | UAv$;btx]P T ( P  ] P<I1]K 4 tSVo !\9W aye6s9f;8fCMNLTRO=,:^` , - ] D2v&XE"+] * " c y  >./W {Z.]} a q @G>4 V1)[3wDmu6,KUh  M 2y &K fa!U|]h   ] U)+K$E F  Q#n{0e8)@WdJp h*=|w99Gv~K7afJq ct[ m \FG^pE>} k:SG# e k Lj.J@.w+ (   ]qAZ.3{}0w757[z 6F1YS`Ww$9 7:+gmR c go_M;~5z_ / 0 qc9^+%TQQK i K X D,RAb!yd T'FY;E9 |*w= ^R6?\= $%t- ; n %f2kk/_{{hik>q ^  : #7S|mctJy T 9 (IlQ\qA`F-rg(:[!# T/yUVRG@Ghl K t~U\`h6| R ]: \ B| `|#z J ` D u4-#gg)V64_UO_  f f G|$gWkp s Q X"|rQA*}K * h~dAOJ6hnGM?pc1!w)Q m.tvBysCCB C h(-g9Y7Z   5tJ:|mF6o$@1L7mz`B)mm%}^?ouv7   R H   x!2 s aY30!F:3Y `C?!#4zt%[DN &!P|{1P H'#(6 n t4{emj s Ua N2 ]R"^&  m3]u>{ . 8i!pSVp[V; C  :% [6 V$. }~-o 55 c l K4=jX D== x y W =Uq0Z KF~` +]z\ |m<  5KsKH } PZh 8"o4%m ] q9h J[ X* *[m V(9 x%]P|6 R > +;{)5m 5" WQ a1}U9i3x.+el:w buK'$oA] de~ t , yhE}: 6Ay5 @ o aB HRqSIVU @  tYG |< ~]t Dzy@Pe G ~ !"Vi A2@VRoZ u jOW' /3g\$kX65 Jy~ :A"wKwO e E7 IiSF  y.Y; &i ]5f  GAk(SHd n L. 18ngT &u]Kp50 Ub=?4s =3=~5( ~ Taii B_f >@ "w(!dH P \db1%<GZF N  P!4/G " Lx2lQ?-}US: Kp !((^e+qK7"  lYy^lJV'N?:   _  hesSSR' |'t, \xdrw&\m jB b 9K%K?hX iG5 8 6qB<}zG x LT& h#3XRQ<~WR } @. B ]X`5qJGMbMeL? `u~7cXm7S;3 t jtx4Q2Yv R L*LcF0- T *]1M j En 5 2z=s - c8Fk` T m8g$sW TT f {`biOgF3' C) LkfGZ!u< { VB *8"j/z]R z x bs We% } "pJL~HIiy n - cGI/.    f ^} l%1-}e W XF)[9{<(b M? Z  16NrlGu%xiYCQ ?SGrf tI ? -aE0*-uM _2T  bjf"uP/ : " V "F$'j("`pk g +&BQ&7]  \zK GP3yi=k~ F  ix p 2  HSAXy`!.   h g <7QTyVcM \Y=}gQ+=v^ ;>  m n 3dy 4  89SYz(fD%YYw x ) jF,SoeNFLyU/PMI2a]d}6`;t,-=}Of)Pl e. B!  LM<-Et;oM !n $l5%!5YMK4 3 $/ XG,O9eK b G c{uW6^DZO I y:YHz^\VNr{ CW`}<J[JN a SW ?  @ $.B[sC`s @ ~ hInmtJ0m E XdDMN]O q.4VB0Bi9O[" yo$r J1n> j%T 2WB=6  ) P; 2J?FkGJ / BQ"&GShwx 9('Yj:jt k 0+8OaBN?}a [ z|"*,-` 0 G X-\Y`5# Z` Dr_kKtP! c W  *p qU(Hs+F k ~  0b L"FD'Uim%2 $[yBl-f {   U  ,_su?E] wZ b !:\Kg:N : B > x-U>QS @ D @ Ea =CYf%6\e\H?#SE5th%?G0 j > cA$>P (N~8_H:{ x *]{ c^. , u}`B s&mMeT  D\^,{2fW ayQ(1QZFO g a +QB>  } IE?1\I pJ  MmA3:ekV) +v g1tP0qP{5bG(|o;Wq\e!kw;~_ ::*`6;tT8 ( < / > S ;ll ; k#* E 5 O V 50[[" 2q/>a2,Y6Ak,mQ9?EsGZ8SupO(7SZ8R ^fk 3  $ <G |B'7t0 FrA 8: e3}0l?dwC*Shx|GK?bQx.z yk.gqUY+-L.g q Q G k D-hW  ( Bbic6SpU.$eZu oe,h8 k > N  D 9QF9 X [ [# #W$|l^,pg;v#M%FO$b< !_k\jWSDs7> W$jVd]TlKU+ n >  | ^ s~S{d[Y  # )2U)c; 0 }1n5EQ)Y.vwRp0~0Tvs)UNT2eS:[ddN; 0VITC vg! @ )Ch50mxq   3 _ ]h0C {  #.2|tHhX<ZFG~u|;%+CXL30RlTpB[g46lHm4*X * G V ,UNFP^c E(N Mtl/o|ms  :qHZFrF[({ ]ggJ9N2P 6g+(   {\+?[(quP4 Xu [ /n)45Q :{ bbQwcG2XSh" In~8T bW+   cy4wF99zAskPTh V n pc;SU k v G F ~ _g^W< A b8y[? (O  D 2aLwx\N  [IGHI~quTxP 6tL : sq+lO>  X IrB{L'$,OhGT y:EliLBg , ? 0$q:vt? @OP m 4XWDYk(A! |Ab{g~u| } 5 ~  '}9s#b`K 9 b36d9KF c  ,2Y^hO9S   JlW6?q90[ ) -P7c91(ua[66j, rZ 1 =8$"",]N e  6s9B&4lKs o N fe"vHl1p j^4:C  7 RWy,+LQMA V |N%p iN Z 5 w wjZh Dyc$hQ.X4f 8 3882. V9I){PbU/cc4U%Cwa  Y;L1N3nVR,j -V L j .S1|m?r%Kn aU  3xX'fO@ fL0,p{|EIve = b!2$W- f8ENm4e>dv}JX>v<Y 4? C r ? * l1:52F J !dJ;~E^oV38Ayvj)5^foT ]-u|~2{O5h#e>afM~,J,(V 5 , / P'5 < L 4U T=W"Kq5}{/ U.?(`PB}-&X.9Isq&2,*qP7\{q u aw . 45f%R% Q= r 1/jvp@n3kwA2}-Km} `wr3B|* XE>UfWJ (5)N.W- "%V[JA  3 b H~a x d 3 Ogk{+Y.8ni]]?'=o}vDt5H)lgFvn=:)ZkF#B)9Ben&ZHM n O Dc! R l) ~/ b#k;(8UB0vq/6Jos.;4%' $^uDn/fY;"P:uF{)1Kgt-N.  @#e+`A)B,6nn  WW{ \ V E'Y+NN4"(* u4 < 0 QX'a'XIL+D,|9[W.A]Q=vd/Oql  | q G e'DS,I*zY@ W P w a SaPdM8AWH [;@O4e (q ; YO*mM,)uzX63fUyfNCi2 N tEfSGnCjQ} "    TBx 5:JZx ! k19nVkBT $ V WDcqD3"~} ) uJ$;Ox-5 lsrH8A =2N=pG< i v ?rGkXx?u=k+i c @KeY3][?1 Q x9tUA b  d A`oh3 c U f8iUj2ljhZ}Wi_6* 9 1+[[z+VXt ~C,!F) 4 6 o "(&4d 9UvQ. ] #USY8)R8*Z@>VfhHdnc3v%3GcPHsdq 2 B!%y 68:d|\R  qoa* c ] Y/Uhun9a  0i+?>Q yv%%W8'8fISK(+pdYN^5`h - T xG2K#':@3Em 9 J @ 1D<]s"!S \ & F   D CpKEXU>(&TvKzAYx q vp]ox SuEM<4Yr|d.vT:N  y ~ ;L N=b5;?`y, 8 U  x6P*U\Khgbu69{7jjEO{dY"&jE/l4,ucad0ceD"[t j CN zZkSvI| 8 Uu /  M: :o4F# ]v'bxzucQ o&WVLzU Cr+9]L du<3UHaBxGBcJIm]c|4 0m[7#H-6@p]*|2EV2q V & KJM yL2%` n M 5F W5 m@dAqnUm&%}tOuhqu5I8l<*-T@+O_hIB|:&   Z)::&Cx~;  B sE>n_-(~#0OSqGX (;g]h*X6,WA=yM G ; N $  X a@ 1mB = @ t::>j2y|X! I vLTH&pqr$ _1 1yR)9HY<@ )   e ?s.)8gK?S. i :  }v2z4 <rf]  gB`Sc_(+wJX+ X=4y-M2u2alB>B=;2;t | Y #yM\x~   '  q]=e?, 6WvJb4 -k? H  cflR .3bk8:sm!X?PB>(>co[>Tl\WZ 3  %)*HT n.7# sCx;U S |RJ63sAu7IVa6s9tqgl HA= h "g .j3CP_E 3 qJS8x_?a L ko[gSe0 mFwT*q&BH|R?zJAft?y`-| H'`&WT gF/5&20]DU]L}[X hT  gU)Dl5ecQR@xM y2sXi2c ubhjfVx lDB(hCHq2~`oNPKyU138/AvI10~ " Z _|3k=Fn3 T 8   . [:a;%: .emg "jCOoRfJuj%J1As$XP =w( qL^gC'FD-  = u  cR$R4Wb } E K ]yIssL)Sb%GZ2.'RhX T]#/ G[Eb>1V*~|; D[MQ+cH$9 i  $6UjpEOj1T C"Hz-hHi}-hR;gq9'b1m\C6{e{Y\B  6 w~-7;"B!^_ \  y  pR @)RjBw KC4iwH Qt?uX^*YQhX~>L s ^N>fo*qDfo  a qn^vU<4 3X/s5$u5(5j\~GOf,BK']*r s?*,%2t v5e,} h M 1 Q+9)a5X( X 5p/\M9%]{G?G&{&\B P  @-D2;A JCz;G57}h&;hv_"|g ST"7,C^xO u  ~jq#Hz!}^'ls 4B=>W5<W bG J62_@E0rX?5O,fo~'6%C EK3W% RD4c'uE <p@u@cM ]Rfoa m N D J#$oCqzH<ld+<;mE00G@wFQ }sd` ipEg, ]vo-<BZ2/t g e O b 9\?+QeN## ~ $'OMzzBM"dsx]P6>Bn6g2:345K{)[x[) P:.?af=b# z  bS7}? F ~ , 'rU 1g:VF-WdG.9i !vJc-gZ ( ![l$"siR 4 >62 " 3 "||{ >^>| 8 7YvPDu51?j$e+=_w>rOzcGyB9)1OC2"5EEC!$*~ '  v JW]C_TA  ? .^d Z\+`$b@dc;7nAz!M:7f 5WZCQQdpeN@L-Qo"y2K* < c MaWUp*b; lZEj,C ,/rX<<xl;A$TKsv&Y~y _|WHO;?"lvE{3yS MAJ~iXA  y 6@Rw nOMv*  N8osUha$ \Sq!"y?P}Xxl`L9F%gd`cTF;y.~ J1; ] w H~Ms\,{ $ u pafNedZJ],Q 9i 2 h:wpWeQ|."u}n nB/7dULw ,v_h t '5G 2^ m  X4=*OA6}] S;Zj2b? ]!2:u0N&=i &gy{]/QZF`ckD[]6 7 R&GtM.Qqu>P[g.7P7vfl[ [  S?[ s7vt bW 9 1 H cbH%Q>w6=DnNx> z{pb!$dN=s%@ kRTzd?*z* :I3 0AFT?t u S z K'C|k!O6byrpu~E`r|Zh0E/7((9 MYJ4Q  F < ` yj7T-S 4  ] D: / 0$%u-Pv&I!iwuM/UF 1 `lWElGUFZ} Il(J0ub+K3qgzm  -z4  A @ GG\'0dN{Y"-,[wbJ*v,A@TYE~)'b~OuRBZ' ] MM\mz/TFQ4Zdyz} aqa6,K1a3tL?r7>C}q!0xf4n%rl!1OMFt'Ev{ H 0r5Hn^ s 6 z ,;Nw&?[{q & wc(5\_n=o!s?l>R i!u!</z2 ;$!aGo;' : QMKd'CU@0X + | , n euqP 4^rP: H\shVripEc=It]3T|GlJVHS_7hT&{xb  e~Lfy\@oV6_B   "  dOpRJ3 - k ,y~JDD~# H^>Z$!8b)fbT`l\2"$#e CM*Xgj\nK h  GB z)nP HJy:  k GMG3=d$kDa=C&QTU2Gh=w]x\()29(vGa/WGzHdU=G%4  F v2w :P :Z ]O-%o7.`/oWx1JDOd>\ u$YL=3h>||LwqAs05 bknI/YC @ :u`7,NJ !J%r=CbK {1TH+E*:(F`;K$q\w%3 ,IZ1>swi .L O LFh`E [ 2+IBlz\0t~fs?: ' wp:H^=4n5""<qJ/,|<${WH }Xizrnsu.("o( , g2L1=gCLil~<-*wq[4RzUV~ i Zc#(Y Ecq S %HV Y48@Km)_~RD*s4I/F}O7! }BF65I~wQRh?Wu , C _ BN* f^mV$:7".ur#<<x bp mYU9q%2YatH_2is^-vw ) D ,o>sY g}T <   iYPwv1R5?_1K4#d`n;vnvY(aI,(jp/T `<\,sc%7|U?@qg l Ctw.8{m0*4  U t  I M"`l@^Yi%ll49C2)7w|#scP< ypua`A3NV;#FM.F}| p BRH?S]f A \  M,; Ru3gN4 'pe}#fwn57eXFf?=W_)O `3l 3 ,l5vR' I"Eyrk E K 5z;d:ov$8uY)== N(?# AA P8^'%3C2L]!DO}C$P=jH_!]_Tc| = 'UWly3\$s5oh4T51AM X;?<J_ : L6Q5 < p_d@O+bljc a{<\>W`qE7#4L*Xx <;- *}?|)Kbe25kC6aCN[L'(,WLEPsK}k J##BWGKhdMi*Lf2=T/;Hx·e,,T!}"|` e0D1OމdopQ)o D:* W -4L!58E'Mf &Ol@4T_^"9(U&r$:t~1h. Un~# Ni̟ ">7J>#  EuJ* M ze  7 ++^%%% <>׳. W #o Lv9oI4XyprIhLof--l"'{$_QܾQ 4"+=&u vg=V*rY YvR'#]qjqnKl6G # f S,m 5 kUq nnn>qޑUa@b".{# FWe|j ;o 1*(nT[@.^G/./+<2{p (/Wd=G[ ^ *<(_g ̽[/  a!- ?yit.9{ UlM 'v#X & T G޼^WTD  \bEu c6*  (9v"lA3=|5v!c  k }  #6} ,^prH ,5"0y\RMjE]Sqj  U- c#ӛ8Efo"#^%NFaX9EWN6 9' KJ`wtk' x +%C ^` t]mB j U"7,  -s==3#ֈءI " ICu4Z )#  k ") n&DZ"w 7 6 =*;l=!!# z > V{^,H+dox > VdOzD~a$`K) : LbGOnBG<E ?43W+N*  / &JLV6ۢ j b]~G}vC 9 c%-6PtXBa:(+\v  x"*#z]:[p ~"*%iY P,)#~& k PN 3|^Fi{|h. < }$ |LsqwF,_ G = sOEYb P P1[hYHdhI=  I ވKU$"  Z,i2ޖAi'2+Y8 ~UuG+su sNmbh> !1K !:n[ =  t cG }u7xߦ 5*  -%  P#qB>9! % M)f)t )  j jQI!  /IC݇jnJT3aF {.D6%$%; B8 #tyy0K 37TK {!?N{ Db$q"kT r|;5Mj]"VE z U2-Fy m 4= A ^3 ~(cLD N ?<xE&0zD d6 !W[ eg[J DU  y w@zC' N Sh az~aK&s"Z ?i&]yWqF%' ]$tF>QؒFc8p:gQ_/ g   ]:`~3 rm\ Z x Oݙc qU2/ Hgfloa {hDdzJZ"C sc   LbC~'c'cPS _Y  H*n $'VR gc1}k<j"_Vw'V '=xz + - AqoXLR  h8il' /  R + 8yH z[ . LsnA[@oASNc|4 o^Ti" MW Xva@eL * %A@oEwe +A~V!tr 6[.@Y \ , Tp KU8 A! 1Z4:zqtQ  3ZWj^(1r 3 ] 1  Qej% # 5c<"&% lziLp b( X|- ab~ &*f|r K%w U X:oPlKLy)  p Kma6 r i tg]t!~- t:>b7jR i + ' ; ' 3 qf( , N 6JZW:] #ESX ]j1 *BMd|  chvJqILs _qeF(qT~ [ zjh t x)Eja2 FWYE  6)H K >6 5Ykg+i[; {9 ] %G!X r Ky[Tz9? hN&a I$#nG Po!X"v(2><> 1k.   LlVtz { #HMM68D`L hx|Uj8q |Z {I .y<(;QDb j ?: T =$D[k c}V&`NcEl#vDgWs 3oC+eS)Jt r 9  \o_,{ [3 @$65 # :Bz"jXp Iq  P k;E'Vx A 9% CPoM$* " 8j z Pa4 V9&CT<B'qV pC F t.?\Vvg B  NIEy 5j^rX%! =+ 4 - $?ujZw*O u z"n h# 4 {( v3gz}&5~wKAroQ |w  ]?=OEkg -! kl-tJ mn o] r;mPp! cee3n ky 9yq V LkQ $\i yKD++v+4GJB   ` tM8dt4BoR q[D|) r i urnSsy OI }o^X 5 A zRB A6si)-@rR B =&yx FSdg 5   [,n"U(S 2/6 4 _f P f_ 0U/ y @%Ns[rO) (&g 3 I  }H 0N(f z8'} l>5  y % B[}I ql> " !&]Ri BM zOWh= E5ztL?9b yobmh D 8tT   \k.($1r X'ib+~ApU . Im 5jmj9 QvL  a   VkG aHm W f?T9 vZ _{R 8t5a a;    hZ6%x  1 # H^z[4P)Z Z g@3[ n==4> *i" FdKD3S@@  WIyk6>q~2 $Xm I'?8r[ VhAR?n! y @ GKX#- R"W kep_;} Oq",K  P _+XT 2 {aO V u+]:JS 2  Gk] _y +0u MhM$xD~W2pI " v U+-E1i<B  :b SJ_%IcT 1 "Ths6o<&D~c lAP 6 x0opn L ))_`$    *K\=*W P] /:H"7 w o.<xPB"kQ #cE E$#,3F@}|0 9p1 6P&^, iS |FUe U  3 ''K<. i;  y_ Y.+t\cRg k,+? a4clB, xF!mj:*,  sYwLV  p2T6?$ e[ :Yd9)L $ 3$4> S ; ,1&Fq B "?F#s)5xU d5 >08[ <0 Tc^V_Qpe i  s]!9  # JYAx 4q6 ) g llTnjI >' p;8  rk 0 e XA"uf}{ >~}/3 & on@ [x+ S 5u+ (`M O ~ G_Q1Zoz v@X M-7 8Y%rlk 0+!H &6 . =%' 1K}z z i  E 6~'N rAL  v kS#xkAcdaZq4 A;X Z0   2r,;c5aQ   E~0*[ E }zN l64&nT  C H; +LD C 6 " a}`gQ 8 @3h`l~_ X _S-G ) d?nnZ{6Z2VA  =e5;Rn 9!C%"z 3C: \de'/}( > q5?l( rw#_?$=xDmD~N 2n \IY`M *fL$  b+\:42 BC- ]8R ?/Q a .~67]@ b  % | /&J[ XE x<+-O0?} ]NDa* *C Yg *? wF;)9 & *Q  K,8kwQV: 4x 3GZK" v< HH YS,FLV ]-6.g[z'"* d }-9g V a! b3t"i] x)G 0 pqN6x r3r}zb"$` v w a5qsS" |? )  ~VWJ9r8R[  ZCE#S} o Bo,C3)^0xN:& 5'a "bBmP j4  "u9<c R8" "== N % Tc|d S: b. u: Ulq+ 3> J OyM>Z;{N   GY j  7= J\ '  S-}\zq :3  .ybnTy $0 Xr =  ? 0}aPn ? y qPQ/^}vC MwK]0KWYA,Q 8VA')STG S Ck '~:"Q_C*g" ; Z -(rM[aI H]b  q|+5q *`  R{c+  \ 8y7wr%  Ks4vA f H OX 5 K   [S};t B }RP{#RZ  )V5U(k. as & <<8/`lsO [ ] j ^?hH:BM82V O ! ^lNa~ `I @ fSv5A9$1 !/ f4\"s vR r._s 2 t i A 2RI v@( AngT MCp 6  i_L3 #06 O3xPDL]% 0 W 7.Y>, ӵu$T.bX_iw-N<B W1u%{ L NlNAMj"  Y;c xCvH AHL 'K:bzj G?w04F ArH '`{,  =ope 5R +Y6D[Lt ISr/ E \]])BGOrW} Gbs GN ` !FK]w "W 'Phz  9gS W@j  Pd4[gI1y  LT{1=7 [   s (> 40ySZ m, t rPI!a4H^ Y `f  & `Q {  L & &Vh}=X & L  vpps  P" 'hu1=#b h  b v(8*;^'K)= V}1r5qDi)A2J EvXn(` cTGz<coy$  ? J 7N4|? (7n?] z @DiupEN? v*Ks& `   6 NWgcfp\ Tf t3[MQ wHh LW }E: hh5~wN 6$ " ;  OP g RH SATWM/3H  607mV' {YQ  v> ^'?, E j  UK\7YZ)L[ePr =~TY:J  Z u 3c (v >(C 9 P7  -567*d Z qoa C 0 TRC6 ` V SOiLNM D_m ylx @gI ! {[v) Vy 4%4Mb/@pc u p)MtHJ`& GHqHoe zhJ{blc89(U|yAqESD\ p"LbMCE2J/i7H:ZVN3+ s=45Y(Dg?',w`: u Q>px n`[)S]hVm@nG +4 .  qW eu SH #$183>q z W ^ OPx~)Xa d ~Y)@b)| x {} ~.w/i.y q =!{z[PWc/ V -\ve,5s S f u F= eW b Nhap^uT v'= < 3 n](r6LjX ]Elew'B\ X  tU eT V } Hz D==u}D <@[xU h :2Du,5Nms L t? _Y_/wE +#nekj q~"&  e CY W\s,` }= ="?`j D0Brig k V Xx.'$R[3o5 !w N O MKr'o $'BPL%%Cp@S S w|||IV V k? _OJFN [lq b/ImT _  8 Y zn\Y Wk'VTz?R A :  `?2? xC(> = < )99HXL5h  )}a(y9|.hY[ c_o 4]O: ycSf S:N?i%nD G  m J O3B 7 l O@[eK d cfAq oF4 bL]nK s 2=2)w ' x ^1 ?%U TMHg/t].jARd -D' qeelP r LxH2aB< B(`fp,  5 =? FW5d t .B6r L6"vgV D  x ] _=T 6bd vPTA20 zTdn } 12/ d &N YLu>6E R D d C I{MX @ %W%~ (d|G:}|h Q\ raK5}% @c _ "'&B   i Ld,)Ex%3 Z  Z 9yr/ :Z? hgcqZa  a < s  UC /4 ^ :Q{ Nl (W7C nd $[%]480V' Q ,,!o)n'L % J9oEvMK Z t `^; k #W Avc]u  }  P#x S }*g R  _ u bi~ Z <V #r= _dTGp1F[YR D A ddw  B=Bbv  % OPPd.W7 U q  R <YvC ! o< d%;(Q = 9to@B l F X dvPBI s|! GZ * u }Et^a l  W hW,e{)5 2o~ . ^w3& -2P\ Ibs! X a C ]{}KF? <Ac &;fa'oH \tG5x zTKjl! L \ rB`h   X-D[ rc vh9uK.F d#Z 5h B@ W MF   J /musyEQ6 EN C\\$mYL<UA  ] &9K+i|po TKrbyCD( 7 k I LC% R S qPvefa x J6  :H/ >  Af[6h I~ =MU 1b .x4JC?ThT I @ "n ? < 9Y,1Vv  0v F ;Tj sE3 h u f Z(3)  } gOfclK8 U oPlp}0'  FE!Y0XW }% %  Gi'FKMz  T 8 %R` Gb9 2x Mj]0 `x ` : b) `  QQuv{5QVh L< `hV KWM YQ(}U;1 C q%" kst  h Rh^ ?Qe+h x' `Gse'i  <`n/h`aE  ':'e.8q R  Vre`M j& Tw{IURT P` & ;_K BrI]HxB g  Ax! 2 wmC SSq NVc)do g > [ 3.C N3\ ;tWQ~ ox `#"cmS .Y 2 chzz@% /gb -"7! o K h 8iA=2Gq`a y  [ H w:5 ^C "8g: ] o k0 " InHtD-+ k 8P9a _[ - 1uI\RSC ~ Y8w Mg=L5Mi[n =RvP 8# dd0R_;n1  W2cBu2 O, ;Pg  V & #ZASq L   \ B n,U<@ Y~ V X  B (s,mR%X j # 2y.&d` x J '"c s'~ 7q4 i]/@ } Z4 G:B, w QzkBhzk00a F8 = i/ DZ4 R# =0 <F ] yhG]8!|86I~."xs/  E'/ &Zbni|vj d# Wof1fp .  LQXR@>A^} p c5}lc,8 a V  %{k} Y " ?N B8# E | * %VKzdm' 5 V  kD *G`   G7[h_qs7 } = XW! .)$FI(5D1'V] ` )B KH>BI$)',)Cޔ[  Cy0&[c$єܘC:i u R!Mnӻ" )o$* ] /IYG"uQߤ z~7Y=m4~~  O%*{xp$(4%Q"" ڍqlJf~`(~vqc  # ,tk4&  =-iLGRNzo 8 cQO I ) 8.33O r lf :h9*"v=2]f"&g[pS [N );*56to["y!1S9kiA\ "4)- 9fr 2ph ! (#K= }G b8'ܪ0K S'#WxM%t tO$x%c @$VSmR \*=s" BE ~%JQ4e Z" Q#y!UT / ?W1 og]j M݂ 3 / 9/8׮%zBj}%`!kz [ G n ݧt! !&Q[*gWH֘ v8> a %h ]op-.5 > &Uި2$*J  8`g| v`  JwP6Wq TY [,!MOzR  !!f;hAWzF0|% uӞ>~4+A' 9 I3H-v'|=. yl(ޒhj#JS# `&!._Eg 7nd#)#"}QF޴bj: '&aIGnI"ִ;-e {&t[Uc;.> Q 9"MMw$J)u!Z   "{VlWQ f 1s"jLG&+Lz ]I}`dW 2YB| 2e D>'06 =gVDP %"h)EJ}gf |<'L2J1TA ! "> aS^@k Z/f8j݊\nh m "(/ s3 V:s1`Nh73#fl 6Rb W?  x h܏{OtZ$@_ H{ k 30 < <Wp H:צ  G @ ($*"5[K"a+!^|(cS .;)  7G" w0Ufx" (iIdeK" .b>*&{y_yk D ie+1D3"$ OZa '< D h0# ' np Q#gXeL {)Pm x*.I0&Yyn" | Q-u, E pRk~ji IK Ka'Uc jc6 w "-E!"" F 0 .#z#@9AZ IH.JOBW @0G QQD{z=O@l<%% :z t P <# ! X)bP1] ,Y -( ^9  6z DnENvxFZrH24[ 58 T m0 ZD EkU n .kM6` }#" ' c(gr4^ ~`  LJb:y /(<]t!5(B   %'?: Oh@ {] m@X]##`Qfki 7_ -A@`J ݛ~$$>*O ڴiw :&hRmC!sDe@0%@q*7o N%U| L *Sܔa  _"y cQ܈bG_]G!%}"~ R#s]2#* V aJ~^*L$1 r_$Y ܁ָwX  #$"pML,l/ W wA z_hgJ+ K)rwHb}WOoOߨ.6 'i* oVm${1. K~Gx,[>0 -u Vr܄#j [#m 4vJPx b b& x`wrf1K]D@%]a`[0_ pHa6 :<%Vo D}p7O}.&"s mq߹Eh Y`"!t.=#>Qxuf[A)tKg@k&,]` S8 $!*( *݈":< A ;3{o!$m(d/W5vJ :S Qe 4># =QL>W~^Bgbp#T&J hޖW&y4r vM.zEXm] Ks5($:_ p-" [$wZI6$t&@&5<'403Bmjr iA TR f511kh}rx`|/PuB)H= d(A{7v^$#T LH?P HYV|2{g*Y  #RSz< JA;u)'bw$" (V%% \>Qݠc ' #Un  K?T&CW_k`N  R^Aq_:zt|B O$#ue5rlMF;  \>L xv9+;ak suS tsPQd nށ)O 1gb"# *Q$5ށ w!t@!=Bhs \lY1 \ EN J{v 9C\,13:F}  r#$7 r|Yp 8wLeL=Z a} n"  $>BPzF2oxMq/$ NS[6M.!# O!"0W s2 pWqyy lI %ERMS ak 26@h L"$6+5y< T-P vR@Tb RGV% p.kx3l ;Y8 !@9 ߂3 ir M"s%0 /FIu "3L<7&Q\OZ^ s+ UQQl')Y&(k :QH.^ !`!0]b\R g:! SNZn7 m i'0d%I( J'd;} ߨHis g!h"s/ p*Y' 1b78 gL" )PC lI'w4F }$ ?C+Yit" x$&tkX 4fۊhmpyWfS+iK(!1 : AL|{p:B2SN7 =r`v*MJ 7|"p Q%ެ+\7K `F"  RsSl F sFjI7Sq BW Na "![ 9@l`)k@ xh{"zO8)1V\2Y:GO\$ 5%|2r =g%&%V; qM%ܫ݄oZ0_]Qc (gT):O  e%`'-g`6H[f >L\B_ *s "s b  W]*\ 0~Y g.@p #|8n k/m?:T (0 " "Kݯ#g("#" No< z GF 5c4)!T{[A _g/|I9 j[TTQt^Ft}x ! q cqJZPNlA/qtS> ]yBRCRw5kc]n :HYmpbR"#'{ *N{ {y\3\m$|I jN5Eq*`ca djC*R"| "" NEyx3eb8 MqC N0OZ e Al 'H f,9!5z.h( 1$ RN^ Ul< :3b" # U';k%,s .p,HvZi G"@zy ?pQ.n_ 0O9E e$Q]Y xy; m+^ ;OMf x  j_6k4!2dy% 1E Wk 0esln=f1 )N [Ek0+ & 8g  xy" &.QMp5K {CY\ b8@K rZ1 gxs eU|P %-T 5 j ug {,lQc0bOzM1q+l u% BMsf?9> 6;@Qfa=  o @ a[)5[]2 _&R X#y:5- CV[x~n YjP }* I r&~!F xvu 5W, mSV$ Ib _. %5. V!o {MEZHtkhT9~#3jX  FI @=p?" :eA ;->o |R BA w[k q9\t`^T 5b tz;9 s: @_)1vbg O<x{zkS(L) <o w6Zl\Y3BU  lf<2b 5 ' RQb4\}SD 6DKhJ+6l o   jq1 VW lCO< 9 j3 !sI5pJ N>6"0p C -9_3N OJ~ EV _m7# 0\C$(B5D C/tb`gWA f%E*ba >UO mdE ]|2,Y7}8R e< mz0Tsa5z8"$ PHBR s/C r}zeS T W Mw;G!eg `Y_" Yd e fTa=FAu ILS 9'j}%ZP%_ qR 5Mu 4WWWjoj>xLVLxEv'J  3 }gF= +NA6 i(s+:" z>  " Z$J2>" (ukG Ev h7e,;E 4A4lyFa?HO  R*::!-p  l,{*P:!BQ٣-%$5' =&ضB Z gP;* S$N lC!`V( 6 .ڨ׈vT  x({!>E}tKGxj<"&;!-}  2 Seց{ al c#&!qW!G%p)8 d.")!]nm   S"!i _'%&$(3cX39؍܏$ P )+ W 8AbM! C;"d n#Q4t)V` & #& 3cP8 .#^Q 7 cJC@i $ @ /X7Y44N>(_*"B?k=+`(_  W!ov7dtWsp0&# }\.c K uFBmzQlr#!O&a E q&aa  (  C z{߉MQ ) n?o! WiOwc#f%q*u m  I   sߤ:`S ))!`=v+ A :g n q9Jm>j$m& Y"OwgG7 0c/v a o Tz#>R[_ !#&$ Fhls ; E ,d M/  e j~(ZD$#s {kn*֊׮"V(b + ߥ9+TDs { AgPUfz6L U*HNh\ HS$0' cNb9\E#(^KG . mGe][nAj {a KjoNAnk :k+b31R tnsp@>%/a - SJ)S#0"\5z >u n&;#9G%C)P;<  & I T v[aT) xM%$7:!56  N  HI2m9 6^[ 9Zx'"maww ,4tuq{ K GMn9.fEk*Ozc)p D|! j ^ 2 #sN}j~wu "g'U".bUm:82cY&sa=htf 88^Ie5E\CL% 9a RA\:US f d JUuV(4 f _{^Bf%u ? h v  M B]ra#  r (N$O7YS '} t $q(op!@?o" h8 zk H ) } U \w, F0 cBH\L` p c OmTXo'a ` 6!WI$ F 3- A H~4B s3po"cZ/CY 9N# NGQDO &pI:U-^$L&F gP*kl#4 t"hm3pFBa1 BFu<'#&bf e C 6 Ld 4G8 MLLyD)CrTU  a$aM T,tU [X ? [1Fr > sokb^J(KpZm Z +#}}N"_ Na/BZBB$nPX >O 0 hMSy z  =dFHz >tJvu\ /#(\ @lbbv'|  Fd]uM J#m CwyT+?yGd :V c Eu-v2_iHL"2w]MG~ TpOy Q,w#k $ j@]p^o c/ X 3t j}Rw.T RS\  ei3 {n 4k)j(j G+/]tH  h _U .$$f TnekqPiv_ =U ްU% 5;xm]; ;~}mlVh i`D Pws{.Y j ]ykYCU[$ P-;8*W' X]3X &Wp L^TQ } | Xhe4~y b 0];"?< T]Ap$ 7  ?O i`gz+ A^k f1V+ Y H+ V7Ke=F "=AYAv& v% >~(o @|Z -L  Hb1x^>Z  1xO S [YSN -wngBf@F :-e o !L "y| AJ9.  y F ?} iI P"M - J ! Z9gH RQt > D_lhn" D.EB  - j{0YWL[l Z/$ _)|v n1w4U = ^CIC "T Z  XYt  k B >KIDmCzvqU 6Z 1RDkO }\ !WZ nF5 >a8NJlwl s'y92a8 orT~ l5 lL6Ox3#@z}: $v_r2-  gKC IMY=r jt6> JN"\)r ]T6& t@9)1 g9Ul r & MNN 4WZH2lb j'F"%8 Do?S )AI;Pp K J.9 T$<tK]:&Co  f f! >dR= p6H" + .K")R, ~w( @ X w =.Z C "+nQo^A2<! ]Y% {r rz>R7?tz[o  N K<d($yb=*X\ 0xJJfE<r fNQ`  .K IZ= r kG kJpFc 6 a/Q\G ?i ?a ZeUZv _/ d9q{b t 72g 6Zn)gD+"Mx  le{O s  scn-g k -a J $'sB=C @nr <3/a m $ WbLEV / a$O}jh`LX1> OrBru qk mbw7wI|i j+v\z ~8 JWlhKs iL[~-p^ , -# $ :W,  d\ [ &6^ Di KYxt)IGzu ky5`^ j  E%PmF  / Uyf )  .^> 4s * ;Z <Vdbi2 0I E_b+l r'nZP e]} S nTc:0w) 5 p;9ks K,RFqj dbOo }l}T8 $o>p 6@ Zv61XV5m :g' aZpX\U& w uWe#W ~)`g 4,a0oS> g^ 1yy_S9>   ]PzrFe* lf NuXu 622| nUq\+Z .[< C~  xkym z4 &)sMga 99:m lCkgP~a pC{  n/` T=  ze =2' /Ci j ,pB|S P h y#r\y7njJ] ( I&v*Hb l$ n'[; $qU2  PK;p IdaD "y]>.;C e{"4L^ R u!| Ut*{= w (W vA+WBt B&8m7 '5w`) Lg ).q"J dU NNrgl_4 ;& Yvcgjg WIh 8UO]*T P1l ;cpjs ~ (Fx(i? 6w5 7*Y 6?0; :[i . q,/~ .) +Z0p. ? ="C" sfZ Tpy&VCR <# '9 I ^ 0&I ]Gg %UUm Fv{|<;h b XC sHbb W-xyTf E K  O.m` %+R+Mj 0"D -{UYA5 # q,?^EIq\ tP  pU?' w Yyv- k{  '+Q" (=t0QY) ds  h&yEeJ DMo ~{@ u{{O 1 MV]9  D fk$LELAn F 1zT/% o  [:$)<" D$"D 4IsB X3Ho <W0 ht Xu</@^ } <`tDo Pu Gul5O KVU> Xk4 K@b B !D|.W z 4 cv>a3zU\ Ie J qZtT>H . Q ^x\+)  ! 9}%9,  m _*67F  8 ~Gp   *Y4L[ `Ty ]>  |eVNB3` {? uLZl | C$ MRP\  O+Oi ? e. l n __u`ILd  hJX}g `= 442s\}\{' u  /&st1qn>"` [ /  X$g< ( f.fV Mw KrD9e 1R ~& dX@x K) p?WD U2i 8VyfYK!` 1OZ K)o k eU i/{d = w$\  { myn=( e@ ,z\?p . R N' lAt[ mX Gqz@Xlbh wF fO?v r x #IjPv}u p[uO ^;ukww7 io Jd'41) u 0 X~#m r & G H 6HY3 A orUS,$Cf |\<%D l = o (4 N juH}1 Zz 4`| xF m L3ku !X3 hJ>g%Q! ,() <} V }yHhL q 9 N  ]"%?!si_  6)\qr^f,M K%N >( Jy 0[qV 0&S nZ}  <v^^e   AA|={ V @~k$JthiK  QZpf'%0n ~'.ӳ3W-'2 XM ۪աHZBd/4/p7E!Z Zl43y2fxl>YV4&4g #Q*Rdpވ8Y/9 $$ *+gP7#h0)(&"p25N[GZ&""v }qE 7%$[h1 Y}!I A\ =TK 4, h(3'"GbN c# -Y#;t!U z Vmv_[݋e$bm /" "65,k\"u %*(- . &3ߕPݣU7Y*#"{j ) dݿ[x &^""  +'oPFj1}STk%Ekqؓ߉: O $!'o= 43=;l/SY s 6wCfC[V=L l!YT!} kd7;,eKg8l^J"*/l "|)Tyu!.+! ݖQ} p _'-$ YcjؘDL| U o!X&3!O`b=lAY"&|&JV N#C=h]57=\w&:2ަf4= 'u Yezdt^ V \%)! Ya |7XߍsBTy t"d#NDL ,޹  Sd#s" #VEtqp E >!#xncQYG a[I "*;/xݿьB.,mc7 vyzٖ/ \##?!x(ݓRGކ<  CQ Q8Mߘm'B>5UBFߝرc (Rg%ht jaM0$)GW_{% R_ އnr}i 5 gtfw/ۅ1~ ")p! Nr@)ڵ߸NH[ (h%" -C%U&*]/S7 ۏN~M vFG%,!cA ;ٚ߶8%1G :TI[ڢ\ ] Y"$9M߫ܬ_P$d%[VTYg^hzd8A;7! MnR_h;kl (o"  y\ Ebj>Z'%PW|"ܳ|2 4$%qsL'g\B1C2 PL!I@E d]o=!!d!$" ?[׾)X ] #7(o" L0t#O6H .)!( _xk~{  }-%&:vx?~fx7a/`ClG9ݮ3 } !J SGAJU#P `z݊ޮjl &\% i VP'&> x 6$"!@&ߗې\ Y "c 2.R* Y  C=1=FN#;6c\ FoYJ !!6 PbzT B *o8l%*b ?C7@x R*= tm!"!w),urp/ ,&&/3cYm݅ wE!$! Ngl`dnG8 }T". qF 8(oi "X(AF TCCQ D9b [5vgo 1<nO w >Fi L3' (&P h v.&F*]]j `[[FUN m ~1F=/ M!&)!+1V`!nTNX N&(#&V?]@=58W+P~]M Y]Tt d) l^U y6V݃f: eg!+ a0~ Xix 9O\z'n o3D$ho\[] 1WX# I%"c @ 'm9݆ޮ+t^W -#`#{ ~4a {Wv &X!( TEXyu +u#! IxݪH _!$z@ z}G>" "U | 4=` EW 8g {3OAI J '[x:0a^C"& #Qk8ݱ"#- wr` ^etvb*0{J&PwP+ $ ?:Q5 $z`_    CAFw.[m[U 5{p #yzAV$ng!! Uz6jqݓcs !,#Y! j,t݀ PQ!"< oit;s>\1m H*=kM=""U R a5 q5ZW[ q4)67V8   IF-B -!" kn]Q] ! 7 oihi^[E !"v! +<,[  \F51 &@&sD}j !$ :9ݸ#P{ A7$#"\Wp0P #<#pq8 =.i hey YwEO 3|&_t0ݷn$/IUS q W z8+ ;Wca4]F Qa 5wA@A>P!# C[ qZ< ?{,n 2,Pt8jVP .ih 7(HU:/LeH |  dh= x`48H|Ns idocލ2t KE$L#Q)1 جY) !%l#/Y T`90QQ{rbQWL4 4^>= !U6 J9a F0y H=S?k? PB*-kZQ aapZ1]eU h"v + !Wp, @$!Xd p PoݼV x!\!)k =q,eH "8^1! v?#N H"Q!Jl/x* o g\ww0XHijZ@B5J~: *Wf ,epIn >LdGߣ-':d\& K2 M5Z ,",7`jKRf Ki =6.CYx?\ \!4#k$!eSڈyBA "| U srY~s T 1V _Y+ z$R={G9pV EC3} AZ}9v =xc&HH^ `"<)ZMV`oLNx.<U v2i%/޺IgX@7$#C R kVߧ/ *! ' |FYlm% Qz ql ~1sA D ~S-uso HtU~WqNY hk_C?5_CU "e v*A*O ::+{J6?< < >Q ]QZw^ p1)j 60V/ N +x zFOq|v iI/sk N*i޹ 'kP 7".!MuBhD)uC3k pD "Aj$v$;@aI )Id}: qM j] _mF=a3^pUz#n,.s3TP42[xs<` 3Tr>}W3f5rkk Gih]G U+[+ r(zz}';Na? 1  n^429}+ :M 87Lr8a S+(&Q0 T+[3XX~+1@2^{we3 hOzph#N 0*>z(coSWB>ymC\!B!@l T< :2'MF72 BGk *pqZ3 ? ]N YkT ^Rs a .lp |a Fr&-A) nT>,98M!s!L N@ݒN S EF $xf </ "PQWG  7`OVh?|\gMz &| ET=".H }l zr, fF%HHblb{KOX 2=1k  9 M _ i@DsFA;LtL7VR4%t xc\B }lc<( oAEw !Dt|/a  |^ p@2((; u \"! 6PgުHh-@  5#*\0 p55DK r9  Lbglfn:DL1i 5t9~ o@l TQD'r'pph rJ{SaNN I5#  1Z o7!!3 N:e72 GU X(w [,J[ , a WGaY  jEt )^q3 hw~Z*~xQUD &mj dRrT$\  6 x:O|M "jt8f  OaU!9~w=Km c [ 4l)xA+QL-|BNs;+WzUD 9V gdP ^ xClkmS3|7 9[ 4 d<<?vBYw[Y 1f% iEDgX>j)u m +Zz> cO5 7 b,zuNaFg`uY^M#rgR0 g 58 ; `faXv r>"4h!t` B| Z6` sI:j; ^} }G) 1t6r pCeVGLdr +} & { qXX &U +fY N [yW= e|g  3T,>GqI19h[&'[{xG?' k)Q%$ _E9B'Zu T Qy Ih |]fm][U |6 }_/TWX&t0 EUT 2 7MyF$߶RJXd gT)dytzB=3@T B\UB19O gZ k*Ua =WPvuQ'DzAp4 E&~C 9I 6lm \Sp :KsF = :U+ /D!r   >+Z:{e >\{ b: U^ '2"4 ']!m8az!  ~ RwxW|j ._Uy4` FJ v ?H>1\/ V8 NL%/LM(c c?,Wyw e u   cr;9KQ$ Q   nd0 Y.q>ap/e m+^_y =ET TG6 W{}^WE tldg K?"F g!o/xzHk>X}+wf&p\L,]/  $CVk iX _R _x)7l|BF#[8FM tD4W # B uP/;6 O_G'6{ev Nz-D*m8 ^})K. .c*1GX EN q^xc &S{0  WKW +1hA P 3 (?612#EZ W}C g|^RkUj Fuow}#+A@<-H'2Pg L_( Gq` ]I h!Wqzs (6yu0aY4vG  6 lK .MJ, ip j/O_ )Wi[kH^ -K q?h=PVq  W0fG 'p W//o) =-Um4 6+ 3KLN ":Bi/qc' d0`4L bFWU 9S 8..7])Z+ \]KL{Q< y {1UX5F 2 ur33*z [=Gl,WE7+ i}g  iUrK-&x4| i*8&j MWF$}$.H@ he (g9` wfq.:)={  D Q.R b2Yq @tK3[W k!{E7v4y P]k{u $,eJ4f5V+ `13.4/k0[ ?&,Wzq vI hvrg^Q7:. o U-;d0Yz< fD P,,1 9"%b /Ky ujhC-b %c4yO c*ua o$3 x OH lglyEsA$Q ^FkB 1Mj {G  9K. y]eZS+dV=B !Oe ['uu kN+7WwwRNa Msi 3H' ;Wx xa%:|K \~s V. U9 ftQNt{~ 7]\7z$uX7S &!eSfy`! \;+ fJ\iM@#wP$ 'Gf.~^[>z hWu73 &Cq-;h  6'' cCY5Q ;[ FX B . kqY: g 7,l cL  =v3g0,. id@ hk\w`\ w2 z)u H?8 Rm1!(*=Dp 1.d8=Uf94J xT,L_/U w{NCKs W'1av +P ,R ; T\ : ^t}\ {4,b?3 =P]/ } }_25 Q mtz9S4 XX2ak [d{*+} W8~ =taeu9B oj :7@eKYT N3 l> W p`n| 9i Oc ^*j unz ] tU.lMr J _tbQp {,.] h=5Sz) ;KO1 "K+B ~ 'ipLPL,s -@xC+E; |pm Yc6-tos d OezdeC[9 9Q)ePZRFC?r La0 d.Ws `kG; |7oEz +'y 2b SDjJ/ Ph4^  $ 0l nO 9 'g M @g .N4N; skE5 I{X^CRa I #;z@E<*. eq(:^ U2Z`+SV |sag' ~IN)ikn'O7 gg X lNXT ' 3OtcA@ H'cHB I.mI1l(x2 9 R =*{{*5Zx   ~e/m R-',G -kQ!lo oTx < ! %" ] n7[ 6t@ +Pw w{O fP]K1q@P   u?jA  K\- 6my#x>~ iR}  Po  R$S T nB*?\vYe N< d(l%~6 "J v|/p =^7 ,#%B:RZ [ )t3 V,7 Hg '{@mX\PGO% -R/4#^ N'0 ~ eW q.+E |0t  8@.7NIy-S FH_O e:e] JTQrq+n   ipPQpE'x FSm XEao pZgHj(=: g.yjZ(EvV r: -nV?vyL5]z _=mwZ iqG6O5ZV <7 =Z}{ ] o mM~z= !wT t: ;Ss>O; WLe YEK6|: ;,V y? ]i H2] " O+27Q_4;K3/[  3K u'" bT ;I ?r ~@[)t 9Y >#se  ,wFv& ojd )iA| 7q}L]&  Sw"b"t|v v y  0 uKeH =-8c |@|I ?q_Kh^+o Lmi 2gd@lS d.( 5u1N  3  Z*ONy) jye V&wN Rk CLyuZA,Fl @Q`;* r@)Tvq ;vAQ wftFaSOfW [zNaMfC k } @B1@a  Y &0T_R> inr.$]i$ U$gz[E*+/9 ph F ?}m|> |C  ~9-kf?: 7PLm% FPs >e]d7 -g$ uzZ Fd O/c c, ,.[a( &Y  ^(?N/qC[r pbF ^c* +a,& LTqV F7DG5:Xl nk  #uydP G|w VG3-V +B -AI_ k "^~.9Y vAT LUBtrJyCD@ &9API ! ?7 {/YI\& $ @9 @[`O-d 70 DK ~eek;Lg" m + in*, O(X\D $|(J_ x /!CNpK =V \9U<u|7Y D'3t_ oOiXQd4 <U "2/0#iD HB~' Nym&Ir {{j='EZRSD XcD 6'EF? Q0 7yS'&|2 |OZK S, &aA;* i~L T _\`6zX&R @NT+2 > 4'7A -zm[ aMG'w.[tQZA-|t$c a,!Ov_, 8w 2l VA[vL YI F5m1WLK i.#0"wZ|> frYEoZ S6U ~iWoSF g,db g M s$F PO!*s7G @R4 o|3 F $~ 9F,\t c3 T(;h` 3N \L%8OWk1 =_ <A 'n ]Lc} QF,8"t@ Ft8O. 7: 2H[CZ=j C l_ 9 umQN R6%kP B 1M Dy"&hzJ \ r.n % N gt<P_%@ A*nSo . Gk}+Mk@ 3n[Q lf ni g_U+:b$ a@j) Sk/Ny /\ qa7xzQiO ,tt:a,T &Y{  g_)  u<=6$g6k Y| P F&aH :Q' wL~s(6R ^<a zRaN)t{n  !Ku@< 9SLh\ GNV!w` !i 4,RO[ ]HA }@O }"{PK z\Hu6)[)  E $? JK` M#5 phB LjbSm a6w E2Z) E \k/` R( #h<G 6doT7VI# R4 ..fG + Oeb '^l.eE F\q ~^ e wU0E Pv <i t E WZ% D9+(n5i|+ }@7 k,R W:Ep1$Ov W(D%U;x >q jZvgVXR Ln ;Q "<+qJ+{d Y5} c %|b:eH (05 8-o! r4B DaiZW/w. F wE^?O SMCD:@%lS >l' uG:%H Oed\> u+`Sh CO o mhXUg ZG FUgP lA* mr b[@C { xm|@6G5 o ED- 7T')7@ )=~h VFH^o 5yn 1VF.p d& Mn7z a GAF & fFEk&y| y";"U = , k'C iQ#! bk }\ R$4 b6 *+6 5dpf  !c FJ~;yol 85 A[2s*' (< Fv=O6]T]P! gR^;S ehrXv q"y :L 3n>V#X,W } ~#Y(E$wf }U b QcIJ2 9mA ;d"rVHC,gJ +n _wvqw!$k; ]7 O-3 3, ne=%'QB( ? [ 4s:U'  9  N/tv$L u h4 ;(ywF F !5'M9|zw Sh" dR@2hU} | zW! _2) z TU ,jl kr^uj SJ, 8i $s- ]J* ^Cki >vy "5fBOx ^:-hUq~ , hU &# rb ^g U A:8HC . ]iW _rn s Yp3Zc %j jhO] Xb  48At^dy Bix2 j\W| [K $yc l i ~ \I(LS }Lm rctX,: twE Z9gstk  uSawC W acr<9 [   x3j Hg] sfO;bF jPZ IAI >)o!Lp >5 2y`;e :6) j.Yr/j=  \>:9'P|  0fiGT ` =hv80A@ < tn( f%/BBd X[d ix @Z5i  ?pv<@  ! J %Lrvb*gT$~ @l Tntn $z # _pD 75_\ ' Dv.;mZ9h  3 Sf)}vlv Lg1 Kc Qa a lCvM X c* p%~ 3{`p1/;i,Z 6hp[ p pp8] }: Sf<#PPI  3]h} w W%j}-lX W#T `~Ve=o?Ce q XK 2(1Ja7FO$M`x5tJ@4e8n"ּڃ Q  @ Lk|&ٵWϣi' oh"w ; &DFa&OI Y$V]4MFef@jZt1F; 5"hd   -qtbJ(,I  ++_iR$?  8 (RYe ${ U/|?c. 1?|U% $LX :xR?$A/  704usJ^ O g#`߬.ېh y i$d%w' ݷ i C@&o q!߲ڋh  > E&~'g On &!Nb'J?<=-'$'%UbTp/q׺h`e >0(9 #[qZ *D  [?n 1' gbw9^0m<j$, B" b]8ݴYvQ x `t SMI L g 9" u vu QVH5)2n -% ~uYT\ r !$ 0 z"Q:+ J uiLzc-(t >DHB(;v8 / sx M%$Uۄ^b5$#_%]}EUCt^ de## @&3۴7v6*sXAR ) jgLD3~ J[pcfewf+ I `n/[  iI S+p-i | 7~!0:!cklZ\ Q %]/v [B YpRK# FX / j\I:WJEc  :z?0Ig) ~ rG& $M=EFڊ/"O X.7OEuAlvq `_gQ\@ W c&h& /7 A(?NG/,+! XE( p" V  S9 1O@ D  J;bI c  d6);ai+c &^FE~X  89x5C( Pu$'1meks4O {'( b?25sW |lM, P.rya|3  n P nFEu% ty?!U6|Jݟ    ."-l ;5t Gg 'V MB J-Ow ZDtf#c@kO  .3"y/a {uiP*5 2 \ @$rodRY> ; $68!*nuZ   : qv((g] Z 8vwEU\#DiD  ~ "}+V(M0@%< eDZ+9[*.z{K&j# i Mw5r)}TAFy~'  8 2Ml Fo]'r  d|=s-Y} 0f-<. rr.E g VA T Ih) = *RPNd% EDK JN!JemT  (T AuM!"  * 3g,  @e9D7s~%l# LsRhgk BaQ`w P +E]pDbB sM C+D2X K v ps17r ^~^ I/,  , ft-Ztw a/ZLV2&*}l(9 =g ll-Fj!jT  c n  Wipy n # 3 7`"Nz%x-} Ds {VJ$`Sxu 'N-rp9jp!' "_w;nM7@   c BSG} hf}0 /#>U L%J1\. <*o(D i   J.W!r. W g$b9Rn0xj | 9<G R! @s'WqGz;% TbJ=z=p3UY d+#2l}"sIq1 =7 '&p:*@_eM1P  M t& 'uv -i#t/ v J 6x T snW g _ k' _=rj@{ d  'J&1Tq )2(>j*l F/Ol 5 uz  @ D * K;"{XM / 5m\ q`+ Bi>gNRP)   nbF?IRdQmW>H|C b  5N+^., 0 } !z( v|. W| CA: mq 3F#I` = W 3To 3  :NMk"<r* QF   VP ~ln L 51U M &v  VE,0w9g Hf  ? V $cz*Hy d|M-m b@ q5A Mzr%?GJHi (EK %FZ/Sa+Ht ,]+$jrt_4I PGd + kU*_*016\  La`: s.3 SS  6 v XT] ?%i$( QClO D-Ry(<)=:i d  LIlCh5 3m+*U ~ hg T[. ;/ , K=u|' XR{-O^/ &:3 v1en  b5t1 w : :|  S e #CaO7rRKQ G7H/yJ9 * j$j . Q f = W chN / #P5|IK $>>j *Gu E1 Ietj 1IHK \p.E` 8 T )5 Cr+o; _[V2Qn\ . ( }p c Jt~ UGiXJ1L K *&%R s K U >AI^asq E= dsT2cjU #HD 4b,f3F1]5qIm;u-[" 2K >!O* Q v Ps(#sc j e=N0}M n N ^5 )&Y3xw eVo ~1yqz E <l /cET' Z V @ ,/M|5`K M Q7sotcE5 x 1Gl P|, m CFUC9U0  D;4sY&qt# q :  )fyQW~A[   n&{W5$ # v 0Le[nix' {x25$< Yc  i>C)   ij H*qi/ L' wpl  u jb OzUDQ :k3 K) . i'W"/z IOyPoWHu g~ w:t`u.u V L }W{ 1ve9 \ ]k/Vq }t X,K d.JE`{,E GRF0 I / Hxu%3g 1Z ` broap nG2p'X^? e [=d[m  ) <5qN? g )DL z 5/O\ kLI X> t+s #FPU +3,%tgNS& n2k(iN S /S e 7?1oRU2 )B nE/k O 4/)sXK`S8xB %/ PfIUm R yK)Iv(R ) ) 5 68b|TE } < //G>]%eQ%P UT\/Aa4 c30A$e  ]e[ u  `  #,) 8 _ ;QpVa2^=UH# . y `X_h@+/b 7#Oh} l 3K vPaq+,n g@ @EDxT=.nR 5 1}9c  6@9.smU{72 !C#a"w`j8  * ( A PMMQ(6ln P pIo= N&RI[   ""oI9 \ ib 74OKU }  oUTPS[  f /8=[,w,EQP#@  y hcQw b xbQzE@K \R, E{L y 8UT|adD' 4G[ SS^UVLdb Wb SR/ 1x e0TK? rt> HU K oW4m &QLEp[   1q# Lh ;[F Hh &@ I>>3N$ *nA ?l cG^cI , :r\ 7 u Q _ eor3 U s) O{ nb;V_!J+! nD[E: \* >  '_= N8 \+B x[[ O C% qsW rM 84"j .%6:Zb Dj;  /K&di[}v V2X`  Sm] ~ rrYl'  c G  AK}n: " N.4b|P =w-Z( ,  !2Vi6 2_& D 7-u c t gjD _ + |t5Z^oh B[ 9Com\0 ^ gd(HO0}z= . _X#tL!;F j H 1 }9`2R ZFAcCg jS!H5,F{wK~E p#$;krgr E "dc   u Nip0F.E $f )L7/tn! v* mM G 8 1Z1mF?{ Q8a'3 Y@ >bO' + 6 u5 Adqa  A vnHd_b 0|1\ - \40  ({ [yn ? }PB 0= P"sX1  @ < |B  Odu xy|q tfP H9 W/I{0@#E[ [K yrn+9]_ o #  1 <c.&sJcP ` vyA|;S g ~"&_2 =YXI+ T64|U0G  Cq V q ( A\}N ; x'  * <u}_Os kz # TNC8 N beo2 h  & : Z)p3d4R { MV<yOG: q B % } Lu|ERK Ld> (Zk x\w#*z8 / Rf )"JY@-i $I YYS_.{R [  m )WG? uE 8 IK$cn' %uErf N5d m >G2\e \  r r@-AoH` > G J5s! 4   N/4. W&9BX[{ S W8TC9 J _gfJzTjDE[ a) # E[ I?j@])$ OS HD9{32 x I $fz7q @wn[z u   e XJvcGOS z   7p~q8Wy u-jv f `\wiw HgNr^?HoYn  ic(\(Pq X*~}of*sf  l V+H G U!=G, ^ o ] J\yp-g/ 4  o?+E{OW { }1eQ8Ga  W.zhj) lm )JAcQ2YXj)mL3 1<j 7$T7Bp@s |8 r!~N / : Fylp]1 \   /n?=  ( jO>If em/ /OjD :d,kI > Io 3o  < : BdT * 1 n  ZDaryYUx1    oHZem   @ zta |pG- U 4(8.973 C a>CP A: M;)0bmk a E CZ) p T2xOd#<; < S~x RU  EBqjk m f  ^Y$(B 2 U 4 oY{H!  ,5M fOUz QSiO A 6+ tuie   *%&0;n9 K  o?R.m3m \ ./oY 4^v~q %^Y}ZPPOk ]KxE T(9sJ^xp ;  c5C,oIpp [ - uot-Ce; ?w NES~uJ R! q<nc$ Y U$+Sb" & .i0? # = yM 4t a tl1 z= E c (H@ = Z{`DKd \  Wtfy: t uQ(,*' S8 BWA]%Nv i~  /C5 u HOm_=  Pj\SQYx!qO: [ 9? _ Hv[?)w;3o 9ZKx" uS ZN+5_#D| < | ,>x6s p aCx_/% y \ ^u`uWMF ]J (W (# 9[j' *l c?y O/iJ 7  4 5|C!Rq ) [ U O(dN5 B )Im IEATo {  =t]Sy'> Jw% /v`uJ. r l W'|Ve]0  $9"!" 6 q L AC, j}qmu EXQD e=9lE m` G n(W : R71%>  ynId]=PVv  w F+9 c nNM _[u6^ =5 8u{;  5 {QuQVXalf p>Xcf N$A v  ! >AMK# > O : +oK/1 "NW c{9HRlM{ uMv?w # h   yFP+`@A S-E _ij0v>. 0 \_yN )GG j u7Q7 > i 4UNc?zC X x _qJ D 4 rr|{1 Y  PG g9v7: w c @ t}BV)Aa K#]B:qG @Q#mPB a2 YilK qsv. :X~8 iVdd ek; C-N<Bd  ?-)7r2/] N E  - S6f- V w1:`a )V og9,[ Pg6Q #  5:&B  ;  u[94o% ak8GR8 m Ha$ v A!N Yp } WY`'c &ds FH%0Fhj " {}[1OjP^  &"k LtYzc 5 F O 7\  ] N U?xI >] yR`n}"o W _5e'{J[8v V;ggx$~;;   *F9 1:, r 68zG h w! w+ WBms% 9 k \aqs 4 J>@ W@zvo 8 ( 5 K\Xhpb{ , a :S- Jj " ?7>HB > LJw_bX_ |KC+P%i   j _hMMahl = ~A~Ib P /o  g\:26 + " F1Gk m1me,h] % # pl-Bv  " A?&@j n I [ ~Cc< 6  3 ^* 5= c e RD,Bp_ijC6 A b - #JZ7-A%V & b G]X2 A\_ &j'IdSS x l|2rn ^Tk&1OPjS~ 8 ;]G^P_@   F^5) c iDY G  \pJcG  P:Vw}|*] ibONWCI\ o#f * 7#'`Rm_ || ~uIX iGl F yF8hnw1M& = F9i0.V98o=U.?.&  2(FK; c[ K ,O 8 L svc\ #4 ,n |B,AA P )f)Z)HBU V 1 - C&3]5Jg 8  k M].l X 9 _(2 -tU  x Y z\iHR"%{2o)r;wNc_fOU^@ 4M $C N`{eU~*y9 + ^z@S*jNT <= 7# F=0,< z  @)T1eV7Ef3BH0:"64" $ 0 R }:B  1 "9D.ab X WE1Tw~ E h   u11mk>xw).:OshK8  Y 9*=!@ ao E < H ]9odu ` Pl;d-e" : 8o&Z:D~LV5j9\r@uE_ ;3A#= u 5[&fb  %{ J   ~KtFC= b r91_+H=d .  ~0Ep B~  vHt`Q k 5 m (#F~h | e]v7ZK'5}(arCEt HBEOY>Z~ Q (oLe7 i ?j ndef1l{ 7 =rin`e9@TIox9U@I. Y-S)t!: 45 k  XU%dU*  x s Za[5yh nW;3,|T! GoCa<9 d _o<3  D " IU)u][ g-" cx9 = { .aBI AEo  L l XpzokE>Q*v4i>  ~aFv` <7*E;d {  >Qi 981 V p lD^ >mKKz9 3Q Gn! (# R _7[De& * I uHAyg+b` Bi ao! vC l r v;$Z-ODW~*X L3 P 6* RF8 a 2d+~x  _ Msr & B G Z3W;s2" T = - E~S w8<R? Y5EfX @ i ] fQSzxO4j* m eof6Hx^; >  uYSm ca6 KJXnbUi=qo5LFvKk  iMX,%u  SoO  k a %% _ b8 coq"RR 9  D_vg#;~Nn^/v^#  fxG D _{`-? s . { B A$K$ ] > N{F O= w vO-T)GuK$oUH^K:6B0i { {V`>GGnp } (8  G[dPu& 2 =tN u 2oS;sPc,Pb3.?m1:E/ j  hr>Kd5& V f - ^'#! v jSdXvu,UD  @= @FaXE!\e 7 l)<50T`?%C I z##, E ,+| Z  8O5!u % A 6T;UV2@:zA(U#_fxD{toIJk;2  Iv"jnH i: bj > 3 T Jdigv4`-> x ' Z^ii WDr]aAO y 7 Q3m\D5T z  |aE1!(} _,Q+@~kf=9d$Zz.C($l elWP~v-  aMP4(z`c S 7  S B6H| h M  a++V Z w !jJ(;J  ph%sa3<3RqQ18RwT]u~%G "ZlAdY! J M 1v0/IF {pggpmn#Jtd }?8 E=hp  s \  [iF?7R D i bQ ]ch r D G !e!(78d^H(RJf,kl2lf~k ]  $V{>q ? ;bT <P, ' AjNZq@-Z o  G/! 1$;+  JmWq5"7 _ 5bW0ht[ B  2  _ k5])t#l{" K 6  /^uiM&K5IVvB` 0e=T3+|T6'5K' EAxpC  F  Jp/BaI  @ [-'$,e^,  !M_\5 k qk1$YoF[k B 6r@ i &y;,k,X B 69^ ? w)<4rYF3*u'A )qP9M3r ;@. 5 y o1}iDR    b|92GTL*  f & xU`j!Spm.M[0y@@V.g9d }:I3 Q H  picLmL|Ze w AzlYK&o Rr#iX69 9F  %v{hwq } n p=o<  C <  lz a ( D ,gW%(0 & PE *3drUFr DK3g _ o   ^K" O d. e/eDQ02I  g cJ<#I-`L=4ZU A s$.P|F| K. @_?<pp e ~ ]0}{If` Pn1hBN&<7Mj}xC3"e]L`/]* ~ y k MRi z%$h V " n6|^   q OhnU KTl;?&|xz S 7hUnUr" T J  ~b?^8 / Dy""z= Y54+'AcG5.^{l) h #$+2|ҥu# #Kv=A +i ^u &| n ) bn[sQ]Mzn0J 3( \qg%_PDt'/"q ]  #JRT e1$S/Obbe P74Z~ x<* -P':<mS~ fjw 7Y s;{Cqb @!Z>$@03-|\ _zq  wK0S| - , VZO ~ cQPFfޱ d""<YVbbo ON Y?MI/N2bQR'H;F Zz `vmI 1h;jfQ Yl*APt\$"V% -rv4o^B ))- zPQ "@.$iQ9]Dlq+_  . f E5' hf q^Jkg (9Q *Dh )s!;A  ;Z1MO= @^ u }$ [u&~wuK1 Nz9- FT(nHJ~  s9/j2U;bK ARP d #e Js % &bYUALjf  rP:_ TCu -] C $p{m b)XKpE! Nu-Wk0JZ 1 0 H~= !  Z:~,"9 2   R7|CK  }K}S{5 ?m:Y n} V>.D7 2Y  7"q&G\S ? ;wRg eLBBcj < n}H l9  a Gs<R K8{ &"T <}_$[& ogufC i D i  (<T Z1fVSyJ  `@IJK0 }IAal F  ^8vW.LMh $IQL$%0} #m F Z ,tr ? gg?lt>[%P \X: bY?<>gN 5Ohd 8j@rSI p:N2qc3x!E W="k   7c}6 |V i2&OK [N>G  \H)Q~)\ tx"~y_>ZT > QH z  r !9d3sG R=$f  Nsq ug4A2o  7$  = mNxt| jp%zh  D q" d#9hY{dm P:LTWO 7V"Q]$a4C dKlKq: 6kbhqvo'Q I4i<. @VhlAl qe-A SX KoY^a> Vrysg  \ y &koP$ MoY> LIN? U|hgKDo m c?u? kfP x%plv[u i 5tP`Ogy ) eCD"sf .?gI/H 4b#b0 _&jRiZsQ{& o! YN~$ F}9po~P{ 6XA[\ )q,%' P X~.'(a~h*P)N i) TD a}6($ /ssrMWk p#'V\H+=}[X P'<)MN_ >zVL2 6 :Rg_ Y: mF=za a~]h_ Q 9o3 S< C 9wXPJg[a@ ng x^0}A^qDsIy Em :}Em> 8HABr{ YL(QJd9 #> ?D/?  '@>{^ 8ibaD*zh8 (VX9mGI/\@xX< mSz QMC2] M 8F` i FkI P_  PB#s58 ~& ?7y Mc";)f emq< xF%p }Z 1 (WRO [@N d ttWO E{ -zB -8g7gtv J +O!DC ZAlD uH :3ZT/& ] eY;  a5G#\ MEYFJ j[. `  dED CjiU^ C &[>}$M mB}-6 C4GNU e _ $,,Ly\ |kz1M J QL 6fTqzcB ) gO Z_}+R . e/f {H l|ye bI mE4 Q]KxR  FbP#7 Z=; e7<= Arn O#SqXQU|`BeMt 'Aroc :-x2 ! A EP[ 781>. HGC MjTw:go? o ET%2i?u4 ] =Tuo\%Gj u {cE2&c/@ ezD _A Io *9L 2 "dF@&.JTIoC  SG+ 76m^ Fo Nl^d 9|. dOH]b kG;=+d_ \:  Kma{X a:o bZ MC13!yNm-HOs)WD *;je N^Q+  C!~A R  WZ%r*?2dziyQ w!XQrqOCN > rQ l6HAG I )am v5Nn "&~FDC S")G5k[ t  !2ASJRElq'cX{$%  in  RQ]$G~UdbcRiv889 Oaj YB Svshb ; pOa klv, gwwzYaa MqHi<*K?;76C6 :?@y |_  @J/%  {DpH(A ( i5dGo`FI T;W6 bVL?@ ! q&aCU['#JL{,,B( R h% }ZS\'- d@ '{Au# gE\a9 u6:5*#>eTSs  C/|MT*HqYf(b]9m k#@m$v>#{ I @=Ly #}wc TxV\Gi "l99BOK c?s [2M*u-3fO!7 Lz IJku 1 Jn}~  \(9: bw _.qN"k I'ldloc V(YkO < .D?zW  2Bd0= > _M{L!6@) k:l`:7t-YJX 0| #OrHC 2xT'}GOCbU,>1\ 88s; A`64 VDC eo'A ~= +p`J' N9ZXFD y  Yz5 VtaR 3<xB =h1Y~" r= f6i eA- ^:noB sr"+xi=S&` oE #= ~4303 B^6 7W uSXqtV{ Tn[ d% gS?e L cr0"I0Fp. | `Zfn.E ` E+#;!lL. @ E}TzeQ=~ 2(dk CS{4do #$ +{z  lCH ], "I7 ?KzN!gci*}c+lhq=R |]z% }?$f n\e{v" q_Ja@+Gi NWUc"x > CC: 4g  C2[t@ PW @tU0 *  F!.X|  J 0R^| 2E?baLz ' X$mB 8n#p FY2R  4^Ft[>)LCw=D 9 *0cGN ")|Bn f$g1yG~# Ns ey`M@Z~` 1 o ( % 8>Kg oFsph ) Re4*d_ _N5_UG_^ i/F`?p? >N zy0WZzV@4^L aR0vI 3CiLrt#A[*$5_84 oD+6}= Ue/]$;:_L HQ Y$Wh  x> xPvJ N!0}4jb~G5 c@G   vU+gpiOwbg_ Bq \*Bc4 4G6OM ,iO=3U'1 @ c :##c? w 9pd4+J=x gR a)pk 2 yB"lfVQ[Q8, cV,:b)p #s5^Y4  9Y) Gh S # ru;@&l1?+\ H*>& o aKn-C92G3^ mF" 0  "lw+O Cn I w7K0[o` 85c; oK \z_p3fC. Ic ?7 i Dy &+@fC^B(Y9 5 |FC_Tys% 7b\ `5?O k 3oDs U  ] nh  =" : w T(JHR$] | ,up E C-U1 A xk~ \r J%# ]1 ~dZV">$2 %3] f-Z~ { R`3}[3%ilRg ,# }, Wsv!b-W 4x :L~- x mb 1+e+[k..z 5T 1L UY 7 &}G YXl z8 N )LDV@V 1 * g _Hqj h  [TmT0w(9 ;-i 4 U  vD4|Q3 ] ZW A6lQr t ~ l}Y3;KrO7"yP=f *p W+Rf6,>=   v/Mpckc   / ,H|~1uc=@ THD  9_@a@ f/`- ]2= *<\F< qP&j |CTf+(; )p ^$fx #aN__ rY'DPD x H )]^j"1+ g|s VI KiZ7;c=H {;pRK? R 8y[ _xX98E 3a C>yIKv2 >Y  xIq  {'2f\  _lz#f ) [%QOuO{B y U\   6@bP` i^`Nd a  T!){ ] 1AW$B0Y ei D+Y  E$K i&E5( o5d  .SdWyEZ ET x xoG,|,* 0{ kTg u.B @jlgR  &L*Wd I | Z98 Tus  oT B /D  2 T U s$ m#)"4\ t5IX-K0D >*  ]m=$ $k .92Oc n z r]' u fYL'U9 F6*II n q7{ Wp1"yXn XkK wTET/j = k~_"I&9 n;m#DlaYQ -<' uM1B h  pwt }221CW97cQtR@p +tNd  T W#:@G m D_Xlur Y R,/+o n S@G= ]I '? `( F T [ Y( Y P ye  j]y^wK@u t 6u3n\ y  ~Be4 6vF2b !CK [.bL* EAA7\8 IZI @|k) .0)1 O } c E. N"XC| H )& {!r.4Q oGFrxIhY Z?z~'A1 x[{m:tX7  6 +fp Ke9B T? uq dCz|# wwk1DT[dZ, ! rB% ? t  .JJ ' /]' 1= &,L_`  !~l;2 o^mf G \o_ B pU4MUPw ? !$\Ga\ q 8C0" u N>tqk |.CI; 3  vB@Ar s& X,.  i)? X)rm & !Jr{S 2L+E  P1O 0> yZEI{ * ~ ,!FzJ*`9]i&2gM  R#: '{  .8-" +; 2 d,PI%X:Tgt$ Szl b ju^% zS#^'*  N!9T <|\D8  { H[J)6oi &N?5p o DkZL`.tb&ec~B P0 '>{ # D 5}z^v7 _CV  RJuI) r 9  q_+q | TmlGcmTfw@ 2@Ga * L9j4}am R 5 9W9x @(VVs c 4 cyRHUj%# `;  ^o,h6u*9s  U { V!,g fg| 9\7j<  p,v,F \.s eVWX5 WY3  H cc%LlX X q][2=>5| Py 0wv5}  j{k==Mw)Ql e?l>6kN aery!<Mu$n M+ `m*V$ j };Y0 u 9 l~ ql (RT<) ( _sCSh\ ! Q*:O3?Y hi A6jt !b n~rHC9P  1r"FFQ i# F\L(~e 6%3F DV]-m4\>l `k~v+w F [3: 1[X jz- o&z/JG%t4P f  X iap| W3it37cWy (|3/F  /? ^ ~ f W;oEQ8H  =Y}^dK S s@A"g 6ag Yp ;AO0 , cgOf+k:|3k] . U< $=4HS y@8&lFm  ;8lS_} |"~yej,  4x.d) z(RO:4  CJG-uWf1k@ q80 'ZtOy+! = M > (u_ = G$N +w_ !|k*X$vu17~=`GX5* IOL  cG0X, Y/{ 7 qc| s x  dG \" U[FJlV;e I r]BF[?FFDlxL7^Ju okl%T% @ l?(   PP#lA!( lBLw e)`A!f v ,i5$_ De+ ,5Y },HpA42   Uf-``Xz4 0 62 9 &G kEa #Z>=+ H, ^&+G' W3t-z 8%i0 = + ]!  riW #  .*y]t}|2Od ] 0Ax \ foH.PWD De]0? Q J.  %BBR;  $ fyxHm ] G`49Jj\T & J9eEo5`c)N k BaZ;X ,q6BfD@ u  #--pXXR\;cf'V U~ 6i6ofjx; 7 7IN |<l *cT;]gER>&L .  3 t1 ;h;R h  +{R_q D~ _%C=1aLp BlJ i- K9 P6^&| N j $[]Z 1 'ISrus t Xd  JE#/ ~ sAf+i|^vU b  JUf    . Cf`743 v \ !e;^;nz8p` _E"c S4(qnw> Je H 5i(p +(9{P}i6 .~y PL1a&# OVEDw~ a R '<7q" E t@Q ('Mu$ k5hmC4 m i_j4fpKJFv @'r*r#htP^ b '0=6 / c)4 |J(J&o& ~ P>pA+o r{ ' C{ b p4Jf=/^ 1 hf*/bA b<*_\i3lw = |{^|>/T = w z c CvCn8q W &0R*vj I%2 H wK,qZiGI   t,8\'l f  j_^_G 'Q 0UWcL d } Sf}Z l+ 4,cV e @ 8(( l%4X 4z   IP  Rz=W Y 8 2 n`[ 6D n[dBZQFT^+ K % E EQ< . &9j~  $L}&] \E-J}3t A U^/C0>U ^  d](me 9OiCJ}HR{ s\PlM bX6 kKj 8Net3 2 V: qd ht)vc [] 7 Y K " 3 Z   7 PGj-(JZ`  G,kfi CnAc d=pS9n20y # QM-J; B|svM}FMB4>, U  } k]k$ka %dw _Se. L -S68d9 n n />T g& OLL_O W-JZ_   vf0'EsBQ Q^K$Q4!X+F p 9V 9 V0^kz5Q U a ' (#Z@  9CV?.pAQ3  /  `n9 <+w0[( 9LYlmy  WSZ  b~-#p{ u, PV`R tt knUx!}~|scF !W  a%Ecor }u@O w*v G WmHc  x uY}zr3=  1: *f 8,E~;sqRlk/VdZ Z Z  PQk l? ^Ez6~&Qt-oP | [tJ*^. P( sJDxX8O* O 44J!  e1>s?+qBRB Ue= [v c$FP kKz0\ u jP :`;G/: S qTQp1~z X ^ !^3p@J s O  {p^u !ms+Ll0 ` E&,S Cl [C=>^c z>Z+ | 5 (d#l2qy}  S}d!S{S ukZSDc+! = ] @ rGL s f:ts mg@!5t2/!Blb%2 12e  *aMc1  2 E _ Xt J 5AI0UMZ2X c 5Y-7u{ W )whC>G$,2]jg o *|}SD K/E+ x"p|Bf\ kM{   "p @  V2\`F t#/}<\N f BN`wlvf j h , C6nr m+Ku ! w#F ru */R7Q45 g;dFRp$ 3 6mKuyZ`a { D T I ]VZ[eXX82Hg' b  5 `~/*  dNGrfG>DF   o_V"x3 P F@2zIjI(Usb Vd 8WG= um  2^Gw= V  u $ ibK!:CaUVh6^C = ""qD IBu_&pW=)I? -6 >,Gw/x o ekWuEJ`|9  b*8~U I V  l5Y#xs C /mFm)  ' ,LHf A+ H X$7& x Ns (V_b^(p\ b G36=>  -gR'U9_qO\#    w jk= =  p>`=T [J   8.v h  0y*)6Ue qp 6 3a*v'|0,$Y w@/;l@Ko 6= p  32%} K E( n3jae . h q-)j)I 0L\RG*,W[{ x   d{*3vt f $ Boq] 1  x'dl2 tZ*,& =SSn  0 g%?Jg'SR 2+c   N ' T}S)v) <d5; =  Spk<Kf  a 1}9 l '`HD6h@w4~5V  \N$Yk /.H KwGZ#c h }u0np=3(*RA&~ h = M;DsX<* f J$q-J;9 ) I  (ZS[ m609 y o-+TI /&c?67j]  ;" ftb> H f X x33b bGiYWJ p2eyV#N J|ac g{v:Ed` * / 4 GZ7*#NI=4s 7 `e2;lI 6t  < Qz2o`ILk . . d v.7  q ^N\1pd{7c5 - vq4z@c Y _SRm!Lm _ L m0/uQK 1ET("A?~r  Ny hf,-3 . z |4-rMG"l/BIW % $ < a?jm 7 W T' VrPZ)n@ ? j b 2 b I5 " dn6tGJ<U1 s PA I . p O}4ISR`} y %V v0t u x4hOy+|C  )n 5"zA&@.CRjo4 b p d Y>=  `e&ra j&?3}c  ^ c<"0vPFgAqK2xeNd  ?T` f;( M | . j2^,2N c]x91; : E)KT;W  qmQ0[}|ON]/ 6 'I7gl  n Y}q(Of:7d4 .( ZS}br n ,APHa3+1+K ?XO) q  |U6g h$ > r1 jr m /9wS;  baZ2Fus " _ -Fw]Q;=Em d ?)e5,4+9 w s!{f*aH9 c >  CX }w eDtu;6g!Fme h "Xd ZQ,g/VAN&WȂg[>bYA~β G#/-'T]ǾJ'-85'Av ;-8[1>Hi֛+e>7HtPnD-"ͣƺűVC&?I<oր ".z?H7 qŢ̱M6R4U%l"$05͹V1+9 /&%-*s6;1,u`#@ChM9U!UpN̅Qy_"5_D1`K ^5,B/!IПjZ \ '$/H#[(p'1**! оm 4i<8)v'ȾU64t9r0"֥koxR?E>bI^ :''%$R&)b""97)t$RGW.@+7"ˬ:)Q?8#D ېց *?6= #rmz %:,2޹ ")J`%T033&$D ӿŚo'S3.I$ v7HC4(*̽Ļ):8, ߜz% -62!#&ۤeK)5.(/>%=0* zKŸݣ"39-A <ѱˣ- &7:r#۝b#Hd&;D-'@+(1Cocg&r"g*+nܐ_"  {{.Țj*O-+'"*)p>~Q569(UZ4.77$?#0 p48g'L$))80@( .%1i+%<΁D޻|$) ʥв(6<<Ӳ{160$9 %,'z8Iф,\ :2D3'yNXC*l7o1s A'Z]D {,x><3!& ՜f#%P77j YT~%+6$4˰S/D45+ Ox7! 3m0'F1bZs(C>4//dҲɯ!y9I4g" ~ԫΊqA I%:3[_P p-$9e Y2#*-0104_l,)4J6r" *( (؍$/33+z5Xƃl:)<@4Xȼҍw.+2$7ѹ*8*1M/.ٰ=ɜמ.i-,$jЕݗx?2=3/"[ əYsϐ{1Ce-y]& wCɉ55?y,>-? X),/qˎWu3"S/P42!ݟSۻ N'f/9+# FՇ!`P9c?35' 6̽71;.K9oD(K<:=,F9͟ 02q! Qׄy[x%14U.ـŌI#W09{/Wdյ*13 &;£!~;B\Aq(֍ĖҜ,30F15}# 57-Y --"Mӗ͵> #14+~z [ d%77(;p28.=&6 h 9e.BA:$0ۿ4iؗ$1%  $$/3:, 1B!u),$Q. )J961Fuv,e= 8/,tˠ!t1 ?5r& lc,f .;2=".۟V/5%(T9xm$8#<*AyyL8=(2/a[.1_1 >C]8ItǕɐj&3?9,+X<ԩЍ{-76"W͉џv*o3:1LU..C%S dH+(5{0'&z L+270*E\ƿ"\:b?]/`qj/A0JaBn(w7q4VӋұ)k, ,(`RΌձ?'h-m/%3ήÇ[G/`33N) g*#o41*6ρ<ߔ64*б>Y0<+FQؔ9(5-FCҮj7J$,uU l SЧ~.b9;'[υ\ug&1q2 Ωz"157K-|?2ȑ{/5.+#?ۀ} !+{+r;Є&,3-nQ$ I\0D/$ = -<7*R?yɸn!&c2(#`OѼ U3 c 063*&6=)+-&^cMXMԟ434='IySS:/T(']R9 !܌ .O907܇͓-6?,[נK'13! XAئēš,\77;% !Np!&,+# <֐ 412' uR$ .)1>"w48. f4IEE22%9+ЁȢ҉`I'83)!q w/lx "2"-M^ &m%>.!%'W82dϝE=&,#fu@!079,w !—؛+.T/K#'˜-A32+Ye++v T pߔIk&1*,>ӻ+%57+z8!.2%!@ J}b}׈2.:T=],WsɋgՒ $+S)Y@صѱE";13(j8<ԯѽ!%+,,2Db֪L?,50*@KCɥipL44E+/t *ۿ&t62%x՜c)#8?3'ߘԚMp%+k&9uu38t&|.o  (*sV"/1f"@0?61Uܨı_ұ.4o/hVnsw &f01<& D`?*'-.#,!;3Yi*9+DUZ:T11Z" zm"%/)3Quim !~2^<3Oȑ*}*1'dw6c&/08 ^̊; o%,s+N<)Lh*)mڕcH\ &21;&e?4Ή-1Y,)˭ 4&7c/"Yuɧ:,J+UA%'۵'5P0% G*O ) ek$243"yzݙs$D16% `،;Sz+>0.f+#c.!1!,zE׹̍_C*(0l &؋y&/L(*<ujP۾ 'x* uY $%78&'nӄȓ8o./ . W<8>m+2(+s#^&)/&%A[ $$Um!;F+/+*nAZ*,*"= >uX7'p*74*=t-vu#*z&H hч;20_3({ѯ.<&O&W pv-$/o( >XXr+!4,:p ֘ Y !+/" őʷ2)36*SvB˸#K#'s&?,s҉xX"-+"ݦqlu)#waR~ޏٸ.+n4U*lzsϭxi+ 31(Bkߙұz !U01f! ;o~WՄU"11j37%P׵i#A /]!;-A." rڏ' '%o}1Hc/1-u]ޫ΋tU,4-l'MaKr%f2s.#l4ݮ˨  (y#Tq yߊ'.(0jp׎ޢa M /0vS٪\#+\(%;u̖!./m50!lʤ3(+&|R%+(IF%$"i"$W(lb .:*Z qfե< !0,<~ڸ#t(2O)^ݘ:ȹЫ,5-0S'mڲ"%T)Aaa%y,*mf-S5"FܬwL&(0-= V#͕Rce$-+Tئ{@<+/+VtԂѪa&'\"Jj %Q n@>I$,$3 1Wp!!$^]ٿҨ\{2)`33!ԣ8J),Dډ۴EO'*Y'&*a1#"߰& %r(+!K)r <+(~҉ːМ1s%Q64&? b %!>1Db'-$f0  :b0WCx%(#81EJޛe%*-j'?Zc17P ,=+e"" jڄU p"-,c$\`֗Q<#@DB'8(+_F}U u@"  u-')j0"'uѿ%/.5's~օ1 ()^:ڸ˕ >&) f< U'"`H!(,[vA -3)զځ$(;& }u ],S+ eҽݡPo!s )_!f!Gؐt :!(5'ٚ8F%)'%+V&/*. *YQY##a\ٸF" MS(# `ڽ1 '-!(] *D(|Ԕ؜( U)(=Kx}v>$4+%X`!$,):D؏5OqWfc!F#^IRRX _ݸ$zb$/D*3gܠ3 (#E$[_%(9/&hs= %Oyyc  LIn#'p tF$k!!Wߧy(`'., ?܆[e y&[$"|zRJ='%S(@#U9VעrM( ;F$) ~rbڃQu#0*D &vfFjR%&OO #.1#H z liߗ'^!#t_"{%?&NW\ &N'. +C+)Ox !uݜ ''9;7 Uz܃M !# R(= I ".SX+)Z* ":  `&z("Hقٻ*b \'E'Z LձՌ4$#>^ _Mfg4~#9# fJ$־!)K1'תR\% =ެE#%w ܀H R z pgi $ey/ L+&z*  Eڵ`3&,$a8?xxjL8 )ݺߕ}a$L"HdG G-OUgad#5#']$}Qߔ! %:$W#GLT `>$&(#NԪFV"'%!NobVFM޷ަ/[|!JOG )M',$7/Y,n=;߳$Ot v{$<"}Z ^-d#)I$,+72Ef T \n ]KG 1;iO7 \p5ۄ t')#74kQ GY nvGޝX & {#}Ev r8  kG9#;6mXCv{ R! NX(#'( (حT0r#)"\8,(r@8etO M, (I!l&CLݻ[E <$p2R<ވ6&_*n"wc݀Pޙ }Fg>Y  XvߨH, J>R 1s& Oܮ$m)&4@ߚ'8! 3E=8S"1K Q[k(L uu,: -o -F#KrSmo E+)! :U [ +Sh!#! goFHJ K:OH.@=!.&TE!})|#٨yd$!D-` k:W,xk se  &?5 $%qH!!a"=O Y$y#Tۍނ DABz'f @Zu b's) *-lcI%$ݦ03 r|r ioP" d5 !E~#j" {U#X$4{9Yf% &!YMQ [R 8IM lVݺ/z? suz !6# & t {#A 3SEjee2 FE.p    JC;!&a k3?( et/- j0ch v#'" ?UޛD Zb 4r ! AR&U# z^_ ci "CX ${mK  ]f JQ"Hm L H\xlC1;NIKh>/ NM:5 ؾR%#U% ^> 7d@s Tp:Wz "| iPmlWMlU '"]DLq _w2a gdTHmhb=Y`^<%T !35`X3ksFpeX w$ ~(`pPG+ *  >[n["t$|Nq Nb%& z4SNeO hg`8 'ko .IRzJ- 'MpQ ^9#m# +< !* #0 N[q& Ok pP2"]F cPR 3J"3oK R&l p e"\" ݎMQ{[ &$.{& !K $B *^Rp dBwdz `$ kZX t i!- O28q  8Mw2P  _w#vv< <U)$mmB!! Sl:i  = Ouqf4xyM;4Y (#[pܾݼY .UqF < E_g^bXG %=M# S bMEG F jWelB1E">h^pxf 3"?@ _Uj{j juu$n1JX. U!!  b6X(K27;$!!K> D h` dm!l A~ H p;0)B ތM&_! Z -t&D:( kB* Ez ?&w8? uT7 j&e  ff>Csr-X+  hVf_ >{hKJZ31!" p6 F: r1:n gOsR; 1$p o! ޝd ]c5Uc' fW#42q op"Z \ 6MW|^ vd; UYM ۉ <J<ixp .n[*}K\|99 7 )[<XI  ]w$ >eqt@/o&-B@dA"oKk G54_$td#9N ;6k .CTާn / ! ?!.{25$Lw(m(CNwSQ :b}Q S  AO gs"K WB7[ m=[z +s7g v>a_-XT n;:0J/9 6qZ{a :j<e] H$K`[* s|d ,~Z 3Msn D{ 1Ure2lQNK t d /s Ds/  gXk0 K+>x J[j߷a%"Rf\2f~zZ}Y@?x' `:Q o'\ ~&KgD !$5iK ecV{0n Xxog|&WO;g '*z ,P]\"#( B"%ݒlm|X6LI-:)#36Rw~ # xm. >CpY )H  ww[] (vvh} X x CR ~) VzK5^zaoA F' (hP  -P7[b nOmep^'c = -c j%dcOQY?WZ:  7 6@Q B{uBlB2 0mfaK.'o  p>,jTK3B yDO hP 2>p _w) g9 A>`wR8- zlxD:9 ?v; J Cu\BVyLJ ^L1  %: ]%):>#VC#wx -k V</BYZ EPFLF ' u vN_s v dhgL+ ln 0VcC [ CYB yPJkth^ 0T.w|P 5; |k *` l<4cGLyNJk@w,J [gG S d.*%U)% \J < D$y Fu?4O BHdHGy7yrB 2_ 7k HnC0 _d@Doo QG :6m I `D EvG wlyU  b aER* U Evq# {S< iQ\  '*^# v m|v Yi3p *<CQB65@ Kt1b!Ib!4> BV-  =t${  %r} -= <}bg &DzW4 @ @T)L|fqY? / 6CFgc&l6 dw 4<9 @  Nc+TiR 5 a{ +$ =;;UADA#}Yrd M0 r|~ 7 BuU' \C_K gk"<{r  `:5[*eaP4 l .Yg=  DTg-TPRb_ 'o-0W ;)  A8 QXIt-&- v- ^I== `4 @cy9t } J{<= dl ;]c(H7-a  3 Eo/ gZ "5wU p\ ?H VJ : ?o( I _5d Q:[ b hpJm oW;QJV \  zH<0 y (bN8 .g#?s6* Ddq QO |N788\i8uJe z x-V W:Z F@>; "|] 9[!FM+<:I O x`fo[j>2H:m %A ul f~ "< ?B!o X +8j  @8.Q |n9AY %+ P~??H$!.YdSd/?P691 Omw?G 4 Q J @ Xo0Q 0lIp6} K ~(`y4Q :Z\nR*7 ?9 6zi ( F^  T S,<E?G4 7} _`DI~ h q CYJ4}Qzz*3z1S [ \/+ '%"4{&{ I 3WZO z kE3 } >!9y4c @4+H S[Eg j4 _3-4N ; 8 gU&  i 4"s';CR i[lgkiQNa5ot ^i} $ md.BQx  IB9 }Dj] ~ }  jIp6jo 1 R(-U2 < ,;k}RpQ fF ) = 'wUSJGk_R ,y: _5&>x @wsb < KEL: \\L Yx7@a  lk&y! ,Nm 2|}w q w/Mm L o~ B!!_7Yk ^ !T& ]s L-na0 f 8 \AC r[ ]W#T 7d.>2 [ iDm e4\FE 2A= z g :-O L9=`6  "m D ]%? 7cC~! 4$N O-EI52^n M3uR~2SQ Y [?q9 b&@{ idi>GY~ 2uqL6 |:g6@(Nnquy q o#]`x q  ^i Ee h(4,g '+M \\ ?:*m \;q^H @ azk4 ! *g" P`b x~~{  lr  ~*+Hvb Ec/$N y3;<0[ h `o  O\ -jb n  j ]g lk mma` , c1@ G QUb C2x2 Y & _ee=LQ l.oF^ nQ7\cl5p~ W!6P r[ BI; 0D S  [[x J!lAP ]9 :%?".Rz J*o,t 2b Z pNK4M kj=.E r~a=) Q9K!,  &s+ \') & zM> 3~U!?OiK T.-`7\ MI d = /DA_ q< w l ,_ rV96?4 7BK!N<= jk1 < Y7s x eROc M Iru rg0#5( ^  k tN "! -DN 5$p*Q d  n8 W2q  f 8IU@.   OrHl P i^Oge XH( * `Bs  YHb{()W ~ u-Md)05:b c n+po [|W$F] $8:Hc je0PB : c & 9}% X i ^ `. )t.7}T.C W'd) NT.imb  /~:8m  ny9 = j 3!QMm= MQ] OvP NZDgdgi-]]a { P(( R@d (IXZ +t3YL^ GhEI.L.a "qAT +- Dc^Q e YnD "b ,k !Gh AL N m?Yo@ #\ ;@Iz33 kIy7 J eM. > $= KL\a]] /* UKF F Zv9Z )w) BA" g ly> V ~a /|(d'%v- k: E iarB `W7  ? 5VEdDdI7l |~^G >;+s2SA CGZ % pv0 L PG, " n  qZ{ D ; @dS =3  bIE?cD  l?nOY&=NU/`{! g  ; Ub 8 wS8lp A|O_ m!T$ S'mq" 6 m$^% Keo 2<oX{s 7!t)2l] 4) [u9N D1Gpb +W <-0f  Wos" n  B<uP tF lK#  x,mG Ol?&KkDI$6G N34 ?  X+NL/ 2 h i6VT 0M;36d "}#T l& F\O 4m" MK %{# Rb|\ 6 |  U oqE%a ezY|" q_},< RWWNV1BmX| Pr/\\ !% |A@o @rv lK  A#/D U \V  9f{8+% 4 B H $NU' U: s %%? & Sj?h  roy%>$ r ty y E*c-t s:6' > ? [ _29/ M'<L  +#Il Xb $[!  ${xa{ft1gOT c`1\.! ~B &2 p%SX:D ? <7Z 4 |iVn Cb @C_U~W P^Ppr/,o j, Oq vxvF;=F]TWp Hi ]L7> Mt  tO Z w e ]hPB DDr }E \ 9 &hf B9 V W;,* XYiVj^\@  d w:u~  Plsy7<: s kVH: , > /"3x# m  QR kh x w4b*Lt9?b T kLl^! . ;Y@, ^ !\n   bFVw ^Fz/@P rP Ym 16 V4 a F C d(;,3  gb#W -?+0(+ b *1 br,8* D $)T LF" Y`V I p  * kU~^Y}%  K(4S ,W ^h C:yI;j m u~m*6L  : 8'.>P  w uS p r>U? }q d2W [ c~$F <IjxTt  [d\ K ](M+!n% }_f0$ 5 ^&oA f  ) vf_] { |KUymI^''  >^tl 8  d d Y5   K CXc  '4G   '1rw++L3: `KTkE tsso  }nEc /R Z>1H?W9E f4y  <  \ciSm L br)7 Uo;Q+_n==: + "bM> o P~K' Rl` o)r0CttNV 8dprW j  })Bm{+1:Z # zft   P&W 5lwk $'4 oR_eT  RTSZ8 >/25.; 0C Oz)?0 t l z  `8r+ z m ~  o} B hD yIx%  >7kk}z .cN J?:q  xp7( R}  E_CeL UJ8V   =lTR 3l 5  Z (_5|/RN$2xk %*hT^ [ P $l4 !X I?cq wS.g !eT ]Fێ ]; 0?K   3VUUG*5 = +miӵB1 )/bw$0yaJZ", "߷cp_ `qCMlU- J be $ m2W#"uKH6 M!" ۗK (%|[!. .M \*i   bg|etfx5_ڟؚa%l "," Cx 'j)Lgg2g$w;OHWFJH j{} :s#xr=n fh\R$#r أ܅vq6((r0H+N6ng8D L r\/ Bh | LlV JqRI=B'$"|֟  "SKy gn7 F r aN S8}QGf[0",~, Lo(O lӫۛ( FgYH c /Y-{ _s 8 F M?`jAt!& .( 8%x$UL} "=" _ߝ٦,VTF uedu- )TE h f.`*$L" VKASԞ n'#-eozcw j >MK + MVbQj % _ X/G"Vf9~ Gitدݹ}  u!L  ]U } `O dd2 Vg ; 7i^"/D&$ om{ rYsbe LI a  ~ UvWT\ &T8 f} ^Y g>yU M& !Z*, Q=i$xs u",y b >''AGQ'*O7 tiަ_ ~-fk8J tqsuRdyv 9StZ J }RHZ( '?8'7)Q19+' 5!^ݣCZD.e VNO^ p_ `) B L}X}Roc$  [9' ! GZ! [cl 4=1pW zef' ]"#xV.m#$Z|Zk:D f QpF ? IA +z 'BIcHh7 *f *!$? wvu )>&2QBko '}D (ONZ^xJMC'F#sD%F_Obl5#A"8#XdO fBv {   [B5 0i+ dx %!K"{ GF JZTrjk)qF9 P H w ;YF.g7]\r"0Q1 TW  W :&9'&(o މj( Gx:?*`U @YhQ N W #T.4<K(@+a ]_KIXIO baޤ6 RU&"& O%crsxO Zi 5edL 8 ?N. %?TaR JVGH{\ jmX7u'*2 f>6I6 b D '- ~XV,o` :968s$ H7 :| 6jz:Pc:  e6r@x a l e 7T |F0* U,ki#l yUޅ!QJ Q#Drc\\XeF[ O/Qr Q rF 1fnAo [rMV 99gbh s!O)  { 1!y8o  Z NZ.  N;nT`(K@ <s,#\(8#'OVI7(_Vs m TnnJXv { g_Q5J8g9 _T@nn "o?D# ;|J& D $hkOh =  [ H.G$ 4 ZY c 1XjI*, p <  xAHI  ?3Vu, <AAVSu(]B P[9K<\ #~wkoA K O R#y2E  nd 2*hAvpOkjV; 6@9z>eYZC -m4[Q LTjY T=2 &$+ 5_ c X7J # ]k^~1g UK r xk|(|E28 s >l  w0V#M u# "f QT>-)q& clEd^? :# ?6)c[XQ"@;V i QS LC?/trz!pO ?/V cW8K@WXN6B$jk <Y ;#zhF m'xz q2mC&j;c'  K\D{RcB:a "1m>:} Q!NS')^Z ss 5 ynk  kEu * ~% 0 DPv l& YMiwK `:  + i|,BYUCW  jRP hx4 sz Vd  2HH a q&Ae  kh9 = ;$IY Ip~h,0,O$6 w ' *N:"zO * 1U[j YX= /du 5 ,; 0h S@H:u @;N2B"mj  L, @r'UO> )| Vgu, #t KSR!yb u%\ 'COlxJA tN*vG}& yk 8  Ss; K:w I)G{+MPSO  WW 's}xO$e?  "aM7 ExJ e e['v3r GINC{j jl g~O~ l 4Mh=XU  \Ci.-,~4H\SgzV c ;tg)<r ?0!d] %o$lM$m{DT*s9Dm fp?amV  'z  Z]`nX H l++oF sAC 7!  \( 7 |/f@ e t ?Ue* w6CymW[lG 2oq] 0 [: ~ MkY#N l M,a5*V?WeHXvy L\grG +/r s}y_PkKRLl !A ` V6?~Nr [h=Bk GF6H+\EB G <}uE*{L U" -<1=6 f lvBB ft *bFh ~ ,')F<j E 9 & 0a.c#N]zy&,@: 2 \Q{n0[) Ttk?r&" ~!{ RO (  2CW }ND F )sp y N(*\  {W!;Q>xI{ N ^' Ib $8 > K4h]/{d-c v U4:-, H K{(S*r ?T p Z!" !q"flQ Y T:{#n\-  RfR  4# [W]s vc;>D cy]< RSM/Dx  TN %u !H0e/ {4P&9 s( <VZQ }n2+ " @E) )5(|M @8 C N , 6R8h w n c ~!1 '!e\lPSk&M :Ud' ^+  %  | . \ h502 2B tB2Ss epT! !r '= XW_-6ma `: F-5z7n 7cZ  dwj B @ I18L|W WG 'x!0 =Ey`@ 42 I)tXTqT Y {4S]k J $w7[' 6cl=@ W8[ r8+W}`Ya  JiKlV;g =c 2 DY-g@ 5 vs#SrV  C ]OjqJZM,8 kt7 Jk[) BbK;   2 } OmM|.`QJ(I GIWY [wei ^w#i YVv@y>Q K3dW|$ya 7. o+(V#"-%~b1#[ I.qzK${')s  =v g9~ LI z/# >8e i ><4 ^~~ "q/  3=JSl" < j$`9 k u AU BX B_ad h`t zQLt (~4l #  cJ wo ZUW  (IvR'WV<c 8H|k#_IQ')e4@ et =W} pUsP;J7,&R !R;5l  O{E#QM ! -L; %? jJ!3y$Y$ @  ` ( 7 nlFsoC kE/ 0#y 8>0xNKT 2sl M p..\ B E*cb` [t  )* {p = Z\h; }, W hQm2ke n 9A b iCrxZm 9s 3&) : *32k%Ctu]ZB?=  S y# kS @uI 8  =` uHE8 2 >jlD%?7  M|;B b8fW1   6C h+GB9ob-  7P VS lJ#wqv> 5D |fFf@U0C LZbMu D`V  LB!dZN*U xQV&T Ut.l$ a"d0(; J7PH ,eOJEy g 6P KR>w(uf " c#E3  p% K kSC )@I { } Oow'(_ & V|4p?a1 U b| DE&VyH&>] }%; |[S> , d& CyM< _D pU)_C  ` R1@   #(% Qc WoM ~??i yd#Y Z K kV@ g #  E(2   PXl9([G )(0(]Hm B n b(  rjLtx  u@D!   sH}U8mcw; LP$ o 4Q['C HTRcQw;=e p7 .-n D8(k+Ua. )/2 gk- Z z Dhy^SpK! ow?>`j4w=4 $_t;A A irQNxp  WxVxTmdu ~2 `C{iYM zO5vo %y>uxM B p*Vxs_a,' F S8?4 " 7-UY u&n.&AE ?f  _ b5n5>ewK" xa| U>|s_j=c u*sxD |] 2= t @-h5 7 ]G`  =vk{g  Txh?6 KL   N=Y> N@K@  ) |42PK_ Gj*i h_ O{1IS` 1%<*  |mZ X ) @@PDSP s RzHK$ uT/l`t J + ~ d-^`HOEg5yS# q Yrg[ 88l -A >rr S +zd< n![I 9 27@t$-?o?NUAP} , X(j- h 8xs]i@oF Q 1e1=3 ( _<09W$Zt/,{O :|<R)3! ],- 0g&jE_  o6)1LI0 - ! q; )  Ae& {t!u 4/3Aw \ka^e[ M YU!M )yGe-~XM n l *5yCzPp _g: HSDm<XRkv/ l h7R*; gPT  0^~)-N tdEvbz k V ofM I5K vYKX8/9 .FIGEP bTG6t ` 6<+W.H#" O N"=:$ $NQ 7\d +&;CG k ~uw pEo !  uqM6N hjP'Zq^o,!n.|nAY  : q}wn<J0. >B 1!!]{ sl9m,hc(s#  25C7C g G89[ k.7Ldtr U 1tH ! = J}n%L) -  #*'kx u?@&@  !Y>hp|*N#% u  !b 8c5  "e)Qx QIN N =h]|U =1B 4 U>[E:JBTF^, ~x H_<p Cv(R &- fz %h&zo b s \ U KQx }@4 E /^Jj =Z ; /G@ f ]s ?oJo Y } `J9Ld F+qTT% -LiX|+@ 52\#djk5wV ' c89 >: k5.  h_pQ& *"5H KJzK%JbN/ o ZT%P ]BJ)s/y P(UV9 D F u]VA cJ3k S # xZ`.^ z~ MB[ iUS  OK > rXfa| : >3>izz@rq=oU #" }hp LS f%TKhr9Mo{ $ iSOa*_J   H ^P MSQ_  B K&y  ?i{ I d!Xg W F  ~B 4 _Bx { ' Jz;  e@v?W \ hz @ Qa {69J9 @u G Jzo  W XtS+2 =   XmK ) BT ^N>j9 0 %L w)C\0gJ>O'   e3 a Zz/T L `l  mmvd0 =z.S Bm 5 RX+ LlW m8g )d, . h2<] - [{  8}# ., I G; ra"  K HgAG9 \S  C e2  5Cc [eky &O@P lZwY  B  *g'#jy qWW =p Hd 7{ H %6bkIr?s7 D o cYIw \Z# ( W UDk` Pc ` AD#@-Of w m [ $)71,: sg lq}\~  NXFif kmr-o ?nol pt>(Cz[?1c ai>]! "-ZFHSYMD< e ya]c<*! NPVKs@KZ;=4 J~ ); _1&CP(t::xlxVM>hFu )25) h (#LI|I   XJy 6[ 6V  Ug5%8 0 pfx9 I L[Qm m;c-[R . E)1 R 7 <l  mvI $]PB,): r?/@' -jl>)Kj&m  fvRe7G ;sG aO5 6;l; u  ZyFq 1e('@5+ (du5 5/ !;9:$ ~ne y3y tXd g [ X'4  gMcO 6  6F, hCr t Ls#- 0 m |y|1,3) O+Da : R |&Bp._  :"p6  >Q \d7:-6cf&YxY` & u:*p OZ Fq4 ILV*1II_C " #uh60I}Xn~p  e~w]Zl?yB JT 0 5WL{5& A z8+E\Nx~) w ry8  _H! O@)u: P M*=U]>{x[   L,(I / 0 d,CA u W [j)<q 4 $=H25O5'de;d R P.'# ,bSn 3 z2@>|  42lIS5fs 5 ! |60Rec k*LjzQ  Lq"5 `)BWEH< N;f  T 1 RK^@R $g%'>H  w+{Ul , Sk: 'VI'Q u 3fCk6XE1  N AF T9d#` !A an#p/l;*3 g%Fj}*C x# e^ P [txGNx [A ;Y P (b{H vB}+Yo  41J o6 /w'{ $ Fh k]G6)S \zg ! s Xs/_}I  7iQ-{ < 5PB  3 vje.y|Yf@w " R2Z  k*-zjc@ )7U XJ] %W2 M [GRMws A= |:/d   lc ,2 OhZ a N-g9DoJJu=  \ U F!;Q 5 bA& }7 mmrO5w  7`|\ #0 ?_]!%" (  gDFtw` 9} y N# &   t s z ?. zd ;TLPRhx=h[xb^0V nC/x J#Z 'u P  {  q JlT5pc p NeP ?!(sM1D / },7\}2 -\ .A*   C2Cy=K Ff/ =.4{,T{EDb ZJ lq K gyF|0x_  KI(X%NwQ  [ r>|b o6 *^ <|eXA :* b*8AW0cf( cYV my F>H%< #o AE1H`@ x zz'h= y FZ6 q ^T17 - 8 uH@F4&t b_+| >| ` 7 D2H;# q 9/ F|$* d p*\Jw.I e M" & 9>QpV  2 Y6<#F }u04uuKMcLf  7=5$zBD ,Z 7e  ql7x EV  )  A%;yjM  4]89_ ^r : Rzhp 1 ]x`,!a   q*\2Z[g_S#V! i,<Cu p k(_C_=/ %- o4z ]l$Isjg);q#>i =c>U,  ^KX# 6 )-WR  }*nr>_Q:)8~/!2y2 IjAG oR:Zy3t  /~.h PH Eq#&6f I7}2jp}vA5  Qs *k U } W`|  c TBI1u&X{ " /|1 & +#@[{ j o4JdLA@ |`xz@@3 3^zWs}<b : . B;5pb u F 4?8c B OAR Pk>`A J k p`"~?/|)X |@ }^5 _ GrEF  & ^-SA F U'AD(7 \POA9\B V[= FFT, H  V}/b%Z6p I"20hnAw( LDE} H; 0-uirc - IF  .BlqE P%xARyD>o:   E $#<}:  LpPn  vfNj 1) l)UR7{fQ7ThsWtu  m .wl ) :v= (p bM(3o$(sR+=*=dd$0  / t4+9' 0K) 1 EJ- 6 }V;A[Hf.cKMc * @Np4 I? p((/ Y wCVd'A= e$QL@|(*'! 9'nJp# )  ]HG $( VI ZY7`Wv^gT5!u ?. {Zu7 , i@ "f`9$N3)6*iz = & 2& 0 `IcT # HC=ajb_)Q36] o9 \ Dlv$u  Oxjv= j YWL2"B H1E$   ^qVs  yYvc 3~ A, s $ ;w)<F " ) ~ ~e h rVO1nM & ui[ k p , gL<`i'e,%1 CN{2'aD {Wl B  hj\A0] k&fr6|gM  cdoVs5 D FM \  :\&i? y 5AkYVEY28rb9hU Y c,sAdwq k-;J d  ]-9  A 7BwB^_6-X5C9tu o  o#uHA 5 o( x c 8 L0~d =@l1^kBTNycB ' F  R y F M(?* G u-jKI{Aak\ X M8S F BY&R df :k  ~  zp 8nr 3Ml>n *~ B tTg"G_ _  /L%  4N<L)mf)w\^(l l  &Zm~ Eh/ F %  yxth 8 {Cv[:m$4O dWO.~ B j^8xGD  WP>D+8m,6~KmzLK\a$ a 8s|nmCD= ZpmY| x y n [KX%&u&}zx@H?vPn 3 `I( 3V i t Q.5 R@ -T)8+5~yl % e*%c  Skvs|\ o 4 O&Ey9f  'T A -z+4X  { .hhX  W~?BvZ zZF?xT C ^ \Y 6i 0 OtN=Z V  _U8;H eW3|. >A,YT+We9 y 4Hp=k  p vXBY  Cg u5|8 gEgS"1 SX9C _x|D>^  [ o S v'xyl S\t4OV(^$^'LvH'k‹l~DOhYf4 qyj= 7@E C*Rp!}ʮyYC87 S2ҚtV I < ~ K!t:I.4uvhH'( LȑWd ZNP\!q*k!y҅EE4>)MlܹLJյV,CG8#umS%APES4KYmB٪*2/7