Microphone Testing

Getting access to the microphone should be a simple process. Depending on the browser and operating system, it may be more or less difficult.

Do we have access to the microphone?

Once the checkbox above is checked, we should be able to listen to the microphone.

Microphone Access Allowed

If we can hear audio then we should show the audio level in the following div.

On some operating systems, the audio input signal can be modified by various filters by the operating system. For instance, on windows Dolby spatial audio can modifies the output audio. On the microphone, noise reduction can block the audio signal used by ribbit. To operate properly, the ribbit signal should be unprocessed or the data will be filtered out. To test this we'll need a known audio signal to listen to the microphone while playing a good signal and if we cannot decode the signal then we know that the signal has been corrupted.

Audio Test

To test we begin with a known test signal called test.mp3. The audio is then recorded by the microphone to compare the recorded signal to the test signal. We expect some loss, but the signal should be recognizable.

The correlation between the test signal and the recorded audio should be close to 1. If the correlation is less than 0.9 then the audio signal has been corrupted.

Correlation: 0.0

Bug: the microphone recording buffer returns a float32 array filled with 0s this infers that it's not recording anything. Is it possible that the microphone is not allowed to hear the test signal as it's being played?

Sinwave Test

Lets try playing a sinwave and recording it.

Draw the two waveforms on top of each other on a small canvas.

From the looks of it, the microphone is still not recording any speaker output. As a matter of fact, the OS will actively prevent the microphone from recording the speaker output, which is why the microphone is not recording anything. I suppose this is a feature to prevent feedback, which does make sense, but if we don't attach the speaker to the microphone then we should be able to record.
If we don't play() the audio element attached to the mic then the microphone doesn't interrupt or filter out incoming audio as much, but it seems like the sinewave is still being filtered out. The Operating system is actively preventing the microphone from recording the speaker output.

Conclusion

The microphone is not recording anything. The OS is actively preventing the microphone from recording the speaker output. This is a feature to prevent feedback, which does make sense, even if it's annoying, it's a feature.
So what do we do? I can't really test the microphone's ability to record unprocessed audio. Nor can I test if the audio output is being modified by the operating system. The best I can do is to test if the microphone is working at all.
If we decode the audio signal at all then we can test for data integrity. If the data is corrupted then we know that the microphone may not be working. Or the audio signal generated by another user may be improperly filtered.
If both users check all their system sound settings then we can be sure that the microphone and speakers are working once data is being transferred between client apps.
The best we can do is present the user with a set of instructions based on the operating system and browser they are using. If the user follows the instructions then we can at best hope everything works.

        const constraints = {
            audio: true,
            echoCancellation: false,
            noiseSuppression: false,
            autoGainControl: false
        };
    

Even with the browser's audio constraints set to prevent Echo Cancellation and other audio processing, the microphone is still not recording anything from the speaker. So I can't test if the microphone is hearing unprocessed audio, nor can I test if the speakers are sending unprocessed audio to the microphone. 😞

If the user follows the instructions then we can at best hope everything works.