Real-Time audio processing on FPGA (Lab)
2022-2024
In this Lab, you will implement digital signal processing functions on audio signals. The audio signals will be generated by your PC and processed in real-time on the FPGA of the DE1-SoC board.
The DE1-SoC board includes an audio CODEC connected to standard audio jacks. The audio CODEC contains both an ADC and a DAC to convert:
The digital signals (the output of ADC and the input of th DAC) are connected to the FPGA, so we can implement real-time digital signal processing using the FPGA resources.
In addition to the digital data signals, the CODEC can be configured through an I2C interface (sampling rate, gain…). This configuration interface is also connected to the FPGA.
As a starting point for this Lab, we will use this Quartus project. In addition to the top-level module, this project contains modules to configure and communicate with the CODEC.
The following figure shows the structure of the provided project.
The top-level module is DE1_SoC
, it represents the FPGA
with all available IOs. Inside this module, two submodules are
instantiated:
codec
module, contains the necessary logic to
configure and interface with the audio CODEC.
audio_proc
module, which will contain the user
logic. As provided, the module implements a loop that sends back audio
from the ADC to the DAC.Note The configuration module will configure the CODEC to sample the audio at 48 KHz. The sample are quantified as a 16-bits signed number.
Note regarding SystemVerilog syntax As the samples
are signed, all the signals must be declared adequately using the
signed
keyword.
The following figure shows how audio data are received at the user logic level.
All signals should be synchronous to the 12MHz audio clock,
Additionally, the audio_proc
module receives as
inputs:
adc_data_l
and adc_data_r
for left and
right audio channels (stereo audio)audio_data_enable
,
The valid signal will go high for one clock cycle every 20.83µs (because of the sampling rate of 48 KHz).
The outputs of this module also represent 2\times 16-bit signed audio samples
(dac_data_l
and dac_data_r
). These outputs
will be captured by the CODEC interface module each time the enable
signal is high to be sent to the DAC.
For this lab, we will implement the signal processing functions.
Scrambling/Voice inversion is an old method to obfuscate an audio transmission by inverting the spectrum of the signal (high and low frequencies are swapped).
This scrambling, of a band-limited signal, is achieved with amplitude modulation.
A sinusoidal carrier signal, with a frequency f_0 higher than the bandwidth of the audio signal is modulated. The resulting signal is filtered to only keep the lower frequencies. This process is depicted in the following figure, and we see that the shape of the resulting spectrum is the inverse of the initial spectrum.
Note that the scrambling can be inverted by applying the same process again.
Mathematically, amplitude modulation can be obtained by multiplying the signal by a sinusoidal (sine or cosine) carrier.
S_i(t) = S(t) \cdot \cos(2\pi f_0 t)
Or in discreet time
S_i(n) = S(n) \cdot \cos(2\pi \frac{f_0}{f_s} n)
Where f_s is the sampling frequency.
You can find here an example of a scrambled audio signal. This signal has been generated with the following configuration:
Work to do Implement the amplitude modulation part
of the scrambling in the audio_proc
module.
You should have noticed that by just multiplying the signal by a sinusoidal function, the audio signal is correctly unscrambled. Theoretically, an additional low-pass filter needs to be implemented, but here it seems unnecessary here.
Why?
Mainly because your ears (and the earphone that you are using) are not that sensitive above 12 KHz and naturally act as a low-pass filter.
To make it possible (with the lab equipment) to hear something, we will use an artificially modified audio sequence where a high-pitch noise (11 KHz sinusoidal signal on the left channel) have been intentionally added before scrambling.
This modified signal can be found here.
After unscrambling, you should still hear the high-pitch noise on the left channel.
To filter the signal, we want to implement an 8-tap FIR filter (not the best solution in terms of signal processing, but, it should be easy to implement in SystemVerilog).
The discrete-time equation of this filter is:
S_f(n) = \sum_{i=0}^7 c_i \cdot Si(n-i)
Where c_i are the 8 coefficients of the 8-tap FIR filter.
We have used a FIR filter calculator to compute these coefficients, and we have obtained the following values:
index | value |
---|---|
0 | -0.075163 |
1 | 0.024881 |
2 | 0.150253 |
3 | 0.288582 |
4 | 0.34898 |
5 | 0.288582 |
6 | 0.150253 |
7 | 0.024881 |
Note To keep things simple for the lab, this filter is designed to reject frequencies above 10 KHz with a transition starting at 6 KHz. A more efficient filter will necessitate more taps or a different architecture (IIR for example).
Work to do
© Copyright 2022-2024, Tarik Graba, Télécom Paris. | |
Le contenu de cette page est mis à disposition selon les termes de la licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International. | |
The content of this page is licensed under a Creative Commons Attribution-ShareAlike 4.0 International Licence. |