Decoding BPSK Modulation from Audio

Prologue

In this text, I tried to explore the possibility of transmitting binary data with sound via BPSK modulation. Why BPSK? The fact is that this modulation is very common. BPSK modulation literally permeates our bodies every day right now, since the BPSK signal is the physical interface that GPS satellites emit. Also BPSK is supposedly used in WiFi and Sigfox. In general, there are reasons to understand how this works.

BPSK modulation is a way to transmit binary data at high frequencies. This topic came from radio electronics. Rado can only be transmitted at high frequencies. In radio, the higher the carrier frequency, the smaller the antenna needed. However, nothing prohibits the use of BPSK modulation in waves of a different nature. For example, in sound, optics, or even in coaxial cable. From the DSP and SDR processing side, what the radio is, what the sound is, what the light intensity is, what the voltage is – everything doesn’t matter. There is an array of signed samples in RAM memory and it needs to be processed.

But recording and playing back sound is much cheaper, easier and more convenient than radio waves. Have you ever seen voice recorders for radio waves? And sound recorders are present in any mobile phone + audio file player. Including the simplest ones – *.wav files.

Statement of the problem

Decode BPSK from audio recording on a voice recorder.

Theory

All these modulations (ASK, OOK, BPSK, FSK, 256-QAM, CSS, GFSK, MSK) can be classified as physical layer interfaces of the OSI-7 model, since modulations explain how exactly bits are transmitted in the physical medium. BPSK can also be considered as a physical layer interface.

What are the parameters of a BPSK signal?

No.

Parameter

Unit of measurement

1

carrier frequency

Hz

2

carrier amplitude

PCM

3

duration of one chip

seconds (microseconds)

4*

Sampling frequency

Hz

5

bit order when packing a byte inside a BPSK signal

least significant bit forward or most significant bit forward

6*

Bit depth of one sample

bit

This is what a BPSK signal looks like in the frequency domain. Br is the bit rate.

BPSK signal spectrum

BPSK signal spectrum

As the bit rate Br decreases, BPSK degenerates into a sine. Therefore, as the bit rate decreases, the signal width narrows. As the BPSK bit rate increases, the spectrum expands.

chip (chip) – this is the minimum fragment of the BPSK signal where the phase of the carrier frequency does not change. The actual BPSK chip is one bit of data.

What software do you need?

No.

Program name

Purpose

1

Audacity

Sound file editor

2

Voice Recorder (Android)

Voice recorder for smartphones, capable of recording *.wav files.

3

VLC media player

Audio file player on PC

4

GCC Toolchain

Compiler, linker, for building a console utility that decodes BPSK data from a *.wav file.

Implementation

BPSK modulation (Encode)

First of all, I synthesized a *.wav file which contains binary data 0x55aa which is encoded with BPSK modulation. Why wav? Yes, because it is the simplest audio file format. It's just an array of int(s) packed into a binary file with a preamble (header) attached to the front. The header contains all the necessary metadata about this audio track: sampling rate, sample size, number of channels.

Here he is in front of you. As you can see, this is real BPSK modulation.

The signal sounds like a running well pump.

I uploaded the *.wav file via messenger to my smartphone and began to play *.wav with an ordinary music player from an Android smartphone.

Demodulation of BPSK signal (Decode)

In technical systems, accepting anything is always much more difficult than sending something. Throwing a ball is easier than catching it. The UART receiver is much more complex than the UART transmitter. So here, in modulations, receivers are much more complex than transmitters. However, the received BPSK signal must be decoded.

Before you rush to decode BPSK samples, you need to tell the decoder at what carrier frequency we will be looking for the signal and what the bit rate is in this stream. In the case of SDR, also specify the ADC sampling rate.

What's the plan?

The classic circuit for demodulating a BPSK signal is Costas Loop. Here he is in front of you.

Costas Loop

Costas Loop is an automatic control system (hello TAU). Its task is to control the phase of the local oscillator so that it continuously matches the phase of the input signal. The peculiarity of the Costas Loop local oscillator is that it can be adjusted phase carrier frequency. The phase has the main role here.

The advantage of Costas Loop is that it self-regulating. The transmitter can even be moved, and the Costas Loop circuit itself will adapt to the new phase of the incoming signal. Each new sample adjusts the phase of the local oscillator. Theoretically, Costas Loop can even be assembled from analog components.

However, this chain may seem complicated if you are not used to it. Next there will be a short comment on this scheme.

Phase 1: Multiplication

At the first stage, the incoming BPSK signal on a 1kHz carrier is divided into two copies and each is multiplied by the cosine and sine version of the signal from the local oscillator. The local oscillator frequency is also 1kHz, as is the carrier frequency.

Phase 2 High Frequency Removal

As you know from school trigonometry, multiplying sine by cosine gives a high-frequency term. It must be discarded. In my SDR implementation this is done by a 200th order digital FIR filter. I chose twice the BPSK bit rate as the cutoff frequency. In this case it is 200 Hz

Phase 3: Extract the phase error (phase discriminator).

There are three ways to measure the error phase between the input signal and the local oscillator.

a) Arcsine phase measurement

Due to the fact that we mix with two versions of the local oscillator at once, we get the phase error of the signal with the phase of the local oscillator signal. The error is obtained numerically. It is clear that it is necessary to configure the local oscillator signal with this phase error. At the same time, you can notice that in Costas Loop, pure data is taken from arm I. This means that inside there the sine should always turn to one. Sine becomes 1 only at 90 degrees. Or at pi/2. Therefore, after processing each sample, it is necessary to assign a new phase to the local oscillator phase: error phase + pi/2. In this case, the error phase is considered an analytical formula with arcsine.

However, the disadvantage of this method is that the input signal must be normalized. That is, its amplitude was always 1. However, in practice this never happens. Signals from the microphone come with noise. Therefore, I will not use this method.

b) Phase measurement by arctangent

The error can be measured using the atan2() function. Moreover, the phase error must be integrated before assigning it to the local oscillator. This is how a horizontal signal constellation will be created interactively. Such a controller will press the vector (I,Q) to the nearest side to obtain a horizontal constellation.

b) Phase measurement by angle between vectors

The phase error can be determined using linear algebra. Essentially, you need to find the angle between the vector that lies on the x-axis (1, 0, 0) and the vector that is formed at the output of the quadrature mixer (I, Q, 0).

Due to noise, the phase error may vary with very high frequency. Even if the source is initially static. Therefore, the phase error must be passed through another low-pass filter (FIR or IIR). You also need to control the local oscillator phase via a PID regulator. The proportional coefficient is usually 2 orders of magnitude less than 1. The integral coefficient can be made around unity.

Phase 4: Comparator

After the filter on wire I, the data is still analog. Our goal is to remove binary data. To do this, you need to pass the signal from the I_Filt wire through a comparator. And it’s better, even to be on the safe side, to let it pass through Schmitt trigger. This will be another kind of filter.

Phase 5: Allocate data bits

However, the output of the comparator is just a clear picture. For the upper software, it is necessary to select the data bits. The current situation is that there are 441 ADC signal samples per bit.

Therefore, it is necessary to perform the so-called decimation (Downsampling). Leave one out of N samples. This problem is ideally solved by a finite state machine. Here is the graph of the thinning state machine.

As soon as the counter of received ones (or zeros) reaches a certain number of samples samples_per_bit, the decimation state machine will output a signal that a bit has been recognized (1 or 0).

Phase 6: Byte Allocation

At the output of the BPSK demodulator we only get bit stream, which were initially superimposed on the carrier frequency.

How can you take the data itself and form bytes from it? Finding the beginning of a byte is already the task of some link layer protocol. Alternatively, you can enter something similar to the preamble of the beginning of the packet and parse it from the binary stream. But this no longer applies to BPSK.

Debugging

Any development begins only when debugging tools appear. It is customary to debug the BPSK decoder (like any other modulation) using graphs signal constellations. Ideally, the BPSK diagram should be in the form of two clusters (clusters) on the X-axis [она же ось I, она же действительная часть, она же выход cos()*signal()] equidistant from the origin.

ideal BPSK modulation signal constellation

ideal BPSK modulation signal constellation

Here is an example of one real signal constellation. To me it looks quite bizarre.

Debugging on a refined file

Before you rush to decode an audio file from a voice recorder, you must first feed the BPSK decoder just a pure, refined array of BPSK signal samples without any noise. I need to make sure that my SDR algorithm, written in pure C, generally works in these hothouse conditions.

Signal constellation for a refined BPSK signal. Phase selection using asin() function

Signal constellation for a refined BPSK signal. Phase selection using asin() function

With different FIR filter order settings, the signal constellation can take on bizarre shapes.

Even if normalize passing the input signal through the sign function, the data bits are still allocated

input signal via sign

input signal via sign

This is a signal constellation without normalizing the input signal when extracting the phase using the atan() function.

phase selection using the atan() function

phase selection using the atan() function

By passing the filtered I signal through a 0/1 comparator, I got a signal like this. It exactly corresponds to the same binary message 0x815F that was modulated by the original BPSK signal.

This means that the Costas Loop implementation itself works. Here is a report that my BPSK encode decode unit test passes.

These are the oscillograms of the main circuit variables, I, Q, local oscillator phase and the data themselves.

Checking on a real recording from a voice recorder

I programmatically generated a *.wav file that continuously and cyclically transmits only one word 0x55AF on a 1kHz audio carrier frequency. This is what a BPSK signal looks like on a voice recording. You can even tell by eye that this is phase modulation.

Then I played this *.wav file on one mobile phone and recorded it with a voice recorder on another phone. Then, I submitted the recorded *.wav as an argument to my console utility bpsk_demodulator.exe and it was able to allocate data bits! This is how the signal constellation turned out.

The spot in the center is a pause between signals. And this is the decoded sound. As you can see, the bit rate was set to 16 bps.

You may notice that data 0x55AF is retrieved. Although initially the control system even captured the inverted bits. How to deal with this is not yet clear. Apparently this is the task of the link layer protocol. However, in general, we can say that everything worked out. Bytes are sent and received via sound!

Further development

–You can increase the bit rate and try to understand the bandwidth limit.

–It would be great to make an FPGA or even an ASIC that can decode acoustic BPSK in real time and output the raw m

Similar Posts

Leave a Reply

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