The search term you want is: time stretching

Here's another case where discovering the right search term unlocks a wealth of information.

I've used the Web Audio API for a number of different projects at this point, and I'm pretty familiar with it. But a couple years ago I discovered something surprising: adjusting the playback rate of an AudioBufferSourceNode will also change the pitch of the audio.

This was surprising, because when you change the playback rate of an HTMLMediaElement (e.g. an <audio> or <video> element), the pitch of the audio does not change.

I think it's safe to say that most folks that work with audio on the web only ever need to use the <audio> tag. Most of the time, you have an audio src URL, like https://example.com/my.mp3, and you just need to play it. The <audio> tag works great for this simple, common use case. The Web Audio API is much lower level. You might use it if you wanted to add sound effects to game, build a synthesizer in the browser, or maybe build a custom audio player with some very specific requirements.

It's also pretty common that a user might want to adjust the playback rate of the audio. If they want to get through audio a bit faster, they'll speed it up, and if they need more time to process it (for example, if it's in a foreign language, or the speakers are talking unusually fast), they'll slow it down. And if you're working with an <audio> tag, all you have to do is adjust the playback rate; the audio will speed up or slow down, but the user will notice no change in pitch.

Not so with the Web Audio API—a playback rate above 1 will give you a chipmunk voice, and playback rate below 1 will give you a drunk voice (reliably hilarious).

What I didn't realize—what I never had to think about—was that the <audio> tag was actually doing some extra work for me whenever I adjusted the playback rate. Think about it: if you play an analog audio source, like tape or vinyl, faster or slower than expected, you get the chipmunk/drunk effect. You can also think of it as an actual wave: increasing the speed of wave means shortening the wavelength (and thus a higher pitch). So why doesn't that happen with <audio>? Well, it's right there in the MDN docs:

The pitch of the audio is corrected by default. You can disable pitch correction using the HTMLMediaElement.preservesPitch property.

Ah. Does AudioBufferSourceNode have this property, or something like it?

No. I've been subscribed to that issue for about two years now. My guess is we'll get something eventually, but I'm not holding my breath.

Searching in vain for a simple, native solution, I tried variations of "web audio change playback rate without changing pitch". Here's a Stack Overflow question that asks the very same thing (note that the answers are not very helpful).

But the term you want is time stretching. Here's Wikipedia:

Time stretching is the process of changing the speed or duration of an audio signal without affecting its pitch.

You can search this on npm to get started, but I should warn you: there really is no easy way to do this. There's no native solution, and no library I've ever found that implements it in a simple and straightforward way (probably because it's neither a simple nor straightforward problem).