【问题标题】:plotting volume-time graph of .wav file绘制 .wav 文件的体积时间图
【发布时间】:2015-10-01 14:08:12
【问题描述】:

我正在尝试获取 .wav 文件的体积时间图。首先,我通过 android 将声音(患者呼气)录制为 .wav 文件,但是当我在 MATLAB 中读取此 .wav 文件时,它具有负值。负值是什么意思?其次,MATLAB 专家,请您检查一下下面的代码是否与我的 cmets 中编写的代码相同?还有另一个问题。 Y = fft(WindowArray); p = abs(Y).^2; 我利用了从 fft 返回的值的力量...正确吗?这一步的目标是什么??

[data, fs] =  wavread('newF2');
% read exhalation audio wav  file (1 channel, mono)
% frequency is 44100 HZ
% windows of 0.1 s and overlap of 0.05 seconds
WINDOW_SIZE = fs*0.1; %4410 = fs*0.1
array_size = length(data); % array size of data
numOfPeaks = (array_size/(WINDOW_SIZE/2)) - 1;
step = floor(WINDOW_SIZE/2); %step size used in loop
transformed = data;
start =1;
k = 1;
t = 1;
g = 1;
o = 1;
% performing fft on each window and finding the peak of windows 
while(((start+WINDOW_SIZE)-1)<=array_size) 
    j=1;
    i =start;
    while(j<=WINDOW_SIZE)
        WindowArray(j) = transformed(i);
        j = j+1;
        i = i +1;
    end
    Y = fft(WindowArray);
    p = abs(Y).^2; %power
      [a, b] = max(abs(Y)); % find max a and its indices b
      [m, i] = max(p); %the maximum of the power m and its indices i
      maximum(g) = m;
      index(t) = i;
      power(o) = a;
      indexP(g) = b;
      start = start + step;
      k = k+1;
      t = t+1;
      g = g+1;
      o=o+1;  
  end
% low pass filter 
% filtering noise: ignor frequencies that are less than 5% of maximum frequency
for u=1:length(maximum)
    M = max(maximum); %highest value in the array
    Accept = 0.05* M;
    if(maximum(u) > Accept)
        maximum = maximum(u:length(maximum));
        break;
    end
end
% preparing the time of the graph, 
% Location of the Peak flow rates are estimated
TotalTime = (numOfPeaks * 0.1);
time1 = [0:0.1:TotalTime];
if(length(maximum) > ceil(numOfPeaks));
maximum = maximum(1:ceil(numOfPeaks)); 
end
time = time1(1:length(maximum));
% plotting frequency-time graph
figure(1);
plot(time, maximum);
ylabel('Frequency');
xlabel('Time (in seconds)');
% plotting volume-time graph
figure(2);
plot(time, cumsum(maximum)); % integration over time to get volume 
ylabel('Volume');
xlabel('Time (in seconds)');

【问题讨论】:

  • processing 标签只能用于处理语言相关的问题。
  • @KevinWorkman - 再次代表所有 MATLAB 用户致歉。他们似乎经常滥用处理标签。

标签: matlab signal-processing audio-processing


【解决方案1】:

(我只回答我理解的部分)

默认情况下,Matlab 将音频波标准化为 - 1...1 范围。如果需要整数数据,请使用 native 选项。

【讨论】:

    【解决方案2】:

    首先,在您的代码中它应该是p = abs(Y)**2,这是对从 FFT 返回的值求平方的正确方法。您采用 FFT 返回值的绝对值的原因是因为这些数字是具有实部和虚部的复数,因此虚数的绝对值(或模数)是该数字的大小。获得权力的目标可能是潜在地获得整体幅度值的 RMS 值(均方根),但您也可能有其他想法。当您说音量时间时,我假设您想要分贝,因此请尝试以下操作:

    def plot_signal(file_name):
    
    sampFreq, snd = wavfile.read(file_name)
    
    snd = snd / (2.**15) #Convert sound array to floating point values 
                         #Floating point values range from -1 to 1
    
    s1 = snd[:,0] #left channel
    
    s2 = snd[:,1] #right channel
    
    timeArray = arange(0, len(snd), 1)
    timeArray = timeArray / sampFreq
    timeArray = timeArray * 1000  #scale to milliseconds
    
    timeArray2 = arange(0, len(snd), 1)
    timeArray2 = timeArray2 / sampFreq
    timeArray2 = timeArray2 * 1000  #scale to milliseconds
    
    n = len(s1)
    p = fft(s1) # take the fourier transform 
    
    m = len(s2) 
    p2 = fft(s2)
    
    nUniquePts = ceil((n+1)/2.0)
    p = p[0:nUniquePts]
    p = abs(p)
    
    mUniquePts = ceil((m+1)/2.0)
    p2 = p2[0:mUniquePts]
    p2 = abs(p2)
    
    '''
    Left Channel
    '''
    p = p / float(n) # scale by the number of points so that
                 # the magnitude does not depend on the length 
                 # of the signal or on its sampling frequency  
    p = p**2  # square it to get the power 
    
    
    
    
    # multiply by two (see technical document for details)
    # odd nfft excludes Nyquist point
    if n % 2 > 0: # we've got odd number of points fft
        p[1:len(p)] = p[1:len(p)] * 2
    else:
        p[1:len(p) -1] = p[1:len(p) - 1] * 2 # we've got even number of points fft
    
    plt.plot(timeArray, 10*log10(p), color='k')
    plt.xlabel('Time (ms)')
    plt.ylabel('LeftChannel_Power (dB)')
    plt.show()
    
    '''
    Right Channel
    '''
    p2 = p2 / float(m) # scale by the number of points so that
                 # the magnitude does not depend on the length 
                 # of the signal or on its sampling frequency  
    p2 = p2**2  # square it to get the power 
    
    
    
    
    # multiply by two (see technical document for details)
    # odd nfft excludes Nyquist point
    if m % 2 > 0: # we've got odd number of points fft
        p2[1:len(p2)] = p2[1:len(p2)] * 2
    else:
        p2[1:len(p2) -1] = p2[1:len(p2) - 1] * 2 # we've got even number of points fft
    
    
    plt.plot(timeArray2, 10*log10(p2), color='k')
    plt.xlabel('Time (ms)')
    plt.ylabel('RightChannel_Power (dB)')
    plt.show()
    

    我希望这会有所帮助。

    【讨论】:

    • 感谢您的帮助
    猜你喜欢
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多