📜 ⬆️ ⬇️

Another way to decompose a signal into a spectrum

Hello everyone, here I want to tell you about the sound signal analysis algorithm that allows you to parse the signal into separate waves, of course, it does not give 100% accuracy, but nevertheless the result is pretty good in my opinion.

image

The work on any music is best seen:


And links to other examples of different genres. Metaldeth-Tornado of souls:


Out of Touch:


So for the expansion you need to do the following steps:

- From the original signal you need to get 8 intermediate signals;
- From these intermediate signals and the original signal you need to get 8 signals - layers, which can be divided into separate waves;
- Calculate how much in each layer of waves and what is their amplitude.

Now more about each stage: in order to get an intermediate signal, you need to take a derivative of the original signal. In essence, this is a derivative of a discrete function. To find it for each moment of the original signal you need to set 1 parameter: the period for which this derivative is located. The value of the derivative is the coefficient of the slope in a given interval, you can find for example the method of least squares.

It is required to calculate 8 intermediate signals with 8 different periods. The simplest set of periods: 4, 8, 16, 32, 64, 128, 256, 512. When the period is specified, for each sample of the signal, the derivative is calculated using the least squares formula. It is like a moving average, only here is not a moving average but a sliding derivative of the current interval.

Thus, 8 derived signals and 1 source signal are obtained. Now each of the 8 derived signals needs to be integrated. In this case, this means that each subsequent sample is equal to the sum of all previous samples. After that, 8 intermediate layers are obtained.

The next step is to obtain layers that can be disassembled into separate waves. So now you need to get 8 layers. Layers are calculated as follows:

layer0 = intermediate0-ref signal
layer1 = intermediate1-intermediate0
layer2 = intermediate2-intermediate1
layer3 = intermediate3-intermediate2
layer4 = intermediate4-intermediate3
layer5 = intermediate5-intermediate4
layer6 = intermediate6-intermediate5
layer7 = intermediate7-intermediate6
layer8 = intermediate7

The last layer is not a difference, but is simply equal to the last intermediate signal.

You can try differently, namely, to calculate the subsequent intermediate signals from the previous intermediate ones. But in the current program uses 1 option.

Now, to break down the layers into separate waves, you just need to count the areas where the values ​​increase and where they decrease. Actually the duration of the sections is their wavelength. Signal areas where signal values ​​are constant must be simply skipped. To find the amplitude of the signal in the spectrum in a certain interval, you need to add all the amplitudes of the waves multiplied by their length.

image

The code that calculates the intermediate signal looks like this:

here wavesize is the number of samples
signal [] - the array with the source signal
SY = 0, SX = 0, SXX = 0, SXY = 0, Ky = 0 - variables of type float
Step2 = STEP / 2 where STEP is the period (4,8,16,32,64,128,256,512)

for(int i=Step2;i<wavesize-Step2;i++){ SY=0,SX=0,SXX=0,SXY=0,Ky=0; for(int j=i-Step2,fromZ=0;j<i+Step2;j++,fromZ++){ SX+=fromZ; SY+=signal[j]; SXX+=fromZ*fromZ; SXY+=fromZ*signal[j]; } Ky=float((STEP)*SXY-SX*SY)/float((STEP)*SXX-SX*SX); OutSignal[i]=OutSignal[i-1]+Ky; } 

To subtract one signal from another, simply subtract each sample from each.
For example, for layer 0:

 for(int i=0;i<wavesize-1;i++) layer0[i]=OutSignal0[i]-Signal[i]; 

If you add up all the layers, and take the last one with the opposite sign, you get the original signal, thus multiplying some layer, it is possible to make a frequency filter. The next question is how to calculate the amplitudes of specific harmonics. The fact is that in a constant interval, for example = 4000 samples, there can be a lot of short waves and relatively few long ones.

You can certainly find the average amplitudes for each layer and fold. But this method is not very good since the long waves are very small, and their amplitude is usually very large, and a strong non-uniformity of amplitude towards low frequencies is obtained.

In the program that displays the color music on the links, the amplitude of each harmonic is calculated as: wave amplitude * its length. Still, unevenness arises, but not as strong as in the case of averaging.

In general, I don’t think that a person perceives sound as a decomposition into a spectrum, rather a sound consists of sound images that consist of waves of different lengths. Accordingly, the volume of a sound is rather the average volume of all the waves of which the sound consists. But so far it is not clear what parameters make up the sound image, perhaps the average frequency, standard deviation or something else.

Source: https://habr.com/ru/post/410357/