سؤال

هل هناك أي الأغراض العامة شكل وقت قصير تحويل فورييه مع المقابلة معكوس تحويل بنيت في SciPy أو NumPy أو أيا كان ؟

هناك pyplot specgram وظيفة في matplotlib التي المكالمات ax.specgram(), الذي يدعو mlab.specgram(), الذي يدعو _spectral_helper():

#The checks for if y is x are so that we can use the same function to
#implement the core of psd(), csd(), and spectrogram() without doing
#extra calculations.  We return the unaveraged Pxy, freqs, and t.

ولكن

هذا هو مساعد الوظيفة التي تطبق القواسم المشتركة بين 204 #psd, csd, والطيفية.فمن لا من المفترض أن يتم استخدامها خارج mlab

لست متأكدا إذا كان هذا يمكن استخدامها للقيام STFT و ISTFT ، على الرغم من.هل هناك أي شيء آخر ، أو أن أترجم شيئا مثل هذه MATLAB وظائف?

أنا أعرف كيف أكتب بلدي المخصص التنفيذ ؛ أنا فقط أبحث عن شيء كامل المواصفات ، والتي يمكن التعامل مع مختلف وظائف النوافذ (ولكن لديه عاقل الافتراضي) ، تماما invertible مع الكولا ويندوز (istft(stft(x))==x) ، تم اختبارها من قبل عدة أشخاص ، لا من جانب واحد الأخطاء يعالج ينتهي صفر الحشو جيدا, سريع RFFT تنفيذ حقيقي المدخلات ، إلخ.

هل كانت مفيدة؟

المحلول

وأنا في وقت متأخر قليلا لهذا، ولكن scipy أدرك له يحمل في ثناياه عوامل <لأ href = "http://scipy.github.io/devdocs/generated/scipy.signal.istft.html#scipy.signal.istft" يختلط = "noreferrer نوفولو"> istft وظيفة اعتبارا من 0.19.0

نصائح أخرى

هنا هو بلدي كود بايثون مبسطة عن هذا الجواب:

import scipy, pylab

def stft(x, fs, framesz, hop):
    framesamp = int(framesz*fs)
    hopsamp = int(hop*fs)
    w = scipy.hanning(framesamp)
    X = scipy.array([scipy.fft(w*x[i:i+framesamp]) 
                     for i in range(0, len(x)-framesamp, hopsamp)])
    return X

def istft(X, fs, T, hop):
    x = scipy.zeros(T*fs)
    framesamp = X.shape[1]
    hopsamp = int(hop*fs)
    for n,i in enumerate(range(0, len(x)-framesamp, hopsamp)):
        x[i:i+framesamp] += scipy.real(scipy.ifft(X[n]))
    return x

ملاحظات:

  1. على قائمة على الفهم هو خدعة صغيرة أود أن استخدام لمحاكاة كتلة معالجة الإشارات في numpy/scipy.انها مثل blkproc في Matlab.بدلا من for الحلقة, وأنا تطبيق الأوامر (على سبيل المثال ، fft) لكل إطار من الإشارة داخل قائمة على الفهم ، ثم scipy.array يلقي ذلك إلى 2D array.يمكنني استخدام هذا لجعل الطيفية, chromagrams, MFCC-غرام و أكثر من ذلك بكثير.
  2. على سبيل المثال ، استخدام السذاجة التداخل-و-إضافة طريقة في istft.من أجل إعادة بناء الإشارة الأصلية مجموع متتابعة نافذة الوظائف يجب أن تكون ثابتة ، ويفضل يساوي بوحدة (1.0).في هذه الحالة, لقد اخترت هان (أو hanning) نافذة و 50% التداخل الذي يعمل تماما.انظر هذا النقاش للحصول على مزيد من المعلومات.
  3. ربما يكون هناك أكثر المبدئي طرق حساب ISTFT.هذا المثال هو أساسا من المفترض أن تكون تعليمية.

الاختبار:

if __name__ == '__main__':
    f0 = 440         # Compute the STFT of a 440 Hz sinusoid
    fs = 8000        # sampled at 8 kHz
    T = 5            # lasting 5 seconds
    framesz = 0.050  # with a frame size of 50 milliseconds
    hop = 0.025      # and hop size of 25 milliseconds.

    # Create test signal and STFT.
    t = scipy.linspace(0, T, T*fs, endpoint=False)
    x = scipy.sin(2*scipy.pi*f0*t)
    X = stft(x, fs, framesz, hop)

    # Plot the magnitude spectrogram.
    pylab.figure()
    pylab.imshow(scipy.absolute(X.T), origin='lower', aspect='auto',
                 interpolation='nearest')
    pylab.xlabel('Time')
    pylab.ylabel('Frequency')
    pylab.show()

    # Compute the ISTFT.
    xhat = istft(X, fs, T, hop)

    # Plot the input and output signals over 0.1 seconds.
    T1 = int(0.1*fs)

    pylab.figure()
    pylab.plot(t[:T1], x[:T1], t[:T1], xhat[:T1])
    pylab.xlabel('Time (seconds)')

    pylab.figure()
    pylab.plot(t[-T1:], x[-T1:], t[-T1:], xhat[-T1:])
    pylab.xlabel('Time (seconds)')

STFT of 440 Hz sinusoid ISTFT of beginning of 440 Hz sinusoid ISTFT of end of 440 Hz sinusoid

وهنا هو رمز STFT التي أستخدمها. STFT + ISTFT هنا يعطي <م> إعادة الإعمار المثالي (حتى بالنسبة للإطارات الأولى). I معدلة بشكل طفيف رمز معين هنا من قبل ستيف Tjoa: هنا حجم إشارة أعيد بناؤها هو نفسه كما ان من إشارة الدخل

import scipy, numpy as np

def stft(x, fftsize=1024, overlap=4):   
    hop = fftsize / overlap
    w = scipy.hanning(fftsize+1)[:-1]      # better reconstruction with this trick +1)[:-1]  
    return np.array([np.fft.rfft(w*x[i:i+fftsize]) for i in range(0, len(x)-fftsize, hop)])

def istft(X, overlap=4):   
    fftsize=(X.shape[1]-1)*2
    hop = fftsize / overlap
    w = scipy.hanning(fftsize+1)[:-1]
    x = scipy.zeros(X.shape[0]*hop)
    wsum = scipy.zeros(X.shape[0]*hop) 
    for n,i in enumerate(range(0, len(x)-fftsize, hop)): 
        x[i:i+fftsize] += scipy.real(np.fft.irfft(X[n])) * w   # overlap-add
        wsum[i:i+fftsize] += w ** 2.
    pos = wsum != 0
    x[pos] /= wsum[pos]
    return x

librosa.core.stft و <لأ href = "HTTP: //bmcfee.github.io/librosa/librosa.html#librosa.core.istft "يختلط =" noreferrer نوفولو "> istft تبدو مشابهة جدا لما كنت تبحث عنه، على الرغم من أنها لم تكن موجودة في الوقت:

<اقتباس فقرة>   

وlibrosa.core.stft(y, n_fft=2048, hop_length=None, win_length=None, window=None, center=True, dtype=<type 'numpy.complex64'>)

وانهم لا عكس تماما، على الرغم؛ ومدبب ينتهي.

وجدت آخر STFT لكن لا المقابلة معكوس الدالة:

http://code.google.com/p/pytfd/source/browse/trunk/pytfd/stft.py

def stft(x, w, L=None):
    ...
    return X_stft
  • w هو نافذة وظيفة كما صفيف
  • L هو التداخل في عينات

وأيا من الإجابات أعلاه عملت بشكل جيد OOTB بالنسبة لي. لذلك أنا تعديل ستيف Tjoa ل.

import scipy, pylab
import numpy as np

def stft(x, fs, framesz, hop):
    """
     x - signal
     fs - sample rate
     framesz - frame size
     hop - hop size (frame size = overlap + hop size)
    """
    framesamp = int(framesz*fs)
    hopsamp = int(hop*fs)
    w = scipy.hamming(framesamp)
    X = scipy.array([scipy.fft(w*x[i:i+framesamp]) 
                     for i in range(0, len(x)-framesamp, hopsamp)])
    return X

def istft(X, fs, T, hop):
    """ T - signal length """
    length = T*fs
    x = scipy.zeros(T*fs)
    framesamp = X.shape[1]
    hopsamp = int(hop*fs)
    for n,i in enumerate(range(0, len(x)-framesamp, hopsamp)):
        x[i:i+framesamp] += scipy.real(scipy.ifft(X[n]))
    # calculate the inverse envelope to scale results at the ends.
    env = scipy.zeros(T*fs)
    w = scipy.hamming(framesamp)
    for i in range(0, len(x)-framesamp, hopsamp):
        env[i:i+framesamp] += w
    env[-(length%hopsamp):] += w[-(length%hopsamp):]
    env = np.maximum(env, .01)
    return x/env # right side is still a little messed up...

وكما أنني وجدت هذا على جيثب، ولكن يبدو أن تعمل على خطوط الأنابيب بدلا من المصفوفات العادية:

http://github.com/ronw/frontend/blob /master/basic.py#LID281

def STFT(nfft, nwin=None, nhop=None, winfun=np.hanning):
    ...
    return dataprocessor.Pipeline(Framer(nwin, nhop), Window(winfun),
                                  RFFT(nfft))


def ISTFT(nfft, nwin=None, nhop=None, winfun=np.hanning):
    ...
    return dataprocessor.Pipeline(IRFFT(nfft), Window(winfun),
                                  OverlapAdd(nwin, nhop))

وأعتقد scipy.signal لديه ما كنت تبحث عنه. لديه افتراضات معقولة، ويدعم أنواع متعددة نافذة، الخ ...

HTTP: // مستندات. scipy.org/doc/scipy-0.17.0/reference/generated/scipy.signal.spectrogram.html

from scipy.signal import spectrogram
freq, time, Spec = spectrogram(signal)

وهناك نسخة من الجواب basj الثابتة.

import scipy, numpy as np
import matplotlib.pyplot as plt

def stft(x, fftsize=1024, overlap=4):
    hop=fftsize//overlap
    w = scipy.hanning(fftsize+1)[:-1]      # better reconstruction with this trick +1)[:-1]  
    return np.vstack([np.fft.rfft(w*x[i:i+fftsize]) for i in range(0, len(x)-fftsize, hop)])

def istft(X, overlap=4):   
    fftsize=(X.shape[1]-1)*2
    hop=fftsize//overlap
    w=scipy.hanning(fftsize+1)[:-1]
    rcs=int(np.ceil(float(X.shape[0])/float(overlap)))*fftsize
    print(rcs)
    x=np.zeros(rcs)
    wsum=np.zeros(rcs)
    for n,i in zip(X,range(0,len(X)*hop,hop)): 
        l=len(x[i:i+fftsize])
        x[i:i+fftsize] += np.fft.irfft(n).real[:l]   # overlap-add
        wsum[i:i+fftsize] += w[:l]
    pos = wsum != 0
    x[pos] /= wsum[pos]
    return x

a=np.random.random((65536))
b=istft(stft(a))
plt.plot(range(len(a)),a,range(len(b)),b)
plt.show()

إذا كان لديك الوصول إلى مكتبة ثنائي C أن تفعل ما تريد، ثم استخدم HTTP: // code.google.com/p/ctypesgen/ لتوليد واجهة بيثون إلى تلك المكتبة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top