2013-02-22 113 views
1

我實現了一個讀取wav文件並對其進行分析的matlab代碼。 wav文件的大小約爲(3-4 G)。 當我跑我得到以下錯誤的文件:如何在Matlab中解決內存不足錯誤?

"Out of memory. Type HELP MEMORY for your options" 

我試圖增加虛擬內存,但沒有奏效。 以下是我使用的代碼:

event=0; 
[x, fs] = wavread('C:\946707752529.wav'); 
Ts=1/fs;% sampling period 
N = length(x);% N is the number of samples 
slength = N*Ts;%slength is the length of the sound file in seconds 


% Reading the first 180 seconds and find the energy, then set a threshold value 
calibration_samples = 180 * fs; 
[x2, Fs] = wavread('C:\946707752529.wav', calibration_samples); 
Tss=1/Fs; 
[b,a]=butter(5,[200 800]/(Fs/2)); 
y2=filter(b,a,x2); 


%This loop is to find the average energy of the samples for the first 180 seconds 
startSample=1; 
endSample=Fs; 
energy=0; 
for i=1:180 

    energy=energy+sum(y2(startSample:endSample).^2)*Tss; 
    startSample=endSample+1; 
    endSample=endSample+Fs; 

end 
mean_energy=energy/180; 
Reference_Energy=mean_energy;% this is a reference energy level 
Threshold=0.65*Reference_Energy; 


% Now filtering the whole recorded file to be between [200-800] Hz 
[b,a]=butter(5,[200 800]/(fs/2)); 
y=filter(b,a,x); 
N = length(y); 
N=N/fs; % how many iteration we need 


startSample=1; 
endSample=fs; 
energy=0; 
j=1; 
while(j<=N) 
    counter=0; 
    energy=sum(y(startSample:endSample).^2)*Ts; 

    if (energy<=Threshold) 
     counter=counter+1; 

     for k=1:9 

      startSample=endSample+1; 
      endSample=endSample+fs; 
      energy=sum(y(startSample:endSample).^2)*Ts; 

       if (energy<=Threshold) 
        counter=counter+1; 

       else 
        break; 
       end %end inner if 
     end % end inner for 



    end % end outer IF 
    if(counter>=10) 
     event=event+1; 

    end 
    if(counter>0) 
     j=j+counter; 
    else 
     j=j+1; 
    end 
    startSample=endSample+1; 
    endSample=endSample+fs; 

end % end outer For 

系統:Windows 7 64位
RAM:8 GB
Matlab的:2013

+0

也許相關http://askubuntu.com/q/799834/25388 – 2016-07-17 19:14:53

回答

1

從你的代碼來看這可能工作:

  • 文件中讀取刪除一切,除了第180秒後
  • 確定treshold值
  • 一切的清除內存除了第一塊數據
  • 分析這條數據並存儲結果
  • 清除除下一條數據之外的所有內容...

這是假設你的算法是正確和有效的。

也可能是你的算法有問題,檢測到這個請用dbstop if error運行代碼,檢查所有變量出錯時的大小。然後檢查其中一個是否太大,你可能發現了這個錯誤。

+0

@ user1773886 感謝您的幫助。以下是關於您的建議的一些注意事項: 關於讀取wav文件,第一個向量包含整個錄製的文件。另一方面,第二個僅包含30秒的記錄文件。 calibration_samples = 30; [x2,Fs] = wavread('C:\ 946707752529.wav',calibration_samples); 所以第二個向量不應該消耗內存。我對嗎 ? 爲矢量化,我已經查看了提供的鏈接,並試圖改變我的代碼基於它,但我認爲它不能改變。例如: – user1741938 2013-02-23 19:09:41

+0

在我的代碼中,我正在使用: for i = 1:30 energy = energy + sum(y2(startSample:endSample)。^ 2)* Tss; startSample = endSample + 1; endSample = endSample + Fs; end 這部分代碼計算長度爲Fs(頻率)的窗口的能量。 我嘗試使用鏈接中提到的「cumsum」函數: energy = energy + cumsum(y2,Fs)^ 2 * Tss; 但問題是我如何在Windows中移動?首先我需要1 - > Fs,然後Fs - > 2Fs等等 我會嘗試使用「dbstop if error」,看看我會得到什麼 – user1741938 2013-02-23 19:10:33

+0

@ user983722 ,,,,如果錯誤,我已經使用了dbstop ,並得到了wavread函數中的錯誤,它在wavread函數中拋出異常: catch exception fclose(fid);拋出(例外); 結束 任何想法? – user1741938 2013-02-23 20:26:38

2

我猜wavread實際存儲波形文件到系統的所有數據記憶。此外,它可能會添加額外的信息。

我看到你正在調用這個函數兩次,將結果存儲在不同的矩陣中,所以當你的文件是3-4G時,你至少需要6-8G的內存。然而,你的操作系統,Matlab和其他程序也需要一些內存,這就是爲什麼你有這個內存不足的錯誤。

一個解決方案是將WAV文件分成多個文件並分別讀取它們。另一種解決方法是隻調用一次wavread,並在需要的地方使用已加載的數據,但不要爲此重新分配新的內存。

+0

該死的,忍者我。 :D +1重用'x'。另一個提示:for循環應儘可能避免在Matlab中出於性能原因。改爲使用[矢量化](http://www.mathworks.de/de/help/matlab/matlab_prog/vectorization.html)。另外,for循環不使用索引字符,這是一個很大的指示器,可以通過矢量化/矩陣操作更高效地完成操作。 – Christoph 2013-02-22 10:36:34

+0

@Christoph Vectorization可能會加快速度,但是一次只做一件小事通常不會需要更多的內存,而不是一次完成所有事情。 – 2013-02-22 10:42:12

+0

記憶,沒有。 CPU週期,是的。 ;-)(是的,這不是100%的問題,我只是在代碼中看到它,這是在Matlab中做的壞事),所以我認爲值得一提。 – Christoph 2013-02-22 10:43:54