sigrok + UNIX = Awesome! - part II - Audio

So today I have another example of the powerful ways sigrok-cli can be used, this time with digital audio.

In the modern world there are a wide variety of devices that handle digital audio internally including HiFi equipment and mobile phones. Common signalling schemes include S/PDIF, and various clocked serial PCM schemes. I²S is a specific variant of PCM signalling. It has 3 signals: Clock, Word Select (which signals the beginning of sample words for the left or right channels), and Data which transmits the audio samples MSB first.

sigrok has had support for I²S decoding for a while, and now in the latest Git builds of PulseView, it's possible to see the decode results. This example was taken from the 32-bit I²S example in the sigrok-dumps repository.

But once again thanks to the power of UNIX, sigrok-cli is the far more powerful tool, because it allows us to do interesting things with the decoded information.

The basic syntax for I²S decoding is as follows:

$ sigrok-cli -i -P i2s:sck=0:ws=1:sd=2 -A i2s=right

i2s: "Right channel: f6780000" "Right: f6780000" "R: f6780000" "R"
i2s: "Right channel: f4b80000" "Right: f4b80000" "R: f4b80000" "R"
i2s: "Right channel: f3ac0000" "Right: f3ac0000" "R: f3ac0000" "R"
i2s: "Right channel: f3060000" "Right: f3060000" "R: f3060000" "R"

Here 32-bit samples are being printed for the right channel only. In itself this is very cool, but we can go much further.

The next step is to extract the data as binary.

sigrok-cli -i -P i2s:sck=0:ws=1:sd=2 -A i2s=right | \
    cut -c22-25 | xxd -r -p > file.bin

The cut command strips all the text except for the 4 most significant hexadecimal nibbles, and in the same way as in the previous blog posting, we use xxd's reverse mode to convert this hexadecimal data to binary.

We now have a binary dump of the PCM data for the channel.

But I want more.

The SoX suite has some really handy tools for manipulating audio, and we can use these tools to convert the audio to a WAV file.

sigrok-cli -i -P i2s:sck=0:ws=1:sd=2 -A i2s=right | \
    cut -c22-25 | xxd -r -p | \
    sox -t raw -B -b 16 -c 1 -e signed-integer -r 16k - right.wav

Here we tell sox that it will receive a raw data stream, containing big endian, 16-bit, signed integer mono audio at 16kHz sample rate, and that it should output the data to a wav file.

Opening the wav file in Audacity, we can see the decoded analog waveform:

...or we can use the sox play tool to play the audio directly out of the headphones:

sigrok-cli -i -P i2s:sck=0:ws=1:sd=2 -A i2s=right | \
    cut -c22-25 | xxd -r -p | \
    play -t raw -B -b 16 -c 1 -e signed-integer -r 16k -

I've never had the chance to try it, but I really want to see if it's possible to do this in real time on a live device.

At this time, it will be a tall order to ask this of libsigrokdecode, but it may nonetheless be possible. It would require a logic analyser capable of continuous streaming, such as the FX2 family of devices, and the I²S logic data would need to be acquired at the lowest possible sample rate without aliasing. If the logic data is captured at a higher sample rate, libsigrokdecode stands no chance of processing all of it.

There is some talk of various ways we can make great increases to libsigrokdecode's performance, so in the future this type of realtime activity should be rather easier to do.