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