Amarisoft

IQ Capture

There are roughly two different way of capturing IQ data. One is to capture IQ using sdr_spectrum and another way is to capture the IQ from callbox/UEsim software using Remote API. For capturing IQ with sdr_spectrum, refer to this tutorial. In this tutorial, I will demonstrate on how to capture IQ from callbox software.

Why do we want to capture IQ ? There can be various answers, but the common typical answer would be : (Of course, you may have your own purpose that are not listed here. )

The data format of IQ capture file in Amarisoft product is very simple. It is the repetition of 32 bit - I value and 32 bit Q value and it does not have any other information (e.g, file header or meta data) at the beginning of the file (NOTE : check out here if you want further details). so you may easily read the saved IQ file and process it with your own program.

Table of Contents

Introduction

In the context of wireless communications and signal analysis, In-phase and Quadrature (IQ) data capture is a foundational process for accessing raw baseband signal samples. IQ data represents the complex-valued signal components that preserve both amplitude and phase information, enabling advanced analysis, troubleshooting, and custom signal processing. There are multiple approaches to capturing IQ data, with two prominent methods being the use of SDR-based tools such as sdr_spectrum and leveraging callbox or UESim (User Equipment Simulator) software via a Remote API. This tutorial focuses specifically on capturing IQ data using callbox software, which is widely used in laboratory environments for simulating cellular network conditions and interacting with mobile devices in a controlled manner. Capturing IQ data directly from a callbox enables engineers to analyze low-level PHY (Physical Layer) behaviors, validate custom signal processing algorithms, and diagnose issues that are otherwise hard to observe at higher protocol layers. The Amarisoft product line, commonly employed in such setups, outputs IQ data in a straightforward binary format: a sequence of 32-bit integers for I and Q values, repeated throughout the file without headers or metadata. This simplicity allows seamless integration with custom analysis tools, as users can easily parse and process the data using their preferred programming environment. The ability to capture, interpret, and manipulate IQ data from callbox systems is critical for researchers, developers, and test engineers working on wireless networks, device validation, and PHY-layer innovations.

Summary of the Tutorial

This tutorial outlines the procedures for capturing IQ samples from an LTE system using a Remote API, followed by spectrum analysis using both built-in tools and external software such as Matlab or Octave. The document includes detailed steps for configuration, data capture, and post-processing, as well as tips for adjusting sampling rates.

The tutorial provides a comprehensive methodology for IQ data capture and analysis in LTE systems, supporting both basic and advanced signal analysis workflows.

Test Setup

TestSetup Callbox UE 1sdr 01

Configuration

I would not suggest any specific configuration here. You can use any configuration that fits your demand. enb.default.cfg or gnb-sa.cfg can be a good start.

Test 1 : Capturing IQ with Remote API

Run LTE service and check some basic information as shown below. It is not mandatory to check all these information but it is worth knowing sample rate and center frequency at least.

In this example, the LTE service is running on band 7 with 5 MHz bandwidth. The sample rate is 5.760 MHz, the downlink center frequency is 2680.000 MHz, and the uplink center frequency is 2560.000 MHz. The cell configuration also shows DL ARFCN 3350, UL ARFCN 21350, SCS 15 kHz, and 2 DL / 2 UL antennas. This information is not mandatory for starting IQ capture, but it is useful to record it before saving the IQ file. Especially, sample rate and center frequency are important because they help you interpret the captured IQ data correctly later.

The rf_info command shows the current RF port status. TX0 and TX1 are both transmitting at 2680.000000 MHz with gain 89.8 dB, and RX0 and RX1 are receiving at 2560.000000 MHz with gain 60.0 dB. This confirms the actual Tx and Rx center frequencies being used by the RF frontend. It is a good practice to include this kind of information in the captured file name or in a separate note, so that when you process the IQ data later, you can easily identify the sampling rate, carrier frequency, band, bandwidth, and antenna configuration.

IQ signal capture and analysis results related to IQ Capture Test 1 Run 01

IQ signal capture and analysis results related to IQ Capture Test 1 Run 02

Before starting IQ capture, put the UE and network into the target status that you want to analyze. If you only want to capture the idle-mode downlink signal, you do not need to connect a UE. The cell can stay active and you can capture the broadcast and idle-mode downlink signal directly. If you want to capture connected-mode behavior, power on the UE and wait until it enters connected mode.

In this example, the t command is used to monitor the live LTE status. The trace shows PRACH activity first, and then UE_ID 1 appears in connected mode. The UE is attached to cell 001 with RNTI 003d. The downlink side shows CQI 15, rank indicator 1 or 2, MCS around 22.1 to 24.0, and downlink bitrate values such as 5.44k, 137k, 248k, and 1.94k. The uplink side also shows PUCCH/SNR and MCS information, with UL bitrate values such as 11.6k, 191k, 274k, and 1.43k. This confirms that the UE is active and exchanging traffic or control information. Once the UE is in this desired state, you can start the IQ capture so that the saved IQ file contains the signal condition you intended to observe.

IQ signal capture and analysis results related to IQ Capture Test 1 Run 03

Once the call is in the target status, you can start IQ capture using the Amarisoft Remote API. The command format uses ws.js enb with the message trx_iq_dump.  (NOTE : If you are not familiar with RemoteAPI basics, refer to this tutorial).

# ws.js enb '{"message":"trx_iq_dump", "duration":<value in ms> , "rx_filename":<file name>, "tx_filename":<file name>}'

In this example, duration is set to 5000, so the IQ capture runs for 5000 ms. The received IQ samples are saved to /tmp/rx.bin, and the transmitted IQ samples are saved to /tmp/tx.bin. The command is executed from /root/enb.

./ws.js enb '{"message":"trx_iq_dump", "duration":5000 , "rx_filename":"/tmp/rx.bin", "tx_filename":"/tmp/tx.bin"}'

IQ signal capture and analysis results related to IQ Capture Test 1 Run 04

NOTE : This dumps the IQ samples directly extracted out of the RF, i.e baseband IQ samples in time domain.

When the capture is complete, the tool prints the result including the time value. This indicates that the IQ dump request has finished successfully. The captured files are baseband IQ samples taken directly from the RF path in the time domain, so they can be copied out from /tmp and used later for plotting or offline signal analysis.

IQ signal capture and analysis results related to IQ Capture Test 1 Run 05

NOTE : You can also capture multiple RF channels when you want to analyze MIMO or compare signals from different antenna paths. In this format, rx_channels and tx_channels specify which RF channels should be captured. For example, rx_channels [0,1] means RX channel 0 and RX channel 1 are captured at the same time. The duration value defines the capture time in ms. The filename can include %d so that each channel is saved into a separate file automatically. In the example command, rx_filename is set to /tmp/rx_file%d, so the capture creates two files in the /tmp directory: rx_file0.bin for RX channel 0 and rx_file1.bin for RX channel 1. This is useful when you want to inspect per-antenna IQ data, compare RX paths, or analyze MIMO behavior from multiple RF chains.

# ws.js enb '{"message":"trx_iq_dump", "rx_channels":<array>, "tx_channels":<array>, "duration":<value in ms> , "rx_filename":<file name%d>, "tx_filename":<file name%d>}'

Plotting Spectrum with sdr_spectrum

This section explains how to use sdr_spectrum for basic spectrum analysis after IQ data has been captured. Once the IQ files are saved, you can process them with your own tool, such as Matlab or Python, if you want full control over the analysis. But for a quick check, you can use the sdr_spectrum program included in the Amarisoft installation package. This tool is useful for basic spectrum inspection because it can directly read the captured IQ file and display the signal in the frequency domain. It is a convenient first step before doing more detailed offline analysis. (If you are not familiar with sdr_spectrum basics, refer to this tutorial)

You can plot spectrum with sdr_spectrum with the syntax as below : sdr_spectrum -iq <filename> -rx_freq <frequency> -rate <sample_rate>

The command that I used in this specific case is as follows : In this example, the input file is /tmp/tx.bin, the receive frequency is set to 2560e6, and the sample rate is set to 30.72e6. The command runs sdr_spectrum from /root/trx_sdr and opens the captured IQ file for spectrum display. This is useful for quickly checking whether the captured IQ data has the expected frequency-domain shape before doing more detailed analysis with another tool.

/root/trx_sdr/sdr_spectrum -iq /tmp/tx.bin -rx_freq 2560e6 -rate 30.72e6

NOTE : If you want to run this program vis ssh, you need to use -X option for the command (e.g, ssh -X root@192.168.1.1)

IQ signal capture and analysis results related to IQ Capture SdrSpectrum 01

IQ signal capture and analysis results related to IQ Capture SdrSpectrum 02

IQ signal capture and analysis results related to IQ Capture SdrSpectrum 03

Plotting Spectrum with Octave/Matlab

This section shows how to post-process the captured IQ data with Octave or Matlab. The captured file tx.bin is read as single-precision floating-point data. The IQ samples are stored in interleaved format, so the first value is I, the second value is Q, the third value is I again, and the fourth value is Q again. After reading the whole file into the data variable, the example selects only a small chunk of the data because the full capture can be very large.

In this example, ChunkStart is set to 1 and ChunkLength is set to 1024 x 2 x 10. The factor 2 is used because each complex IQ sample has two float values, one for I and one for Q. After slicing the chunk, DataChunkI takes every odd-indexed sample and DataChunkQ takes every even-indexed sample. Then these two arrays are combined into a complex IQ array as DataChunkComplex.

After creating the complex IQ data, FFT is applied and fftshift is used to move the center frequency to the middle of the plot. The FFT result is converted into dB scale with 20 x log(abs()). Finally, the script plots two views. The left plot shows the frequency-domain spectrum of the selected IQ chunk, and the right plot shows the time-domain magnitude of the same chunk. This is a simple example, but it shows the important file format rule clearly: Amarisoft IQ dump data is stored as float32 values in interleaved I/Q order.

    % By following routine, the whole data are read and stored in the variable 'data'. I ran this on Windows PC and tx.bin file is located in C:\temp folder.

    fid = fopen('C:\\temp\\tx.bin','r');

    [data,count] = fread(fid, 'single');

    fclose(fid);

    % I want to display the data in frequency domain, but I will slice out only a small portions of the data

    % since the total number of data is too big.

    ChunkStart = 1;

    ChunkLength = 1024*2*10;

    DataChunk = data(ChunkStart:ChunkStart+ChunkLength-1);

    % Now I will separate I value and Q value and save them into separate variable.

    DataChunkI = DataChunk(1:2:length(DataChunk));

    DataChunkQ = DataChunk(2:2:length(DataChunk));

    % I will combine the I data and Q data into an array of Complex Number

    DataChunkComplex = DataChunkI + (DataChunkQ .* j);

    % Do FFT and plot it in dB scale.

    DataChunkFFT = fftshift(fft(DataChunkComplex));

    DataChunkFftdB = 20*log(abs(DataChunkFFT));

    % Plot the data in frequency and time domain

    subplot(1,2,1);

    plot(DataChunkFftdB);xlim([1, length(DataChunkFftdB)]);

    subplot(1,2,2);

    plot(abs(DataChunkComplex));

    xlim([0 length(DataChunkComplex)]);

This figure shows the result of the sample Octave/Matlab code. The left plot is the FFT result of the selected IQ chunk, displayed in dB scale. The center portion has higher power, and the power goes down near both edges. This gives a quick view of the occupied spectrum of the captured LTE downlink signal. The right plot shows the time-domain magnitude of the same IQ chunk. Since this capture was taken from LTE downlink without any UE connected, the signal does not look continuous in time. Instead, it appears as repeated burst-like regions. This is expected because the cell is mainly transmitting broadcast, synchronization, reference, and control-related signals rather than continuous user traffic. So this example confirms both the IQ file format and the basic behavior of idle-mode LTE downlink capture.

IQ signal capture and analysis results related to IQ Capture Octave 01

Tips

Changing Sampling Rate

If the captured IQ file does not use the sampling rate you wanted, you have two choices. One option is to capture the data first and then resample it later with your own post-processing tool. The other option is to set the desired sample rate directly in the Amarisoft configuration file before starting the service.

You can specify the sample rate in the configuration file as shown below.

In this example, the sampling rate is configured in the rf_ports section. The parameter sample_rate is set to 15.36, which means the RF port uses 15.36 Msps. The same setting can be applied in both CHANNEL_SIM and non-CHANNEL_SIM cases. This value affects how the IQ samples are generated or captured, so it is useful to check this setting before running the IQ dump. When you process the captured IQ file later, make sure the plotting tool or analysis script uses the same sample rate value. Otherwise, the time axis and frequency axis in the plot may be interpreted incorrectly.

IQ signal capture and analysis results related to IQ Capture Tips SampleRate 01

You can confirm the changed sampling rate from the eNB screen after restarting the LTE service. In this example, the service is started with ltestart.sh ENB, and the RF0 status line shows sample_rate=15.360 MHz. This confirms that the sample_rate value configured in the rf_ports section has been applied correctly. The same line also shows dl_freq=2680.000 MHz, ul_freq=2560.000 MHz, band 7, dl_ant=1, and ul_ant=1. Before capturing IQ data, it is a good practice to check this line because the sample rate directly affects the time and frequency scale of the captured IQ file.

IQ signal capture and analysis results related to IQ Capture Tips SampleRate 02