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.cached_session(use_gpu=True) as sess:
                hann_window, inverse_window = self.evaluate(
                    [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]))
    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.cached_session(use_gpu=True) as sess:
                hann_window, inverse_window = self.evaluate(
                    [hann_window, inverse_window])

            self.assertAllClose(hann_window, inverse_window * 1.5)
示例#3
0
  def test_stft_round_trip(self, signal_length, frame_length, frame_step,
                           fft_length, np_rtype, threshold,
                           corrected_threshold):
    # Generate a random white Gaussian signal.
    signal = np.random.normal(size=signal_length).astype(np_rtype)

    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))
    inverse_stft, inverse_stft_corrected = self.evaluate(
        [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_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.cached_session(use_gpu=True) as sess:
        hann_window, inverse_window = self.evaluate(
            [hann_window, inverse_window])

      self.assertAllClose(hann_window, inverse_window * 1.5)
示例#5
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.cached_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)
示例#6
0
  def test_inverse_stft_window_fn(self, frame_length, frame_step):
    """Test that inverse_stft_window_fn has unit gain at each window phase."""
    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)
    hann_window, inverse_window = self.evaluate([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]))
示例#7
0
 def test_inverse_stft_window_fn_special_case(self, frame_length, frame_step):
   """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.
   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)
   self.assertAllClose(hann_window, inverse_window * 1.5)
示例#8
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.cached_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)
示例#9
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.cached_session(use_gpu=True) as sess:
        hann_window, inverse_window = self.evaluate(
            [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]))