2010-08-04 4 views
1

Я пытаюсь написать файл .m для извлечения энергии из функции звуковой дорожки, но я, кажется, возникают проблемы в ее реализации:Помощь требуется со звуком в MATLAB

% Formula for calculating RMS 

[f, fs, nb] = wavread('Three.wav'); 

frameWidth=441; %10ms 
numSamples=length(x); 
numFrames=(numSamples/1); 
energy(frame)=0; 

for frame=1:numFrames, 
    startSample=(frame-1)*frameWidth+1; 
    endSample=startSample+frameWidth-1; 
% Calculate frame energy 
    for i=startSample:endSample 
     energy(frame)=energy(frame)+x(i)^2; 
    end 
end 

Я бегу этот файл в MATLAB и получить следующую ошибку:

??? Attempted to access x(2); index out of bounds because numel(x)=1. Error in ==> myrms at 12 energy(frame)=energy(frame)+x(i)^2;

Любая помощь будет очень признательна.

ответ

2

Вы должны использовать f вместо x, так как f - это фактический сигнал, загруженный из вашего .wav-файла. Переменная x была, вероятно, всего лишь некоторым другим скаляром в вашей рабочей области, поэтому вы получили ошибку, которую видели.

Есть еще несколько исправлений/улучшений, которые должны быть внесены в ваш код. Сначала, как Paul R pointed out, вам нужно исправить то, как вы вычисляете numFrames. Во-вторых, energy должен быть инициализирован как вектор нулей. В-третьих, вы можете уменьшить внутренний цикл для однострочной векторизации.

Вот как я бы переписать код (EDIT: На основе замечаний, я обновил код, чтобы сэкономить несколько дополнительных переменных, вычисленных в цикле):

[y, fs, nb] = wavread('Three.wav'); %# Load the signal into variable y 

frameWidth = 441;       %# 10 msec 
numSamples = length(y);     %# Number of samples in y 
numFrames = floor(numSamples/frameWidth); %# Number of full frames in y 
energy = zeros(1,numFrames);    %# Initialize energy 
startSample = zeros(1,numFrames);   %# Initialize start indices of frame 
endSample = zeros(1,numFrames);   %# Initialize end indices of frame 

for frame = 1:numFrames        %# Loop over frames 
    startSample(frame) = (frame-1)*frameWidth+1;  %# Starting index of frame 
    endSample(frame) = frame*frameWidth;    %# Ending index of frame 
    frameIndex = startSample(frame):endSample(frame); %# Indices of frame samples 
    energy(frame) = sum(y(frameIndex).^2);    %# Calculate frame energy 
end 
+0

Блестящий. Только что заметил ошибку, которую я сделал в начальном посте, я не должен был использовать f вообще, я даже не записал нигде на листе бумаги, где я писал исходный код. Как неловко. Благодарим за помощь в любом случае, это очень ценится. – Velocity

+0

Я понятия не имею, получите ли вы уведомление о том, что я ответил на это, но здесь все равно. Есть ли способ применить ярлык или тег к каждому созданному кадру? Даже если это так же просто, как «Frame 1» «Frame 2» и т. Д. Я хочу выполнить несколько функций самостоятельно, чтобы найти области песни, которые я хочу извлечь, но я понятия не имею, как вызвать кадры как только у меня есть данные. Например, если я выполняю функции автокорреляции, а затем функции обнаружения пика, я затем хочу отобразить этот кадр обратно в его конкретное положение в песне, чтобы затем извлечь эскиз. – Velocity

+0

@Velocity: Один из способов сделать это - сохранить значения 'startSample' и' endSample', которые вы вычисляете в своем цикле. Я обновил код в своем ответе, чтобы показать, как это сделать. – gnovice

0

В случае, если это не строка:

numFrames=(numSamples/1); 

быть что-то вроде:

numFrames=(numSamples/frameWidth); 

или возможно:

numFrames=((numSamples + frameWidth - 1)/frameWidth); 

?

+0

Я изначально был: numFrames = поток (numSamples/numFrames) , но MATLAB тоже не понравилось. – Velocity

+0

Вызов [FLOOR] (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/floor.html) также может потребоваться в случае, если 'numFrames' не выдается как точное целое число , – gnovice

+0

Да, общий идиотизм с моей стороны. Я не мог прочитать свой собственный набросок почерка. FLOOR - это то, что я хотел, а не поток. – Velocity