Skip to content

Commit

Permalink
Merge pull request #317 from uezo/fix-webgl-mic-input-bug
Browse files Browse the repository at this point in the history
Fix WebGL microphone input handling
  • Loading branch information
uezo committed Jul 15, 2024
2 parents 1a94879 + eaa3a20 commit b4c97e3
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
25 changes: 18 additions & 7 deletions Plugins/WebGLMicrophone.jslib
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ mergeInto(LibraryManager.library, {
document.webGLMicrophone.isRecording = 0;
document.webGLMicrophone.targetObjectName = UTF8ToString(targetObjectNamePtr);
document.webGLMicrophone.audioContext = new (window.AudioContext || window.webkitAudioContext)();
document.webGLMicrophone.source = null;
document.webGLMicrophone.scriptNode = null;

// Observe the state of audio context for microphone and resume if disabled
setInterval(function() {
Expand All @@ -16,14 +18,18 @@ mergeInto(LibraryManager.library, {
},

StartWebGLMicrophone: function() {
document.webGLMicrophone.isRecording = 1;

if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ audio: true })
navigator.mediaDevices.getUserMedia({ audio: {
sampleRate: { ideal: 44100 },
}, })
.then(function(stream) {
// Setup nodes
var audioContext = document.webGLMicrophone.audioContext;
var source = audioContext.createMediaStreamSource(stream);
var scriptNode = audioContext.createScriptProcessor(4096, 1, 1);
scriptNode.onaudioprocess = function (stream) {
scriptNode.onaudioprocess = function (event) {
SendMessage(document.webGLMicrophone.targetObjectName, "SetSamplingData", event.inputBuffer.getChannelData(0).join(','));
};
// Connect nodes;
Expand All @@ -32,21 +38,26 @@ mergeInto(LibraryManager.library, {

document.webGLMicrophone.scriptNode = scriptNode;
document.webGLMicrophone.source = source;
document.webGLMicrophone.isRecording = 1;

console.log("WebGLMicrophone started recording");
})
.catch(function(err) {
console.log("Failed in GetUserMedia: " + error);
document.webGLMicrophone.isRecording = 0;
});
}
},

EndWebGLMicrophone: function() {
document.webGLMicrophone.source.disconnect(document.webGLMicrophone.scriptNode);
document.webGLMicrophone.source = null;
document.webGLMicrophone.scriptNode.disconnect();
document.webGLMicrophone.scriptNode = null;
console.log("EndWebGLMicrophone");
if (document.webGLMicrophone.source != null) {
document.webGLMicrophone.source.disconnect(document.webGLMicrophone.scriptNode);
document.webGLMicrophone.source = null;
}
if (document.webGLMicrophone.scriptNode != null) {
document.webGLMicrophone.scriptNode.disconnect();
document.webGLMicrophone.scriptNode = null;
}
document.webGLMicrophone.isRecording = 0;
},

Expand Down
24 changes: 18 additions & 6 deletions Scripts/IO/WebGLMicrophone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class WebGLMicrophone : MonoBehaviour
private float[] capturedData;
private bool loop;
private int currentPosition;
private bool isAlreadyStarted = false;

// Singleton
private static WebGLMicrophone instance;
Expand Down Expand Up @@ -52,11 +53,21 @@ private void Awake()

public static AudioClip Start(string deviceName, bool loop, int lengthSec, int frequency)
{
if (Instance.isAlreadyStarted)
{
Debug.Log($"WebGLMicrophone is already started");
return Instance.microphoneClip;
}
else
{
Instance.isAlreadyStarted = true;
}

if (!IsRecording(deviceName))
{
Instance.loop = loop;
Instance.currentPosition = 0;
var channels = 1; // デバイスから取得できるのであればするけど・・・
var channels = 1;
Instance.capturedData = new float[FIXED_FREQUENCY * lengthSec * channels];
if (Instance.microphoneClip != null)
{
Expand Down Expand Up @@ -98,17 +109,17 @@ public static int GetPosition(string deviceName)
private void SetSamplingData(string samplingDataString)
{
var samplingData = samplingDataString.Split(',').Select(s => Convert.ToSingle(s)).ToArray();

var pos = currentPosition;

for (int i = 0; i < samplingData.Length; i++)
{
capturedData[currentPosition] = samplingData[i];
currentPosition++;
if (currentPosition == capturedData.Length)
capturedData[pos] = samplingData[i];
pos++;
if (pos == capturedData.Length)
{
if (loop)
{
currentPosition = 0;
pos = 0;
}
else
{
Expand All @@ -121,6 +132,7 @@ private void SetSamplingData(string samplingDataString)
{
microphoneClip.SetData(capturedData, 0);
}
currentPosition = pos;
}
#endif
}
Expand Down

0 comments on commit b4c97e3

Please sign in to comment.