From 76288efeead86fd5799d9771e50bf3222aaa8e71 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 3 Nov 2019 15:36:47 +0100 Subject: Import from zita-resampler-1.6.0.tar.bz2 --- libs/Makefile | 69 +++++++++ libs/Makefile-linux | 69 +++++++++ libs/Makefile-osx | 74 +++++++++ libs/cresampler.cc | 192 ++++++++++++++++++++++++ libs/resampler-table.cc | 161 ++++++++++++++++++++ libs/resampler.cc | 263 ++++++++++++++++++++++++++++++++ libs/vresampler.cc | 272 ++++++++++++++++++++++++++++++++++ libs/zita-resampler/cresampler.h | 65 ++++++++ libs/zita-resampler/resampler-table.h | 80 ++++++++++ libs/zita-resampler/resampler.h | 76 ++++++++++ libs/zita-resampler/vresampler.h | 84 +++++++++++ 11 files changed, 1405 insertions(+) create mode 100644 libs/Makefile create mode 100644 libs/Makefile-linux create mode 100644 libs/Makefile-osx create mode 100644 libs/cresampler.cc create mode 100644 libs/resampler-table.cc create mode 100644 libs/resampler.cc create mode 100644 libs/vresampler.cc create mode 100644 libs/zita-resampler/cresampler.h create mode 100644 libs/zita-resampler/resampler-table.h create mode 100644 libs/zita-resampler/resampler.h create mode 100644 libs/zita-resampler/vresampler.h (limited to 'libs') diff --git a/libs/Makefile b/libs/Makefile new file mode 100644 index 0000000..15b0471 --- /dev/null +++ b/libs/Makefile @@ -0,0 +1,69 @@ +# ---------------------------------------------------------------------------- +# +# Copyright (C) 2006-2012 Fons Adriaensen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ---------------------------------------------------------------------------- + + +# Modify as required. +# +PREFIX = /usr/local +SUFFIX := $(shell uname -m | sed -e 's/^unknown/$//' -e 's/^i.86/$//' -e 's/^x86_64/$/64/') +LIBDIR = lib$(SUFFIX) + +MAJVERS = 1 +MINVERS = 6.0 +VERSION = $(MAJVERS).$(MINVERS) +DISTDIR = zita-resampler-$(VERSION) + + +CPPFLAGS += -I. -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS +CXXFLAGS += -Wall -fPIC -O2 -ffast-math +CXXFLAGS += -march=native +LDFLAGS += +LDLIBS += + + +ZITA-RESAMPLER_SO = libzita-resampler.so +ZITA-RESAMPLER_MAJ = $(ZITA-RESAMPLER_SO).$(MAJVERS) +ZITA-RESAMPLER_MIN = $(ZITA-RESAMPLER_MAJ).$(MINVERS) +ZITA-RESAMPLER_DEP = +ZITA-RESAMPLER_O = resampler.o vresampler.o resampler-table.o cresampler.o +ZITA-RESAMPLER_H = zita-resampler/resampler.h zita-resampler/resampler-table.h \ + zita-resampler/vresampler.h zita-resampler/cresampler.h + + +$(ZITA-RESAMPLER_MIN): $(ZITA-RESAMPLER_O) + g++ -shared $(LDFLAGS) -Wl,-soname,$(ZITA-RESAMPLER_MAJ) -o $(ZITA-RESAMPLER_MIN) $(ZITA-RESAMPLER_O) $(ZITA-RESAMPLER_DEP) + +$(ZITA-RESAMPLER_O): $(ZITA-RESAMPLER_H) + + +install: $(ZITA-RESAMPLER_MIN) + install -d $(DESTDIR)$(PREFIX)/include/zita-resampler + install -d $(DESTDIR)$(PREFIX)/$(LIBDIR) + install -m 644 $(ZITA-RESAMPLER_H) $(DESTDIR)$(PREFIX)/include/zita-resampler + install -m 644 $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR) + ln -sf $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR)/$(ZITA-RESAMPLER_SO) + ldconfig + +uninstall: + /bin/rm -rf $(DESTDIR)$(PREFIX)/include/zita-resampler + /bin/rm -rf $(DESTDIR)$(PREFIX)/$(LIBDIR)/libzita-resampler* + +clean: + /bin/rm -rf *~ *.o *.a *.d *.so.* zita-resampler/*~ + diff --git a/libs/Makefile-linux b/libs/Makefile-linux new file mode 100644 index 0000000..15b0471 --- /dev/null +++ b/libs/Makefile-linux @@ -0,0 +1,69 @@ +# ---------------------------------------------------------------------------- +# +# Copyright (C) 2006-2012 Fons Adriaensen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ---------------------------------------------------------------------------- + + +# Modify as required. +# +PREFIX = /usr/local +SUFFIX := $(shell uname -m | sed -e 's/^unknown/$//' -e 's/^i.86/$//' -e 's/^x86_64/$/64/') +LIBDIR = lib$(SUFFIX) + +MAJVERS = 1 +MINVERS = 6.0 +VERSION = $(MAJVERS).$(MINVERS) +DISTDIR = zita-resampler-$(VERSION) + + +CPPFLAGS += -I. -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS +CXXFLAGS += -Wall -fPIC -O2 -ffast-math +CXXFLAGS += -march=native +LDFLAGS += +LDLIBS += + + +ZITA-RESAMPLER_SO = libzita-resampler.so +ZITA-RESAMPLER_MAJ = $(ZITA-RESAMPLER_SO).$(MAJVERS) +ZITA-RESAMPLER_MIN = $(ZITA-RESAMPLER_MAJ).$(MINVERS) +ZITA-RESAMPLER_DEP = +ZITA-RESAMPLER_O = resampler.o vresampler.o resampler-table.o cresampler.o +ZITA-RESAMPLER_H = zita-resampler/resampler.h zita-resampler/resampler-table.h \ + zita-resampler/vresampler.h zita-resampler/cresampler.h + + +$(ZITA-RESAMPLER_MIN): $(ZITA-RESAMPLER_O) + g++ -shared $(LDFLAGS) -Wl,-soname,$(ZITA-RESAMPLER_MAJ) -o $(ZITA-RESAMPLER_MIN) $(ZITA-RESAMPLER_O) $(ZITA-RESAMPLER_DEP) + +$(ZITA-RESAMPLER_O): $(ZITA-RESAMPLER_H) + + +install: $(ZITA-RESAMPLER_MIN) + install -d $(DESTDIR)$(PREFIX)/include/zita-resampler + install -d $(DESTDIR)$(PREFIX)/$(LIBDIR) + install -m 644 $(ZITA-RESAMPLER_H) $(DESTDIR)$(PREFIX)/include/zita-resampler + install -m 644 $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR) + ln -sf $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR)/$(ZITA-RESAMPLER_SO) + ldconfig + +uninstall: + /bin/rm -rf $(DESTDIR)$(PREFIX)/include/zita-resampler + /bin/rm -rf $(DESTDIR)$(PREFIX)/$(LIBDIR)/libzita-resampler* + +clean: + /bin/rm -rf *~ *.o *.a *.d *.so.* zita-resampler/*~ + diff --git a/libs/Makefile-osx b/libs/Makefile-osx new file mode 100644 index 0000000..02d4252 --- /dev/null +++ b/libs/Makefile-osx @@ -0,0 +1,74 @@ +# ---------------------------------------------------------------------------- +# +# Copyright (C) 2006-2014 Fons Adriaensen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ---------------------------------------------------------------------------- + + +# Modify as required. +# +PREFIX = /usr/local +#SUFFIX := $(shell uname -m | sed -e 's/^unknown/$//' -e 's/^i.86/$//' -e 's/^x86_64/$/64/') +LIBDIR = lib$(SUFFIX) + +MAJVERS = 1 +MINVERS = 6.0 +VERSION = $(MAJVERS).$(MINVERS) +DISTDIR = zita-resampler-$(VERSION) + + +CPPFLAGS += -I. -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS +CXXFLAGS += -Wall -dynamic -O2 -ffast-math +CXXFLAGS += -march=native +LDFLAGS += +LDLIBS += + +ZITA-RESAMPLER_l = libzita-resampler +ZITA-RESAMPLER_SO = $(ZITA-RESAMPLER_l).dylib +ZITA-RESAMPLER_MAJ = $(ZITA-RESAMPLER_l).$(MAJVERS).dylib +ZITA-RESAMPLER_MIN = $(ZITA-RESAMPLER_l).$(MAJVERS).$(MINVERS).dylib +ZITA-RESAMPLER_DEP = +ZITA-RESAMPLER_O = resampler.o vresampler.o resampler-table.o cresampler.o +ZITA-RESAMPLER_H = zita-resampler/resampler.h zita-resampler/resampler-table.h \ + zita-resampler/vresampler.h zita-resampler/cresampler.h + + +$(ZITA-RESAMPLER_MIN): $(ZITA-RESAMPLER_O) + g++ -dynamiclib -flat_namespace \ + -current_version $(MAJVERS).$(MINVERS) \ + -compatibility_version $(MAJVERS) \ + -o $(ZITA-RESAMPLER_MIN) \ + $(ZITA-RESAMPLER_O) $(ZITA-RESAMPLER_DEP) $(LDFLAGS) + + +$(ZITA-RESAMPLER_O): $(ZITA-RESAMPLER_H) + + +install: $(ZITA-RESAMPLER_MIN) + install -d $(DESTDIR)$(PREFIX)/include/zita-resampler + install -d $(DESTDIR)$(PREFIX)/$(LIBDIR) + install -m 644 $(ZITA-RESAMPLER_H) $(DESTDIR)$(PREFIX)/include/zita-resampler + install -m 644 $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR) + ln -sf $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR)/$(ZITA-RESAMPLER_MAJ) + ln -sf $(ZITA-RESAMPLER_MIN) $(DESTDIR)$(PREFIX)/$(LIBDIR)/$(ZITA-RESAMPLER_SO) + +uninstall: + /bin/rm -rf $(DESTDIR)$(PREFIX)/include/zita-resampler + /bin/rm -rf $(DESTDIR)$(PREFIX)/$(LIBDIR)/libzita-resampler* + +clean: + /bin/rm -rf *~ *.o *.a *.d *.so.* *.so *.dylib zita-resampler/*~ + diff --git a/libs/cresampler.cc b/libs/cresampler.cc new file mode 100644 index 0000000..ca3cabf --- /dev/null +++ b/libs/cresampler.cc @@ -0,0 +1,192 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2013 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 +#include +#include +#include +#include + + +CResampler::CResampler (void) : + _nchan (0), + _buff (0) +{ + reset (); +} + + +CResampler::~CResampler (void) +{ + clear (); +} + + +int CResampler::setup (double ratio, + unsigned int nchan) +{ + if (! nchan) return 1; + clear (); + _inmax = 50; + _buff = new float [nchan * (3 + _inmax)]; + _nchan = nchan; + _pstep = 1 / ratio; + return reset (); +} + + +void CResampler::clear (void) +{ + delete[] _buff; + _buff = 0; + _nchan = 0; + _inmax = 0; + _pstep = 0; + reset (); +} + + +void CResampler::set_phase (double p) +{ + _phase = p - floor (p); +} + + +void CResampler::set_ratio (double r) +{ + _pstep = 1.0 / r; +} + + +double CResampler::inpdist (void) const +{ + return (int)(3 - _nread) - _phase; +} + + +int CResampler::inpsize (void) const +{ + return 4; +} + + +int CResampler::reset (void) +{ + inp_count = 0; + out_count = 0; + inp_data = 0; + out_data = 0; + _index = 0; + _phase = 0; + _nread = 4; + _nzero = 0; + return 0; +} + + +int CResampler::process (void) +{ + unsigned int in, nr, n, c; + int nz; + double ph; + float *pb, a, b, d, m0, m1, m2, m3; + + in = _index; + nr = _nread; + nz = _nzero; + ph = _phase; + pb = _buff + in * _nchan; + + while (out_count) + { + if (nr) + { + if (inp_count == 0) break; + n = (4 - nr) * _nchan; + if (inp_data) + { + for (c = 0; c < _nchan; c++) pb [n + c] = inp_data [c]; + inp_data += _nchan; + nz = 0; + } + else + { + for (c = 0; c < _nchan; c++) pb [n + c] = 0; + if (nz < 4) nz++; + } + nr--; + inp_count--; + } + else + { + n = _nchan; + if (out_data) + { + if (nz < 4) + { + a = ph; + b = 1 - a; + d = a * b / 2; + m0 = -d * b; + m1 = b + (3 * b - 1) * d; + m2 = a + (3 * a - 1) * d; + m3 = -d * a; + for (c = 0; c < n; c++) + { + *out_data++ = m0 * pb [0] + + m1 * pb [n] + + m2 * pb [2 * n] + + m3 * pb [3 * n]; + pb++; + } + pb -= n; + } + else + { + for (c = 0; c < n; c++) *out_data++ = 0; + } + } + out_count--; + + ph += _pstep; + if (ph >= 1.0) + { + nr = (unsigned int) floor (ph); + ph -= nr; + in += nr; + pb += nr * _nchan; + if (in >= _inmax) + { + memcpy (_buff, pb, (4 - nr) * _nchan * sizeof (float)); + in = 0; + pb = _buff; + } + } + } + } + + _index = in; + _nread = nr; + _nzero = nz; + _phase = ph; + + return 0; +} + diff --git a/libs/resampler-table.cc b/libs/resampler-table.cc new file mode 100644 index 0000000..daaf9f3 --- /dev/null +++ b/libs/resampler-table.cc @@ -0,0 +1,161 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2006-2012 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 +#include +#include +#include +#include + + +int zita_resampler_major_version (void) +{ + return ZITA_RESAMPLER_MAJOR_VERSION; +} + + +int zita_resampler_minor_version (void) +{ + return ZITA_RESAMPLER_MINOR_VERSION; +} + + +static double sinc (double x) +{ + x = fabs (x); + if (x < 1e-6) return 1.0; + x *= M_PI; + return sin (x) / x; +} + + +static double wind (double x) +{ + x = fabs (x); + if (x >= 1.0) return 0.0f; + x *= M_PI; + return 0.384 + 0.500 * cos (x) + 0.116 * cos (2 * x); +} + + + +Resampler_table *Resampler_table::_list = 0; +Resampler_mutex Resampler_table::_mutex; + + +Resampler_table::Resampler_table (double fr, unsigned int hl, unsigned int np) : + _next (0), + _refc (0), + _fr (fr), + _hl (hl), + _np (np) +{ + unsigned int i, j; + double t; + float *p; + + _ctab = new float [hl * (np + 1)]; + p = _ctab; + for (j = 0; j <= np; j++) + { + t = (double) j / (double) np; + for (i = 0; i < hl; i++) + { + p [hl - i - 1] = (float)(fr * sinc (t * fr) * wind (t / hl)); + t += 1; + } + p += hl; + } +} + + +Resampler_table::~Resampler_table (void) +{ + delete[] _ctab; +} + + +Resampler_table *Resampler_table::create (double fr, unsigned int hl, unsigned int np) +{ + Resampler_table *P; + + _mutex.lock (); + P = _list; + while (P) + { + if ((fr >= P->_fr * 0.999) && (fr <= P->_fr * 1.001) && (hl == P->_hl) && (np == P->_np)) + { + P->_refc++; + _mutex.unlock (); + return P; + } + P = P->_next; + } + P = new Resampler_table (fr, hl, np); + P->_refc = 1; + P->_next = _list; + _list = P; + _mutex.unlock (); + return P; +} + + +void Resampler_table::destroy (Resampler_table *T) +{ + Resampler_table *P, *Q; + + _mutex.lock (); + if (T) + { + T->_refc--; + if (T->_refc == 0) + { + P = _list; + Q = 0; + while (P) + { + if (P == T) + { + if (Q) Q->_next = T->_next; + else _list = T->_next; + break; + } + Q = P; + P = P->_next; + } + delete T; + } + } + _mutex.unlock (); +} + + +void Resampler_table::print_list (void) +{ + Resampler_table *P; + + printf ("Resampler table\n----\n"); + for (P = _list; P; P = P->_next) + { + printf ("refc = %3d fr = %10.6lf hl = %4d np = %4d\n", P->_refc, P->_fr, P->_hl, P->_np); + } + printf ("----\n\n"); +} + diff --git a/libs/resampler.cc b/libs/resampler.cc new file mode 100644 index 0000000..097acfd --- /dev/null +++ b/libs/resampler.cc @@ -0,0 +1,263 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2006-2012 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 +#include +#include +#include +#include + + +static unsigned int gcd (unsigned int a, unsigned int b) +{ + if (a == 0) return b; + if (b == 0) return a; + while (1) + { + if (a > b) + { + a = a % b; + if (a == 0) return b; + if (a == 1) return 1; + } + else + { + b = b % a; + if (b == 0) return a; + if (b == 1) return 1; + } + } + return 1; +} + + +Resampler::Resampler (void) : + _table (0), + _nchan (0), + _buff (0) +{ + reset (); +} + + +Resampler::~Resampler (void) +{ + clear (); +} + + +int Resampler::setup (unsigned int fs_inp, + unsigned int fs_out, + unsigned int nchan, + unsigned int hlen) +{ + if ((hlen < 8) || (hlen > 96)) return 1; + return setup (fs_inp, fs_out, nchan, hlen, 1.0 - 2.6 / hlen); +} + + +int Resampler::setup (unsigned int fs_inp, + unsigned int fs_out, + unsigned int nchan, + unsigned int hlen, + double frel) +{ + unsigned int g, h, k, n, s; + double r; + float *B = 0; + Resampler_table *T = 0; + + k = s = 0; + if (fs_inp && fs_out && nchan) + { + r = (double) fs_out / (double) fs_inp; + g = gcd (fs_out, fs_inp); + n = fs_out / g; + s = fs_inp / g; + if ((16 * r >= 1) && (n <= 1000)) + { + h = hlen; + k = 250; + if (r < 1) + { + frel *= r; + h = (unsigned int)(ceil (h / r)); + k = (unsigned int)(ceil (k / r)); + } + T = Resampler_table::create (frel, h, n); + B = new float [nchan * (2 * h - 1 + k)]; + } + } + clear (); + if (T) + { + _table = T; + _buff = B; + _nchan = nchan; + _inmax = k; + _pstep = s; + return reset (); + } + else return 1; +} + + +void Resampler::clear (void) +{ + Resampler_table::destroy (_table); + delete[] _buff; + _buff = 0; + _table = 0; + _nchan = 0; + _inmax = 0; + _pstep = 0; + reset (); +} + + +double Resampler::inpdist (void) const +{ + if (!_table) return 0; + return (int)(_table->_hl + 1 - _nread) - (double)_phase / _table->_np; +} + + +int Resampler::inpsize (void) const +{ + if (!_table) return 0; + return 2 * _table->_hl; +} + + +int Resampler::reset (void) +{ + if (!_table) return 1; + + inp_count = 0; + out_count = 0; + inp_data = 0; + out_data = 0; + _index = 0; + _nread = 0; + _nzero = 0; + _phase = 0; + if (_table) + { + _nread = 2 * _table->_hl; + return 0; + } + return 1; +} + + +int Resampler::process (void) +{ + unsigned int hl, ph, np, dp, in, nr, nz, i, n, c; + float *p1, *p2; + + if (!_table) return 1; + + hl = _table->_hl; + np = _table->_np; + dp = _pstep; + in = _index; + nr = _nread; + ph = _phase; + nz = _nzero; + n = (2 * hl - nr) * _nchan; + p1 = _buff + in * _nchan; + p2 = p1 + n; + + while (out_count) + { + if (nr) + { + if (inp_count == 0) break; + if (inp_data) + { + for (c = 0; c < _nchan; c++) p2 [c] = inp_data [c]; + inp_data += _nchan; + nz = 0; + } + else + { + for (c = 0; c < _nchan; c++) p2 [c] = 0; + if (nz < 2 * hl) nz++; + } + nr--; + p2 += _nchan; + inp_count--; + } + else + { + if (out_data) + { + if (nz < 2 * hl) + { + float *c1 = _table->_ctab + hl * ph; + float *c2 = _table->_ctab + hl * (np - ph); + for (c = 0; c < _nchan; c++) + { + float *q1 = p1 + c; + float *q2 = p2 + c; + float s = 1e-20f; + for (i = 0; i < hl; i++) + { + q2 -= _nchan; + s += *q1 * c1 [i] + *q2 * c2 [i]; + q1 += _nchan; + } + *out_data++ = s - 1e-20f; + } + } + else + { + for (c = 0; c < _nchan; c++) *out_data++ = 0; + } + } + out_count--; + + ph += dp; + if (ph >= np) + { + nr = ph / np; + ph -= nr * np; + in += nr; + p1 += nr * _nchan;; + if (in >= _inmax) + { + n = (2 * hl - nr) * _nchan; + memcpy (_buff, p1, n * sizeof (float)); + in = 0; + p1 = _buff; + p2 = p1 + n; + } + } + } + } + _index = in; + _nread = nr; + _phase = ph; + _nzero = nz; + + return 0; +} + + diff --git a/libs/vresampler.cc b/libs/vresampler.cc new file mode 100644 index 0000000..c4e5ea3 --- /dev/null +++ b/libs/vresampler.cc @@ -0,0 +1,272 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2006-2013 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 +#include +#include +#include +#include + + +VResampler::VResampler (void) : + _table (0), + _nchan (0), + _buff (0), + _c1 (0), + _c2 (0) +{ + reset (); +} + + +VResampler::~VResampler (void) +{ + clear (); +} + + +int VResampler::setup (double ratio, + unsigned int nchan, + unsigned int hlen) +{ + if ((hlen < 8) || (hlen > 96) || (16 * ratio < 1) || (ratio > 256)) return 1; + return setup (ratio, nchan, hlen, 1.0 - 2.6 / hlen); +} + + +int VResampler::setup (double ratio, + unsigned int nchan, + unsigned int hlen, + double frel) +{ + unsigned int h, k, n; + double s; + Resampler_table *T = 0; + + if (! nchan) return 1; + n = NPHASE; + s = n / ratio; + h = hlen; + k = 250; + if (ratio < 1) + { + frel *= ratio; + h = (unsigned int)(ceil (h / ratio)); + k = (unsigned int)(ceil (k / ratio)); + } + T = Resampler_table::create (frel, h, n); + clear (); + if (T) + { + _table = T; + _buff = new float [nchan * (2 * h - 1 + k)]; + _c1 = new float [2 * h]; + _c2 = new float [2 * h]; + _nchan = nchan; + _inmax = k; + _ratio = ratio; + _pstep = s; + _qstep = s; + _wstep = 1; + return reset (); + } + else return 1; +} + + +void VResampler::clear (void) +{ + Resampler_table::destroy (_table); + delete[] _buff; + delete[] _c1; + delete[] _c2; + _buff = 0; + _c1 = 0; + _c2 = 0; + _table = 0; + _nchan = 0; + _inmax = 0; + _pstep = 0; + _qstep = 0; + _wstep = 1; + reset (); +} + + +void VResampler::set_phase (double p) +{ + if (!_table) return; + _phase = (p - floor (p)) * _table->_np; +} + + +void VResampler::set_rrfilt (double t) +{ + if (!_table) return; + _wstep = (t < 1) ? 1 : 1 - exp (-1 / t); +} + + +void VResampler::set_rratio (double r) +{ + if (!_table) return; + if (r > 16.0) r = 16.0; + if (r < 0.95) r = 0.95; + _qstep = _table->_np / (_ratio * r); +} + + +double VResampler::inpdist (void) const +{ + if (!_table) return 0; + return (int)(_table->_hl + 1 - _nread) - _phase / _table->_np; +} + + +int VResampler::inpsize (void) const +{ + if (!_table) return 0; + return 2 * _table->_hl; +} + + +int VResampler::reset (void) +{ + if (!_table) return 1; + + inp_count = 0; + out_count = 0; + inp_data = 0; + out_data = 0; + _index = 0; + _phase = 0; + _nread = 2 * _table->_hl; + _nzero = 0; + return 0; +} + + +int VResampler::process (void) +{ + unsigned int k, np, in, nr, n, c; + int i, hl, nz; + double ph, dp, dd; + float a, b, *p1, *p2, *q1, *q2; + + if (!_table) return 1; + + hl = _table->_hl; + np = _table->_np; + in = _index; + nr = _nread; + nz = _nzero; + ph = _phase; + dp = _pstep; + n = (2 * hl - nr) * _nchan; + p1 = _buff + in * _nchan; + p2 = p1 + n; + + while (out_count) + { + if (nr) + { + if (inp_count == 0) break; + if (inp_data) + { + for (c = 0; c < _nchan; c++) p2 [c] = inp_data [c]; + inp_data += _nchan; + nz = 0; + } + else + { + for (c = 0; c < _nchan; c++) p2 [c] = 0; + if (nz < 2 * hl) nz++; + } + nr--; + p2 += _nchan; + inp_count--; + } + else + { + if (out_data) + { + if (nz < 2 * hl) + { + k = (unsigned int) ph; + b = (float)(ph - k); + a = 1.0f - b; + q1 = _table->_ctab + hl * k; + q2 = _table->_ctab + hl * (np - k); + for (i = 0; i < hl; i++) + { + _c1 [i] = a * q1 [i] + b * q1 [i + hl]; + _c2 [i] = a * q2 [i] + b * q2 [i - hl]; + } + for (c = 0; c < _nchan; c++) + { + q1 = p1 + c; + q2 = p2 + c; + a = 1e-25f; + for (i = 0; i < hl; i++) + { + q2 -= _nchan; + a += *q1 * _c1 [i] + *q2 * _c2 [i]; + q1 += _nchan; + } + *out_data++ = a - 1e-25f; + } + } + else + { + for (c = 0; c < _nchan; c++) *out_data++ = 0; + } + } + out_count--; + + dd = _qstep - dp; + if (fabs (dd) < 1e-30) dp = _qstep; + else dp += _wstep * dd; + ph += dp; + if (ph >= np) + { + nr = (unsigned int) floor( ph / np); + ph -= nr * np;; + in += nr; + p1 += nr * _nchan;; + if (in >= _inmax) + { + n = (2 * hl - nr) * _nchan; + memcpy (_buff, p1, n * sizeof (float)); + in = 0; + p1 = _buff; + p2 = p1 + n; + } + } + } + } + _index = in; + _nread = nr; + _phase = ph; + _pstep = dp; + _nzero = nz; + + return 0; +} + diff --git a/libs/zita-resampler/cresampler.h b/libs/zita-resampler/cresampler.h new file mode 100644 index 0000000..b51ed44 --- /dev/null +++ b/libs/zita-resampler/cresampler.h @@ -0,0 +1,65 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2013 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 __CRESAMPLER_H +#define __CRESAMPLER_H + + +class CResampler +{ +public: + + CResampler (void); + ~CResampler (void); + + int setup (double ratio, + unsigned int nchan); + + void clear (void); + int reset (void); + int nchan (void) const { return _nchan; } + int inpsize (void) const; + double inpdist (void) const; + int process (void); + + void set_ratio (double r); + void set_phase (double p); + + unsigned int inp_count; + unsigned int out_count; + float *inp_data; + float *out_data; + void *inp_list; + void *out_list; + +private: + + unsigned int _nchan; + unsigned int _inmax; + unsigned int _index; + unsigned int _nread; + unsigned int _nzero; + double _phase; + double _pstep; + float *_buff; +}; + + +#endif diff --git a/libs/zita-resampler/resampler-table.h b/libs/zita-resampler/resampler-table.h new file mode 100644 index 0000000..22e694a --- /dev/null +++ b/libs/zita-resampler/resampler-table.h @@ -0,0 +1,80 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2006-2012 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 __RESAMPLER_TABLE_H +#define __RESAMPLER_TABLE_H + + +#include + + +#define ZITA_RESAMPLER_MAJOR_VERSION 1 +#define ZITA_RESAMPLER_MINOR_VERSION 6 + + +extern int zita_resampler_major_version (void); +extern int zita_resampler_minor_version (void); + + +class Resampler_mutex +{ +private: + + friend class Resampler_table; + + Resampler_mutex (void) { pthread_mutex_init (&_mutex, 0); } + ~Resampler_mutex (void) { pthread_mutex_destroy (&_mutex); } + void lock (void) { pthread_mutex_lock (&_mutex); } + void unlock (void) { pthread_mutex_unlock (&_mutex); } + + pthread_mutex_t _mutex; +}; + + +class Resampler_table +{ +public: + + static void print_list (void); + +private: + + Resampler_table (double fr, unsigned int hl, unsigned int np); + ~Resampler_table (void); + + friend class Resampler; + friend class VResampler; + + Resampler_table *_next; + unsigned int _refc; + float *_ctab; + double _fr; + unsigned int _hl; + unsigned int _np; + + static Resampler_table *create (double fr, unsigned int hl, unsigned int np); + static void destroy (Resampler_table *T); + + static Resampler_table *_list; + static Resampler_mutex _mutex; +}; + + +#endif diff --git a/libs/zita-resampler/resampler.h b/libs/zita-resampler/resampler.h new file mode 100644 index 0000000..5dbff4f --- /dev/null +++ b/libs/zita-resampler/resampler.h @@ -0,0 +1,76 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2006-2012 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 __RESAMPLER_H +#define __RESAMPLER_H + + +#include + + +class Resampler +{ +public: + + Resampler (void); + ~Resampler (void); + + int setup (unsigned int fs_inp, + unsigned int fs_out, + unsigned int nchan, + unsigned int hlen); + + int setup (unsigned int fs_inp, + unsigned int fs_out, + unsigned int nchan, + unsigned int hlen, + double frel); + + void clear (void); + int reset (void); + int nchan (void) const { return _nchan; } + int filtlen (void) const { return inpsize (); } // Deprecated + int inpsize (void) const; + double inpdist (void) const; + int process (void); + + unsigned int inp_count; + unsigned int out_count; + float *inp_data; + float *out_data; + void *inp_list; + void *out_list; + +private: + + Resampler_table *_table; + unsigned int _nchan; + unsigned int _inmax; + unsigned int _index; + unsigned int _nread; + unsigned int _nzero; + unsigned int _phase; + unsigned int _pstep; + float *_buff; + void *_dummy [8]; +}; + + +#endif diff --git a/libs/zita-resampler/vresampler.h b/libs/zita-resampler/vresampler.h new file mode 100644 index 0000000..95fefc4 --- /dev/null +++ b/libs/zita-resampler/vresampler.h @@ -0,0 +1,84 @@ +// ---------------------------------------------------------------------------- +// +// Copyright (C) 2006-2012 Fons Adriaensen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General 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 __VRESAMPLER_H +#define __VRESAMPLER_H + + +#include + + +class VResampler +{ +public: + + VResampler (void); + ~VResampler (void); + + int setup (double ratio, + unsigned int nchan, + unsigned int hlen); + + int setup (double ratio, + unsigned int nchan, + unsigned int hlen, + double frel); + + void clear (void); + int reset (void); + int nchan (void) const { return _nchan; } + int inpsize (void) const; + double inpdist (void) const; + int process (void); + + void set_phase (double p); + void set_rrfilt (double t); + void set_rratio (double r); + + unsigned int inp_count; + unsigned int out_count; + float *inp_data; + float *out_data; + void *inp_list; + void *out_list; + +private: + + enum { NPHASE = 256 }; + + Resampler_table *_table; + unsigned int _nchan; + unsigned int _inmax; + unsigned int _index; + unsigned int _nread; + unsigned int _nzero; + double _ratio; + double _phase; + double _pstep; + double _qstep; + double _wstep; + float *_buff; + float *_c1; + float *_c2; + void *_dummy [8]; +}; + + +#endif -- cgit v1.2.3