素人ではないが、ガチ勢でもないレベル・・・(˘ω˘ )
##まさかWebAudioの勉強会が開催される日がくるとは!
ざっくり言うと、
SkypeがWebの技術でできるようなもの。
ただ、このモバイル全盛期でもiOSのWebで使えない!!
WebRTCアプリの会話・音を聞くだけでも・・。
というわけで、
なんちゃってWebRTCできるのでは!
##(WiFiがあれば)
var crx = new AudioContext();
navigator.mediaDevices
// 今回は音さえあればOK
.getUserMedia({ audio: true })
.then((stream) => {
var micSrc = ctx.createMediaStreamSource(stream);
// micSrc: AudioBufferSourceNode
// コレをつないでいく
})
getUserMedia()
は、localhostかhttps環境でお試しください!
var filter = ctx.createBiquadFilter();
filter.type = 'bandpass';
// アナログ電話は300Hz ~ 3.4kHz / ひかり電話は100Hz ~ 7kHz
filter.frequency.value = (100 + 7000) / 2;
// 固定ならだいたい聴き良いのがこれくらい・・?
filter.Q.value = 0.25;
micSrc.connect(filter);
リアルタイムに周波数帯を検知して、ダイナミックにフィルタも変動したかったけど面倒なのでやめた・・。
var analyser = ctx.createAnalyser();
analyser.smoothingTimeConstant = 0.4;
analyser.fftSize = BUFFER_SIZE;
var fbc = analyser.frequencyBinCount;
var freqs = new Uint8Array(fbc);
analyser.getByteFrequencyData(freqs);
// freqsの中身を、canvasにグラフとして描画
入力音によって波打つアレ。
これがあるとそれっぽい感じに!
var processor = ctx.createScriptProcessor(BUFFER_SIZE, 1, 1);
processor.onaudioprocess = _onAudioProcess;
function _onAudioProcess(ev) {
var inputBuffer = ev.inputBuffer;
var outputBuffer = ev.outputBuffer;
// 1chなのでインデックスは0
var inputData = inputBuffer.getChannelData(0);
var outputData = outputBuffer.getChannelData(0);
// Bypassしつつ飛ばさないとダメ
outputData.set(inputData);
// これをそのままWebSocketで流す
worker.postMessage({
type: 'AUDIO',
data: outputData.buffer
});
}
音質にこだわるなら、ここで巨大なバッファに2chつめこめば・・?
var ctx = new AudioContext();
// WebSocketで受けたバッファを処理する
function _handleAudioBuffer(buf) {
var f32Audio = new Float32Array(buf);
// 送られてきたのとあわせる
var audioBuffer = ctx.createBuffer(1, BUFFER_SIZE, ctx.sampleRate);
audioBuffer.getChannelData(0).set(f32Audio);
// 後はいつも通り
var source = ctx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audio.gain);
}
後は鳴らすだけ!
var _startTime = 0;
var currentTime = ctx.currentTime;
// つまってるので未来に再生
if (currentTime < _startTime) {
source.start(_startTime);
_startTime += audioBuffer.duration;
}
// すぐ再生
else {
source.start(_startTime);
_startTime = currentTime + audioBuffer.duration;
}
これが地味に重要で、こうしないとプツプツとぎれとぎれになります・・。
やってみた本人が一番驚いてるけど、意外にイケる😊
一部はブログに!もしくは懇親会🍕で!