NameError:name' nmax'没有定义

时间:2017-05-20 05:59:09

标签: python numpy scipy

我收到了一个错误, NameError:name' nmax'没有定义。 跟踪就像

  Traceback (most recent call last):
  File "mfcc.py", line 143, in <module>
    tmp=get_feature(wavfile,nfft,nceps)
  File "mfcc.py", line 135, in get_feature
    ceps = mfcc(wavdata,nfft,fs,nceps)
  File "mfcc.py", line 97, in mfcc
    spec = np.abs(np.fft.fft(signal,nfft))[:nmax]
NameError: name 'nmax' is not defined

我的代码是

#coding:utf-8

import wave
import numpy as np
#Signal Processing
import scipy.signal
#Fourier Transforms
import scipy.fftpack
import scipy.fftpack.realtransforms

from pylab import *

def wavread(filename):
    wf = wave.open(filename,"r")
    fs = wf.getframerate()
    x = wf.readframes(wf.getnframes())
    x = np.frombuffer(x,dtype="int16")/32768.0
    wf.close()
    return x,float(fs)

def hz2mel(f):
    return 1127.01048 * np.log(f/700.0+1.0)

def mel2hz(m):
    return 700.0 * (np.exp(m/1127.01048)-1.0)

def melFilterBank(fs, nfft, numChannels):
    fmax = fs/2
    melmax = hz2mel(fmax)
    global nmax 
    nmax = nfft/2
    df=fs/nfft
    dmel = melmax/(numChannels+1)
    melcenters = np.arrange(1,numChannels+1)*dmel
    fcenters = mel2hz(melcenters)
    indexcenter = np.round(fcenters/df)
    indexstart = np.hstack(([0],indexcenter[0:numChannels -1]))
    indexstop = np.hstack((indexcenter[1:numChannels],[nmax]))

    filterbank = np.zeros((numChannels,nmax))
    for c in np.arrange(0,numChannels):
        increment= 1.0/(indexcenter[c]-indexstart[c])
        for i in np.arrange(indexstart[c],indexcenter[c]):
            i=int(i)
            filterbank[c,i]=(i - indexstart[c])*increment
        decrement = 1.0/(indexstop[c]-indexcenter[c])
        for i in np.arrange(indexcenter[c],indexstop[c]):
            i=int(i)
            filterbank[c,i] = 1.0-((i - indexcenter[c])*decrement)
    return filterbank,fcenters

def preEmphasis(signal,p):
    return scipy.signal.lfilter([1.0,-p],1,signal)

def mfcc(signal,nfft,fs,nceps):
    p = 0.97 
    signal = preEmphasis(signal,p)

    hammingWindow = np.hamming(len(signal))
    signal = signal * hammingWindow

    spec = np.abs(np.fft.fft(signal,nfft))[:nmax]
    fscale =np.fft.fftfreq(nfft,d=1.0/fs)[:nmax]

    numChannels = 20 
    df = fs/nfft 
    filterbank,fcenters = melFilterBank(fs,nfft,numChannels)

    mspec = np.log10(np.dot(spec,filterbank.T))
    ceps = scipy.fftpack.realtransforms.dct(mspec,type=2,norm="ortho",axis=-1)
    return ceps[:nceps]

def get_feature(wavfile,nfft,nceps):
    wav,fs = wavread(wavfile)
    t = np.arange(0.0,len(wav)/fs,1/fs)

    center =len(wav)/2 
    cuttime = 0.8 
    global wavdata
    wavdata = wav[int(center-cuttime/2*fs):int(center+cuttime/2*fs)]

    global time
    time = t[int(center-cuttime/2*fs):int(center+cuttime/2*fs)]
    ceps = mfcc(wavdata,nfft,fs,nceps)
    return ceps.tolist()

if __name__ == "__main__":
    wavfile ="3_7_9.wav"
    nfft=2048
    nceps=12
    tmp=get_feature(wavfile,nfft,nceps)
    print(tmp)


    plot(time*1000,wavdata)
    xlabel("time [ms]")
    ylabel("amplitude")
    savefig("waveform.png")
    show()

我通过使用全局变量在我的代码中写了nmax,所以我不知道为什么会出现这个错误。全局变量不能在所有文件中使用,对吧?那么,我该如何解决这个问题呢?

2 个答案:

答案 0 :(得分:0)

在函数melFilterBanks中定义nmax。但是在之后使用nmax变量称之为。 所以nmax在你打电话之前不会初始化。

以下是您出错的地方:

spec = np.abs(np.fft.fft(signal,nfft))[:nmax]
fscale =np.fft.fftfreq(nfft,d=1.0/fs)[:nmax]

snip

filterbank,fcenters = melFilterBank(fs,nfft,numChannels)

所以要么在使用nmax之前调用melFilterBank,要么在调用melFilterBank之后定义specfscale

答案 1 :(得分:0)

问题不在于您本身使用全局变量。问题是,当您在abs()中呼叫mfcc()时,nmax尚未定义,因为直到您稍后在函数中调用melFilterBank()后才会发生这种情况。将nmax的定义移至mfcc()的开头,而不是:

def mfcc(signal,nfft,fs,nceps):
    global nmax 
    nmax = nfft/2

    p = 0.97 
    signal = preEmphasis(signal,p)

    hammingWindow = np.hamming(len(signal))
    signal = signal * hammingWindow

    spec = np.abs(np.fft.fft(signal,nfft))[:nmax]
    fscale =np.fft.fftfreq(nfft,d=1.0/fs)[:nmax]

    numChannels = 20 
    df = fs/nfft 
    filterbank,fcenters = melFilterBank(fs,nfft,numChannels)

    mspec = np.log10(np.dot(spec,filterbank.T))
    ceps = scipy.fftpack.realtransforms.dct(mspec,type=2,norm="ortho",axis=-1)
    return ceps[:nceps]

但是,在当前代码中,我宁愿不使用global,而是明确传递所需的参数。