예제 #1
0
    def test_inverse_stft_window_fn_special_case(self):
        """Test inverse_stft_window_fn in special overlap = 3/4 case."""
        # Cases in which frame_length is an integer multiple of 4 * frame_step are
        # special because they allow exact reproduction of the waveform with a
        # squared Hann window (Hann window in both forward and reverse transforms).
        # In the case where frame_length = 4 * frame_step, that combination
        # produces a constant gain of 1.5, and so the corrected window will be the
        # Hann window / 1.5.

        # Tuples of (frame_length, frame_step).
        test_configs = [
            (256, 64),
            (128, 32),
        ]

        for (frame_length, frame_step) in test_configs:
            hann_window = window_ops.hann_window(frame_length,
                                                 dtype=dtypes.float32)
            inverse_window_fn = spectral_ops.inverse_stft_window_fn(frame_step)
            inverse_window = inverse_window_fn(frame_length,
                                               dtype=dtypes.float32)

            with self.test_session(use_gpu=True) as sess:
                hann_window, inverse_window = sess.run(
                    [hann_window, inverse_window])

            self.assertAllClose(hann_window, inverse_window * 1.5)
예제 #2
0
    def test_inverse_stft_window_fn(self):
        """Test that inverse_stft_window_fn has unit gain at each window phase."""
        # Tuples of (frame_length, frame_step).
        test_configs = [
            (256, 32),
            (256, 64),
            (128, 25),
            (127, 32),
            (128, 64),
        ]

        for (frame_length, frame_step) in test_configs:
            hann_window = window_ops.hann_window(frame_length,
                                                 dtype=dtypes.float32)
            inverse_window_fn = spectral_ops.inverse_stft_window_fn(frame_step)
            inverse_window = inverse_window_fn(frame_length,
                                               dtype=dtypes.float32)

            with self.test_session(use_gpu=True) as sess:
                hann_window, inverse_window = sess.run(
                    [hann_window, inverse_window])

            # Expect unit gain at each phase of the window.
            product_window = hann_window * inverse_window
            for i in range(frame_step):
                self.assertAllClose(1.0, np.sum(product_window[i::frame_step]))
예제 #3
0
    def test_stft_round_trip(self):
        # Tuples of (signal_length, frame_length, frame_step, fft_length,
        # threshold, corrected_threshold).
        test_configs = [
            # 87.5% overlap.
            (4096, 256, 32, 256, 1e-5, 1e-6),
            # 75% overlap.
            (4096, 256, 64, 256, 1e-5, 1e-6),
            # Odd frame hop.
            (4096, 128, 25, 128, 1e-3, 1e-6),
            # Odd frame length.
            (4096, 127, 32, 128, 1e-3, 1e-6),
            # 50% overlap.
            (4096, 128, 64, 128, 0.40, 1e-6),
        ]

        for (signal_length, frame_length, frame_step, fft_length, threshold,
             corrected_threshold) in test_configs:
            # Generate a random white Gaussian signal.
            signal = random_ops.random_normal([signal_length])

            with spectral_ops_test_util.fft_kernel_label_map(), (
                    self.test_session(use_gpu=True)) as sess:
                stft = spectral_ops.stft(signal,
                                         frame_length,
                                         frame_step,
                                         fft_length,
                                         pad_end=False)
                inverse_stft = spectral_ops.inverse_stft(
                    stft, frame_length, frame_step, fft_length)
                inverse_stft_corrected = spectral_ops.inverse_stft(
                    stft,
                    frame_length,
                    frame_step,
                    fft_length,
                    window_fn=spectral_ops.inverse_stft_window_fn(frame_step))
                signal, inverse_stft, inverse_stft_corrected = sess.run(
                    [signal, inverse_stft, inverse_stft_corrected])

                # Truncate signal to the size of inverse stft.
                signal = signal[:inverse_stft.shape[0]]

                # Ignore the frame_length samples at either edge.
                signal = signal[frame_length:-frame_length]
                inverse_stft = inverse_stft[frame_length:-frame_length]
                inverse_stft_corrected = inverse_stft_corrected[
                    frame_length:-frame_length]

                # Check that the inverse and original signal are close up to a scale
                # factor.
                inverse_stft_scaled = inverse_stft / np.mean(
                    np.abs(inverse_stft))
                signal_scaled = signal / np.mean(np.abs(signal))
                self.assertLess(np.std(inverse_stft_scaled - signal_scaled),
                                threshold)

                # Check that the inverse with correction and original signal are close.
                self.assertLess(np.std(inverse_stft_corrected - signal),
                                corrected_threshold)
예제 #4
0
  def test_stft_round_trip(self):
    # Tuples of (signal_length, frame_length, frame_step, fft_length,
    # threshold, corrected_threshold).
    test_configs = [
        # 87.5% overlap.
        (4096, 256, 32, 256, 1e-5, 1e-6),
        # 75% overlap.
        (4096, 256, 64, 256, 1e-5, 1e-6),
        # Odd frame hop.
        (4096, 128, 25, 128, 1e-3, 1e-6),
        # Odd frame length.
        (4096, 127, 32, 128, 1e-3, 1e-6),
        # 50% overlap.
        (4096, 128, 64, 128, 0.40, 1e-6),
    ]

    for (signal_length, frame_length, frame_step, fft_length, threshold,
         corrected_threshold) in test_configs:
      # Generate a random white Gaussian signal.
      signal = random_ops.random_normal([signal_length])

      with spectral_ops_test_util.fft_kernel_label_map(), (
          self.test_session(use_gpu=True)) as sess:
        stft = spectral_ops.stft(signal, frame_length, frame_step, fft_length,
                                 pad_end=False)
        inverse_stft = spectral_ops.inverse_stft(stft, frame_length, frame_step,
                                                 fft_length)
        inverse_stft_corrected = spectral_ops.inverse_stft(
            stft, frame_length, frame_step, fft_length,
            window_fn=spectral_ops.inverse_stft_window_fn(frame_step))
        signal, inverse_stft, inverse_stft_corrected = sess.run(
            [signal, inverse_stft, inverse_stft_corrected])

        # Truncate signal to the size of inverse stft.
        signal = signal[:inverse_stft.shape[0]]

        # Ignore the frame_length samples at either edge.
        signal = signal[frame_length:-frame_length]
        inverse_stft = inverse_stft[frame_length:-frame_length]
        inverse_stft_corrected = inverse_stft_corrected[
            frame_length:-frame_length]

        # Check that the inverse and original signal are close up to a scale
        # factor.
        inverse_stft_scaled = inverse_stft / np.mean(np.abs(inverse_stft))
        signal_scaled = signal / np.mean(np.abs(signal))
        self.assertLess(np.std(inverse_stft_scaled - signal_scaled), threshold)

        # Check that the inverse with correction and original signal are close.
        self.assertLess(np.std(inverse_stft_corrected - signal),
                        corrected_threshold)
예제 #5
0
  def test_inverse_stft_window_fn(self):
    """Test that inverse_stft_window_fn has unit gain at each window phase."""
    # Tuples of (frame_length, frame_step).
    test_configs = [
        (256, 32),
        (256, 64),
        (128, 25),
        (127, 32),
        (128, 64),
    ]

    for (frame_length, frame_step) in test_configs:
      hann_window = window_ops.hann_window(frame_length, dtype=dtypes.float32)
      inverse_window_fn = spectral_ops.inverse_stft_window_fn(frame_step)
      inverse_window = inverse_window_fn(frame_length, dtype=dtypes.float32)

      with self.test_session(use_gpu=True) as sess:
        hann_window, inverse_window = sess.run([hann_window, inverse_window])

      # Expect unit gain at each phase of the window.
      product_window = hann_window * inverse_window
      for i in range(frame_step):
        self.assertAllClose(1.0, np.sum(product_window[i::frame_step]))
예제 #6
0
  def test_inverse_stft_window_fn_special_case(self):
    """Test inverse_stft_window_fn in special overlap = 3/4 case."""
    # Cases in which frame_length is an integer multiple of 4 * frame_step are
    # special because they allow exact reproduction of the waveform with a
    # squared Hann window (Hann window in both forward and reverse transforms).
    # In the case where frame_length = 4 * frame_step, that combination
    # produces a constant gain of 1.5, and so the corrected window will be the
    # Hann window / 1.5.

    # Tuples of (frame_length, frame_step).
    test_configs = [
        (256, 64),
        (128, 32),
    ]

    for (frame_length, frame_step) in test_configs:
      hann_window = window_ops.hann_window(frame_length, dtype=dtypes.float32)
      inverse_window_fn = spectral_ops.inverse_stft_window_fn(frame_step)
      inverse_window = inverse_window_fn(frame_length, dtype=dtypes.float32)

      with self.test_session(use_gpu=True) as sess:
        hann_window, inverse_window = sess.run([hann_window, inverse_window])

      self.assertAllClose(hann_window, inverse_window * 1.5)