diff --git a/assets/template.html b/assets/template.html
index 7fcf68c..ff07a2d 100644
--- a/assets/template.html
+++ b/assets/template.html
@@ -292,6 +292,7 @@
+
diff --git a/bin/web/css/demo.css b/bin/web/css/demo.css
index 9d6d978..7ebf71d 100755
--- a/bin/web/css/demo.css
+++ b/bin/web/css/demo.css
@@ -964,3 +964,6 @@ h4{
margin-bottom: -3px;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.7), 0 3px 4px rgba(0, 0, 0, 0.7);
}
+.invisible {
+ display: none;
+}
diff --git a/bin/web/js/audio.js b/bin/web/js/audio.js
index 036856f..2dbfeaa 100644
--- a/bin/web/js/audio.js
+++ b/bin/web/js/audio.js
@@ -19,6 +19,7 @@ const AudioMappingOptions = function() {
this.max_out = 1.0;
this.smoothing = config.audio.defaultSmoothing;
this.sync = 'volume';
+ this.source = 'microphone';
this.value = 0.0;
};
@@ -270,8 +271,26 @@ const Audio = function(tp, record) {
const ld = panel.querySelector(toCssClass(`audio_letterDelay${propTitle}`,'#'));
mappingOptions.letterDelay = typeof ld.value === 'number' ? ld.value : parseInt(ld.value);
}
+ mappingOptions.source = panel.querySelector(toCssClass(`audio_source${propTitle}`, '#')).value;
};
+ const source_Dom = document.createElement('select');
+ source_Dom.id = toCssClass(`audio_source${propTitle}`);
+ const source_mic = document.createElement('option');
+ source_mic.value = 'microphone';
+ source_mic.innerHTML = 'microphone';
+ source_Dom.append(source_mic);
+ FS.readdir(config.fs.idbfsAudioDir)
+ .forEach((file) => {
+ if (file[0] !== '.') {
+ const source_file = document.createElement('option');
+ source_file.value = file;
+ source_file.innerHTML = file;
+ source_Dom.append(source_file);
+ }
+ });
+ audioOptions.append(source_Dom);
+
const min_max_Dom = document.createElement('div');
min_max_Dom.classList.add('audio_min_max');
const min_Cont = document.createElement('div');
@@ -391,6 +410,7 @@ const Audio = function(tp, record) {
fft_Dom.append(fft_imgDom);
fft_Dom.append(fft_selectDom);
audioOptions.append(fft_Dom);
+ source_Dom.addEventListener('change', updateMappingOptions);
min_inputDom.addEventListener('change', updateMappingOptions);
max_inputDom.addEventListener('change', updateMappingOptions);
smoothing_inputDom.addEventListener('change', updateMappingOptions);
@@ -588,6 +608,56 @@ const Audio = function(tp, record) {
}
});
};
+ const audioFileStuff = {};
+ const readAudioFiles = () => {
+ FS.readdir(config.fs.idbfsAudioDir).forEach((file) => {
+ if (file.indexOf('.') !== 0 && !audioFileStuff.hasOwnProperty(file)) {
+ const audioElement = document.createElement('audio');
+ audioElement.classList.add('invisible');
+ audioElement.classList.add('audio_file');
+ audioElement.classList.add(toCssClass(`audio_file${file}`));
+ document.querySelector('body').append(audioElement);
+
+ const arr = FS.readFile(`${config.fs.idbfsAudioDir}/${file}`);
+ let type = 'audio/wav';
+ const filesplit = file.split('.');
+ const extension = filesplit[filesplit.length - 1];
+ if (extension === 'wav') {
+ type = 'audio/wav';
+ } else if (extension === 'mp3') {
+ type = 'audio/mpeg';
+ } else if (extension === 'ogg') {
+ type = 'audio/ogg';
+ }
+
+ const src = URL.createObjectURL(
+ new Blob([arr], {
+ type
+ })
+ );
+
+ audioElement.src = src;
+
+ const source = audioCtx.createMediaElementSource(audioElement);
+ source.connect(audioCtx.destination);
+ const analyser = audioCtx.createAnalyser();
+ analyser.fftSize = config.audio.fftBandsAnalysed;
+ const bufferLength = analyser.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+
+ source.connect(analyser);
+
+ audioElement.play();
+
+ audioFileStuff[file] = {
+ dataArray,
+ analyser,
+ audioElement,
+ };
+ }
+ });
+ };
+
const init = () => {
if (!started) {
@@ -647,6 +717,8 @@ const Audio = function(tp, record) {
analyser.smoothingTimeConstant = 0.85;
window.analyser = analyser;
+ readAudioFiles();
+
//const distortion = audioCtx.createWaveShaper();
//const gainNode = audioCtx.createGain();
//const biquadFilter = audioCtx.createBiquadFilter();
@@ -800,7 +872,11 @@ const Audio = function(tp, record) {
canvasKeys = Object.keys(canvasCombos);
drawVisual = requestAnimationFrame(drawAlt);
- analyser.getByteFrequencyData(dataArrayAlt);
+ //analyser.getByteFrequencyData(dataArrayAlt);
+ //Object.keys(audioFileStuff).forEach((afs) => {
+ //afs.analyser.ByteFrequencyData(afs.dataArray);
+ //});
+ audioFileStuff['hito_steyerl_about_suicide_cameras.ogg'].analyser.getByteFrequencyData(dataArrayAlt);
for (let i = 0; i < canvasKeys.length; i++) {
canvasCombos[canvasKeys[i]][1].fillStyle = "rgb(0, 0, 0)"; // AUDIO COLOR
diff --git a/bin/web/js/config.js b/bin/web/js/config.js
index 11f13b8..5da5973 100644
--- a/bin/web/js/config.js
+++ b/bin/web/js/config.js
@@ -114,6 +114,7 @@ const config = {
fs: {
idbfsDir: '/idbfs',
idbfsFontDir: '/idbfs/fonts',
+ idbfsAudioDir: '/idbfs/audio',
idbfsTmpDir: '/idbfs/tmp',
},
timeline: {
diff --git a/bin/web/js/main.js b/bin/web/js/main.js
index 3719162..1b9a936 100644
--- a/bin/web/js/main.js
+++ b/bin/web/js/main.js
@@ -156,6 +156,11 @@ const findInjectPanel = () => {
bottomButtonsContainer.append(hideuiButton);
hideuiButton.classList.add("main_panel_button");
}
+ const audiofileButton = document.querySelector('#upload_audio');
+ if (audiofileButton !== null) {
+ bottomButtonsContainer.append(audiofileButton);
+ audiofileButton.classList.add("main_panel_button");
+ }
const exportButton = document.querySelector('#exporter_open');
if (exportButton !== null) {
bottomButtonsContainer.append(exportButton);
@@ -562,4 +567,21 @@ const initPanels = () => {
document.addEventListener('keypress', handleUiKeypress);
});
}
+ let audiofileButton = document.querySelector('#upload_audio');
+ if (audiofileButton === null) {
+ audiofileButton = tp.getPanel().querySelector('#upload_audio');
+ }
+ if (audiofileButton !== null) {
+ audiofileButton.addEventListener('click', () => {
+ uploadFile('audio')
+ .then((file) => {
+ moduleFS
+ .save(file)
+ .then(() => {
+ console.log('ermh... done uploading?', file);
+ });
+ });
+ });
+ }
+
};
diff --git a/bin/web/js/moduleFS.js b/bin/web/js/moduleFS.js
index 3611916..a3d872d 100644
--- a/bin/web/js/moduleFS.js
+++ b/bin/web/js/moduleFS.js
@@ -13,6 +13,9 @@ const ModuleFS = function() {
if (!FS.analyzePath(config.fs.idbfsFontDir).exists) {
FS.mkdir(config.fs.idbfsFontDir);
}
+ if (!FS.analyzePath(config.fs.idbfsAudioDir).exists) {
+ FS.mkdir(config.fs.idbfsAudioDir);
+ }
if (!FS.analyzePath(config.fs.idbfsTmpDir).exists) {
FS.mkdir(config.fs.idbfsTmpDir);
}
@@ -59,6 +62,19 @@ const ModuleFS = function() {
.then(() => {
resolve(filePath);
});
+ } else if (file.type.indexOf('audio') === 0) {
+ var uint8View = new Uint8Array(file.arrayBuffer);
+ console.log('trying to save the audio file, file, uint8View', file, uint8View);
+ if (!FS.analyzePath(`${config.fs.idbfsAudioDir}/${file.name}`).exists) {
+ FS.createDataFile(config.fs.idbfsAudioDir, file.name, uint8View, true, true);
+ this.syncfs(MODE_WRITE_TO_PERSISTENT)
+ .then(() => {
+ resolve(true);
+ });
+ } else {
+ alert(`It seems as if an audiofile with the name "${file.name}" already exists. Please rename your file and upload again, thanks <3`);
+ resolve(false);
+ }
} else {
resolve(false);
}
diff --git a/bin/web/js/utils.js b/bin/web/js/utils.js
index 958ce23..166753c 100644
--- a/bin/web/js/utils.js
+++ b/bin/web/js/utils.js
@@ -119,7 +119,7 @@ function uploadFile(expectedType = 'application/json') {
let reader = new FileReader();
- if (expectedType === 'application/zip' || file.type === 'application/zip') {
+ if (expectedType === 'application/zip' || file.type === 'application/zip' || file.type.indexOf('audio') === 0) {
reader.onload = (e) => {
const f = e.target.result;
console.log(e, file.name, file.size, file.type, f);