Changed around line 1
+ document.getElementById('music-upload').addEventListener('change', function(event) {
+ const file = event.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ const audioData = e.target.result;
+
+ audioContext.decodeAudioData(audioData, function(buffer) {
+ visualizeAudio(buffer);
+ });
+ };
+ reader.readAsArrayBuffer(file);
+ }
+ });
+
+ function visualizeAudio(buffer) {
+ const canvas = document.getElementById('music-canvas');
+ const ctx = canvas.getContext('2d');
+ const width = canvas.width;
+ const height = canvas.height;
+
+ const audioData = buffer.getChannelData(0);
+ const step = Math.ceil(audioData.length / width);
+ const amp = height / 2;
+
+ ctx.clearRect(0, 0, width, height);
+ ctx.beginPath();
+ ctx.moveTo(0, amp);
+
+ for (let i = 0; i < width; i++) {
+ let min = 1.0;
+ let max = -1.0;
+ for (let j = 0; j < step; j++) {
+ const datum = audioData[(i * step) + j];
+ if (datum < min) min = datum;
+ if (datum > max) max = datum;
+ }
+ ctx.lineTo(i, (1 + min) * amp);
+ ctx.lineTo(i, (1 + max) * amp);
+ }
+
+ ctx.strokeStyle = '#ff6f61';
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ }
+
+ document.getElementById('image-upload').addEventListener('change', function(event) {
+ const file = event.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ const img = new Image();
+ img.src = e.target.result;
+ img.onload = function() {
+ const audio = imageToSound(img);
+ const audioOutput = document.getElementById('audio-output');
+ audioOutput.src = URL.createObjectURL(audio);
+ };
+ };
+ reader.readAsDataURL(file);
+ }
+ });
+
+ function imageToSound(img) {
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0);
+
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ const data = imageData.data;
+
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ const buffer = audioContext.createBuffer(1, data.length, audioContext.sampleRate);
+ const output = buffer.getChannelData(0);
+
+ for (let i = 0; i < data.length; i++) {
+ output[i] = (data[i] - 128) / 128;
+ }
+
+ const source = audioContext.createBufferSource();
+ source.buffer = buffer;
+ source.connect(audioContext.destination);
+
+ const blob = new Blob([bufferToWav(buffer)], { type: 'audio/wav' });
+ return blob;
+ }
+
+ function bufferToWav(buffer) {
+ const numOfChan = buffer.numberOfChannels;
+ const length = buffer.length * numOfChan * 2 + 44;
+ const bufferArray = new ArrayBuffer(length);
+ const view = new DataView(bufferArray);
+
+ writeString(view, 0, 'RIFF');
+ view.setUint32(4, 36 + buffer.length * numOfChan * 2, true);
+ writeString(view, 8, 'WAVE');
+ writeString(view, 12, 'fmt ');
+ view.setUint32(16, 16, true);
+ view.setUint16(20, 1, true);
+ view.setUint16(22, numOfChan, true);
+ view.setUint32(24, buffer.sampleRate, true);
+ view.setUint32(28, buffer.sampleRate * 2 * numOfChan, true);
+ view.setUint16(32, numOfChan * 2, true);
+ view.setUint16(34, 16, true);
+ writeString(view, 36, 'data');
+ view.setUint32(40, buffer.length * numOfChan * 2, true);
+
+ let offset = 44;
+ for (let i = 0; i < buffer.length; i++) {
+ for (let channel = 0; channel < numOfChan; channel++) {
+ const sample = Math.max(-1, Math.min(1, buffer.getChannelData(channel)[i]));
+ view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);
+ offset += 2;
+ }
+ }
+
+ return bufferArray;
+ }
+
+ function writeString(view, offset, string) {
+ for (let i = 0; i < string.length; i++) {
+ view.setUint8(offset + i, string.charCodeAt(i));
+ }
+ }