예제 #1
0
def test_stft_istft_identity(ctx, window_size, stride, fft_size, window_type,
                             center, pad_mode):
    backend = ctx.backend[0].split(":")[0]
    if backend == 'cuda':
        pytest.skip(
            'CUDA Convolution N-D is only supported in CUDNN extension')

    x_shape = create_stft_input_shape(window_size)
    x = np.random.randn(*x_shape)

    # Skip for NOLA condition violation
    length = x_shape[1]
    if is_nola_violation(window_type, window_size, stride, fft_size, length,
                         center):
        pytest.skip('NOLA condition violation.')
        return

    x = nn.Variable.from_numpy_array(x)
    with nn.context_scope(ctx):
        yr, yi = F.stft(x, window_size, stride, fft_size, window_type, center,
                        pad_mode)
        z = F.istft(yr,
                    yi,
                    window_size,
                    stride,
                    fft_size,
                    window_type,
                    center,
                    pad_mode="constant")
    z.forward()

    assert (np.allclose(x.d, z.d, atol=1e-5, rtol=1e-5))
예제 #2
0
def test_istft_double_backward(ctx, seed, window_size, stride, fft_size, window_type, center, pad_mode, as_stft_backward):
    backend = ctx.backend[0].split(":")[0]
    if backend == 'cuda':
        pytest.skip('CUDA Convolution N-D is only supported in CUDNN extension')

    if not as_stft_backward:
        if pad_mode != "constant":
            pytest.skip(
                '`pad_mode != "constant"` is only for `as_stft_backward == True`')

    from nbla_test_utils import backward_function_tester
    rng = np.random.RandomState(seed)

    # Generate istft inputs by calling stft
    x_shape = create_stft_input_shape(window_size)
    stft_input = rng.randn(*x_shape).astype(np.float32)
    y_r, y_i = ref_stft(stft_input, window_size, stride,
                        fft_size, window_type, center, pad_mode, False)
    istft_inputs = [y_r, y_i]

    if not as_stft_backward:
        # Skip for NOLA condition violation
        length = x_shape[1]
        if is_nola_violation(window_type, window_size, stride, fft_size, length, center):
            pytest.skip('NOLA condition violation.')

    rng = np.random.RandomState(seed)
    func_args = [window_size, stride, fft_size,
                 window_type, center, pad_mode, as_stft_backward]
    backward_function_tester(rng, F.istft,
                             inputs=istft_inputs,
                             func_args=func_args,
                             ctx=ctx,
                             atol_accum=6e-2)
예제 #3
0
def test_istft_forward_backward(ctx, seed, window_size, stride, fft_size, window_type, center, pad_mode, as_stft_backward):
    backend = ctx.backend[0].split(":")[0]
    if backend == 'cuda':
        pytest.skip('CUDA Convolution N-D is only supported in CUDNN extension')

    if not as_stft_backward:
        if pad_mode != "constant":
            pytest.skip(
                '`pad_mode != "constant"` is only for `as_stft_backward == True`')

    func_name = "ISTFTCuda" if backend == 'cudnn' else "ISTFT"

    from nbla_test_utils import function_tester
    rng = np.random.RandomState(seed)

    # Generate istft inputs by calling stft
    x_shape = create_stft_input_shape(window_size)
    stft_input = rng.randn(*x_shape).astype(np.float32)
    y_r, y_i = ref_stft(stft_input, window_size, stride,
                        fft_size, window_type, center, pad_mode, False)
    istft_inputs = [y_r, y_i]

    # Check violation of NOLA condition
    if not as_stft_backward:
        length = x_shape[1]
        if is_nola_violation(window_type, window_size, stride, fft_size, length, center):
            check_nola_violation(
                y_r, y_i, window_size, stride, fft_size, window_type, center, pad_mode, as_stft_backward)
            return

    function_tester(rng, F.istft, ref_istft, istft_inputs, func_args=[
                    window_size, stride, fft_size, window_type, center, pad_mode, as_stft_backward], ctx=ctx, func_name=func_name, atol_f=1e-5, atol_b=3e-2, dstep=1e-2)
예제 #4
0
        def ref_istft_torch(y_r, y_i, window_size, stride, fft_size, window_type, center):
            y_r = np.reshape(y_r, y_r.shape + (1,))
            y_i = np.reshape(y_i, y_i.shape + (1,))
            y = np.concatenate((y_r, y_i), axis=3)

            y = torch.tensor(y)
            y = torch.view_as_complex(y)
            window = torch.tensor(create_window_func(window_type, window_size))

            x_shape = create_stft_input_shape(window_size)
            length = x_shape[1]

            x = torch.istft(y, n_fft=fft_size, hop_length=stride,
                            win_length=window_size, window=window, center=center, length=length)
            return x
예제 #5
0
def ref_istft(y_r, y_i, window_size, stride, fft_size, window_type, center,
              pad_mode, as_stft_backward):
    if not as_stft_backward:
        # Use librosa.istft as the forward reference.

        # Convert to librosa.istft input format.
        y = y_r + 1j * y_i

        # Get original signal length.
        x_shape = create_stft_input_shape(window_size)
        length = x_shape[1]

        # librosa.istft does not support batched input.
        b = y.shape[0]
        xs = []
        for i in range(b):
            x = librosa.istft(y[i],
                              hop_length=stride,
                              win_length=window_size,
                              window=window_type,
                              center=center,
                              length=length)
            xs.append(x)
        return np.array(xs)
    else:
        # Use F.stft backward as the reference

        y_r = nn.Variable.from_numpy_array(y_r)
        y_i = nn.Variable.from_numpy_array(y_i)

        # Just create stft inputs
        x = F.istft(y_r, y_i, window_size, stride, fft_size, window_type,
                    center, pad_mode, True)

        # Execute istft backward
        x.need_grad = True
        x.grad.zero()
        z_r, z_i = F.stft(x, window_size, stride, fft_size, window_type,
                          center, pad_mode)

        z_r.g = y_r.d
        z_i.g = y_i.d
        z = F.sink(z_r, z_i, one_input_grad=False)
        z.forward()
        z.backward()

        return x.g