ギターの音をphyphox(Physical Phone Experiments)のオーディオスペクトルで記録しました。
1. 記録したのは下の写真のギターの1弦と6弦を一つずつ鳴らしたときのオーディオスペクトルです。
2. スマートフォンでphyphoxを起動し、下のスナップショット写真の緑の枠で囲ったボタンを順に押し、ギターの音データを記録します。2つ目の写真で▶ボタンを押してから3つ目の写真で停止ボタンを押すまでの音データが記録されます。
記録した音データは、こちらの方法と同様の方法でExcelファイルに保存し、パソコン等に送ることができます。
3. phyphoxからエクスポートしたExcelファイルのシート”Raw Data”には、約0.000020833秒(約20.833マイクロ秒)ごとに音データが記録されていました。(私が使用している端末はiPhone SE(第1世代)です。)
4. 下の画像はphyphoxのオーディオスペクトルの測定結果のスナップショット画像です。アコースティックギターの1弦の開放弦の音の高さをE4(329.628Hz)にして弦を鳴らし、測定しました。
1つ目の画像のピーク周波数はE4(329.628Hz)の周波数に近い328.12Hzとなっています。中央の図の横軸は音の周波数、縦軸は横軸に対応する周波数成分の強度です。ともに対数をとってプロットされています。基本となる弦の振動の周波数成分(329.628Hz)に加え、第2倍音(659.256Hz)、第3倍音(985.884Hz)あたりの周波数成分も大きくなっています。
1つ目の画像の下のほうに使用サンプル数と動作時間が記されています。音の生データ(“Raw Data”)は約20.833マイクロ秒間隔で記録されています。(MEMSマイクロフォンを使って音圧が記録されています。) 使用サンプル数が2,048の場合、周波数は20.833マイクロ秒 x 2,048 = 42.665ミリ秒(約42.67ミリ秒)のデータを使って計算されることになります。この時間が動作時間としてスナップショット画像に表示されています。
2つ目の画像の中央の図は各周波数成分の大きさの履歴を表示しています。縦軸は測定開始からの経過秒数で、横軸に対応する周波数成分の大きさを色で表しています。大きな周波数成分は白で、小さな周波数成分は黒で表されています。測定開始から0.6秒ほど経過したときにギターの弦を鳴らしたため、0.6秒後あたりからギターの音のデータが表示されています。
2つ目の画像の下の図はピーク周波数の時間変化を表しています。0.6秒から0.7秒後あたりで一度、第2倍音(659.256Hz)に近い約680Hzの周波数がピーク周波数となり、その後、基本周波数(329.628Hz)に近い約328Hzがピーク周波数となっています。
3つ目の画像のようにFFT(高速フーリエ変換)で利用するデータのサンプル数を変更することもできます。サンプル数を大きくすると周波数分解能を改善すること(横軸の周波数の間隔を細かくすること)ができますが、データの取得により多くの時間を要するようになります。
4つ目の画像はMEMSマイクロフォンで約0.000020833秒(約20.833マイクロ秒)ごとに計測された音圧の時系列データです。
5. 下のグラフは4.の一つ目の画像に対応するオーディオスペクトルをGoogle Chartsでプロットしたグラフです。こちらのグラフは、縦軸、横軸とも対数を取っていません。
音圧の生データを約0.000020833秒(約20.833マイクロ秒)ごとに計測しているため、サンプリングレートは 1.0 / 0.000020833 = 約48,000(Hz)になります。計測可能な音の振動の最大周波数(ナイキスト周波数)はその約半分の約24,000(Hz)になります。横軸の最大周波数はこの値に近い約23,977Hzとなっています。
人の可聴域は20Hz程度から20,000Hz程度までで、グラフにはこの範囲の周波数が含まれています。
6. 下のグラフは5.のグラフの横軸を対数スケールに変換したグラフです。
音の周波数は1オクターブで2倍になり、1オクターブ内の12の音の周波数は $\sqrt[12]{2}=2^{\frac1{12}}$ 倍ずつ大きくなります。そのため、対数を取って表示するほうが音名との対応は付け易くなります。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
C |
C# D$\flat$ |
D |
D# E$\flat$ |
E | F |
F# G$\flat$ |
G |
G# A$\flat$ |
A |
A# B$\flat$ |
B |
ド |
ド# レ$\flat$ |
レ |
レ# ミ$\flat$ |
ミ | ファ |
ファ# ソ$\flat$ |
ソ |
ソ# ラ$\flat$ |
ラ |
ラ# シ$\flat$ |
シ |
7. 下の図はピーク周波数の時間変化を表しています。0.6秒から0.8秒後あたりで一度、第2倍音(659.256Hz)に近い約679.6875Hzの周波数がピーク周波数となり、その後、基本周波数(329.628Hz)に近い328.125Hzがピーク周波数となっています。
8. 次に、アコースティックギターの6弦の開放弦の音の高さをE2(82.407Hz)にして6弦を鳴らし、phyphoxでオーディオスペクトルを測定しました。4.から7.の実験と同様、FFT(高速フーリエ変換)の計算に使用するサンプル数は2,048、動作時間は42.67ミリ秒です。
下のグラフは5.と同様、オーディオスペクトルをGoogle Chartsでプロットしたグラフです。
9. 下のグラフは8.のグラフの横軸を対数スケールに変換したグラフです。
E2(82.407Hz)の周波数の約2倍、約164Hzに大きなピーク周波数が見られます。E2(82.407Hz)に近い周波数、70.3125Hzと93.75Hzの周波数成分も大きな値となっています。また、E2(82.407Hz)の3倍、247.221Hzに近い周波数、234.375Hzと257.8125Hzの周波数成分も大きな値となっています。
対象としている300Hz以下の周波数領域において周波数分解能が不足しているようにも見えたため、FFT(高速フーリエ変換)の計算に使用するサンプル数を32,768に増やして再計測しました。
10. 下のグラフはFFT(高速フーリエ変換)の計算に使用するサンプル数を32,768に増やして計測したオーディオスペクトルです。9.と同様、横軸は対数スケールです。phyphoxのオーディオスペクトルの設定画面(4.の3つ目の画像)でサンプル数32,768を選択して再計測しました。基本周波数のE2(約82Hz)ではなく、第2倍音(E3:約165Hz)に近い周波数がピーク周波数になっています。
補足3:シートRaw dataに記録された音圧の時系列データについて
phyphoxからエクスポートしたExcelファイルのシートRaw dataには音圧の時系列データが記録されていますが、こちらに記録されているのは音圧の時系列データの一部です。1回のFFTの入力サンプル数(サンプル数32,768なら32,768行分)と近い数の時系列データが記録されています。
音圧の時系列が記録されている時間間隔は1/48,000秒(約0.00002083秒)です。
こちらのフォーラムで話題に上がっているのを確認しました。
下記のJavaScriptを使用しました。
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript"> google.charts.load('current', {packages:['corechart']}); google.charts.setOnLoadCallback(Spreadsheet); function Spreadsheet() { const query_1st_string = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1gRX4qkrKdkqWuJP4TQvU2CiF_LxGVO7w6xGcRAqGG34/edit?usp=sharing'); drawFFTSpectrumWithSpecifiedIds(query_1st_string, 'audio_spectrum_1st_string', 'audio_spectrum_1st_string_logx'); const query_1st_string_peak_history = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1gRX4qkrKdkqWuJP4TQvU2CiF_LxGVO7w6xGcRAqGG34/edit?usp=sharing&gid=1189174742'); drawPeakHistoryWithSpecifiedId(query_1st_string_peak_history, 'peak_history_1st_string'); const query_6th_string = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1liO8u6jAH0RvGiImDf9KMllMChGQXJ4tKQAzhEk9WlI/edit?usp=sharing&gid=1865279680'); drawFFTSpectrumWithSpecifiedIds(query_6th_string, 'audio_spectrum_6th_string', 'audio_spectrum_6th_string_logx'); const query_peak_history_6th_string = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1liO8u6jAH0RvGiImDf9KMllMChGQXJ4tKQAzhEk9WlI/edit?usp=sharing&gid=639781049'); drawPeakHistoryWithSpecifiedId(query_peak_history_6th_string, 'peak_history_6th_string'); const query_32768_samples_6th_string = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1aqCJyhGPknS17G-OV0inHyg3nmPBXK-reLxEdisMAyM/edit?usp=sharing&gid=61378112'); drawFFTSpectrumWithSpecifiedIds(query_32768_samples_6th_string, 'audio_spectrum_32768_samples_6th_string', 'audio_spectrum_32768_samples_6th_string_logx'); const query_peak_history_32768_samples_6th_string = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1aqCJyhGPknS17G-OV0inHyg3nmPBXK-reLxEdisMAyM/edit?usp=sharing&gid=2072645406'); drawPeakHistoryWithSpecifiedId(query_peak_history_32768_samples_6th_string, 'peak_history_32768_samples_6th_string'); } function drawFFTSpectrumWithSpecifiedIds(query, graph_id, graph_id_logx) { query.send( function(response) { const data = response.getDataTable(); // audio spectrum const options = {title: 'phyphox audio spectrum', hAxis: {title: 'Frequency [Hz]'}, vAxis: {title: 'FFT Magnitude'}}; const chart = new google.visualization.LineChart(document.getElementById(graph_id)); chart.draw(data, options); // audio spectrum : horizontal axis is logarithmic scale const options_logx = {title: 'phyphox audio spectrum : horizontal axis is logarithmic scale', hAxis: {title: 'Frequency [Hz]', scaleType: 'log'}, vAxis: {title: 'FFT Magnitude'}}; const chart_logx = new google.visualization.LineChart(document.getElementById(graph_id_logx)); chart_logx.draw(data, options_logx); }); } function drawPeakHistoryWithSpecifiedId(query, graph_id) { query.send( function(response) { const data = response.getDataTable(); // Peak History const options = {title: 'phyphox peak history', hAxis: {title: 'Time [s]'}, vAxis: {title: 'Peak Frequency [Hz]'}}; const chart = new google.visualization.LineChart(document.getElementById(graph_id)); chart.draw(data, options); }); } </script>