Converting audio bit depths in C#

Para a versão em português deste post, clique aqui.

Digital audio signals can be stored in a myriad of different formats. For example, digital audio could be stored as a raw 16-bit PCM signal buried inside a WAVE file or as an encoded lossy format such as MP3. But invariably most digital signals are represented by a sequence of values, called samples, which are the measurement of a choosen sound characteristic over time, so they can be manipulated digitally.

Samples are a discrete-time (digital) signal tipically originated from a continous (analog, such as sound waves) signal through some kind of conversion procedure or algorithm. There is, however, many ways to represent a sample, such as a 8-bit byte, a 32-bit integer or a 32-bit float. And sometimes converting between those different representations (performing some kind of resampling) is an requirement in many applications.

Converting between different sample bit depths in C#

To convert between different sample representations, besides changing the data type we also have to rescale our samples. To convert from 32-bit float to 8-bit unsigned byte, for example, we have to rescale the original sample from its [-1;1] interval to a unsigned, [0;255] interval. The class below has a single (heavily overloaded) method suitable to convert, for example, 16-bit to 8-bit, 16-bit to float, float to 16-bit, and so on. In fact, it can convert in between unsigned 8-bit bytes, signed 16-bit integers, signed 32-bit integers and 32-bit floating point single precision numbers. I hope someone finds it useful!

Other thoughts

Please note, however, that conversion isn’t always perfect. This is true for almost everything, specially for digital signals. Converting from one encoding to another may introduce conversion errors in the data. To help with this, God invented a technique known as dithering. Dithering is the same as pourposely introducing noise in a signal.

Noise? Yes, noise. Noise isn’t always bad. Just take a look at the image examples in Wikipedia and you will understand that. Unfortunately, this class doesn’t support dithering (yet), but may support in the future, if there is need.

5 Comments

  1. Hello, great example, Can you give a tip how to seperate left & right channel from captured stream ?
    Thx
    Schift

Leave a Reply

Your email address will not be published. Required fields are marked *