Ejemplo n.º 1
0
def recover_from_stft_spectrogram(Zxx, fs):
    '''
    Recover the time-domain signal from a spectrogram via the inverse STFT
    :param : Zxx. np.array. The complex spectrogram
    :param : fs. int. Sample rate of the signal
    :return : data. time-domain signal
    '''

    # According to the paper, the spectrogram is computed using a Hann window with a length of 25 ms,
    # a hop length of 10 ms and FFt size of 512

    # I believe the length of each segment is the hann window length
    n_per_seg = int(hann_win_length * fs)

    # The hop size H = n_per_seg - n_overlap according to scipy
    n_hop_size = int(hop_length * fs)
    n_overlap = n_per_seg - n_hop_size

    # Compute inverse STFT if the nonzero overlap add constraint is satisfied
    if check_NOLA('hann', n_per_seg, n_overlap):
        t, data = istft(Zxx,
                        fs,
                        window='hann',
                        nperseg=n_per_seg,
                        noverlap=n_overlap,
                        nfft=fft_size)
        return t, data
    else:
        raise Exception(
            "The nonzero overlap constraint was not met while computing an inverse STFT"
        )
Ejemplo n.º 2
0
def get_stft_spectrogram(data, fs):
    '''
    Compute the spectrogram of the signal in the data array via the STFT
    :param : data. np.array. The signal
    :param : fs. int. Sample rate of the signal
    :return : spec. Spectogram of the signal
    '''

    # According to the paper, the spectrogram is computed using a Hann window with a length of 25 ms,
    # a hop length of 10 ms and FFt size of 512

    # I believe the length of each segment is the hann window length
    n_per_seg = int(hann_win_length * fs)

    # The hop size H = n_per_seg - n_overlap according to scipy
    n_hop_size = int(hop_length * fs)
    n_overlap = n_per_seg - n_hop_size

    # Compute STFT if the nonzero overlap add constraint is satisfied
    if check_NOLA('hann', n_per_seg, n_overlap):
        f, t, Zxx = stft(data,
                         fs,
                         window='hann',
                         nperseg=n_per_seg,
                         noverlap=n_overlap,
                         nfft=fft_size)
        # Return the complex spectrogram
        return f, t, Zxx
    else:
        raise Exception(
            "The nonzero overlap constraint was not met while computing a STFT"
        )
Ejemplo n.º 3
0
def _check_NOLA(window, hop_len):
    """https://gauss256.github.io/blog/cola.html"""
    if hop_len > len(window):
        WARN("`hop_len > len(window)`; STFT not invertible")
    elif not sig.check_NOLA(window, len(window), len(window) - hop_len):
        WARN("`window` fails Non-zero Overlap Add (NOLA) criterion; "
             "STFT not invertible")
Ejemplo n.º 4
0
def list_stft_hop_size(window):
    (window_size, ) = window.shape
    assert window_size > 0
    l = []
    for i in range(1, window_size):
        if sp.check_COLA(window, window_size,
                         window_size - i) and sp.check_NOLA(
                             window, window_size, window_size - i):
            l.append(i)
    return l
Ejemplo n.º 5
0
def set_window(self,
               window: object = 'hann',
               noverlap: int = None,
               NOLA_check: bool = True):
    if self._window_type == window and self._noverlap == noverlap:
        return
    else:
        self._window_type = window
        if noverlap is None:
            noverlap = self._nperseg // 2

        if type(window) is str or \
                type(window) is tuple or \
                type(window) == float:
            window = scisig.get_window(window, self._nperseg)

        elif window:
            assert len(window) == self._nperseg, 'control size of window'
            if NOLA_check:
                assert scisig.check_NOLA(window, self._nperseg, noverlap)

        elif self._window_type is None:
            window = None
            self._window_type = None

    self._window = window
    # refresh
    self._noverlap = noverlap
    self._nhop = self._nperseg - self._noverlap
    if self._mono_mode:
        self._iwin_buffer = [np.zeros(self._nperseg)]
        self._win_buffer = [np.zeros(self._nperseg), np.zeros(self._nperseg)]
    else:
        self._iwin_buffer = [
            np.zeros(self._nperseg) for i in range(self.nchannels)
        ]
        self._win_buffer = [[np.zeros(self._nperseg),
                             np.zeros(self._nperseg)]
                            for i in range(self.nchannels)]
    self._main_stream.clear()
Ejemplo n.º 6
0
# "Shaky" reconstructions. For check_COLA, see ola.py
# window = "boxcar"           # 25%: COLA not satisfied
# window = "blackmanharris"   # 50%: COLA not satisfied

window_name = window  # Rename explicitly if necessary

#
# Generate data
#

cutoff_duration = sum(durations) * 0.4
noverlap = int(window_length * overlap_percent)

cola = signal.check_COLA(window, window_length, noverlap)
nola = signal.check_NOLA(window, window_length, noverlap)

# A4 C5 E5 for "A4"
chord = notes.minor_chord(scale_name=scale_name, n_notes=3, output="chord")

melody = m21.stream.Stream()
for i in range(1, n_chords + 1):
    inv = i % 3
    melody.append(chord)
    chord_copy = copy.deepcopy(chord)
    chord_copy.inversion(inv)  # Move root note to the top
    chord = chord_copy

# Add the extra notes to each chord - we want to remove these after STFT
for i, name in enumerate(extra_notes):
    melody[i].add(name)
Ejemplo n.º 7
0
    ("Rectangular, 75%: ", rect120, 120, 90),  # True , True
    ("Rectangular, 25%: ", rect120, 120, 30),  # False, True
    ("Hann symmetrical, 50%: ", hann_sym120, 120, 60),  # False, True
    ("Hann Periodic/DFT-even, 1/2: ", hann_asym120, 120, 60),  # True , True
    ("Hann Periodic/DFT-even, 2/3: ", hann_asym120, 120, 80),  # True , True
    ("Hann Periodic/DFT-even, 3/4: ", hann_asym120, 120, 90),  # True , True
    ("Blackmanharris, 50%: ", blackmanharris120, 120, 60),  # False, True
    ("Blackmanharris, 75%: ", blackmanharris120, 120, 90),  # True , True

    # NOLA
    ("62 ones with 2 zeros appended, 50%: ", ones64, 64, 32),  # False, False
    ("Hann symmetrical, 1/64 (not enough overlap): ", hann_sym64, 64,
     1),  # False, False
    ("Hann symmetrical, 2/64 (not enough overlap): ", hann_sym64, 64,
     2),  # False, True
    ("Hann symmetrical, 3/64 (not enough overlap): ", hann_sym64, 64, 3
     )  # False, True
]

results = np.empty((len(tests), 3), dtype="<U64")  # no. tests rows, 3 columns

for i, (desc, w, nperseg, noverlap) in enumerate(tests):
    results[i] = np.array([
        desc,
        str(signal.check_COLA(w, nperseg, noverlap)),
        str(signal.check_NOLA(w, nperseg, noverlap))
    ])

df = pd.DataFrame(data=results, columns=["Description", "COLA", "NOLA"])
print(df)