Contenido principal

La traducción de esta página aún no se ha actualizado a la versión más reciente. Haga clic aquí para ver la última versión en inglés.

Obtener y analizar datos de audio de dispositivos móviles

Este ejemplo muestra cómo utilizar la FFT (transformada rápida de Fourier) para analizar datos de audio de micrófono recopilados por MATLAB Mobile. Se requiere un dispositivo móvil con la opción Acceso a sensores activada. Para activar la opción Acceso a sensores, en la app MATLAB Mobile vaya a Sensores > Más y active la opción Acceso a sensores.

Conectarse a un dispositivo

Cree la conexión con el dispositivo móvil y habilite el micrófono.

mobileDevObject = mobiledev;
mobileDevObject.MicrophoneEnabled = 1;

Grabar sonido de fondo

Encienda el micrófono para empezar a grabar ruido de fondo. Lea los datos de audio de fondo grabados durante 2 segundos. Los datos grabados son un matriz doble de tamaño NúmMuestras-por-NúmCanales. Encuentre el valor máximo para establecer el umbral entre el ruido de fondo y la voz detectada.

mobileDevObject.logging = 1;
disp('Sampling background noise...')
pause(2)
mobileDevObject.logging = 0;
audioData = readAudio(mobileDevObject);
disp('Maximum sound of the background noise: ')
threshold = max(abs(audioData), [], "all")
Sampling background noise...
Maximum sound of the background noise: 

threshold =

    0.0122

Grabar voz

Comience la grabación de voz.

disp('Speak into the device microphone for a few seconds. For example, say: ')
mobileDevObject.logging = 1;
tic
disp('"Testing MATLAB Mobile Audio"')
startTime = 0;
totalAudio = [];
Speak into the device microphone for a few seconds. For example, say: 
"Testing MATLAB Mobile Audio"

Detectar voz para activar adquisición

Intente detectar voz durante 5 segundos. Deténgase cada 200 ms y lea el buffer. Si el valor máximo de la ventana es mayor que el umbral*1,5, descarte los datos de audio de fondo recopilados previamente y comience a recopilar los datos de audio de voz previstos. Si no se detecta voz, procese los datos de audio recopilados los últimos 5 segundos.

while toc < 5 && startTime == 0
    pause(.2)
    audioData = readAudio(mobileDevObject);
    if max(abs(audioData)) > threshold * 1.5
        startTime = toc
        totalAudio = audioData;
    else
        totalAudio = vertcat(totalAudio, audioData);
    end
end
startTime =

    1.4202

Obtener datos de audio

Deténgase cada 200 ms y lea el buffer. Recopile datos de audio hasta que la voz termine o hasta que se alcance el tiempo de espera. Si no se detecta voz en 400 ms, finalice la adquisición.

if startTime ~= 0
    numberOfIntervalsStopped = 0;
    while numberOfIntervalsStopped < 2 && toc < 10
        pause(.2)
        audioData = readAudio(mobileDevObject);
        if max(abs(audioData)) < threshold * 1.5
            numberOfIntervalsStopped = numberOfIntervalsStopped + 1;
        else
            numberOfIntervalsStopped = 0;
        end
        totalAudio = vertcat(totalAudio,audioData);
    end
end
mobileDevObject.logging = 0;

Preprocesar datos de audio

Solo se necesita un canal de datos. n es el tamaño de leftAudio y se utiliza para representar y procesar. Obtenga la tasa de muestreo del micrófono para determinar la escala de frecuencia más tarde.

endTime = toc;
leftAudio = totalAudio(:,1);
n = numel(leftAudio);
if n == 0
    disp(' ')
    disp('No audio data recorded. Try to run the script again.')
    clear mobileDevObject
    return
end
sampleRate = mobileDevObject.Microphone.SampleRate;

Representar datos de audio en dominios del tiempo

Utilice el tiempo transcurrido para determinar las marcas de tiempo de las marcas de la gráfica. Convierta las marcas de tiempo a su muestra correspondiente para encontrar sus ubicaciones en el eje x. Visualícelas con la función xticks. Utilice el arreglo de marcas original para las etiquetas.

figure(1);
plot(leftAudio)
title('Sound wave');
timeElapsed = endTime - startTime
ticks = 0:floor(timeElapsed);
sampleTicks = ticks * n/timeElapsed;
xticks(sampleTicks)
xticklabels(ticks)
xlabel('Time(s)')
ylabel('Amplitude')
timeElapsed =

    8.7632

Procesar datos de audio en dominios de frecuencia

Utilice la función fft para convertir las amplitudes en dominios de frecuencia dados los datos de dominios de tiempo originales.

fftData = fft(leftAudio);
% Signal length is equal to the number of samples.
signalLength = n;
% Normalize the FFT data by dividing by signalLength.
fftNormal = abs(fftData/signalLength);
% The second half of the FFT data is a reflection of the first half
% and is not relevant in this case, so remove those values.
fftNormal = fftNormal(1:floor(signalLength/2)+1);
% Multiply the final values by 2 to account for removed values.
fftNormal(2:end-1) = 2*fftNormal(2:end-1);
% freqs is the x-axis scale of the graph.
freqs = sampleRate*(0:(signalLength/2))/signalLength;
% Convert factor from index to frequency.
scale = sampleRate/signalLength;

Representar datos de audio en dominios de frecuencia de 0-1.000 Hz

cutoff = 1000/scale;
figure(2);
plot(freqs(1:floor(cutoff)),fftNormal(1:floor(cutoff)))
title("Frequency Domain Graph")
xlabel("Frequency (Hz)")
ylabel("Amplitude")
ax = gca;
ax.XAxis.Exponent = 0;

Análisis de frecuencia final y borrado

Imprima la frecuencia dominante, que es el índice de la amplitud máxima de la función fft. Convierta ese valor a Hz usando la escala calculada.

[mVal, mInd] = max(fftNormal);
fprintf("Dominant frequency: %d Hz\n",floor(mInd * scale));
if startTime == 0
    disp(' ')
    disp('The voice of the speech is too low compared to the background noise, analysis might not be precise. Try to run the script again and speak louder.');
end
clear mobileDevObject
Dominant frequency: 125 Hz