Skip to content

Instantly share code, notes, and snippets.

@ofTheo
Created May 3, 2023 02:53
Show Gist options
  • Save ofTheo/560d2b3f34883486a15a815f9194a4b8 to your computer and use it in GitHub Desktop.
Save ofTheo/560d2b3f34883486a15a815f9194a4b8 to your computer and use it in GitHub Desktop.
var LibraryHTML5Audio = {
$AUDIO: {
players: [],
lastSoundID: 0,
},
html5audio_list_devices: function(){
console.log("list devices")
const constraints = {audio: true};
navigator.mediaDevices.getUserMedia(constraints).then(function() {
console.log('getUserMedia completed successfully.');
if (!navigator.mediaDevices.enumerateDevices) {
console.log("enumerateDevices() not supported.");
} else {
// List cameras and microphones.
navigator.mediaDevices.enumerateDevices()
.then((devices) => {
devices.forEach((device) => {
if(device.kind == "audioinput"){
console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);
}
});
return devices;
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
}
})
.catch(function(error) {
console.log(error.name + ": " + error.message);
});
},
html5audio_context_create: function () {
const constraints = {audio: true};
navigator.mediaDevices.getUserMedia(constraints)
.then(function() {
console.log('getUserMedia completed successfully.');
try {
// Fix up for prefixing
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext({});
// Fix issue with chrome autoplay policy
document.addEventListener('mousedown', function cb(event) {
context.resume();
event.currentTarget.removeEventListener(event.type, cb);
});
AUDIO.context = context;
var fft = context.createAnalyser();
fft.smoothingTimeConstant = 0;
fft.connect(AUDIO.context.destination);
fft.maxDecibels = 0;
fft.minDecibels = -100;
AUDIO.fft = fft;
return 0;
} catch (e) {
console.log('Web Audio API is not supported in this browser', e);
return -1;
}
})
.catch(function(error) {
console.log(error.name + ": " + error.message);
});
},
html5audio_context_start: function () {
AUDIO.context.resume();
},
html5audio_context_stop: function () {
AUDIO.context.suspend();
},
html5audio_context_spectrum: function (bands, spectrum) {
AUDIO.fft.fftSize = bands * 2;
var spectrumArray = Module.HEAPF32.subarray(spectrum >> 2, (spectrum >> 2) + bands);
AUDIO.fft.getFloatFrequencyData(spectrumArray);
},
html5audio_context_samplerate: function () {
return AUDIO.context.sampleRate.value;
},
html5audio_sound_load: function (url) {
var audio = document.createElement('audio');
var sound_id = AUDIO.lastSoundID++;
AUDIO.players[sound_id] = audio;
AUDIO.players[sound_id].src = UTF8ToString(url);
var source = AUDIO.context.createMediaElementSource(AUDIO.players[sound_id]);
AUDIO.players[sound_id].soundPan = AUDIO.context.createStereoPanner();
source.connect(AUDIO.players[sound_id].soundPan).connect(AUDIO.fft);
return sound_id;
},
html5audio_sound_play: function (sound_id, offset) {
AUDIO.players[sound_id].play(offset);
},
html5audio_sound_stop: function (sound_id) {
AUDIO.players[sound_id].currentTime = 0;
AUDIO.players[sound_id].pause();
},
html5audio_sound_pause: function (sound_id) {
AUDIO.players[sound_id].pause();
},
html5audio_sound_rate: function (sound_id) {
return AUDIO.players[sound_id].playbackRate;
},
html5audio_sound_set_rate: function (sound_id, rate) {
AUDIO.players[sound_id].playbackRate = rate;
},
html5audio_sound_done: function (sound_id) {
return AUDIO.players[sound_id].done;
},
html5audio_sound_duration: function (sound_id) {
return AUDIO.players[sound_id].duration;
},
html5audio_sound_position: function (sound_id) {
return AUDIO.players[sound_id].currentTime;
},
html5audio_sound_set_position: function (sound_id, position) {
AUDIO.players[sound_id].currentTime = position * AUDIO.players[sound_id].duration;
},
html5audio_sound_set_loop: function (sound_id, loop) {
AUDIO.players[sound_id].loop = true;
},
html5audio_sound_set_volume: function (sound_id, volume) {
AUDIO.players[sound_id].volume = volume;
},
html5audio_sound_volume: function (sound_id) {
return AUDIO.players[sound_id].volume;
},
html5audio_sound_set_pan: function (sound_id, pan) {
AUDIO.players[sound_id].soundPan.pan.value = pan;
},
html5audio_sound_pan: function (sound_id) {
return AUDIO.players[sound_id].soundPan.pan.value;
},
html5audio_sound_free: function (sound_id) {
if(AUDIO.players[sound_id] != undefined){
AUDIO.players[sound_id].pause();
URL.revokeObjectURL(AUDIO.players[sound_id].src);
}
},
html5audio_stream_create: function(bufferSize, inputChannels, outputChannels, inbuffer, outbuffer, callback, userData){
const constraints = {audio: true};
navigator.mediaDevices.getUserMedia(constraints)
.then(function() {
console.log('getUserMedia completed successfully.');
var stream = AUDIO.context.createScriptProcessor(bufferSize,inputChannels,outputChannels);
var inbufferArray = Module.HEAPF32.subarray(inbuffer>>2,(inbuffer>>2)+bufferSize*inputChannels);
var outbufferArray = Module.HEAPF32.subarray(outbuffer>>2,(outbuffer>>2)+bufferSize*outputChannels);
stream.onaudioprocess = function(event){
var i, j, c;
if (inputChannels > 0){
for (c = 0; c < inputChannels; ++c){
var inChannel = event.inputBuffer.getChannelData(c);
for (i = 0, j = c; i < bufferSize; ++i, j += inputChannels){
inbufferArray[j] = inChannel[i];
}
}
}
{{{ makeDynCall('viiii', 'callback') }}}(bufferSize, inputChannels, outputChannels, userData);
if (outputChannels > 0){
for (c = 0;c < outputChannels; ++c){
var outChannel = event.outputBuffer.getChannelData(c);
for (i = 0,j = c;i<bufferSize; ++i, j += outputChannels){
outChannel[i] = outbufferArray[j];
}
}
}
};
if (inputChannels > 0){
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (navigator.getUserMedia){
navigator.getUserMedia(
{audio: true},
function (audioIn){
var mediaElement = AUDIO.context.createMediaStreamSource(audioIn);
mediaElement.connect(stream);
AUDIO.mediaElement = mediaElement;
},
function (error){
console.log("error creating audio in",error);
});
}
}
stream.connect(AUDIO.fft);
AUDIO.stream = stream;
})
.catch(function(error) {
console.log(error.name + ": " + error.message);
});
},
html5audio_stream_free: function () {
return AUDIO.stream = null;
return AUDIO.mediaElement = null;
},
html5audio_sound_is_loaded: function (sound_id) {
if (AUDIO.players[sound_id].src != undefined) {
return true;
}
return false;
}
}
autoAddDeps(LibraryHTML5Audio, '$AUDIO');
mergeInto(LibraryManager.library, LibraryHTML5Audio);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment