Sample Rate Choice Week 7

Hello friends! In Week 7 we chose a sample rate of 48khz, because apparently that's what most audio files use nowadays. I don't know very much about audio, but I'm very curious what would have happened if we set our primary buffer's WaveFormat.nSamplesPerSec = 96000

Would it perhaps interpolate between the 2 samples that were actually written into whatever 48khz WAV file we end up loading? If so, is the reason we didn't set nSamplesPerSec to a higher value due to the performance cost of that interpolation?

Edited by CrajunMinter on Reason: Initial post
If you will configure audio API to use 96kHz, but will load and play back 48kHz audio then it will sound high pitched and will be played 2x faster than normal rate.

There's nothing wrong with using 96kHz, as long as all your source assets are also 96kHz (which costs storage space) or you are converting them on the fly (which costs tiny bit of performance). And if you are porting your game to different platforms, then they maybe don't support 96kHz, now you'll have more work/issues handling different audio assets for different platforms.

But really - your ears won't be able to differentiate between 48kHz and 96kHz. Try the blind test if you want to make sure. Something like 96kHz or 32-bits per sample only makes sense for audio producing/mixing process. Final audio is perfectly fine as 48kHz/16-bit.
@mmozeiko

hey, so I'm on day 11 now, but I recently thought of a new question regarding this. you explained to me the reason why playing a 48kHz song at 96kHz would be bad, but would there be any penalty to setting bitsPerSample = 16, even if we have only 8-bit audio, for example. Seems to me like it would just append 0s to the end of the sample, which seems basically free. Is there any reason not to use the highest possible value for bitsPerSample at all times? Certainly, we would lose resolution if we used a lower bit-depth, but is there any issue with using a higher one?

Edited by CrajunMinter on
There will be no difference in audio output quality whether you use 8-bit input sample for 8-bit output buffer, or you put 8 zero bits in lowest bits for in 8-bit input sample and put it into 16-bit output buffer.

The reason not to use highest possible bit size is that sometimes it is 24-bits. And processing array of 24-bit numbers is not as simple as processing 16-bit samples (or floats).

Edited by Mārtiņš Možeiko on
I'm not sure about this, but wouldn't using 16bit instead of 8bit (if the source is 8bit) change the volume because you would change from an amplitude of +- 7bits to +- 15bits with half the range not used ?
mrmixer
I'm not sure about this, but wouldn't using 16bit instead of 8bit (if the source is 8bit) change the volume because you would change from an amplitude of +- 7bits to +- 15bits with half the range not used ?


make that 255 out of 256 not used.

You need to be careful which bits to expand out, when going from low precision to high precision you add to the least significant bits and keep them 0. It's the reason why sampling software tends to use 0-1 fractional values.
Opps, right - 8-bit sample typically are unsigned. But 16-bits are signed. So simply prepending 0 bits won't work. You'll need to do a bit of math.

1
int16_t sample16 =  (sample8 - 128) << 8;


It will change volume a bit, in 16-bits it will be a bit quieter. Max volume with sample8 is 255. In 16-bit's it would be (255-128)<<8 = 32512, but max volume in 16-bit is 32767.

For max volume stay max volume you could go through float:
1
2
int8_t sample8s = sample8 - 128;
int16_t sample16 = sample8s < 0 ? (int16_t)((sample8/128.f) * 32768.f) : (int16_t)((sample8/127.f) * 32767.f);


Or figure out something smarter (not sure if this works, have not tested):
1
2
int8_t sample8s = sample8 - 128;
int16_t sample16 = sample8s < 0 ? ((sample8s << 8) & ~0xff) : ((sample8s << 8) | 0xff);

Edited by Mārtiņš Možeiko on