주요 콘텐츠

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

모바일 기기에서 데이터 수집 및 분석

이 예제에서는 고속 푸리에 변환(FFT)을 사용해 MATLAB Mobile에서 수집한 마이크 오디오 데이터를 분석하는 방법을 보여줍니다. 센서 액세스가 켜진 모바일 기기가 필요합니다. 센서 액세스를 켜려면 MATLAB Mobile 앱에서 '센서 > 더 보기'로 이동하여 센서 액세스의 스위치를 켜십시오.

기기에 연결하기

모바일 기기와의 연결을 생성하고 마이크를 활성화합니다.

mobileDevObject = mobiledev;
mobileDevObject.MicrophoneEnabled = 1;

배경음 녹음하기

마이크를 켜서 배경 잡음을 녹음합니다. 2초 동안 녹음한 배경 오디오 데이터를 읽어옵니다. 녹음 데이터는 크기가 NumSamples×NumChannels인 double형 행렬입니다. 배경 잡음과 검출된 음성 간의 임계값을 설정하기 위해 최댓값을 구합니다.

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

음성 녹음하기

음성 녹음을 시작합니다.

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"

수집 작업을 트리거하기 위해 음성 검출하기

5초 동안 음성을 검출해 봅니다. 200밀리초마다 중지하고 버퍼를 읽어옵니다. 윈도우에서의 최댓값이 임계값의 1.5배보다 크면 이전에 수집한 배경 오디오 데이터를 폐기하고 의도했던 음성 오디오 데이터의 수집을 시작합니다. 음성이 검출되지 않으면 마지막 5초 동안 수집한 오디오 데이터를 처리합니다.

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

오디오 데이터 수집하기

200밀리초마다 중지하고 버퍼를 읽어옵니다. 음성이 끝나거나 제한 시간이 만료될 때까지 오디오 데이터를 수집합니다. 400밀리초 이내에 음성이 검출되지 않으면 수집을 끝냅니다.

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;

오디오 데이터 전처리하기

필요한 데이터 채널은 하나뿐입니다. n은 leftAudio의 크기이며 그래프 작성과 데이터 처리에 사용됩니다. 나중에 주파수 스케일을 결정하는 데 쓰기 위해 마이크의 샘플 레이트를 구합니다.

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;

시간 영역에서 오디오 데이터 플로팅하기

경과 시간을 사용하여 그래프 눈금의 타임스탬프를 결정합니다. 타임스탬프를 그에 대응하는 샘플로 변환하여 x축에서의 위치를 찾습니다. xticks 함수를 사용하여 위치를 표시합니다. 레이블에 원래의 ticks 배열을 사용합니다.

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

주파수 영역에서 오디오 데이터 플로팅하기

원래의 시간 영역 데이터가 주어졌을 때 fft 함수를 사용하여 진폭을 주파수 영역으로 변환합니다.

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;

0-1000Hz의 주파수 영역에서 오디오 데이터 플로팅하기

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;

텍스트 데이터 전처리 및 정리하기

우세 주파수를 출력합니다. 이 주파수는 fft에서 최대 진폭의 인덱스입니다. 계산한 스케일을 사용하여 값을 Hz로 변환합니다.

[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