Encontre músicas semelhantes usando o FFT Spectrums

16

Tenho experimentado algumas semanas para encontrar uma maneira de combinar / encontrar músicas semelhantes em uma biblioteca contendo diferentes gêneros de música.

Minha primeira tentativa foi detectar recursos como tempo ou quanto baixo há nas músicas para formar grupos, mas eu não fui muito longe com essa abordagem (detecção de batidas com base em alterações de volume), já que cerca de 20% das músicas batidas não precisam ser contadas sempre, às vezes 1/2 ou 1/3 deles e eu não conseguia implementar isso.

Após algumas semanas de tentativas fracassadas, tive uma nova idéia, descrita mais adiante neste Post. Simplificando, funciona usando amostras de arquivos do Spectrum, criando algo como um "espectro médio" de arquivos para compará-los. A idéia por trás disso era que, por exemplo, o Hardstyle tem muito mais baixo do que o rock médio, eu também verifiquei isso observando alguns Spectrums no Audacity.

  • Arquivo 1: Obtenha espectros completos de FFT de arquivo (tamanho da amostra de 2048 atm, log de amplitudes dimensionado)
  • Soma todas as matrizes de espectro, faça a média de cada bin
  • Faça o mesmo em alguns outros arquivos, armazene todos os resultados
  • Criar lista de diferenças de valores FFT entre o arquivo 1 e outros arquivos
  • Faça a média das diferenças entre o arquivo 1 e o arquivo X
  • Classificar em ordem crescente por essas médias
  • Músicas com o "menor valor de diferença" são consideradas semelhantes.

Alguns de vocês, com bom conhecimento, podem me dizer se essa seria a maneira correta / boa de implementar minha idéia?

gfg
fonte
1
Se você está tentando detectar o andamento, pode tentar elevar o sinal e fazer uma transformação de Fourier. Frequências da ordem de 1 Hz não estarão presentes em um espectro FFT comum (sem quartzo), porque são filtradas. Uma ideia relacionada, usada para a detecção de afinação, é chamada de "cepstrum"; você pode descobrir sobre isso pesquisando no Google. Para diferenciar o pop e o jazz do clássico, você pode tentar detectar os sons de uma bateria, que não estão afinados. O vibrato deve ser detectável pela máquina. Existem medidas de dissonância que podem ser computadas na máquina.
1
Talvez você deve perguntar aos moderadores para mover este para dsp.SE
Dilip Sarwate
Sinalizei minha pergunta com pedido para movê-la para DSP do SE. Você quer dizer que eu poderia detectar se há um Drumkit Present ou Não para classificar a Entrada? Você pode explicar como o sinal quadrado leva ao Tempo?
3
A música é gravada e masterizada de maneira a maximizar sua difusão espectral, especialmente nos dias de hoje. Eu não acho que esse espectro completo lhe dê um bom critério para classificar músicas.
Phonon
2
Em vez de espectros, você deve olhar para espectrogramas. Os espectros mostram apenas o conteúdo da frequência de toda a música de uma só vez. Os espectrogramas mostram como o conteúdo da frequência muda ao longo do tempo.
endolith 26/03

Respostas:

17

O que você está tentando fazer foi repetidamente tentado por centenas de pesquisadores e existe um grande corpo de trabalho sobre isso. Verifique os trabalhos da conferência ISMIR. Mesmo que não esteja atualizado, leia a tese de Elias Pampalk: http://www.ofai.at/~elias.pampalk/publications/pampalk06thesis.pdf

Para orientá-lo rapidamente no caminho certo:

A música pode ser semelhante de acordo com várias dimensões: a) timbre / textura / gênero; b) padrão rítmico; c) progressão da melodia / acordes ... e muito mais! Na sua mensagem, não está claro o que você deseja medir!

  • Se você estiver interessado em a), os recursos que você pode querer considerar são os MFCC (Mel Frequency Cepstrum Coefficient), pois eles capturam de alguma maneira a maneira como a audição humana funciona (distorção de frequência, escala de log), uma vez que são correlacionados (facilitando a modelagem) , e uma vez que possuem menor dimensionalidade (13 coeficientes vs 2048).
  • Se você estiver interessado em b), observe um recurso chamado "Padrões de flutuação" (Pampalk, em breve autocorrelação do sinal na faixa de 0,1 .. 10 Hz em algumas bandas); ou os recursos "Penny" de Whitman (FFT do MFCC ao longo do eixo do tempo).
  • Se você estiver interessado em c), observe os cromagrams. Comece com o código de chromagram de Ellis (http://labrosa.ee.columbia.edu/matlab/chroma-ansyn/) e depois vá para a implementação de Mauch se você precisar de algo mais robusto (http://isophonics.net/nnls-chroma )

Isso é para os recursos. Agora você terá que pensar em uma maneira melhor de comparar suas músicas depois que elas forem representadas como uma sequência desses recursos. O cálculo das diferenças entre pares entre as seqüências não é muito inteligente - por exemplo: comparar uma música e a mesma música compensada por algum silêncio produzirá uma diferença enquanto é exatamente a mesma! Você prefere comparar a distribuição desses recursos; por exemplo, calcule o desvio médio / padrão dos recursos em relação à música A e o desvio médio / padrão dos recursos em relação à música B e, em seguida, faça uma distância probabilística (KL, Bhattacharyya sobre esses).

Último ponto, mas que será importante mais tarde: calcular a distância entre uma música e o resto do corpus para encontrar as correspondências mais próximas é bastante ineficiente. Ao lidar com grandes coleções, técnicas como LSH ou árvores Ball permitem que essas consultas de vizinhos mais próximos sejam realizadas sem comparação explícita com todo o corpus.

Como um aparte, a detecção do tempo é uma questão totalmente diferente. Se você quiser investigar, o melhor artigo sobre desempenho / acessibilidade sobre o tema é o Ellis 'Beat Tracking by Dynamic Programming. http://www.ee.columbia.edu/~dpwe/pubs/Ellis07-beattrack.pdf . É incrivelmente simples, mas está próximo dos algoritmos de última geração.

pichenettes
fonte
Obrigado pela sua resposta detalhada, já ouvi falar do MFCC várias vezes neste contexto e parece razoável não usar os resultados da FFT. Parece bastante complexo de implementar com meu atual "estado de conhecimento" e ambiente de desenvolvimento (C #, resultados da FFT da Bass Library), mas tentarei.
GFG