メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

モバイル デバイスからのオーディオ データの取得と解析

この例では、MATLAB Mobile で収集したマイクからのオーディオ データを FFT (高速フーリエ変換) を使用して解析する方法を示します。[センサー アクセス] を有効にしたモバイル デバイスが必要になります。[センサー アクセス] を有効にするには、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 ms ごとに一時停止し、バッファーを読み取ります。ウィンドウからの最大値がしきい値*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 ms ごとに一時停止し、バッファーを読み取ります。音声が終了するまで、もしくはタイムアウトに到達するまでオーディオ データを収集します。400 ms 以内に音声が検出されない場合は、取得を終了します。

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;

オーディオ データの前処理

必要なデータのチャネルは 1 つのみです。leftAudio のサイズは n で、グラフ作成と処理に使用されます。マイクのサンプル レートを取得し、周波数スケールを後に決定します。

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 を使用してサンプルを表示します。ラベルには元の目盛り配列を使用します。

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 ~ 1000 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;

最終的な周波数解析とクリーンアップ

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