Пример #1
0
 def _phase_map(self):
     self.dphi = (2 * P.pi * self.nhop *
                  P.arange(self.nfft / 2 + 1)) / self.nfft
     A = P.diff(P.angle(self.STFT), 1)  # Complete Phase Map
     U = P.c_[P.angle(self.STFT[:, 0]), A - P.atleast_2d(self.dphi).T]
     U = U - P.np.round(U / (2 * P.pi)) * 2 * P.pi
     self.dPhi = U
     return U
Пример #2
0
 def _pvoc2(self, X_hat, Phi_hat=None, R=None):
     """
     ::
       alternate (batch) implementation of phase vocoder - time-stretch
       inputs:
         X_hat - estimate of signal magnitude
         [Phi_hat] - estimate of signal phase
         [R] - resynthesis hop ratio
       output:
         updates self.X_hat with modified complex spectrum
     """
     N, W, H = self.nfft, self.wfft, self.nhop
     R = 1.0 if R is None else R
     dphi = P.atleast_2d((2 * P.pi * H * P.arange(N / 2 + 1)) / N).T
     print("Phase Vocoder Resynthesis...", N, W, H, R)
     A = P.angle(self.STFT) if Phi_hat is None else Phi_hat
     U = P.diff(A, 1) - dphi
     U = U - P.np.round(U / (2 * P.pi)) * 2 * P.pi
     t = P.arange(0, n_cols, R)
     tf = t - P.floor(t)
     phs = P.c_[A[:, 0], U]
     phs += U[:, idx[1]] + dphi  # Problem, what is idx ?
     Xh = (1 - tf) * Xh[:-1] + tf * Xh[1:]
     Xh *= P.exp(1j * phs)
     self.X_hat = Xh
Пример #3
0
 def _pvoc(self, X_hat, Phi_hat=None, R=None):
     """
     ::
       a phase vocoder - time-stretch
       inputs:
         X_hat - estimate of signal magnitude
         [Phi_hat] - estimate of signal phase
         [R] - resynthesis hop ratio
       output:
         updates self.X_hat with modified complex spectrum
     """
     N = self.nfft
     W = self.wfft
     H = self.nhop
     R = 1.0 if R is None else R
     dphi = (2 * P.pi * H * P.arange(N / 2 + 1)) / N
     print("Phase Vocoder Resynthesis...", N, W, H, R)
     A = P.angle(self.STFT) if Phi_hat is None else Phi_hat
     phs = A[:, 0]
     self.X_hat = []
     n_cols = X_hat.shape[1]
     t = 0
     while P.floor(t) < n_cols:
         tf = t - P.floor(t)
         idx = P.arange(2) + int(P.floor(t))
         idx[1] = n_cols - 1 if t >= n_cols - 1 else idx[1]
         Xh = X_hat[:, idx]
         Xh = (1 - tf) * Xh[:, 0] + tf * Xh[:, 1]
         self.X_hat.append(Xh * P.exp(1j * phs))
         U = A[:, idx[1]] - A[:, idx[0]] - dphi
         U = U - P.np.round(U / (2 * P.pi)) * 2 * P.pi
         phs += (U + dphi)
         t += P.randn() * P.sqrt(PVOC_VAR * R) + R  # 10% variance
     self.X_hat = P.np.array(self.X_hat).T
Пример #4
0
def variable_phase_vocoder(D, times_steps, hop_length=None):
    n_fft = 2 * (D.shape[0] - 1)

    if hop_length is None:
        hop_length = int(n_fft // 4)

    # time_steps = P.arange(0, D.shape[1], rate, dtype=P.double)
    # time_steps = P.concatenate([
    #   P.arange(0, D.shape[1]/2, .5, dtype=P.double),
    #   P.arange(D.shape[1]/2, D.shape[1], 2, dtype=P.double)
    #   ])

    # Create an empty output array
    d_stretch = P.zeros((D.shape[0], len(time_steps)), D.dtype, order='F')

    # Expected phase advance in each bin
    phi_advance = P.linspace(0, P.pi * hop_length, D.shape[0])

    # Phase accumulator; initialize to the first sample
    phase_acc = P.angle(D[:, 0])

    # Pad 0 columns to simplify boundary logic
    D = P.pad(D, [(0, 0), (0, 2)], mode='constant')

    for (t, step) in enumerate(time_steps):
        columns = D[:, int(step):int(step + 2)]

        # Weighting for linear magnitude interpolation
        alpha = P.mod(step, 1.0)
        mag = ((1.0 - alpha) * abs(columns[:, 0]) + alpha * abs(columns[:, 1]))

        # Store to output array
        d_stretch[:, t] = mag * P.exp(1.j * phase_acc)

        # Compute phase advance
        dphase = (P.angle(columns[:, 1]) - P.angle(columns[:, 0]) -
                  phi_advance)

        # Wrap to -pi:pi range
        dphase = dphase - 2.0 * P.pi * P.around(dphase / (2.0 * P.pi))

        # Accumulate phase
        phase_acc += phi_advance + dphase

    return d_stretch
Пример #5
0
    def _istftm(self,
                X_hat=None,
                Phi_hat=None,
                pvoc=False,
                usewin=True,
                resamp=None):
        """
        ::
            Inverse short-time Fourier transform magnitude. Make a signal from a |STFT| transform.
            Uses phases from self.STFT if Phi_hat is None.

            Inputs:
            X_hat - N/2+1 magnitude STFT [None=abs(self.STFT)]
            Phi_hat - N/2+1 phase STFT   [None=exp(1j*angle(self.STFT))]
            pvoc - whether to use phase vocoder [False]
            usewin - whether to use overlap-add [False]

            Returns:
             x_hat - estimated signal
        """
        if not self._have_stft:
            return None
        X_hat = self.X if X_hat is None else P.np.abs(X_hat)
        if pvoc:
            self._pvoc(X_hat, Phi_hat, pvoc)
        else:
            Phi_hat = P.angle(self.STFT) if Phi_hat is None else Phi_hat
            self.X_hat = X_hat * P.exp(1j * Phi_hat)
        if usewin:
            if self.win is None:
                self.win = P.ones(
                    self.wfft) if self.window == 'rect' else P.np.sqrt(
                        P.hanning(self.wfft))
            if len(self.win) != self.nfft:
                self.win = P.r_[self.win, P.np.zeros(self.nfft - self.wfft)]
            if len(self.win) != self.nfft:
                error.BregmanError(
                    "features_base.Features._istftm(): assertion failed len(self.win)==self.nfft"
                )
        else:
            self.win = P.ones(self.nfft)
        if resamp:
            self.win = sig.resample(self.win,
                                    int(P.np.round(self.nfft * resamp)))
        fp = self._check_feature_params()
        self.x_hat = self._overlap_add(P.real(P.irfft(self.X_hat.T)),
                                       usewin=usewin,
                                       resamp=resamp)
        if self.verbosity:
            print("Extracted iSTFTM->self.x_hat")
        return self.x_hat