# 信号实验箱 **Repository Path**: powerx/signal-test-box ## Basic Information - **Project Name**: 信号实验箱 - **Description**: 基于QT、z-fft实现的微型可视化信号运算/变换/处理工具 - **Primary Language**: C++ - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 36 - **Created**: 2023-01-11 - **Last Updated**: 2023-01-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Signal Test Box This is a signal calculate/drawing software based on expression, the main function is sample the signal given by a expression or a function, then execute calculate of the sample sequences, and draw the results into diagram. Using shared library to extend functions is supported. This software support multiple platforms deployment, this feature is mainly benefit from QT cross-platform API and CMake multiple platforms build ability, you could build applications of different platforms on one host. Currently, the Ubuntu 22.04(based on Win11 WSL2)、Win7/Win10/Win11、Android x86/Android armeabi-v7a(based on Win11 WSA and Realme X2 Pro) is tested passed This software support translates, powered by QT linguist tool. Currently have Chinese simplified translate data(using English in software is default, then use translate data to translate, this is the solution recommended by QT linguist module), if you want to add more language support, you could use QT linguist tool to generate .ts file of this project, such as this file [ui/zh_CN.ts](ui/zh_CN.ts), then translate the item in the .ts file manually, finally release this .ts file to .qm file. Software will get system locale information at launch time, therefore it can automatically match your system language setting. If your setting is unsupported languages, it will display in English. If you have questions about using this software、reading the code or building this project, please leave an issue, I will handle it if I see. - [1. Simple demo](#1-simple-demo) - [2. Working Principle](#2-working-principle) - [3. The definition of signal](#3-the-definition-of-signal) - [4. Spectrum mode](#4-spectrum-mode) - [5. Built-in compiler](#5-built-in-compiler) - [6. Function library](#6-function-library) - [7. Workspace](#7-workspace) - [8. Release Versions](#8-release-versions) - [9. Build the source code](#9-build-the-source-code) - [9.1. Recommended way](#91-recommended-way) - [9.2. Manual way](#92-manual-way) - [10. Filter guide](#10-filter-guide) - [11. Android build guide](#11-android-build-guide) ## 1. Simple demo Right click in signal list widget(long press for Android), select `Add Signal` in the popup, then input a signal expression, setting the Sample Rate and the Sample Points, click calculate button then you could see the wave. ![signal0](./readme_rc/sig1.png) ![signal1](./readme_rc/sig2.png) Signal can nested use, to make it easy to use multiple signals to calculate, maximum nest level is 32. ![signal2](./readme_rc/sig3.png) Except sin and cos, there are some other functions could be use, such as the software random number function(`rand`) and the hardware random number function(`hrand`). ![signal3](./readme_rc/sig4.png) ![signal4](./readme_rc/sig5.png) Fourier transform, calling `length` function is because of the `fft` function outputs colplex number, the `length` function is to calculate the lenght of complex number, therefore it could calculate the amplitude spectrum. ![input signal](./readme_rc/mix_sig.png) ![amplitude spectrum](./readme_rc/fft.png) The `filters` library has serval filter functions, `lpf` and `hpf` is IIR filters, they are low pass filter and high pass filter. Receive a sample sequence and a stop frequency as arguments, 'fir` is a FIR filter, receive a sample sequence、a filter order and a filter cofficient(can export by Matlab) as arguments. There are 1 order IIR low pass filter、3 order IIR low pass filter and 32 order FIR low pass filter demo, more information about filter, please check out [10. Filter guide](#10-filter-guide) ![OrigSig](./readme_rc/orig_sig.png) ![IIR_filter1](./readme_rc/iir_lv1.png) ![IIR_filter2](./readme_rc/iir_lv3.png) ![FIR_filter](./readme_rc/fir_lv32.png) You could see, the higher order of the filter has the better effect by analyze the spectrum diagram about the signal which after filter. ## 2. Working Principle 1. A signal could be defined by an expression **f**, at any moment **t**, signal amplitude is **f(t)** 2. If given a moment **t**, the result of the expression **f(t)** is the sample value of signal **f** at the time **t** 3. **t** could calculate by software using Sample Rate, then repeat calculate **N** times, **N** is the Sample Points setting. 4. Software will convert the expression into grammar tree by using the built-in compiler. 5. Before calculating the value of every node, it will calculate the value of sub node, therefore, the value of root node is the value of the whole expression. 6. If a signal reference another signal, the inside signal will calculate first 7. Signals have a maximum nest limitation, to prevent signal reference itself or multiple signal cross reference causes the infinite recursion. ## 3. The definition of signal In this software, all the signal is defined as an expression, such as `sin(t)` is the sin signal, `sin(100*t) + sin(200*t)` is add two different signals with different frequencies together. Signal can reference another signal, such as `sig0 = sin(100*t) sig1 = sin(200*t) sig2 = sig0+sig1` Signal reference itself or multiple signal cross-reference will trigger the maximum nest limit ## 4. Spectrum mode After using `fft` function to calculate the Fourier transformation of a signal, if you are only use `length` function to calculate the amplitude spectrum, the X axis of the diagram is the index of the data point, such as the following diagram. ![iir_freq_index](readme_rc/iir_lv1_freq_index.png) You could see that the position of the crosshairs is X coordinate 10, this is the index of that data point in the sample sequence, if you want to know the frequency of this point, you need to calculate it by yourself, we know X=10, sample rate is 5KHz, sample point is 256, so the frequency of this point is `5000/256*10=195.3Hz`, it represents the 200Hz frequency in the original signal. Although, doing that calculation is simple, but it is also annoying, and all of the arguments we use to calculate also in the software, so, you could check the spectrum mode checkbox in the lower right corner to make the software to calculate instead us. After checking the spectrum mode checkbox, the X axis will be the actual frequency, such as the following diagram. It is the signal we used in the diagram above, but the spectrum mode checkbox is checked, you could see that the position of the crosshairs is X coordinate 195.313, it is same as our calculation result. ![IIR_freq1](./readme_rc/iir_lv1_freq.png) Something you need to know is, the spectrum mode actually displays the first half of calculated data, it means if the sample points is 1024, the diagram will display the first 512 data points, this is because of the spectrum is symmetrical, so only need the first half data is enough to analyze. Another thing is, the `fft` function only outputs a half of spectrum, this is also using the symmetrical of spectrum. Such as we assume the sample points is 1024, the 1024 real number input to the `fft` function will get 512 complex number(still are 1024 float variables, but half of them is real part, another half is imaginary part), and after call the `length` function, will get 512 real number, therefore, if you don`t use the spectrum mode, you will find that all the last half of the diagram is zero, that is because of the diagram displays 1024 data points but we actually have only 512 data. If you use the spectrum mode, based on what I said above, the diagram will display 512 data points, this is a way to make full use of the display space to display valuable data. ## 5. Built-in compiler This software have a built-in compiler, it support common math expressions、double-slash single-line comments and **if** condition expressions. Math expressions are the most simplist math equation, such as `(sin(t)+cos(t+3))*6` Double-slash single-line comments are the same as C programming language, such as `sin(t)//sin of t`, chars after the double-slash is ignore by the complier. **if** condition expressions have the same logic than C programing language, but not use `?:` symbols and use **if** and **else** keywords, grammar order is also different, actually, this is the same design as python, the grammar rule is `math expression + if keyword + compare expression [+ else keyword + math expression]`, the content surrounded by the square bracket is optional, such as: 1. 5 if index > 15 else 3//equals to `index > 15 ? 5 : 3` in C 2. 5 if index > 15//omit else sub expression, equals to `index > 15 ? 5 : 0` in C Combine **if** condition expression and **index** variable can generate step signal and impulse signal very easily, such as: 1. 1 if index >= 0//unit step signal 2. 1 if index == 0//unit impulse signal 3. 1 if index >= 5//step signal with right shift 5 4. 1 if index == 5//impulse signal with right shift 5 5. 5 if index >= 0//step signal with amplitude is 5 6. 5 if index == 0//step signal with amplitude is 5 Complier supports those variables: 1. **t** , represent the time, it is **n** divides **fs**, `t = n/fs` 2. **index** , represent the index of samples, it is what we say **n**, such as the sample points is 1024, so **index** is the sequence of [0-1023]. Compiler supports a constant **pi**, represent the value of pi. Compiler is case insensitive, pi equals to PI Pi pI, t is also equals to T. ## 6. Function library ## 7. Workspace ## 8. Release Versions ## 9. Build the source code ### 9.1. Recommended way ### 9.2. Manual way ## 10. Filter guide ## 11. Android build guide