Olá a todos, aqui quero falar sobre um algoritmo de análise de sinal de áudio que permite analisar o sinal em ondas separadas, é claro que não oferece 100% de precisão, mas, no entanto, o resultado é muito bom na minha opinião.

O trabalho em qualquer música é melhor visualizado:
E links para outros exemplos de diferentes gêneros. Metaldeth-Tornado de almas:
Fora de contato:
Portanto, para a decomposição, você precisa executar as seguintes etapas:
- A partir do sinal original, você precisa obter 8 sinais intermediários;
- A partir desses sinais intermediários e do sinal original, é necessário obter 8 camadas de sinais, que podem ser desmontadas em ondas separadas;
- Para calcular quantas ondas em cada camada e qual é a sua amplitude.
Agora, mais sobre cada estágio: para obter um sinal intermediário, você precisa tomar a derivada do sinal original. Em essência, isso é um derivado de uma função discreta. Para encontrá-lo para cada momento do sinal original, você precisa definir 1 parâmetro: o período em que esta derivada está localizada. O valor derivado é o coeficiente de inclinação em um determinado intervalo, por exemplo, pode ser encontrado pelo método dos mínimos quadrados.
É necessário calcular 8 sinais intermediários com 8 períodos diferentes. O conjunto mais simples de períodos: 4, 8, 16, 32, 64, 128, 256, 512. Quando um período é especificado, para cada amostra de sinal, a derivada é calculada usando a fórmula dos mínimos quadrados. É como uma média móvel, mas aqui não é uma média móvel, mas uma derivada móvel do intervalo atual.
Assim, são obtidos 8 sinais derivados e 1 fonte. Agora, cada um dos 8 sinais derivativos precisa ser integrado. Nesse caso, isso significa que cada amostra subsequente é igual à soma de todas as amostras anteriores. Depois disso, são obtidas 8 camadas intermediárias.
O próximo passo é obter camadas que podem ser separadas em ondas separadas. Então agora você precisa obter 8 camadas. Camadas são calculadas assim:
camada 0 = sinal intermediário de saída 0
camada1 = intermediário1-intermediário0
camada2 = intermediário2-intermediário1
camada3 = intermediário3-intermediário2
camada4 = intermediário 4-intermediário3
camada5 = intermediário5-intermediário4
camada6 = intermediário6-intermediário5
camada7 = intermediário 7-intermediário6
layer8 = intermediário7
A última camada não é uma diferença, mas simplesmente é igual ao último sinal intermediário.
Você pode tentar diferentemente, a saber, calcular sinais intermediários subsequentes dos sinais intermediários anteriores. Mas no programa atual, 1 opção é usada.
Agora, para analisar camadas em ondas separadas, você só precisa calcular as áreas em que os valores aumentam e onde diminuem. Na verdade, a duração das seções é o comprimento de onda. Seções do sinal em que os valores do sinal são constantes, basta pular. Para encontrar a amplitude do sinal no espectro em um determinado intervalo, você precisa adicionar todas as amplitudes de onda multiplicadas pelo seu comprimento.

O código que calcula o sinal intermediário é assim:
aqui tamanho da onda é o número de amostras
signal [] - matriz com o sinal original
SY = 0, SX = 0, SXX = 0, SXY = 0, Ky = 0 - variáveis do tipo float
Etapa 2 = PASSO / 2 em que PASSO é o período (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; }
Para subtrair um sinal de outro, basta subtrair cada amostra de cada.
Por exemplo, para a camada 0:
for(int i=0;i<wavesize-1;i++) layer0[i]=OutSignal0[i]-Signal[i];
Se você somar todas as camadas e pegar a última com o sinal oposto, obtém o sinal original, multiplicando assim qualquer camada, é possível criar um filtro de frequência. A próxima pergunta é como calcular as amplitudes de harmônicos específicos. O fato é que, em um intervalo constante, por exemplo = 4000 amostras, pode haver muitas ondas curtas e relativamente poucas longas.
Obviamente, você pode encontrar as amplitudes médias para cada camada e adicionar. Mas esse método não é muito bom, uma vez que existem muito poucas ondas longas, e sua amplitude é geralmente muito grande, e uma forte uniformidade de amplitude é obtida em baixas frequências.
Em um programa que exibe músicas coloridas por links, a amplitude de cada harmônica é calculada como: a amplitude da onda * seu comprimento. Mesmo assim, surge uma desigualdade, mas não tão forte quanto no caso da média.
Em geral, não acho que uma pessoa perceba o som como uma decomposição em um espectro; o som consiste em imagens sonoras, que consistem em ondas de comprimentos diferentes. Consequentemente, o volume de um som é mais o volume médio de todas as ondas nas quais o som consiste. Mas ainda não está claro quais parâmetros compõem a imagem do som, talvez a frequência média, o desvio padrão ou qualquer outra coisa.