()
| 235 | }; |
| 236 | |
| 237 | async function toggleInput() { |
| 238 | |
| 239 | if (!audioContext) { |
| 240 | audioContext = new (window.AudioContext || window.webkitAudioContext)(); |
| 241 | analyser = audioContext.createAnalyser(); |
| 242 | analyser.fftSize = 2048; |
| 243 | } |
| 244 | await audioContext.resume(); |
| 245 | |
| 246 | if (usingMic) { |
| 247 | usingMic = false; |
| 248 | inputToggle.textContent = 'Use Mic'; |
| 249 | songSelect.disabled = false; |
| 250 | playPause.disabled = false; |
| 251 | volumeControl.disabled = false; |
| 252 | timelineControl.disabled = false; |
| 253 | |
| 254 | if (micSource) { |
| 255 | micSource.disconnect(); |
| 256 | micSource = null; |
| 257 | } |
| 258 | |
| 259 | if (sourceNode) { |
| 260 | sourceNode.connect(analyser); |
| 261 | } |
| 262 | analyser.connect(audioContext.destination); |
| 263 | |
| 264 | } else { |
| 265 | usingMic = true; |
| 266 | inputToggle.textContent = 'Use Player'; |
| 267 | songSelect.disabled = true; |
| 268 | playPause.disabled = true; |
| 269 | volumeControl.disabled = true; |
| 270 | timelineControl.disabled = true; |
| 271 | |
| 272 | try { |
| 273 | micStream = await navigator.mediaDevices.getUserMedia({ |
| 274 | audio: { |
| 275 | echoCancellation: true, |
| 276 | noiseSuppression: true, |
| 277 | autoGainControl: false |
| 278 | } |
| 279 | }); |
| 280 | |
| 281 | if (sourceNode) { |
| 282 | sourceNode.disconnect(); |
| 283 | } |
| 284 | |
| 285 | micSource = audioContext.createMediaStreamSource(micStream); |
| 286 | micSource.connect(analyser); |
| 287 | analyser.disconnect(audioContext.destination); |
| 288 | |
| 289 | console.log('Microphone is active'); |
| 290 | |
| 291 | } catch (error) { |
| 292 | console.error("Microphone access failed:", error.name, error.message); |
| 293 | usingMic = false; |
| 294 | inputToggle.textContent = 'Use Mic'; |
nothing calls this directly
no outgoing calls
no test coverage detected