Exemple #1
0
    def test_FakeInterface_output(self):

        h_pri = np.random.normal(0, 1, 5)
        h_sec = np.random.normal(0, 1, 24)
        buffsize = 16
        buffers = 100
        signal = np.random.normal(0, 1, size=buffers * buffsize)
        sim = FakeInterface(buffsize, signal, h_pri=h_pri, h_sec=h_sec)

        ys = []
        xs = []
        es = []
        us = []
        ds = []

        for _ in range(buffers):
            y = np.random.normal(0, 1, buffsize)
            x, e, u, d = sim.playrec(y, send_signal=True)
            xs.append(x)
            es.append(e)
            ds.append(d)
            us.append(u)
            ys.append(y)

        y = np.concatenate(ys)
        x = np.concatenate(xs)
        e = np.concatenate(es)
        u = np.concatenate(us)
        d = np.concatenate(ds)

        assert np.all(x == signal)
        npt.assert_almost_equal(d, olafilt(h_pri, x))
        npt.assert_almost_equal(u, olafilt(h_sec, y))
        npt.assert_almost_equal(e, u + d)
Exemple #2
0
    def playrec(self, y, send_signal=True):
        """Simulatenously play through secondary path while recording the result.

        Parameters
        ----------
        y : (blocklength,) ndarray
            Control signal.
        send_signal : bool, optional
            If `False`, turn of the disturbance. Can be used to 'measure' the secondary
            path.

        Returns
        -------
        x, e, u, d : (blocklength,) ndarray
            Reference signal, error signal, control signal at error microphone, primary
            at error microphone.

        """
        if y is None:
            y = np.zeros((self.blocklength, *self._orig_h_sec.shape[3:4]))
        else:
            y = np.atleast_1d(y)

        if send_signal:
            x = np.atleast_1d(next(self.signal))  # reference signal
        else:
            x = np.zeros((self.blocklength, *self._orig_signal.shape[1:2]))

        subscripts_sec = (
            "nlm"[: self._orig_h_sec.ndim - 1] + "," + "nm"[: y.ndim] + "->n"
        )
        subscripts_pri = (
            "nlk"[: self._orig_h_pri.ndim - 1]
            + ","
            + "nk"[: self._orig_signal.ndim]
            + "->n"
        )
        if self._orig_h_sec.ndim - 1 > 1:
            subscripts_sec += "l"
            subscripts_pri += "l"

        # primary path signal at error mic
        d, self._zi_pri = olafilt(next(self.h_pri), x, subscripts_pri, zi=self._zi_pri)
        # secondary path signal at error mic
        u, self._zi_sec = olafilt(next(self.h_sec), y, subscripts_sec, zi=self._zi_sec)

        e = d + u  # error signal

        if self.noise is not None:
            e += next(self.noise)

        return x, e, u, d
Exemple #3
0
    def test_wiener_filter_unconstrained_causal(self):
        h = [1, -1, 0.5]
        x = np.random.normal(size=2**16)
        y = olafilt(h, x)

        h_est = -np.real(
            np.fft.ifft(wiener_filter(x, y, 32, constrained=False)))
        npt.assert_almost_equal(h, h_est[:len(h)], decimal=2)
Exemple #4
0
    def test_wiener_filter_constrained_noncausal(self):
        h = [1, 0, 1]
        x = np.random.normal(size=2**16)
        y = olafilt(h, x)

        h_est = -np.real(
            np.fft.ifft(wiener_filter(x, y, 256, g=[0, 1], constrained=True)))
        npt.assert_almost_equal([0, 1, 0], h_est[:len(h)], decimal=2)
Exemple #5
0
    def test_FakeInterface_output_multichannel(self):
        L, M, K = 10, 5, 3
        npri = 1024
        nsec = 512
        h_pri = np.random.normal(size=(npri, L, K))
        h_sec = np.random.normal(size=(nsec, L, M))

        buffsize = 16
        buffers = 100
        signal = np.random.normal(size=(buffers * buffsize, K))
        noise = np.random.normal(size=(buffers * buffsize, L))
        sim = FakeInterface(buffsize,
                            signal,
                            noise=noise,
                            h_pri=h_pri,
                            h_sec=h_sec)

        ys = []
        xs = []
        es = []
        us = []
        ds = []

        for _ in range(buffers):
            y = np.random.normal(size=(buffsize, M))
            x, e, u, d = sim.playrec(y, send_signal=True)
            ys.append(y)
            xs.append(x)
            es.append(e)
            ds.append(d)
            us.append(u)

        y = np.concatenate(ys)
        x = np.concatenate(xs)
        e = np.concatenate(es)
        u = np.concatenate(us)
        d = np.concatenate(ds)

        assert np.all(x == signal)
        npt.assert_almost_equal(d, olafilt(h_pri, x, "nlk,nk->nl"))
        npt.assert_almost_equal(u, olafilt(h_sec, y, "nlm,nm->nl"))
        npt.assert_almost_equal(e, u + d + noise)
Exemple #6
0
    def test_nozi_multiple_inputs(self):
        m = 123
        n = 1024
        L, M = (1, 3)
        h = np.random.normal(size=(m, L, M))
        x = np.random.normal(size=(n, ))

        yola = olafilt(h, x, "nlm,n->nl", zi=None)
        y = 0
        for m in range(M):
            yt = lfilter(h[:, 0, m], 1, x, zi=None)
            y += yt

        npt.assert_almost_equal(y, yola[:, 0])
Exemple #7
0
    def test_multiple_outputs(self):
        m = 123
        n = 1024
        L = 7
        h = np.random.normal(size=(m, L))
        x = np.random.normal(size=n)
        zi = np.random.normal(size=(m - 1, L))

        yola, zfola = olafilt(h, x, "nl,n->nl", zi=zi)

        for l in range(L):
            y, zf = lfilter(h[:, l], 1, x, zi=zi[:, l])
            npt.assert_almost_equal(y, yola[:, l])
            npt.assert_almost_equal(zf, zfola[:, l])
Exemple #8
0
        def test_shape(L, M, K):
            m = 123
            n = 1024
            h = np.random.normal(size=(m, L, M))
            x = np.random.normal(size=(n, K))

            yola = olafilt(h, x, "nlm,nk->nl")

            for l in range(L):
                y = 0
                for m in range(M):
                    for k in range(K):
                        y += lfilter(h[:, l, m], 1, x[:, k], zi=None)
                npt.assert_almost_equal(y, yola[:, l], err_msg=f"{L, M, K}")
Exemple #9
0
    def test_behaves_like_scipy(self):
        m = 123
        n = 1024
        h = np.random.normal(size=m)
        x = np.random.normal(size=n)
        zi = np.random.normal(size=m - 1)

        yola, zfola = olafilt(h, x, zi=zi)
        y, zf = lfilter(h, 1, x, zi=zi)

        npt.assert_almost_equal(yola, y)
        npt.assert_almost_equal(zfola, zf)

        assert np.array_equal(zi.shape, zfola.shape)
        assert np.array_equal(zi.shape, zf.shape)
Exemple #10
0
    def test_nozi_many_to_many(self):
        m = 123
        n = 1024
        L, M = (10, 5)

        h = np.random.normal(size=(m, L, M))
        x = np.random.normal(size=(n, ))

        yola = olafilt(h, x, "nlm,n->nl", zi=None)

        y = np.zeros((n, L))
        for l in range(L):
            for m in range(M):
                yt = lfilter(h[:, l, m], 1, x, zi=None)
                y[:, l] += yt

        npt.assert_almost_equal(y, yola)
Exemple #11
0
    def test_does_not_modify_inputs(self):
        m = 123
        n = 1024
        K, L = (4, 8)
        x = np.random.normal(size=(n, K))
        h = np.random.normal(size=(m, L, K))
        zi = np.random.normal(size=(m - 1, L))

        x0 = x.copy()
        zi0 = zi.copy()
        h0 = h.copy()

        yola, zfola = olafilt(h, x, "nlk,nk->nl", zi=zi)

        np.array_equal(h, h0)
        np.array_equal(x, x0)
        np.array_equal(zi, zi0)
Exemple #12
0
    def test_does_not_sum(self):
        m = 123
        n = 1024
        L, M, K = (4, 3, 2)
        h = np.random.normal(size=(m, L, M))
        x = np.random.normal(size=(n, K))
        zi = np.random.normal(size=(m - 1, L, M, K))

        yola, zfola = olafilt(h, x, "nlm,nk->nlmk", zi=zi)

        y = np.zeros((n, L))
        zf = np.zeros((m - 1, L))
        for l in range(L):
            for m in range(M):
                for k in range(K):
                    y, zf = lfilter(h[:, l, m], 1, x[:, k], zi=zi[:, l, m, k])
                    npt.assert_almost_equal(y, yola[:, l, m, k])
                    npt.assert_almost_equal(zf, zfola[:, l, m, k])
Exemple #13
0
    def test_filt(self):
        """MultiChannelBlockLMS.filt behaves like lfilter or olafilt."""
        for (M, K) in [(M, K) for M in range(1, 4) for K in range(1, 4)]:
            length = 16
            blocks = 16
            blocklength = 16
            w = np.random.normal(size=(length, M,
                                       K))  # Random filter coefficients
            xs = np.random.normal(size=(blocks, blocklength,
                                        K))  # blockwise input
            x = np.concatenate(xs)

            filt = MultiChannelBlockLMS(
                length=length,
                blocklength=blocklength,
                initial_coeff=w,
                Nin=K,
                Nout=M,
                Nsens=1,
            )

            # w set correctly
            npt.assert_almost_equal(w, filt.w)

            # many blocks
            y = []
            for xb in xs:
                xb_copy = xb.copy()
                y.append(filt.filt(xb))
                assert np.array_equal(xb_copy,
                                      xb)  # test that xb is not changed
            y = np.concatenate(y)

            npt.assert_almost_equal(olafilt(w, x, "nmk,nk->nm"),
                                    y)  # like olafilt

            yref = np.zeros(y.shape)
            for m in range(M):
                for k in range(K):
                    yref[:, m] += lfilter(w[:, m, k], 1, x[:, k])

            npt.assert_almost_equal(y, yref,
                                    err_msg=f"shape: {(M, K)}")  # like lfiter
Exemple #14
0
    def test_multiple_inputs(self):
        m = 123
        n = 1024
        L, M = (1, 3)
        h = np.random.normal(size=(m, L, M))
        x = np.random.normal(size=(n, ))
        ziall = np.random.normal(size=(m - 1, L, M))
        zi = ziall.sum(axis=-1)

        yola, zfola = olafilt(h, x, "nlm,n->nl", zi=zi)
        y = 0
        zf = 0
        for m in range(M):
            yt, zft = lfilter(h[:, 0, m], 1, x, zi=ziall[:, 0, m])
            y += yt
            zf += zft

        npt.assert_almost_equal(zf, zfola[:, 0])
        npt.assert_almost_equal(y, yola[:, 0])
Exemple #15
0
    def test_many_to_many(self):
        m = 123
        n = 1024
        L, M = (10, 5)

        x = np.random.normal(size=(n, ))
        h = np.random.normal(size=(m, L, M))
        ziall = np.random.normal(size=(m - 1, L, M))
        zi = ziall.sum(axis=-1)
        yola, zfola = olafilt(h, x, "nlm,n->nl", zi=zi)

        y = np.zeros((n, L))
        zf = np.zeros((m - 1, L))
        for l in range(L):
            for m in range(M):
                yt, zft = lfilter(h[:, l, m], 1, x, zi=ziall[:, l, m])
                y[:, l] += yt
                zf[:, l] += zft

        npt.assert_almost_equal(y, yola)
        npt.assert_almost_equal(zf, zfola)
Exemple #16
0
        def test_shape(L, M, K):
            m = 123
            n = 1024
            h = np.random.normal(size=(m, L, M))
            x = np.random.normal(size=(n, K))
            ziall = np.random.normal(size=(m - 1, L, M, K))
            zi = ziall.sum(axis=(-1, -2))

            yola, zfola = olafilt(h, x, "nlm,nk->nl", zi=zi)

            for l in range(L):
                y = 0
                zf = 0
                for m in range(M):
                    for k in range(K):
                        yt, zft = lfilter(h[:, l, m],
                                          1,
                                          x[:, k],
                                          zi=ziall[:, l, m, k])
                        y += yt
                        zf += zft
                npt.assert_almost_equal(y, yola[:, l], err_msg=f"{L, M, K}")
                npt.assert_almost_equal(zf, zfola[:, l], err_msg=f"{L, M, K}")
Exemple #17
0
signal = np.random.normal(0, 1, size=n_buffers * blocklength)

# the adaptive filter
filt = FastBlockLMSFilter(length, blocklength, stepsize=0.1, leakage=0.9999)

# secondary path estimate has to account for block size
plant_model = FIRFilter(np.concatenate((np.zeros(blocklength), h_sec)))

# simulates an audio interface with primary and secondary paths and 40 dB SNR noise
# at the error sensor
sim = FakeInterface(
    blocklength,
    signal,
    h_pri=h_pri,
    h_sec=h_sec,
    noise=wgn(olafilt(h_pri, signal), 40, "dB"),
)

elog = []
y = np.zeros(blocklength)  # control signal is zero for first block
for i in range(n_buffers):
    # record reference signal x and error signal e while playing back y
    x, e, _, _ = sim.playrec(-y)
    # filter the reference signal
    fx = plant_model(x)
    # adapt filter
    filt.adapt(fx, e)
    # filter
    y = filt.filt(x)
    # log error
    elog.append(e)