I'm relying on WebAudio to perform the resampling operation. I haven't found a whole lot of configuration knobs in the API for this operation, so I'm not sure what technique it's using, e.g. Lanczos, sinc, cubic, linear, etc. Probably something fast since it seems to be geared towards real time games in the browser. Another option would be to compile sox or just the filter from C to WebAssembly and use that instead.
Another option might be libavresample (from the ffmpeg project).
I do plan on trying out WebAudio's DynamicsCompressorNode to normalize to the available dynamic range of the target playback method.
If you do, please make it optional, as a dynamics compressor can really mess up your sound. Compression/limiting is not the same as normalization. For normalization purposes, just find (min,max) and adjust the values to max out the available range.
I would like to play with noise shaping. Another benefit of compiling sox to WebAssembly would be to take advantage of its noise reshaping features.
Yes, although I seem to remember it only supports certain sample rates and bit-depths.
I did look at the WebAudio API though, and it seems BiquadFilterNode is what you need to create a proper lowpass filter. IIRFilterNode can be used for odd-ordered IIR filters, but BiquadFilterNode is mentioned as being of higher quality and less sensitive to numerical quirks. A single instance has a 12dB roll-off per octave, but filters can be concatenated to increase their effect. So, for example, you are targeting a 15.6kHz output file. That means no frequencies above half that number (7.8kHz) can be represented. If you leave the higher frequencies in, depending on the resampling method, those higher frequencies can turn up as false low frequencies in the end result. Filtering them out as much as possible, reduces that problem. Usually, one tends to select the cut-off frequency slightly lower, f.e. 7-7.5kHz in this case.