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. )
- Troubleshooting at very low phy level
- Appying my own signal processing algorithm
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 (
Table of Contents
- IQ Capture
- Introduction
- Summary of the Tutorial
- Test Setup
- Configuration
- Test 1 : Capturing IQ with Remote API
- Test 2 : Capturing IQ with IQ Capture Script
- Test 3 : Capturing IQ with Configuration File
- Test 4 : Capturing IQ with sdr_spectrum
- Plotting Spectrum with sdr_spectrum
- Plotting Spectrum with Octave/Matlab
- Tips
Introduction
In the field of wireless communications, In-phase and Quadrature (IQ) data capture is a fundamental technique that enables engineers and researchers to analyze, process, and troubleshoot radio frequency (RF) signals at the physical layer. IQ data represents the raw, baseband signal information extracted from transmitted or received RF signals, encapsulating both amplitude and phase information that is essential for advanced signal processing. This tutorial focuses specifically on capturing IQ data from a callbox or UE simulator (UEsim) using a Remote API, a method commonly used in modern test environments for cellular technologies such as LTE and 5G. Unlike SDR-based tools that may require direct hardware access, callbox-based IQ capture leverages sophisticated software platforms that emulate real-world network and device conditions, allowing for comprehensive testing and analysis. The captured IQ data, typically stored as alternating 32-bit I and Q values without additional metadata or headers, provides a straightforward yet powerful format for custom signal processing and troubleshooting tasks. Understanding how to efficiently capture and utilize IQ data is crucial for tasks ranging from developing novel algorithms, validating RF performance, to diagnosing complex issues at the lowest protocol layers. This tutorial will guide you through the process of leveraging the Remote API for IQ data capture, emphasizing the architectural flow, integration with test systems, and practical considerations for working with the resulting data in Amarisoft environments and similar platforms.
-
Context and Background
- IQ data is a core component in RF signal analysis, representing the digital baseband equivalent of RF signals used in wireless communication systems.
- Callboxes and UE simulators provide controlled environments for emulating network conditions and device behavior, enabling precise capture of signal characteristics via software APIs.
- The Amarisoft platform and similar solutions output IQ data in a simple binary format, facilitating easy post-capture processing without proprietary encodings or complex file structures.
-
Relevance and Importance of the Tutorial
- Capturing IQ data from a callbox via Remote API is critical for low-level troubleshooting, algorithm development, and performance validation in wireless research and development.
- This method allows users to bypass hardware limitations and automate data acquisition, providing flexibility and scalability in test automation or analysis pipelines.
- Understanding this process empowers engineers to gain deeper insights into physical layer behaviors and to design custom signal processing workflows tailored to specific needs.
-
Learning Outcomes
- Acquire practical knowledge of the architectural flow for capturing IQ data using Remote API interfaces in callbox or UE simulator environments.
- Develop the ability to interpret and handle the raw IQ data files generated by Amarisoft and similar systems.
- Gain hands-on experience integrating IQ capture into custom test procedures or signal processing toolchains.
- Understand best practices and limitations when working with binary IQ data formats lacking explicit metadata.
-
Prerequisite Knowledge and Skills
- Basic understanding of wireless communications principles, particularly the concepts of I/Q modulation and baseband processing.
- Familiarity with RF test equipment, such as callboxes or UE simulators, and their role in test automation environments.
- Experience with programming languages or scripting environments (such as Python or C) for reading and processing binary files.
- General knowledge of signal processing and data analysis workflows is advantageous but not strictly required.
Summary of the Tutorial
This tutorial provides comprehensive procedures for capturing IQ (In-phase and Quadrature) samples in a wireless test environment using several different methods. The content is focused on the step-by-step methodologies, configurations, and tools involved in IQ data acquisition, as well as guidance for post-processing and analysis.
-
Test Setup:
- A single callbox and a commercial UE are used, with the antenna connected to the first SDR card (RF 1 on sdr 0). The UE attaches to the eNB over the air. Only one RF port is necessary unless multiple RX or TX channels are to be captured, in which case additional antennas should be connected to the remaining ports.
-
Configuration:
- No specific configuration is required; any configuration suitable for the test scenario can be used. Example config files such as enb.default.cfg or gnb-sa.cfg are suggested as starting points.
-
Test 1: Capturing IQ with Remote API
-
Start the LTE service and verify key parameters: sample rate, center frequency, DL/UL ARFCN, SCS, antenna configuration. These are not required for the capture itself but are recommended to be noted for later analysis.
-
Use the rf_info command to confirm the actual Tx and Rx frequencies and gains before starting the capture.
-
Set the UE and network to the state intended for analysis (idle or connected mode). Monitor live LTE status with the t command to ensure the UE is in the desired state before capture.
-
To capture IQ samples, use the Amarisoft Remote API with the trx_iq_dump message. The capture command format is:
# ws.js enb '{"message":"trx_iq_dump", "duration":<value in ms>, "rx_filename":<file name>, "tx_filename":<file name>}'
This captures both RX and TX IQ samples for the specified duration in milliseconds, saving them to the indicated file paths.
-
Upon completion, the tool reports the elapsed time and the files are available for later analysis. File size is determined by duration and sample rate; ensure sufficient storage for large captures.
-
For multi-channel capture (e.g., MIMO), specify rx_channels and tx_channels as arrays and use filename patterns (e.g., /tmp/rx_file%d) to create separate files for each channel.
-
-
Test 2: Capturing IQ with IQ Capture Script
-
Use the trx-iq-dump.js script located in /root/enb to capture IQ samples split by slot, rather than as a single continuous file.
-
Command format:./trx-iq-dump.js enb --tx --rx /tmp/iqs 10000
This command captures both TX and RX directions for 10 seconds, saving slot-separated files to the specified directory. The existing directory is cleared before capture starts.
-
A configuration JSON file is created alongside the IQ files, providing metadata for post-processing.
-
-
Test 3: Capturing IQ with Configuration File
-
IQ capture can be enabled directly via a configuration file, without API calls. Add a flag (e.g., SAVE_IQ) in the define block; when set, the service writes IQ samples to a file during runtime.
-
Configure two rf_driver blocks:
- The dummy driver branch, used for IQ capture, writes samples to output_filename for a duration specified by output_duration (in ms).
- The normal SDR branch is used for standard operation.
-
Use a symbolic link to point the main config (e.g., config/enb.cfg) to the capture-specific configuration.
-
Start the binary directly (e.g., ./lteenb config/enb.cfg), as service restarts may not work with the dummy driver. The program stops automatically after the configured duration, saving the IQ file as specified.
-
Captured IQ files can be replayed and analyzed with tools such as sdr_spectrum, using the same sample rate and frequency settings as in the capture.
-
-
Test 4: Capturing IQ with sdr_spectrum
-
sdr_spectrum can capture IQ data directly from the SDR, independent of the callbox software.
-
Manual Capture:
- Launch the spectrum display with specified card, frequency, and sample rate.
- Adjust gain and frequency while observing live spectrum; press s to save samples to disk when ready. The file is auto-named and stored in /tmp.
-
Automatic Capture and Exit:
- Use options like -duration (capture length in seconds), -save_delay (wait before saving), and -save-and-exit for automated capture and exit.
- The resulting file size scales with the set duration.
-
Additional Options:
- Use various sdr_spectrum parameters to control gain, bandwidth, sync, clock, and output path. Avoid compression unless the reader supports it.
- Use -h for a detailed list of command options.
-
-
Plotting and Post-processing
-
Spectrum Plotting with sdr_spectrum:
- Use sdr_spectrum -iq <filename> -rx_freq <frequency> -rate <sample_rate> to visualize the frequency spectrum of captured IQ data.
- Supports waterfall and frequency-domain views for quick signal inspection.
-
Analysis with Octave/Matlab:
- Read the IQ binary file as interleaved single-precision floats.
- Separate I and Q components, combine into complex samples, apply FFT and plot both frequency and time-domain magnitudes.
- Adjust the sample rate parameter to ensure correct frequency/time axis interpretation.
-
Spectrum Plotting with sdr_spectrum:
-
Tips and Best Practices
-
Always verify and record the sample rate and center frequency before capturing IQ data, as these parameters are fixed at service start and are necessary for accurate analysis.
-
Test Setup
The setup is a single callbox and one commercial UE. The antenna is connected only to the first SDR card, RF 1 on sdr 0, and the UE attaches to the eNB over the air. One RF port is enough here because every capture in this tutorial is taken from a single port. If you want to dump more than one RX or TX channel, connect the antennas to the remaining ports of the same SDR card first.

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.
The RF0 line at the top is printed by the service when it starts. The cell table below it comes from the cell phy command typed at the (enb) prompt. The table shows cell 0x001 running LTE with QAM 256 on the downlink and QAM 64 on the uplink. The identity line shows PLMN=00101 and eNB_ID=0x1a2d0. The SSB columns are empty because this is an LTE cell. The log line in between shows the log file rotating at 250M under /var/log/lte/. That is where you look if you want to line up the IQ capture with the trace log afterwards.
None of this is mandatory for the capture itself. I would suggest you make a note of it. You can also put it into the name of the capture file. The sample rate, the center frequency and the bandwidth then travel with the file, and you still have them when you process it later.

The listing also reports TRX API version 15. All four channels sit on port 0, so this is one RF port carrying two TX and two RX chains. rf_info can be typed at any time while the service is running. It is the quickest way to confirm the Tx and Rx center frequency right before you start the dump.

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.
The trace opens with a PRACH line for cell=01 with seq=0, ta=2 and snr=16.8 dB. That is the UE coming in. The per-TTI lines follow once it is connected. On those lines phr stays around 30 to 33 dB and pl around 65 to 68 dB. ta stays between 0.0 and 0.2. The retx and #its columns show that a few downlink transports needed retransmission. Pressing return stops the trace without touching the cell. You can stop it and then issue the dump, and the UE stays exactly where you put it.

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"}'
The tool connects to 127.0.0.1:9001 and reports Ready with name=ENB and type=ENB. It then sends the trx_iq_dump message as id#1. Nothing more is printed while the samples are being written. The console just sits there for the requested 5000 ms. The result then comes back with the time value, 1956.255 in this run.

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.
Listing /tmp afterwards shows the two files that the dump created. They are /tmp/rx.bin and /tmp/tx.bin, each 230400000 bytes. That size follows straight from the capture parameters. 5 seconds at 5.76 Msps is 28.8 M samples. Each sample is one 32 bit I value plus one 32 bit Q value. Keep this in mind before you ask for a long duration. The file grows at about 46 MB per second at this sample rate, and proportionally faster at a higher one.

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>}'
Example : # ./ws.js enb '{"message":"trx_iq_dump", "rx_channels":[0,1], "duration":10 , "rx_filename":"/tmp/rx_file%d"}'
// This create two files rx_file0.bin and rx_file1.bin in /tmp directory
Test 2 : Capturing IQ with IQ Capture Script
Amarisoft also ships a script that is specially designed to capture IQ separately for each slot. The script is trx-iq-dump.js which is in /root/enb. It is worth knowing about because it does not save one long file. It splits the capture into one file per slot. It also writes the configuration into a json file next to them. That is what you want when you are chasing one particular slot rather than looking at the signal as a whole.
NOTE : There is a separate tutorial for this showing the detailed usage. Check out IQ Dump tutorialThe script takes the service, then the directions to capture, then the output directory and the duration in milliseconds. Here enb is the service, --tx and --rx ask for the downlink and the uplink together, /tmp/iqs is where the files go and 10000 gives a 10 second capture. The directory has to exist before you run it.
It clears the directory first, so anything already sitting in /tmp/iqs is lost, then runs the capture and splits the samples by slot. The two Process lines are the raw rx and tx captures being cut up, one for each direction.
[root@CBC-2023010100 enb]# ./trx-iq-dump.js enb --tx --rx /tmp/iqs 10000
Clean directory
Start capture
Split by slot
Process /tmp/iqs/rx00
Process /tmp/iqs/tx00Test 3 : Capturing IQ with Configuration File
The third way needs no Remote API call at all. You put the capture into the configuration file itself. The service then writes the IQ file on its own while it runs. I used the gnb-sa-iq.cfg configuration for this. The first thing to add is a flag in the define block at the top. The capture can then be turned on and off without editing the rest of the file.
In this file NR_TDD is 1 and FR2 is 0. The cell is therefore NR TDD in FR1, and the FR2 branch just below it is not used in this test. The FR1 side sets NR_TDD_CONFIG to 2 and NR_BANDWIDTH to 20. The antenna configuration is SISO, with N_ANTENNA_DL and N_ANTENNA_UL both 1. NR_LONG_PUCCH_FORMAT is 0, which leaves the format selection automatic. USE_SRS is 0, so no periodic SRS is configured.
SAVE_IQ is the flag that I added, and it is set to 1 here to enable the capture. Setting it back to 0 returns the file to a normal run without changing anything else.

SAVE_IQ then selects between two rf_driver blocks. The capture branch sets name to "dummy". The dummy driver is what makes this method work. Instead of pushing the samples out to the SDR, it writes them to a file. output_filename is where they go, /tmp/gnb-sa-iq.bin in this file. output_duration is the capture length in milliseconds, set to 100 here.
The other branch is the normal operation configuration with name set to "sdr". It picks the device arguments according to N_ANTENNA_DL. Four or more downlink antennas give dev0=/dev/sdr0,dev1=/dev/sdr1, and anything less gives dev0=/dev/sdr0. It also forces the RX antenna onto the RX connector for TDD, and leaves the gps sync line commented out. Keeping both branches in one file means a single flag switches between capturing IQ and running the cell for real.

Because the capture configuration lives in its own file, I pointed config/enb.cfg at it with a symbolic link to gnb-sa-iq.cfg.
Start it by running the binary directly as ./lteenb config/enb.cfg. service lte restart does not work well with the dummy driver, so use this form instead.
Once it starts, the RF0 line reports sample_rate=23.040 MHz, dl_freq=3489.420 MHz and ul_freq=3489.420 MHz on band n78 with dl_ant=1 and ul_ant=1. Write these values down, because you need the sample rate and the center frequency again when you plot or post process the file. The run then ends by itself with IQ samples saved, stop program once the configured output_duration has elapsed.

The file is where output_filename said it would be. /tmp/gnb-sa-iq.bin is 18432000 bytes, which is the 100 ms of output_duration at 23.04 Msps with 8 bytes per IQ sample.
You can play it straight back into sdr_spectrum with the -iq option, and this is where the values from the RF0 line are needed. -rx_freq 3489.42e6 and -rate 23.04e6 have to match the capture, and sdr_spectrum confirms what it took from the command line by printing Using 1 IQ files (center=3489420 rate=23040 kHz).
[root@CBC-2023010100 trx_sdr]# /root/trx_sdr/sdr_spectrum -iq /tmp/gnb-sa-iq.bin -rx_freq 3489.42e6 -rate 23.04e6

The playback window opens centered on 3489 MHz with a 23 MHz span, and the header confirms sample_rate=23.040 MHz with RBW=22.5 kHz at dft_len=1024. RX1 reads Power=-35.4 dBm and IQ MAX=-8.4 dBFS.
This came from the dummy driver, so the level is not an over the air measurement. It is the digital level of the samples the cell generated. That is why the value in dBm and the value in dBFS are printed as the same number.

Test 4 : Capturing IQ with sdr_spectrum
The last method does not involve the callbox software at all. sdr_spectrum drives the SDR card directly and you get to look at the spectrum before deciding whether the capture is worth taking. It can be driven by hand or told to record and quit on its own, and both are shown below.
NOTE : This test assumes that you connected sdr_spectrum to a transmitter. In my case, I corrected the UEsim sdr card 0 RX port to Amarisoft callbox sdr card 0 TX and the Callbox was running gnb-sa-20Mhz-SISO.cfg without any UE connection.Manual Capture
Manual capture means starting the spectrum display, watching what you are getting, and pressing a key once it looks right. Nothing is written to disk until you do, so you can spend as long as you like on the gain and the frequency first.
-c selects the SDR card, 0 in this case. -rx_freq sets the center frequency and -rate sets the sample rate. Both of them have defaults, 2.4 GHz and the full rate of the card. If you leave them out you will get a capture at values you did not choose. I recommend setting -rate explicitly and writing the value down. You need the same number again when you process the file.
[root@UESB-2021102500 trx_sdr]# ./sdr_spectrum -c 0 -rx_freq 3489.42e6 -rate 23.040e6

The window that opens is the live spectrum and not a file playback. The header therefore reports the actual radio state. It shows rx_freq=3489.420 MHz, spl_rate=23.040 MHz and rx_gain=7.0 dB with AGC in charge. It also shows sync_source=none and clock_source=internal. The card is reported as dev0=/dev/sdr0@0 with FPGA T=60.7 C. RX1 reads Power=-24.9 dBm at IQ MAX=-5.1 dBFS.
Pressing s saves the samples to disk, into /tmp by default. Before you press it, adjust the other parameters until the waveform is in the best shape you can get (e.g, adjusting rx_gain or AGC in particular). The capture takes whatever is on the air at that moment. A signal that is clipping or buried in the noise floor stays that way in the file.

The saved file appears in /tmp without you naming it. The name carries the capture parameters, rec-20260827-133605187-23040-3489420kHz-1.bin, which is the date and time of the capture followed by the sample rate and the center frequency in kHz. At 184320000 bytes it holds one second of samples, which is the default -duration value.

Automatic Capture and Exit
Pressing s by hand is fine while you are watching the screen, but you can also let sdr_spectrum take the capture on its own and quit when it is done.
-duration 2 sets the recorded length to 2 seconds. -save_delay 5 waits 5 seconds after the spectrum starts before the saving begins. That gives the signal and the AGC time to settle. The samples in the file are then the stable ones. -save-and-exit starts the saving automatically and closes the program at the end. The whole capture is one command with nothing to press.
[root@UESB-2021102500 trx_sdr]# ./sdr_spectrum -c 0 -rx_freq 3489.42e6 -rate 23.040e6 -duration 2 -save_delay 5 -save-and-exit

The file lands in /tmp under the same automatic name, rec-20260827-135210033-23040-3489420kHz-1.bin. It is 368640000 bytes this time. That is exactly twice the size of the manual capture, and it matches the -duration 2 that was asked for.

Use Options to get good quality signals
The two runs above used only the options needed to get a file out. I used a bare minium option for the simplicity, but depending on your purpose you may need to add additional parameters to get the proper IQ files that you intended to get
sdr_spectrum has a good many more, and a few of them decide whether what you record is worth analysing at all. -h prints the whole list.
The ones that matter for the quality of the signal are the receive settings. -rx_gain sets the RX gain in dB and defaults to 60. That is a long way above the 7.0 dB that the AGC settled on in the run above. A strong nearby signal will clip if you fix the gain by hand without watching the level. -rx_bw sets the analog receive bandwidth, and it follows the sample rate unless you set it. -sync and -clock choose the sync and the clock source. Both matter if you intend to line the capture up against anything else in time.
-span and -rbw change the display and not the file, so they affect what you see while you are deciding but not what ends up being recorded. -save_path moves the output away from /tmp, and -duration sets the recorded length in seconds with 1.0 as the default.
The one to be careful with is -compr, which selects ci16, cf8 or bf2 IQ compression. The reading routine used in this tutorial assumes plain 32 bit I and Q values, so leave -compr alone unless your own reader knows the compressed format. The rest of the list is there for reference and none of it is needed for a plain capture.
[root@UESB-2021102500 trx_sdr]# ./sdr_spectrum -h
SDR spectrum utility version 2026-08-18, Copyright (C) 2012-2026 Amarisoft
REDISTRIBUTION OF THIS SOFTWARE IS PROHIBITED.
usage: sdr_spectrum [options]
Options:
-h help
-c devnum select a SDR device
-d channel select the device DMA channel (default = 0)
-rx_freq freq set the RX frequency in Hz (default=2400000000)
-span w set Spectrum SPAN in Hz (default=30.72MHz for SDR50; 122.88MHz for SDR100)
-rbw w set Resolution Bandwidth in Hz (default=auto)
Expert mode options:
-args str set the device arguments (default="dev0=/dev/sdr0")
-rate rate set the sample rate to 'rate' Hz (default=30720000 for SDR50; 122.88MHz for SDR100)
-rx_gain gain set the RX gain in dB (default=60)
-channels c set the number of RX channels to 'c' (default=1)
-fitst_ch c index of the first RX channel to display (default=0)
-rx_bw set the analog receive bandwidth in Hz (default=same as sample rate)
-rx_latency set the target RX latency in us; 0 => default(66.7us)
-sync source set the sync source to 'source' (none, internal, gps, external) (default=none)
-clock source set the clock source to 'source' (internal, external) (default=internal)
-save start saving now
-save-and-exit start saving now and exit at end
-save_path path set the directory where the recorded samples are saved (default=/tmp)
-duration d set the recorded sample file duration in seconds when saving (default=1.0)
-save_delay d set the delay (in s) before starting saving samples (default=1.0)
-dft_sample_ratio n set the DFT sample ratio (compute one DFT every n DFT length to save CPU time)
-period n window period in ms when showing sample power
-yoffset n set an offset for the spectrum Y range (in dB)
-xmin n set the spectrum X min value (in Hz)
-xmax n set the spectrum X max value (in Hz)
-dft_len_log2 n set log2(dft_length)
-f fps set the display refresh period in frames per second
-t type select initial format: 0 (freq) or 1 (power)
-iq filename read datas from IQ file
-iq_dir path read datas from multiple IQ files
-full_sp show full spectrum regardless of rx_bw
-cpri_mult CPRI speed mult [1:2:4:5:8:16]
-cpri_offset CPRI sample offset in bits
-cpri_rf_ports # of RF port per SFP (def = 1)
-scan_band scan a LTE band [1..40|UE] and output a signal map file
-scan_start if no scan_band: start scan frequency (in MHz)
-scan_end if no scan_band: end scan frequency (in MHz)
-scan_file output file for scan result (def: stdout)
-scan_bw min bandwidth in MHz to identify a valid signal (def: 4)
-scan_snr min snr to identify a valid signal (def: 6)
-zoom zoom on full spectrum (0 to 6GHz)
-grid show grid
-rfic_config <val> write specific value in RFIC_CONFIG registers
-rx_tx sets RFIC_CONFIG flags to select TX as input
-thema <dark|light> select color thema
-compr <ci16|cf8|bf2> select IQ compression
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)I called the binary by its full path, so the working directory does not matter and you can start it from wherever the IQ file happens to sit.

The spectrum view opens on the file. The header reports sample_rate=30.720 MHz, dft_len=1024 and a refresh period of 20 ms, the center is 2680 MHz with a 30 MHz span, and RBW is 30 kHz. RX1 reads Power=-22.8 dBm at IQ MAX=-4.0 dBFS.
The trace is flat across the occupied band and rolls off at both edges. That is what a downlink carrier should look like. The comb of narrow dips along the top comes from averaging. The signal is not transmitting on every subcarrier in every symbol, so this is not a sign of a bad capture. If the shape ever comes out wrong here, the first thing to check is the -rate value. sdr_spectrum has no way of knowing the sample rate of the file, and simply believes what you told it.

Pressing w switches the same file to the waterfall view, which is power against frequency and time instead of power against frequency alone. The header now shows period=10000.000 us, offset=0.000 us and duration=4882.812 us with samples_per_point=30, and the view is paused so that the frame holds still while you look at it.
Time runs along the horizontal axis and frequency up the vertical one. The color gives the power in dBm on the scale at the right. The red columns are the moments where the carrier is transmitting across the whole band. The blue gaps are the quiet symbols in between. This is the view to use when you want to see when something happened, rather than only how wide it was.

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.
The horizontal axis of both plots runs to about 10240. That is the number of complex samples in the chunk. It is 1024 x 2 x 10 float values divided by the two floats that make up each sample. On the left the dB values reach about +50 across the occupied band and fall to around -100 in the noise. That range is wider than you may expect. 20*log() in Octave is the natural logarithm and not log10. Changing it to 20*log10() gives the usual dB numbers.
On the right there are about six burst regions in this chunk. They peak a little above 0.2 in magnitude and drop essentially to zero in between. Nothing was connected to the cell during this capture. What is left is the periodic downlink transmission. The gaps are the symbols where the cell has nothing to send.

Tips
What follows is a small number of things that are easy to get wrong the first time. They cost you the capture if you only notice them afterwards. The sample rate is the main one. It is fixed when the service starts, and there is no way to change it for the dump alone.
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.
The rf_ports block appears twice in this file. It appears once under CHANNEL_SIM == 1 and once in the else branch, so that the same file works with and without the channel simulator. sample_rate is set to 15.36 in both, and the value is in MHz. The channel simulator branch also carries a channel_dl block with type "awgn" and noise_level -30. That block has nothing to do with the sample rate. It is there only because that branch is the simulator configuration.
Set sample_rate in the branch that is actually compiled in, and set it in both if you switch between them. This changes the rate for the whole run and not only for the dump, so the cell bandwidth still has to fit inside it.

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.
The banner above it reads Base Station version 2022-04-01. The status bar at the bottom shows 0 MME, 1 ENB and 3 IMS, so only the eNB is up in this run. The RF0 line is printed once at start up. If you have already scrolled past it, you can bring the same frequencies back with rf_info at the (enb) prompt.

-