Mike W commited on
Commit
f0821d0
·
1 Parent(s): c8c7d92

Fix: Initial runtime errors with integration

Browse files
Files changed (1) hide show
  1. index.html +47 -17
index.html CHANGED
@@ -44,15 +44,13 @@
44
  if (event.data instanceof Blob) {
45
  const reader = new FileReader();
46
  reader.onload = function() {
47
- const arrayBuffer = this.result;
48
- // Ensure audioContext is initialized before decoding
 
49
  if (audioContext) {
50
- audioContext.decodeAudioData(arrayBuffer, (buffer) => {
51
- audioQueue.push(buffer);
52
- if (!isPlaying) {
53
- playNextInQueue();
54
- }
55
- });
56
  };
57
  reader.readAsArrayBuffer(event.data);
58
  } else {
@@ -75,21 +73,53 @@
75
  };
76
  };
77
 
78
- const playNextInQueue = () => {
79
  if (audioQueue.length > 0) {
80
  isPlaying = true;
81
- const buffer = audioQueue.shift();
82
- const source = audioContext.createBufferSource();
83
- source.buffer = buffer;
84
- source.connect(audioContext.destination);
85
- source.onended = () => {
 
 
 
 
 
 
86
  isPlaying = false;
87
- playNextInQueue();
88
- };
89
- source.start();
 
90
  }
91
  };
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  startButton.onclick = async () => {
94
  // AudioContext must be created or resumed by a user gesture.
95
  if (!audioContext) {
 
44
  if (event.data instanceof Blob) {
45
  const reader = new FileReader();
46
  reader.onload = function() {
47
+ // The server sends raw PCM; we need to wrap it in a WAV header
48
+ const pcmData = new Int16Array(this.result);
49
+ const wavBlob = createWavBlob(pcmData, 1, 16000);
50
  if (audioContext) {
51
+ audioQueue.push(wavBlob);
52
+ if (!isPlaying) playNextInQueue();
53
+ }
 
 
 
54
  };
55
  reader.readAsArrayBuffer(event.data);
56
  } else {
 
73
  };
74
  };
75
 
76
+ const playNextInQueue = async () => {
77
  if (audioQueue.length > 0) {
78
  isPlaying = true;
79
+ const blob = audioQueue.shift();
80
+ try {
81
+ const arrayBuffer = await blob.arrayBuffer();
82
+ const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
83
+ const source = audioContext.createBufferSource();
84
+ source.buffer = audioBuffer;
85
+ source.connect(audioContext.destination);
86
+ source.onended = playNextInQueue; // Chain the next playback
87
+ source.start();
88
+ } catch (e) {
89
+ console.error("Error decoding or playing audio:", e);
90
  isPlaying = false;
91
+ playNextInQueue(); // Try the next one
92
+ }
93
+ } else {
94
+ isPlaying = false;
95
  }
96
  };
97
 
98
+ // Helper function to create a WAV blob from raw PCM data
99
+ const createWavBlob = (pcmData, numChannels, sampleRate) => {
100
+ const header = new ArrayBuffer(44);
101
+ const view = new DataView(header);
102
+ const pcmLength = pcmData.length * 2; // 16-bit samples
103
+
104
+ // RIFF header
105
+ view.setUint32(0, 0x52494646, false); // "RIFF"
106
+ view.setUint32(4, 36 + pcmLength, true);
107
+ view.setUint32(8, 0x57415645, false); // "WAVE"
108
+ // "fmt " sub-chunk
109
+ view.setUint32(12, 0x666d7420, false); // "fmt "
110
+ view.setUint32(16, 16, true); // Sub-chunk size
111
+ view.setUint16(20, 1, true); // Audio format (1 for PCM)
112
+ view.setUint16(22, numChannels, true);
113
+ view.setUint32(24, sampleRate, true);
114
+ view.setUint32(28, sampleRate * numChannels * 2, true); // Byte rate
115
+ view.setUint16(32, numChannels * 2, true); // Block align
116
+ view.setUint16(34, 16, true); // Bits per sample
117
+ view.setUint32(36, 0x64617461, false); // "data"
118
+ view.setUint32(40, pcmLength, true);
119
+
120
+ return new Blob([header, pcmData], { type: 'audio/wav' });
121
+ };
122
+
123
  startButton.onclick = async () => {
124
  // AudioContext must be created or resumed by a user gesture.
125
  if (!audioContext) {