質問編集履歴
1
ソースコードを追加、試してみたことを追加しました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -11,26 +11,102 @@
|
|
11
11
|
- [ ] 録音した音声の周波数の最高値と最低値を取得したい。(もう一度ボタンを押したタイミングで、録音を停止して、録音した音声の周波数の最高値と最低値を取得する)
|
12
12
|
|
13
13
|
### 発生している問題・エラーメッセージ
|
14
|
-
|
14
|
+
録音を停止した際にこのエラーが出てしまいます。
|
15
|
+
```GoogleChrome検証画面
|
16
|
+
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
|
17
|
+
```
|
18
|
+
### 該当のソースコード
|
19
|
+
```html
|
20
|
+
<h1 class="heading">音階を測定する</h1>
|
21
|
+
<button onclick="startRecording()">解析開始</button>
|
22
|
+
<button onclick="endRecording()">解析終了</button>
|
23
|
+
```
|
24
|
+
```javascript
|
25
|
+
// クロスブラウザ定義
|
26
|
+
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
15
27
|
|
28
|
+
// 変数定義
|
29
|
+
var localMediaStream = null;
|
30
|
+
var localScriptProcessor = null;
|
31
|
+
var audioContext = new AudioContext();
|
32
|
+
var bufferSize = 1024;
|
33
|
+
var audioData = []; // 録音データ
|
34
|
+
var recordingFlg = false;
|
35
|
+
|
36
|
+
|
37
|
+
// 音声解析
|
38
|
+
var audioAnalyser = null;
|
39
|
+
|
40
|
+
|
41
|
+
// 録音バッファ作成(録音中自動で繰り返し呼び出される)
|
42
|
+
var onAudioProcess = function(e) {
|
43
|
+
if (!recordingFlg) return;
|
44
|
+
|
45
|
+
// 音声のバッファを作成
|
46
|
+
var input = e.inputBuffer.getChannelData(0);
|
47
|
+
var bufferData = new Float32Array(bufferSize);
|
48
|
+
for (var i = 0; i < bufferSize; i++) {
|
49
|
+
bufferData[i] = input[i];
|
50
|
+
}
|
51
|
+
audioData.push(bufferData);//録音データに追加
|
52
|
+
|
53
|
+
// オーディオデータ取得
|
54
|
+
var fsDivN = audioContext.sampleRate / audioAnalyser.fftSize;
|
55
|
+
var spectrums = new Uint8Array(audioAnalyser.frequencyBinCount);
|
56
|
+
audioAnalyser.getByteFrequencyData(spectrums);
|
57
|
+
|
58
|
+
};
|
59
|
+
|
60
|
+
// 解析開始
|
61
|
+
var startRecording = function() {
|
62
|
+
recordingFlg = true;
|
63
|
+
navigator.getUserMedia({audio: true}, function(stream) {
|
64
|
+
// 録音関連
|
65
|
+
localMediaStream = stream;
|
66
|
+
var scriptProcessor = audioContext.createScriptProcessor(bufferSize, 1, 1);
|
67
|
+
localScriptProcessor = scriptProcessor;
|
68
|
+
var mediastreamsource = audioContext.createMediaStreamSource(stream);
|
69
|
+
mediastreamsource.connect(scriptProcessor);
|
70
|
+
scriptProcessor.onaudioprocess = onAudioProcess;
|
71
|
+
scriptProcessor.connect(audioContext.destination);
|
72
|
+
|
73
|
+
// 音声解析関連
|
74
|
+
audioAnalyser = audioContext.createAnalyser();
|
75
|
+
audioAnalyser.fftSize = 2048;
|
76
|
+
frequencyData = new Uint8Array(audioAnalyser.frequencyBinCount);
|
77
|
+
timeDomainData = new Uint8Array(audioAnalyser.frequencyBinCount);
|
78
|
+
mediastreamsource.connect(audioAnalyser);
|
79
|
+
|
80
|
+
},
|
81
|
+
function(e) {
|
82
|
+
console.log(e);
|
83
|
+
});
|
84
|
+
};
|
85
|
+
|
86
|
+
// 解析終了
|
87
|
+
var endRecording = function() {
|
88
|
+
recordingFlg = false;
|
89
|
+
//audioDataをサーバに送信するなど終了処理
|
90
|
+
// 録音した音声の周波数を取得
|
91
|
+
audioAnalyser.getFloatFrequencyData();
|
92
|
+
// 録音した音声の周波数の最大値と最小値を出力
|
93
|
+
console.log(audioAnalyser.maxDecibels);
|
94
|
+
console.log(audioAnalyser.minDecibels);
|
95
|
+
};
|
96
|
+
```
|
16
97
|
### 試したこと
|
98
|
+
録音機能を搭載して、その後の音声解析の際のコードであるaudioAnalyser.getFloatFrequencyData();の位置を変えてみたりしてみましたが、このコードが何を取得しているのいまいち分かっていません。
|
99
|
+
audioAnalyser.getFloatFrequencyData();の位置を変えたり、audioAnalyser.maxDecibelsの位置を変えたり、オーディオデータを取得する際のコードを変えることで、解決できるのではないかと考えています。
|
100
|
+
|
17
101
|
##### 参考にしたwebサイト
|
18
102
|
1. https://g200kg.github.io/web-audio-api-ja/131010/index.html#AudioContext-section
|
19
|
-
getFloatFrequencyData メソッド
|
20
|
-
現在の周波数データを渡された浮動小数値配列にコピーします。 もし配列の要素数がfrequencyBinCountよりも小さい場合、はみ出した部分は削られます。 もし配列がfrequencyBinCountよりも大きい要素数を持つ場合、余分な要素は無視されます。
|
21
|
-
|
22
|
-
arrayパラメータは周波数領域の解析結果を格納する場所を示します。
|
23
|
-
|
24
103
|
getByteFrequencyData メソッド
|
25
104
|
現在の周波数データを渡されたunsigned byte配列にコピーします。 もし配列の要素数がfrequencyBinCountよりも小さい場合、はみ出した部分は削られます。 もし配列がfrequencyBinCountよりも大きい要素数を持つ場合、余分な要素は無視されます
|
26
|
-
|
27
105
|
arrayパラメータは周波数領域の解析結果の格納する場所を示します。
|
28
106
|
|
29
107
|
getByteTimeDomainData メソッド
|
30
108
|
現在の時間領域データ(波形データ)を渡されたunsigned byte配列にコピーします。 もし配列の要素数がfftSizeよりも小さい場合、はみ出た部分は削られます。 もし配列がfftSizeよりも大きな要素数を持つ場合、余分な要素は無視されます。
|
31
|
-
|
32
109
|
arrayパラメータは時間領域解析データを格納する場所を示します。
|
33
|
-
|
34
110
|
|
35
111
|
2. https://qiita.com/mhagita/items/6c7d73932d9a207eb94d
|
36
112
|
getUserMediaで音声を拾いリアルタイムで波形を出力する
|
@@ -41,8 +117,11 @@
|
|
41
117
|
4. https://saitodev.co/search?q=web+audio+api
|
42
118
|
JavaScriptのWeb Audio APIで録音してみる
|
43
119
|
|
44
|
-
|
120
|
+
5. https://developer.mozilla.org/ja/docs/Web/API/AnalyserNode
|
45
|
-
|
121
|
+
.maxDecibels
|
122
|
+
unsigned byte 型値へ変換する FFT 分析データのスケーリング時の最大のパワー値を表す double 型の値である。一般的に、この値は、getByteFrequencyData()の使用時の結果の範囲の最大値として明記される。
|
123
|
+
.minDecibels
|
124
|
+
unsigned byte 型値へ変換する FFT 分析データのスケーリング時の最小のパワー値を表す double 型の値である。一般的に、この値は、getByteFrequencyData()の使用時の結果の範囲の最小値として明記される。
|
46
125
|
|
47
126
|
### 補足情報(FW/ツールのバージョンなど)
|
48
127
|
|