2010-08-04 26 views
1

Je suis en train d'écrire un fichier .m pour extraire des caractéristiques d'énergie à partir d'une piste audio, mais il me semble avoir de la difficulté dans sa mise en œuvre:Aide requise avec l'audio dans 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 

je lance ce fichier dans MATLAB et obtenez l'erreur suivante:

??? 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;

Toute aide serait grandement appréciée.

Répondre

2

Vous devez utiliser f au lieu de , puisque f est le signal réel chargé à partir de votre fichier .wav. La variable x était probablement juste un autre scalaire dans votre espace de travail, c'est pourquoi vous obteniez l'erreur que vous avez vue.

D'autres corrections/améliorations doivent être apportées à votre code. Tout d'abord, comme Paul R pointed out, vous devez corriger comment vous calculez numFrames. Deuxièmement, energy devrait être initialisé en tant que vecteur de zéros. Troisièmement, vous pouvez réduire la boucle interne pour une opération vectorisée d'une ligne.

Voilà comment je réécrire votre code (EDIT: D'après les commentaires, j'ai mis à jour le code pour enregistrer quelques variables supplémentaires calculées dans la boucle):

[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

Brillant. Juste remarqué l'erreur que j'ai faite dans le message initial aussi, je ne devrais pas avoir utilisé f du tout, je ne l'ai même pas écrit n'importe où sur le morceau de papier où j'écrivais le code initial. Que c'est embarrassant. Merci pour l'aide de toute façon, c'est très apprécié. – Velocity

+0

Je ne sais pas si vous obtiendrez une notification que j'ai répondu à cela mais ici va quand même. Existe-t-il un moyen d'appliquer une étiquette ou une étiquette à chaque image créée? Même si c'est aussi basique que "Frame 1" "Frame 2" etc. Je veux effectuer quelques fonctions moi-même pour trouver les zones de la chanson que je veux extraire, mais je ne sais pas comment rappeler les images une fois que j'ai ces données. Par exemple, si j'effectue des fonctions de corrélation automatique puis de détection de crête, je veux ensuite mapper cette image à sa position spécifique dans le morceau pour pouvoir ensuite extraire la vignette. – Velocity

+0

@Velocity: Une façon de faire est de sauvegarder les valeurs de 'startSample' et' endSample' que vous calculez dans votre boucle. J'ai mis à jour le code dans ma réponse pour montrer comment faire cela. – gnovice

0

Si pas cette ligne:

numFrames=(numSamples/1); 

quelque chose comme:

numFrames=(numSamples/frameWidth); 

ou éventuellement:

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

?

+0

J'avais à l'origine: numFrames = flux (numSamples/numFrames) mais MATLAB n'a pas aimé non plus. – Velocity

+0

Un appel à [FLOOR] (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/floor.html) peut également être nécessaire dans le cas où «numFrames» n'apparaît pas comme un entier exact . – gnovice

+0

Oui, l'idiotie totale de ma part. Je ne pouvais pas lire ma propre écriture gribouillée. FLOOR est ce que je voulais, pas flux. – Velocity