Aiuto richiesto con audio in MATLAB
Domanda
Sto cercando di scrivere un file .m alle funzioni di energia estratto da una traccia audio ma mi sembra di avere problemi nella sua attuazione:
% 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
I eseguire il file in MATLAB e ottenere il seguente errore:
??? Tentato di accesso x (2); indice fuori limite perché Numel (x) = 1. Errore in ==> myrms a 12 energia (frame) = energia (frame) + x (i) ^ 2;
Qualsiasi aiuto sarebbe molto apprezzato.
Soluzione
Si dovrebbe usare f
invece di x
, dal momento che f
è il segnale effettivo caricato dal file wav. Il x
variabile era probabilmente solo qualche altra scalare nell'area di lavoro, che è il motivo per cui si stavano diventando l'errore che avete visto.
Ci sono alcune correzioni altri / miglioramenti che dovrebbero essere apportate al codice. In primo luogo, come Paul R sottolineato , è necessario correggere come si calcola numFrames
. In secondo luogo, energy
deve essere inizializzato come un vettore di zeri. In terzo luogo, è possibile ridurre l'interno ciclo for per un'operazione di vettorializzare una riga.
Ecco come vorrei riscrivere il codice ( EDIT: Sulla base di commenti, ho aggiornato il codice per salvare un paio di variabili aggiuntive calcolate nel loop ):
[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
Altri suggerimenti
non dovrebbe questa linea:
numFrames=(numSamples/1);
essere qualcosa del tipo:
numFrames=(numSamples / frameWidth);
o, eventualmente:
numFrames=((numSamples + frameWidth - 1) / frameWidth);