Loading...

Creating PCM-Wave Test Signals With Python

For testing the I2S bus of an electronic audio circuit I needed audio test signals, such as sine, square etc. Interestingly (and unfortunately) it seems hard to get such test signals, especially when the values of these test signals should be predictable, e.g. in case of a square wave with a bit depth of 16 bit the “1” value should be exactly “1”, (or better, 32767) whereas a “0” should really be a “0” (or -32768). Most available test signals add some tiny white noise to the signal, which is great for testing specific scenarious, but not so great when trying to check if the I2S signal is bit-perfect. This also applies to various audio programs which create test signals (like Audacity).

The only way to solve this seemed to be to manually create these signals by hand, therefore a Python script (soundgen.py) was developed that can do the following:

  • Create basic test signals (sine, square, silence, DC)
  • Support several bit depth (8, 16, 24) and sampling rates (44.1kHz, 96kHz etc.) for mono and stereo
  • Adapt the level (in dB) and choose the frequency for the sine and square

For testing purposes, another script was created (dispwave.py) which can be used to display the wave file data in decimal and two-complement binary form.

Both scripts are freely available at the following address (feel free to either checkout the directory via SVN or simply download the Python files):

https://himmelbauer-it.at/svn/qwer/pysoundgen/

Creating the 8-bit and 16-bit audio was relatively easy, whereas creating 24-bit audio was not that simple as the Python struct() method does not support 3-byte integers. However, with some binary logic this problem could be solved.

With the following simple command a 16-bit, 44.1kHz, 1kHz stereo sine wave is generated:

./soundgen.py -c 2 -o sine.wav

The resulting wave file can then be displayed with the following command:

./dispwave.py sine.wav

Sample 1: left: 0 | 0000 0000 0000 0000 | right: 0 | 0000 0000 0000 0000 |
Sample 2: left: 4652 | 0001 0010 0010 1100 | right: 4652 | 0001 0010 0010 1100 |
Sample 3: left: 9211 | 0010 0011 1111 1011 | right: 9211 | 0010 0011 1111 1011 |
Sample 4: left: 13583 | 0011 0101 0000 1111 | right: 13583 | 0011 0101 0000 1111 |
Sample 5: left: 17679 | 0100 0101 0000 1111 | right: 17679 | 0100 0101 0000 1111 |
Sample 6: left: 21418 | 0101 0011 1010 1010 | right: 21418 | 0101 0011 1010 1010 |
Sample 7: left: 24722 | 0110 0000 1001 0010 | right: 24722 | 0110 0000 1001 0010 |
Sample 8: left: 27525 | 0110 1011 1000 0101 | right: 27525 | 0110 1011 1000 0101 |
Sample 9: left: 29771 | 0111 0100 0100 1011 | right: 29771 | 0111 0100 0100 1011 |
Sample 10: left: 31413 | 0111 1010 1011 0101 | right: 31413 | 0111 1010 1011 0101 |
Sample 11: left: 32419 | 0111 1110 1010 0011 | right: 32419 | 0111 1110 1010 0011 |
Sample 12: left: 32767 | 0111 1111 1111 1111 | right: 32767 | 0111 1111 1111 1111 |
Sample 13: left: 32452 | 0111 1110 1100 0100 | right: 32452 | 0111 1110 1100 0100 |
Sample 14: left: 31479 | 0111 1010 1111 0111 | right: 31479 | 0111 1010 1111 0111 |
Sample 15: left: 29868 | 0111 0100 1010 1100 | right: 29868 | 0111 0100 1010 1100 |
Sample 16: left: 27651 | 0110 1100 0000 0011 | right: 27651 | 0110 1100 0000 0011 |
Sample 17: left: 24875 | 0110 0001 0010 1011 | right: 24875 | 0110 0001 0010 1011 |
Sample 18: left: 21594 | 0101 0100 0101 1010 | right: 21594 | 0101 0100 0101 1010 |
Sample 19: left: 17876 | 0100 0101 1101 0100 | right: 17876 | 0100 0101 1101 0100 |
Sample 20: left: 13795 | 0011 0101 1110 0011 | right: 13795 | 0011 0101 1110 0011 |
Sample 21: left: 9435 | 0010 0100 1101 1011 | right: 9435 | 0010 0100 1101 1011 |
Sample 22: left: 4883 | 0001 0011 0001 0011 | right: 4883 | 0001 0011 0001 0011 |
Sample 23: left: 233 | 0000 0000 1110 1001 | right: 233 | 0000 0000 1110 1001 |
Sample 24: left: -4421 | 1110 1110 1011 1011 | right: -4421 | 1110 1110 1011 1011 |
Sample 25: left: -8987 | 1101 1100 1110 0101 | right: -8987 | 1101 1100 1110 0101 |

In order to check the audio hardware, everything was available now, so the next step was to check the I2S output of the audio device (the Raspberry Pi, in this case). The following pictures show the second and third samples of the above sine wave:

Sample 2: left: 4652 | 0001 0010 0010 1100 | right: 4652 | 0001 0010 0010 1100 |

Sample 3: left: 9211 | 0010 0011 1111 1011 | right: 9211 | 0010 0011 1111 1011 |

So, the values are correct, everything is as it should be. So, in case you also need audio test files and/or want to know how to create PCM wave files with Python, feel free to download the code from the following address:

https://himmelbauer-it.at/svn/qwer/pysoundgen/

Top