diff -Nru octave-signal-1.4.0/debian/changelog octave-signal-1.4.1/debian/changelog --- octave-signal-1.4.0/debian/changelog 2019-01-03 00:57:43.000000000 +0000 +++ octave-signal-1.4.1/debian/changelog 2019-07-10 08:22:14.000000000 +0000 @@ -1,3 +1,19 @@ +octave-signal (1.4.1-2) unstable; urgency=medium + + * Upload to unstable + * d/copyright: Add copyright and license information for the AppStream file + * d/control: Bump Standards-Version to 4.4.0 (no changes needed) + + -- Rafael Laboissiere Wed, 10 Jul 2019 05:22:14 -0300 + +octave-signal (1.4.1-1) experimental; urgency=medium + + * New upstream version 1.4.1 + * d/p/impinvar-tol.patch: Drop patch (applied upstream) + * d/changelog: Reflect upstream changes + + -- Rafael Laboissiere Fri, 12 Apr 2019 17:40:37 -0300 + octave-signal (1.4.0-3) unstable; urgency=medium * d/control: diff -Nru octave-signal-1.4.0/debian/control octave-signal-1.4.1/debian/control --- octave-signal-1.4.0/debian/control 2019-01-01 12:20:09.000000000 +0000 +++ octave-signal-1.4.1/debian/control 2019-07-09 10:19:55.000000000 +0000 @@ -8,7 +8,7 @@ dh-octave, octave-control (>= 3.1.0) Build-Conflicts: octave-nan -Standards-Version: 4.3.0 +Standards-Version: 4.4.0 Homepage: https://octave.sourceforge.io/signal/ Vcs-Git: https://salsa.debian.org/pkg-octave-team/octave-signal.git Vcs-Browser: https://salsa.debian.org/pkg-octave-team/octave-signal diff -Nru octave-signal-1.4.0/debian/copyright octave-signal-1.4.1/debian/copyright --- octave-signal-1.4.0/debian/copyright 2019-01-03 00:28:21.000000000 +0000 +++ octave-signal-1.4.1/debian/copyright 2019-05-23 09:15:41.000000000 +0000 @@ -46,7 +46,7 @@ 2011-2013 Carnë Draug 2012 Robert T. Short 2012-2013 Lukas F. Reichlin - 2012-2018 Mike Miller + 2012-2019 Mike Miller 2013 Rob Sykes 2014 Georgios Ouzounis 2015 Andreas Weber @@ -54,6 +54,7 @@ 2018 Charles Praplan 2018 Leonardo Araujo 2018 P Sudeepam + 2018 John W. Eaton License: GPL-3+ Files: inst/downsample.m inst/dst.m inst/flattopwin.m inst/fwhm.m @@ -62,6 +63,14 @@ License: public-domain This program is granted to the public domain. +Files: io.sourceforge.octave.signal.metainfo.xml +Copyright: 2018-2019 Mike Miller +License: FSFAP + 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. + Files: debian/* Copyright: 2008 Ólafur Jens Sigurðsson 2008-2010 Thomas Weber diff -Nru octave-signal-1.4.0/debian/patches/impinvar-tol.patch octave-signal-1.4.1/debian/patches/impinvar-tol.patch --- octave-signal-1.4.0/debian/patches/impinvar-tol.patch 2018-05-10 07:31:23.000000000 +0000 +++ octave-signal-1.4.1/debian/patches/impinvar-tol.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -Description: impinvar: relax tolerance on failing unit test on some arches -Author: Mike Miller -Origin: upstream, http://hg.code.sf.net/p/octave/signal/rev/93e527afc51d -Last-Update: 2018-05-09 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- a/inst/impinvar.m -+++ b/inst/impinvar.m -@@ -136,7 +136,10 @@ - %! - %!assert(stozerr([1],[1 1],100),0,0.0001); - %!assert(stozerr([1],[1 2 1],100),0,0.0001); --%!assert(stozerr([1 1],[1 2 1],100),0,0.0001); -+## FIXME: The following test needs a wider tolerance on some systems -+## (arm64, i386, powerpc). Is this a problem in this function or -+## in the control package that needs to be fixed? -+%!assert(stozerr([1 1],[1 2 1],100),0,0.0002); - %!assert(stozerr([1],[1 3 3 1],100),0,0.0001); - %!assert(stozerr([1 1],[1 3 3 1],100),0,0.0001); - %!assert(stozerr([1 1 1],[1 3 3 1],100),0,0.0001); diff -Nru octave-signal-1.4.0/debian/patches/series octave-signal-1.4.1/debian/patches/series --- octave-signal-1.4.0/debian/patches/series 2018-05-10 07:31:23.000000000 +0000 +++ octave-signal-1.4.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -impinvar-tol.patch diff -Nru octave-signal-1.4.0/DESCRIPTION octave-signal-1.4.1/DESCRIPTION --- octave-signal-1.4.0/DESCRIPTION 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/DESCRIPTION 2019-02-08 22:00:37.000000000 +0000 @@ -1,6 +1,6 @@ Name: signal -Version: 1.4.0 -Date: 2018-04-30 +Version: 1.4.1 +Date: 2019-02-08 Author: various authors Maintainer: Mike Miller Title: Signal Processing diff -Nru octave-signal-1.4.0/inst/bitrevorder.m octave-signal-1.4.1/inst/bitrevorder.m --- octave-signal-1.4.0/inst/bitrevorder.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/bitrevorder.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,5 @@ ## Copyright (C) 2007 Sylvain Pelissier -## Copyright (C) 2013-2018 Mike Miller +## Copyright (C) 2013-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/butter.m octave-signal-1.4.1/inst/butter.m --- octave-signal-1.4.0/inst/butter.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/butter.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,6 +1,7 @@ ## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2003 Doug Stewart ## Copyright (C) 2011 Alexander Klein +## Copyright (C) 2018 John W. Eaton ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -17,37 +18,69 @@ ## . ## -*- texinfo -*- -## @deftypefn {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{w}) -## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{w}, "high") -## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, [@var{wl}, @var{wh}]) -## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, [@var{wl}, @var{wh}], "stop") +## @deftypefn {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{wc}) +## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{wc}, @var{filter_type}) ## @deftypefnx {Function File} {[@var{z}, @var{p}, @var{g}] =} butter (@dots{}) ## @deftypefnx {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} butter (@dots{}) ## @deftypefnx {Function File} {[@dots{}] =} butter (@dots{}, "s") ## Generate a Butterworth filter. ## Default is a discrete space (Z) filter. ## -## [b,a] = butter(n, Wc) -## low pass filter with cutoff pi*Wc radians +## The cutoff frequency, @var{wc} should be specified in radians for +## analog filters. For digital filters, it must be a value between zero +## and one. For bandpass filters, @var{wc} is a two-element vector +## with @code{w(1) < w(2)}. ## -## [b,a] = butter(n, Wc, 'high') -## high pass filter with cutoff pi*Wc radians +## The filter type must be one of @qcode{"low"}, @qcode{"high"}, +## @qcode{"bandpass"}, or @qcode{"stop"}. The default is @qcode{"low"} +## if @var{wc} is a scalar and @qcode{"bandpass"} if @var{wc} is a +## two-element vector. ## -## [b,a] = butter(n, [Wl, Wh]) -## band pass filter with edges pi*Wl and pi*Wh radians +## If the final input argument is @qcode{"s"} design an analog Laplace +## space filter. ## -## [b,a] = butter(n, [Wl, Wh], 'stop') -## band reject filter with edges pi*Wl and pi*Wh radians +## Low pass filter with cutoff @code{pi*Wc} radians: ## -## [z,p,g] = butter(...) -## return filter as zero-pole-gain rather than coefficients of the -## numerator and denominator polynomials. +## @example +## [b, a] = butter (n, Wc) +## @end example ## -## [...] = butter(...,'s') -## return a Laplace space filter, W can be larger than 1. +## High pass filter with cutoff @code{pi*Wc} radians: ## -## [a,b,c,d] = butter(...) -## return state-space matrices +## @example +## [b, a] = butter (n, Wc, "high") +## @end example +## +## Band pass filter with edges @code{pi*Wl} and @code{pi*Wh} radians: +## +## @example +## [b, a] = butter (n, [Wl, Wh]) +## @end example +## +## Band reject filter with edges @code{pi*Wl} and @code{pi*Wh} radians: +## +## @example +## [b, a] = butter (n, [Wl, Wh], "stop") +## @end example +## +## Return filter as zero-pole-gain rather than coefficients of the +## numerator and denominator polynomials: +## +## @example +## [z, p, g] = butter (@dots{}) +## @end example +## +## Return a Laplace space filter, @var{Wc} can be larger than 1: +## +## @example +## [@dots{}] = butter (@dots{}, "s") +## @end example +## +## Return state-space matrices: +## +## @example +## [a, b, c, d] = butter (@dots{}) +## @end example ## ## References: ## @@ -55,50 +88,90 @@ ## Macmillan Publishing Company. ## @end deftypefn -function [a, b, c, d] = butter (n, w, varargin) +function [a, b, c, d] = butter (n, wc, varargin) if (nargin > 4 || nargin < 2 || nargout > 4) print_usage (); endif - ## interpret the input parameters + type = "lowpass"; + stop = false; + digital = true; + if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("butter: filter order N must be a positive integer"); endif - stop = false; - digital = true; - for i = 1:numel (varargin) - switch (varargin{i}) + if (! isvector (wc) || numel (wc) > 2) + error ("butter: cutoff frequency must be given as WC or [WL, WH]"); + endif + + if (numel (wc) == 2) + if (wc(1) > wc(2)) + error ("butter: W(1) must be less than W(2)"); + endif + type = "bandpass"; + stop = false; + endif + + ## Is final argument "s" (or "z")? + if (numel (varargin) > 0) + switch (varargin{end}) case "s" digital = false; + varargin(end) = []; case "z" - digital = true; + ## This is the default setting. + ## Accept "z" for backward compatibility with older versions + ## of Octave's signal processing package. + varargin(end) = []; + endswitch + endif + + ## Is filter type specified? + if (numel (varargin) > 0) + switch (varargin{end}) case {"high", "stop"} + type = varargin{end}; stop = true; - case {"low", "pass"} + varargin(end) = []; + case {"low", "bandpass"} + type = varargin{end}; + stop = false; + varargin(end) = []; + case "pass" + ## Accept "pass" for backward compatibility with older versions + ## of Octave's signal processing package. + type = "bandpass"; stop = false; + varargin(end) = []; otherwise - error ("butter: expected [high|stop] or [s|z]"); + error ("butter: expected 'high', 'stop', 'low', 'bandpass', or 's'"); endswitch - endfor + endif - if (! ((numel (w) <= 2) && (rows (w) == 1 || columns (w) == 1))) - error ("butter: frequency must be given as WC or [WL, WH]"); - elseif ((numel (w) == 2) && (w(2) <= w(1))) - error ("butter: W(1) must be less than W(2)"); + if (numel (varargin) > 0) + ## Invalid arguments. For example: butter (n, wc, "s", "high"). + print_usage (); endif - if (digital && ! all ((w >= 0) & (w <= 1))) - error ("butter: all elements of W must be in the range [0,1]"); - elseif (! digital && ! all (w >= 0)) - error ("butter: all elements of W must be in the range [0,inf]"); + switch (type) + case {"stop", "bandpass"} + if (numel (wc) != 2) + error ("butter: Wc must be two elements for stop and bandpass filters"); + endif + endswitch + + if (digital && ! all ((wc >= 0) & (wc <= 1))) + error ("butter: all elements of Wc must be in the range [0,1]"); + elseif (! digital && ! all (wc >= 0)) + error ("butter: all elements of Wc must be in the range [0,inf]"); endif ## Prewarp to the band edges to s plane if (digital) T = 2; # sampling frequency of 2 Hz - w = 2 / T * tan (pi * w / T); + wc = 2 / T * tan (pi * wc / T); endif ## Generate splane poles for the prototype Butterworth filter @@ -112,7 +185,7 @@ gain = C^n; ## splane frequency transform - [zero, pole, gain] = sftrans (zero, pole, gain, w, stop); + [zero, pole, gain] = sftrans (zero, pole, gain, wc, stop); ## Use bilinear transform to convert poles to the z plane if (digital) @@ -180,6 +253,11 @@ %!error [a, b] = butter (.5, .2) %!error [a, b] = butter (3, .2, "invalid") +%!error [a, b] = butter (9, .6, "stop") +%!error [a, b] = butter (9, .6, "bandpass") + +%!error [a, b] = butter (9, .6, "s", "high") + %% Test output orientation %!test %! butter (9, .6); diff -Nru octave-signal-1.4.0/inst/cceps.m octave-signal-1.4.1/inst/cceps.m --- octave-signal-1.4.0/inst/cceps.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/cceps.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,5 @@ ## Copyright (C) 1994 Dept of Probability Theory and Statistics TU Wien +## Copyright (C) 2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -22,16 +23,12 @@ ## method is applied. The default is not to do this. ## @end deftypefn -## Author: Andreas Weingessel -## Apr 1, 1994 -## Last modified by AW on Nov 8, 1994 - function cep = cceps (x, c) if (nargin == 1) - c = 0; + c = false; elseif (nargin != 2) - print_usage; + print_usage (); endif [nr, nc] = size (x); @@ -40,12 +37,11 @@ x = x'; nr = nc; else - error ("cceps: x must be a vector"); + error ("cceps: X must be a vector"); endif endif - bad_signal_message = ["cceps: bad signal x, ", ... - "some Fourier coefficients are zero."]; + bad_signal_message = "cceps: signal X has some zero Fourier coefficients"; F = fft (x); if (min (abs (F)) == 0) @@ -54,7 +50,7 @@ ## determine if correction necessary half = fix (nr / 2); - cor = 0; + cor = false; if (2 * half == nr) cor = (c && (real (F (half + 1)) < 0)); if (cor) @@ -77,3 +73,15 @@ endif endfunction + +%!test +%! x = randn (256, 1); +%! c = cceps (x); +%! assert (size (c), size (x)) + +## Test input validation +%!error cceps () +%!error cceps (1, 2, 3) +%!error cceps (ones (4)) +%!error cceps (0) +%!error cceps (zeros (10, 1)) diff -Nru octave-signal-1.4.0/inst/cconv.m octave-signal-1.4.1/inst/cconv.m --- octave-signal-1.4.0/inst/cconv.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/cconv.m 2019-02-08 22:00:37.000000000 +0000 @@ -113,9 +113,9 @@ %!shared x %! x = [1, 2, 3, 4, 5]; -%!assert (cconv (x, 1), [1, 2, 3, 4, 5]) -%!assert (cconv (x', 1), [1; 2; 3; 4; 5]) -%!assert (cconv (x, [1 1]), [1, 3, 5, 7, 9, 5]) +%!assert (cconv (x, 1), [1, 2, 3, 4, 5], 2*eps) +%!assert (cconv (x', 1), [1; 2; 3; 4; 5], 2*eps) +%!assert (real (cconv (x, [1 1])), [1, 3, 5, 7, 9, 5], 2*eps) %!assert (cconv (x, [1 1], 3), [8, 12, 10]) %!assert (cconv ([2 1 2 1], [1 2 3 4]), [2 5 10 16 12 11 4], 1e-14) diff -Nru octave-signal-1.4.0/inst/chirp.m octave-signal-1.4.1/inst/chirp.m --- octave-signal-1.4.0/inst/chirp.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/chirp.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,5 @@ ## Copyright (C) 1999-2000 Paul Kienzle -## Copyright (C) 2018 Mike Miller +## Copyright (C) 2018-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/cplxreal.m octave-signal-1.4.1/inst/cplxreal.m --- octave-signal-1.4.0/inst/cplxreal.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/cplxreal.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,5 @@ ## Copyright (C) 2005 Julius O. Smith III -## Copyright (C) 2018 Mike Miller +## Copyright (C) 2018-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/digitrevorder.m octave-signal-1.4.1/inst/digitrevorder.m --- octave-signal-1.4.0/inst/digitrevorder.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/digitrevorder.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2013-2018 Mike Miller +## Copyright (C) 2013-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/filtfilt.m octave-signal-1.4.1/inst/filtfilt.m --- octave-signal-1.4.0/inst/filtfilt.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/filtfilt.m 2019-02-08 22:00:37.000000000 +0000 @@ -60,6 +60,11 @@ if la < n, a(n) = 0; endif if lb < n, b(n) = 0; endif + if (rows (x) <= lrefl) + error ("filtfilt: X must be a vector or matrix with length greater than %d", + lrefl); + endif + ## Compute a the initial state taking inspiration from ## Likhterov & Kopeika, 2003. "Hardware-efficient technique for ## minimizing startup transients in Direct Form II digital filters" @@ -91,6 +96,9 @@ %!error filtfilt (1, 2, 3, 4); +%!error filtfilt ([0.28, 0.71, 0.28], 1, rand ()) +%!error filtfilt ([0.28, 0.71, 0.28], 1, rand (6, 1)) + %!test %! randn('state',0); %! r = randn(1,200); diff -Nru octave-signal-1.4.0/inst/filtic.m octave-signal-1.4.1/inst/filtic.m --- octave-signal-1.4.0/inst/filtic.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/filtic.m 2019-02-08 22:00:37.000000000 +0000 @@ -72,6 +72,8 @@ zf(nz)=b(nz+1)*x(i)-a(nz+1)*y(i); endfor + zf = zf ./ a(1); + endfunction %!test @@ -139,3 +141,11 @@ %! y=[yy(N+2) yy(N+1)]; %! zf=filtic(b,a,y); %! assert(zf,zf_ref,8*eps); + +## Case when a(1) != 1 +%!test +%! a = [2, -3, 1]; +%! b = [4, -3]; +%! y = [0; 1]; +%! z = filtic (b, a, y); +%! assert (z, [-0.5; 0]); diff -Nru octave-signal-1.4.0/inst/fwht.m octave-signal-1.4.1/inst/fwht.m --- octave-signal-1.4.0/inst/fwht.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/fwht.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2013-2018 Mike Miller +## Copyright (C) 2013-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/gauspuls.m octave-signal-1.4.1/inst/gauspuls.m --- octave-signal-1.4.0/inst/gauspuls.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/gauspuls.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,5 @@ ## Copyright (C) 2007 Sylvain Pelissier -## Copyright (C) 2018 Mike Miller +## Copyright (C) 2018-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/hann.m octave-signal-1.4.1/inst/hann.m --- octave-signal-1.4.0/inst/hann.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/hann.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2014-2018 Mike Miller +## Copyright (C) 2014-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/ifwht.m octave-signal-1.4.1/inst/ifwht.m --- octave-signal-1.4.0/inst/ifwht.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/ifwht.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2013-2018 Mike Miller +## Copyright (C) 2013-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/impinvar.m octave-signal-1.4.1/inst/impinvar.m --- octave-signal-1.4.0/inst/impinvar.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/impinvar.m 2019-02-08 22:00:37.000000000 +0000 @@ -136,7 +136,10 @@ %! %!assert(stozerr([1],[1 1],100),0,0.0001); %!assert(stozerr([1],[1 2 1],100),0,0.0001); -%!assert(stozerr([1 1],[1 2 1],100),0,0.0001); +## FIXME: The following test needs a wider tolerance on some systems +## (arm64, i386, powerpc). Is this a problem in this function or +## in the control package that needs to be fixed? +%!assert(stozerr([1 1],[1 2 1],100),0,0.0002); %!assert(stozerr([1],[1 3 3 1],100),0,0.0001); %!assert(stozerr([1 1],[1 3 3 1],100),0,0.0001); %!assert(stozerr([1 1 1],[1 3 3 1],100),0,0.0001); diff -Nru octave-signal-1.4.0/inst/private/__fwht_opts__.m octave-signal-1.4.1/inst/private/__fwht_opts__.m --- octave-signal-1.4.0/inst/private/__fwht_opts__.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/private/__fwht_opts__.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2013-2018 Mike Miller +## Copyright (C) 2013-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/private/validate_filter_bands.m octave-signal-1.4.1/inst/private/validate_filter_bands.m --- octave-signal-1.4.0/inst/private/validate_filter_bands.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/private/validate_filter_bands.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2014-2018 Mike Miller +## Copyright (C) 2014-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/rceps.m octave-signal-1.4.1/inst/rceps.m --- octave-signal-1.4.0/inst/rceps.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/rceps.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,5 @@ ## Copyright (C) 1999 Paul Kienzle +## Copyright (C) 2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -15,116 +16,128 @@ ## . ## -*- texinfo -*- -## @deftypefn {Function File} {[@var{y}, @var{xm}] =} rceps (@var{x}) -## Produce the cepstrum of the signal x, and if desired, the minimum -## phase reconstruction of the signal x. If x is a matrix, do so -## for each column of the matrix. +## @deftypefn {Function File} {[@var{y}, @var{ym}] =} rceps (@var{x}) +## Return the cepstrum of the signal @var{x}. +## +## If @var{x} is a matrix, return the cepstrum of each column. +## +## If called with two output arguments, the minimum phase reconstruction of +## the signal @var{x} is returned in @var{ym}. +## +## For example: ## -## Example: ## @example ## @group -## f0 = 70; Fs = 10000; # 100 Hz fundamental, 10kHz sampling rate -## a = poly (0.985 * exp (1i*pi*[0.1, -0.1, 0.3, -0.3])); # two formants -## s = 0.005 * randn (1024, 1); # Noise excitation signal -## s(1:Fs/f0:length(s)) = 1; # Impulse glottal wave -## x = filter (1, a, s); # Speech signal in x -## [y, xm] = rceps (x .* hanning (1024)); # cepstrum and min phase reconstruction +## f0 = 70; Fs = 10000; # 100 Hz fundamental, 10kHz sampling rate +## a = poly (0.985 * exp (1i * pi * [0.1, -0.1, 0.3, -0.3])); # two formants +## s = 0.005 * randn (1024, 1); # Noise excitation signal +## s(1:Fs/f0:length(s)) = 1; # Impulse glottal wave +## x = filter (1, a, s); # Speech signal +## [y, ym] = rceps (x .* hanning (1024)); ## @end group ## @end example ## -## Reference -## Programs for digital signal processing. IEEE Press. -## New York: John Wiley & Sons. 1979. +## Reference: @cite{Programs for Digital Signal Processing}, IEEE Press, +## John Wiley & Sons, New York, 1979. ## @end deftypefn -function [y, ym] = rceps(x) +function [y, ym] = rceps (x) if (nargin != 1) - print_usage; + print_usage (); endif - f = abs(fft(x)); + + f = abs (fft (x)); if (any (f == 0)) error ("rceps: the spectrum of x contains zeros, unable to compute real cepstrum"); endif - y = real(ifft(log(f))); - if nargout == 2 - n=length(x); - if rows(x)==1 - if rem(n,2)==1 - ym = [y(1), 2*y(2:n/2+1), zeros(1,n/2)]; + + y = real (ifft (log (f))); + + if (nargout == 2) + n = length (x); + if (rows (x) == 1) + if (rem (n,2) == 1) + ym = [y(1), 2 * y(2:fix (n/2) + 1), zeros(1, fix (n/2))]; else - ym = [y(1), 2*y(2:n/2), y(n/2+1), zeros(1,n/2-1)]; + ym = [y(1), 2 * y(2:n/2), y(n/2 + 1), zeros(1, n/2 - 1)]; endif else - if rem(n,2)==1 - ym = [y(1,:); 2*y(2:n/2+1,:); zeros(n/2,columns(y))]; + if (rem (n,2) == 1) + ym = [y(1,:); 2 * y(2:fix (n/2) + 1,:); zeros(fix (n/2), columns (y))]; else - ym = [y(1,:); 2*y(2:n/2,:); y(n/2+1,:); zeros(n/2-1,columns(y))]; + ym = [y(1,:); 2 * y(2:n/2,:); y(n/2 + 1,:); zeros(n/2 - 1, columns (y))]; endif endif - ym = real(ifft(exp(fft(ym)))); + + ym = real (ifft (exp (fft (ym)))); endif endfunction -%!error rceps -%!error rceps(1,2) # too many arguments - %!test %! ## accepts matrices -%! x=randn(32,3); -%! [y, xm] = rceps(x); +%! x = randn (32, 3); +%! [y, xm] = rceps (x); %! ## check the mag-phase response of the reproduction -%! hx = fft(x); -%! hxm = fft(xm); -%! assert(abs(hx), abs(hxm), 200*eps); # good magnitude response match +%! hx = fft (x); +%! hxm = fft (xm); +%! assert (abs (hx), abs (hxm), 200*eps); # good magnitude response match %! ## FIXME: test for minimum phase? Stop using random datasets! -%! #assert(arg(hx) != arg(hxm)); # phase mismatch +%! #assert (arg (hx) != arg (hxm)); # phase mismatch %!test %! ## accepts column and row vectors -%! x=randn(256,1); -%! [y, xm] = rceps(x); -%! [yt, xmt] = rceps(x.'); -%! tol = 1e-14; -%! assert(yt.', y, tol); -%! assert(xmt.', xm, tol); +%! x = randn (256, 1); +%! [y, xm] = rceps (x); +%! [yt, xmt] = rceps (x.'); +%! assert (yt.', y, 1e-14); +%! assert (xmt.', xm, 1e-14); -%% Test that an odd-length input produces an odd-length output +## Test that an odd-length input produces an odd-length output %!test -%! x = randn(33, 4); -%! [y, xm] = rceps(x); -%! assert(size(y) == size(x)); -%! assert(size(xm) == size(x)); +%! x = randn (33, 4); +%! [y, xm] = rceps (x); +%! assert (size (y), size (x)); +%! assert (size (xm), size (x)); + +## Test input validation +%!error rceps +%!error rceps (1, 2) +%!error rceps (0) +%!error rceps (zeros (10, 1)) %!demo -%! f0=70; Fs=10000; # 100 Hz fundamental, 10kHz sampling rate -%! a=real(poly(0.985*exp(1i*pi*[0.1, -0.1, 0.3, -0.3]))); # two formants -%! s=0.05*randn(1024,1); # Noise excitation signal -%! s(floor(1:Fs/f0:length(s))) = 1; # Impulse glottal wave -%! x=filter(1,a,s); # Speech signal in x -%! [y, xm] = rceps(x); # cepstrum and minimum phase x -%! [hx, w] = freqz(x,1,[],Fs); hxm = freqz(xm); -%! figure(1); -%! subplot(311); -%! len = 1000 * fix (min (length (x), length (xm)) / 1000); -%! plot([0:len-1]*1000/Fs,x(1:len),'b;signal;'); -%! hold on; plot([0:len-1]*1000/Fs,xm(1:len),'g;reconstruction;'); -%! ylabel("amplitude"); xlabel("time (ms)"); -%! hold off; -%! subplot(312); -%! axis("ticy"); -%! plot(w,log(abs(hx)), ";magnitude;", ... -%! w,log(abs(hxm)),";reconstruction;"); -%! xlabel("frequency (Hz)"); -%! subplot(313); -%! axis("on"); -%! plot(w,unwrap(arg(hx))/(2*pi), ";phase;",... -%! w,unwrap(arg(hxm))/(2*pi),";reconstruction;"); -%! xlabel("frequency (Hz)"); +%! f0 = 70; Fs = 10000; # 100 Hz fundamental, 10 kHz sampling rate +%! a = real (poly (0.985 * exp (1i * pi * [0.1, -0.1, 0.3, -0.3]))); # two formants +%! s = 0.05 * randn (1024, 1); # Noise excitation signal +%! s(floor (1:Fs/f0:length (s))) = 1; # Impulse glottal wave +%! x = filter (1, a, s); # Speech signal in x +%! [y, xm] = rceps (x); # cepstrum and minimum phase x +%! [hx, w] = freqz (x, 1, [], Fs); +%! hxm = freqz (xm); +%! figure (1); +%! subplot (311); +%! len = 1000 * fix (min (length (x), length (xm)) / 1000); +%! plot ([0:len-1] * 1000 / Fs, x(1:len), "b;signal;", ... +%! [0:len-1] * 1000 / Fs, xm(1:len), "g;reconstruction;"); +%! ylabel ("Amplitude"); +%! xlabel ("Time (ms)"); +%! subplot (312); +%! axis ("ticy"); +%! plot (w, log (abs (hx)), ";magnitude;", ... +%! w, log (abs (hxm)), ";reconstruction;"); +%! xlabel ("Frequency (Hz)"); +%! subplot (313); +%! axis ("on"); +%! plot (w, unwrap (arg (hx)) / (2 * pi), ";phase;", ... +%! w, unwrap (arg (hxm)) / (2 * pi), ";reconstruction;"); +%! xlabel ("Frequency (Hz)"); %! len = 1000 * fix (length (y) / 1000); -%! figure(2); plot([0:len-1]*1000/Fs,y(1:len),';cepstrum;'); -%! ylabel("amplitude"); xlabel("quefrency (ms)"); +%! figure (2); +%! plot ([0:len-1] * 1000 / Fs, y(1:len), ";cepstrum;"); +%! ylabel ("Amplitude"); +%! xlabel ("Quefrency (ms)"); %! %------------------------------------------------------------- %! % confirm the magnitude spectrum is identical in the signal %! % and the reconstruction and that there are peaks in the diff -Nru octave-signal-1.4.0/inst/rectpuls.m octave-signal-1.4.1/inst/rectpuls.m --- octave-signal-1.4.0/inst/rectpuls.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/rectpuls.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,5 @@ ## Copyright (C) 2000 Paul Kienzle -## Copyright (C) 2018 Mike Miller +## Copyright (C) 2018-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/rssq.m octave-signal-1.4.1/inst/rssq.m --- octave-signal-1.4.0/inst/rssq.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/rssq.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2018 Mike Miller +## Copyright (C) 2018-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/sos2tf.m octave-signal-1.4.1/inst/sos2tf.m --- octave-signal-1.4.0/inst/sos2tf.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/sos2tf.m 2019-02-08 22:00:37.000000000 +0000 @@ -77,20 +77,46 @@ A=A(1:nA-1); nA=length(A); endwhile - B = B * g; + + B = B .* prod (g); endfunction %!test -%! B=[1 1]; -%! A=[1 0.5]; -%! [sos,g] = tf2sos(B,A); -%! [Bh,Ah] = sos2tf(sos,g); -%! assert({Bh,Ah},{B,A},10*eps); +%! B = [1, 1]; +%! A = [1, 0.5]; +%! [sos, g] = tf2sos (B, A); +%! [Bh, Ah] = sos2tf (sos, g); +%! assert (g, 1); +%! assert (Bh, B, 10*eps); +%! assert (Ah, A, 10*eps); + +%!test +%! B = [1, 0, 0, 0, 0, 1]; +%! A = [1, 0, 0, 0, 0, 0.9]; +%! [sos, g] = tf2sos (B, A); +%! [Bh, Ah] = sos2tf (sos, g); +%! assert (g, 1); +%! assert (Bh, B, 100*eps); +%! assert (Ah, A, 100*eps); +## Test that gain is applied to the B vector %!test -%! B=[1 0 0 0 0 1]; -%! A=[1 0 0 0 0 0.9]; -%! [sos,g] = tf2sos(B,A); -%! [Bh,Ah] = sos2tf(sos,g); -%! assert({Bh,Ah},{B,A},100*eps); +%! B = [1, 1]; +%! A = [1, 0.5]; +%! [sos, g] = tf2sos (B, A); +%! [Bh, Ah] = sos2tf (sos, 2); +%! assert (g, 1); +%! assert (Bh, 2 * B, 10*eps); +%! assert (Ah, A, 10*eps); + +## Test that a vector of gain is applied as the total product +%!test +%! B = [1, 1]; +%! A = [1, 0.5]; +%! [sos, g] = tf2sos (B, A); +%! [Bh, Ah] = sos2tf (sos, [2, 2, 2]); +%! assert (g, 1); +%! assert (Bh, 8 * B, 10*eps); +%! assert (Ah, A, 10*eps); + diff -Nru octave-signal-1.4.0/inst/tripuls.m octave-signal-1.4.1/inst/tripuls.m --- octave-signal-1.4.0/inst/tripuls.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/tripuls.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,5 @@ ## Copyright (C) 2001 Paul Kienzle -## Copyright (C) 2018 Mike Miller +## Copyright (C) 2018-2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by diff -Nru octave-signal-1.4.0/inst/tukeywin.m octave-signal-1.4.1/inst/tukeywin.m --- octave-signal-1.4.0/inst/tukeywin.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/tukeywin.m 2019-02-08 22:00:37.000000000 +0000 @@ -21,8 +21,8 @@ ## cosine-tapered window) of length @var{m}. @var{r} defines the ratio ## between the constant section and and the cosine section. It has to be ## between 0 and 1. The function returns a Hanning window for @var{r} -## equal to 0 and a full box for @var{r} equals to 1. The default value of -## @var{r} is 1/2. +## equal to 1 and a rectangular window for @var{r} equal to 0. +## The default value of @var{r} is 1/2. ## ## For a definition of the Tukey window, see e.g. Fredric J. Harris, ## "On the Use of Windows for Harmonic Analysis with the Discrete Fourier diff -Nru octave-signal-1.4.0/inst/zplane.m octave-signal-1.4.1/inst/zplane.m --- octave-signal-1.4.0/inst/zplane.m 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/inst/zplane.m 2019-02-08 22:00:37.000000000 +0000 @@ -1,5 +1,6 @@ ## Copyright (C) 1999, 2001 Paul Kienzle ## Copyright (C) 2004 Stefan van der Walt +## Copyright (C) 2019 Mike Miller ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -18,19 +19,16 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} zplane (@var{z}, @var{p}) ## @deftypefnx {Function File} {} zplane (@var{b}, @var{a}) +## Plot the poles and zeros on a complex plane. If the arguments are column +## vectors @var{z} and @var{p}, the complex zeros @var{z} and poles @var{p} +## are displayed. If the arguments are row vectors @var{b} and @var{a}, the +## zeros and poles of the transfer function represented by these filter +## coefficients are displayed. ## -## Plot the poles and zeros. If the arguments are row vectors then they -## represent filter coefficients (numerator polynomial b and denominator -## polynomial a), but if they are column vectors or matrices then they -## represent poles and zeros. -## -## This is a horrid interface, but I didn't choose it; better would be -## to accept b,a or z,p,g like other functions. The saving grace is -## that poly(x) always returns a row vector and roots(x) always returns -## a column vector, so it is usually right. You must only be careful -## when you are creating filters by hand. +## If @var{z} and @var{p} are matrices, the columns are distinct sets of zeros +## and poles and are displayed together in distinct colors. ## -## Note that due to the nature of the roots() function, poles and zeros +## Note that due to the nature of the @code{roots} function, poles and zeros ## may be displayed as occurring around a circle rather than at a single ## point. ## @@ -48,7 +46,8 @@ ## @end group ## @end example ## -## The denominator a defaults to 1, and the poles p defaults to []. +## If called with only one argument, the poles @var{p} defaults to an empty +## vector, and the denominator coefficient vector @var{a} defaults to 1. ## @end deftypefn ## FIXME: Consider a plot-like interface: @@ -90,46 +89,37 @@ ymin = ymin - yfluff; ymax = ymax + yfluff; - text(); - plot_with_labels(z, "o"); - plot_with_labels(p, "x"); - refresh; - - r = exp(2i*pi*[0:100]/100); - plot(real(r), imag(r),'k'); hold on; + r = exp (2i * pi * [0:100] / 100); + plot (real (r), imag (r), "k"); axis equal; grid on; - axis(1.05*[xmin, xmax, ymin, ymax]); - if (!isempty(p)) - h = plot(real(p), imag(p), "bx"); - set (h, 'MarkerSize', 7); - endif - if (!isempty(z)) - h = plot(real(z), imag(z), "bo"); - set (h, 'MarkerSize', 7); - endif + axis (1.05 * [xmin, xmax, ymin, ymax]); + + hold on; + plot_with_labels (z, "o"); + plot_with_labels (p, "x"); hold off; endfunction -function plot_with_labels(x, symbol) - - if ( !isempty(x) ) - - x_u = unique(x(:)); - - for i = 1:length(x_u) - n = sum(x_u(i) == x(:)); - if (n > 1) - text(real(x_u(i)), imag(x_u(i)), [" " num2str(n)]); - endif - endfor +function plot_with_labels (x, symbol) - col = "rgbcmy"; - for c = 1:columns(x) - plot(real( x(:,c) ), imag( x(:,c) ), [col(mod(c,6)),symbol ";;"]); + if (! isempty(x)) + colors = get (gca (), "colororder"); + for c = 1:columns (x) + color = colors(mod (c, rows (colors)), :); + plot (real (x(:,c)), imag (x(:,c)), "color", color, ... + "linestyle", "none", "marker", symbol); + + x_u = unique (x(:,c)); + for i = 1:length (x_u) + n = sum (x_u(i) == x(:,c)); + if (n > 1) + label = sprintf (" ^%d", n); + text (real (x_u(i)), imag (x_u(i)), label, "color", color); + endif + endfor endfor - endif endfunction @@ -138,37 +128,44 @@ %! ## construct target system: %! ## symmetric zero-pole pairs at r*exp(iw),r*exp(-iw) %! ## zero-pole singletons at s -%! pw=[0.2, 0.4, 0.45, 0.95]; #pw = [0.4]; -%! pr=[0.98, 0.98, 0.98, 0.96]; #pr = [0.85]; -%! ps=[]; -%! zw=[0.3]; # zw=[]; -%! zr=[0.95]; # zr=[]; -%! zs=[]; +%! pw = [0.2, 0.4, 0.45, 0.95]; # pw = [0.4]; +%! pr = [0.98, 0.98, 0.98, 0.96]; # pr = [0.85]; +%! ps = []; +%! zw = [0.3]; # zw=[]; +%! zr = [0.95]; # zr=[]; +%! zs = []; %! %! ## system function for target system -%! p=[[pr, pr].*exp(1i*pi*[pw, -pw]), ps]'; -%! z=[[zr, zr].*exp(1i*pi*[zw, -zw]), zs]'; -%! M = length(z); N = length(p); -%! sys_a = [ zeros(1, M-N), real(poly(p)) ]; -%! sys_b = [ zeros(1, N-M), real(poly(z)) ]; -%! disp("The first two graphs should be identical, with poles at (r,w)="); -%! disp(sprintf(" (%.2f,%.2f)", [pr ; pw])); -%! disp("and zeros at (r,w)="); -%! disp(sprintf(" (%.2f,%.2f)", [zr ; zw])); -%! disp("with reflection across the horizontal plane"); -%! subplot(231); -%! zplane(sys_b, sys_a); -%! title("transfer function form"); -%! subplot(232); -%! zplane(z,p); -%! title("pole-zero form"); -%! subplot(233); -%! zplane(z); -%! title("empty p"); -%! subplot(234); -%! zplane(sys_b); -%! title("empty a"); -%! disp("The matrix plot has 2 sets of points, one inside the other"); -%! subplot(235); -%! zplane([z, 0.7*z], [p, 0.7*p]); -%! title("matrix"); +%! p = [[pr, pr] .* exp(1i * pi * [pw, -pw]), ps]'; +%! z = [[zr, zr] .* exp(1i * pi * [zw, -zw]), zs]'; +%! M = length(z); +%! N = length(p); +%! sys_a = [zeros(1, M-N), real(poly(p))]; +%! sys_b = [zeros(1, N-M), real(poly(z))]; +%! +%! disp ("The first two graphs should be identical, with poles at (r,w) ="); +%! disp (sprintf(" (%.2f,%.2f)", [pr; pw])); +%! disp ("and zeros at (r,w) ="); +%! disp (sprintf(" (%.2f,%.2f)", [zr; zw])); +%! disp ("with reflection across the horizontal axis"); +%! +%! subplot (2, 3, 1); +%! zplane (sys_b, sys_a); +%! title ("Transfer function form"); +%! +%! subplot (2, 3, 2); +%! zplane (z, p); +%! title ("Zero pole form"); +%! +%! subplot (2, 3, 3); +%! zplane (z); +%! title ("Zeros only, p=[]"); +%! +%! subplot (2, 3, 4); +%! zplane (sys_b); +%! title ("Numerator only, a=1"); +%! +%! disp ("The matrix plot has 2 sets of points, one inside the other"); +%! subplot (2, 3, 5); +%! zplane ([z, 0.7*z], [p, 0.7*p]); +%! title ("Matrix of zeros and poles"); diff -Nru octave-signal-1.4.0/io.sourceforge.octave.signal.metainfo.xml octave-signal-1.4.1/io.sourceforge.octave.signal.metainfo.xml --- octave-signal-1.4.0/io.sourceforge.octave.signal.metainfo.xml 2018-04-30 20:48:31.000000000 +0000 +++ octave-signal-1.4.1/io.sourceforge.octave.signal.metainfo.xml 2019-02-08 22:00:37.000000000 +0000 @@ -1,6 +1,6 @@