Jump to content

[Ajuda] Obter a index referente à batida da música


Recommended Posts

  • Other Languages Moderators

Desisto de tentar por mim mesmo!

Então, é o seguinte, quero [título]. Já tentei de diversas formas e sempre retorna com um pouco de voz, quero apenas a batida. Usei todos os iSamples disponíveis e calculei diversas vezes o iBands, porém sempre tem voz no meio.

local self.fftData = getSoundFFTData( self.sound, 4096, 256 ); -- // faço isso pra obter o gráfico do som

if ( self.fftData ) then
	local beat = math.sqrt( self.fftData[ 8 ] ) * 256;
	-- // meu código abaixo (não irei mostrar o código todo, pois não é preciso)
end

Fiz um gráfico com dx-rectangle pra tentar ver qual seria a index do "beat", tentei a 8, mas ainda tem voz. Talvez o problema seja com o valor definido de iSamples ou iBands, não sei muito sobre essas parada de música.

Link to comment

Isso não é minha área, não sei nem o que é iSamples ou iBands :lol:. Mas creio que com essas funções não tem essa separação de batida e voz, provavelmente seja por frequência/amplitude, ou seja, em diferentes sons tais valores serão alterados, não tendo um padrão específico para conseguir diferenciar a voz de uma batida. Imagino que para conseguir fazer o que quer, seja necessário estudar muito sobre acústica, além de deter conhecimento para conseguir implementar algum algoritmo bem complexo que faça essa identificação (ou encontrar algum).

  • Like 1
Link to comment
  • Other Languages Moderators

Não creio que seja possível fazer isso. Pelo menos não por métodos comuns. Programadores experientes já tentaram fazer isso pra sincronizar luzes do cinema com o áudio do vídeo mas não conseguiram. Vc está tentando algo que somente gênios poderiam conseguir.

--------------------------

Fui procurar na Wiki e encontrei isto: https://wiki.multitheftauto.com/wiki/GetSoundBPM

Batidas por minuto, é isso que vc queria?

Edited by Lord Henry
  • Like 1
Link to comment
  • Other Languages Moderators

Muitíssimo obrigado pelas respostas. Acho que eu não expliquei direito o que realmente eu quero fazer, é algo bem simples na real e eu já fiz diversas vezes. O problema não é como fazer, mas sim calcular certo. Fiz um vídeo rápido pra mostrar. Criei a imagem do auto-falante só pra mostrar a vocês.

Então, como vocês perceberam, ao iniciar a música, apenas com as frequências mais graves, o tamanho da imagem sincroniza perfeitamente com a batida da música (usei cálculo simples pra isso). MAAAAS, quando a música começa com as outras frequências baixas, fica uma junção no auto-falante de 'frequências altas + frequências baixas'. É aí que tá. Queria apenas as frequências altas, para que o sincronismo da batida seja perfeito. Irei usar isso para outras coisas, não só com imagens.

O código tá dessa forma:

-- // rodapé - ícone do auto-falante
	if ( theSound ) then
		local fft = getSoundFFTData( theSound, 2048, 2 );
		
		if ( fft ) then
			rot = rot + 5;
			
			local h = math.sqrt( fft[ 1 ] ) * 24;
			
			if ( h > 0 ) then				
				dxDrawImage( sX + 180 - ( h / 2 ), sY + panel_size[ 2 ] - 65 - ( h / 2 ), 8 + ( h ), 8 + ( h ), "images/speaker.png", rot );
				dxDrawImage( sX + 180 - ( h / 2 ), sY + panel_size[ 2 ] - 65 - ( h / 2 ), 8 + ( h ), 8 + ( h ), "images/speaker.png", rot );
			end
		end
	end

Defini o terceiro parâmetro da função getSoundFFTData para 2, pois achei que retornaria apenas o valor 1 como frequência alta, porém acho que estou errado.

Link to comment

Dei uma lida na wiki e vi que ele já ordena por frequência: da mais baixa, para a mais alta (de determinado quadro em execução do som):
“A fast fourier transform generates a table of all the frequencies of the current audio frame which starts at the bass end of the spectrum to mids to highs in that order“ - by Wiki

Possivelmente se você fizer isso:

local tbl = getSoundFFTData ( som, 512 ) --retorna o total de samples/2 = 512/2 => 256
print(tbl[256])

Ele retornará o valor mais alto dessa amostra de 512 “faixas”. 

Agora, quando a gente define o iBands, se você usar um valor baixo, ex: 2, ele “junta” essas 512 faixas em apenas duas, e por isso dá essa “mistura” da batida com a voz, pois foram colocadas em um mesmo conjunto (possivelmente metade com frequência mais baixa, e outra com a mais alta). Se eu fosse você, eu tentaria aumentar o número de iBands e utilizaria esse valor definido para trabalhar apenas com as frequências mais altas.

p.s. Existe a função getSoundWaveData que talvez dê também para usar.

  • Thanks 1
Link to comment
  • Moderators

Mas a questão não vai ser > Como saber quais frequências vai ser necessário remover para chegar ao som ideal? Ou seja, apenas batidas.

Eu sou um leigo nesse assunto também, posso estar dando informação errada, mas acho que pra isso, você vai precisar pegar todas essas frequências e fazer uma análise para julgar aquelas que não fazem parte da batida. E isso não se resume em frequências altas e baixas - cada frequência reproduz certo som (foi o que entendi lendo um pouco sobre o assunto).

Acho que fazer isso de uma forma 100% efetiva pra todos sons é quase impossível, se for para ajustar alguns sons/músicas especificas pode ser mais fácil pra quem não é expert no assunto. Embora tudo isso possa ser mais fácil do que eu imagino, já que hoje em dia encontra-se de tudo na internet xd

  • Like 1
Link to comment
  • Other Languages Moderators

Valeu pela explicação, @MaligNos. Realmente era necessário aumentar o valor do iBands, também fiz uma modificação que não entendi muito bem o porquê que isso fez dar certo. Removi a função matemática 'math.sqrt', deixei apenas o fft[ 1 ] * largura_máxima_da_imagem. Agora o código tá dessa forma:

-- // rodapé - ícone do auto-falante
	if ( theSound ) then
		local fft = getSoundFFTData( theSound, 2048, 512 );
		
		if ( fft ) then
			rot = rot + 8;
			
			local h = fft[ 1 ] * 20;
			
			if ( h > 0 ) then				
				dxDrawImage( sX + 180 - ( h / 2 ), sY + panel_size[ 2 ] - 65 - ( h / 2 ), 12 + ( h ), 12 + ( h ), "images/speaker.png", rot );
			end
		end
	end

Nem mesmo uma voz ou ruído faz a imagem do auto-falante aumentar, apenas quando há batida. Esses negócios são loucos, mas pelo menos consegui entender de certa forma.

@EDIT: Usei essa mesma linha de raciocínio em um shader no veículo, pra deixar a opacidade da cor mais forte e deu super certo. Quando dá uma batida, a cor fica mais forte, ao contrário fica com menos opacidade. Também consegui realizar alguns algoritmos para os DVOs.

  • Like 1
Link to comment
  • Moderators
5 minutes ago, asrzk said:

Valeu pela explicação, @MaligNos. Realmente era necessário aumentar o valor do iBands, também fiz uma modificação que não entendi muito bem o porquê que isso fez dar certo. Removi a função matemática 'math.sqrt', deixei apenas o fft[ 1 ] * largura_máxima_da_imagem. Agora o código tá dessa forma:


-- // rodapé - ícone do auto-falante
	if ( theSound ) then
		local fft = getSoundFFTData( theSound, 2048, 512 );
		
		if ( fft ) then
			rot = rot + 8;
			
			local h = fft[ 1 ] * 20;
			
			if ( h > 0 ) then				
				dxDrawImage( sX + 180 - ( h / 2 ), sY + panel_size[ 2 ] - 65 - ( h / 2 ), 12 + ( h ), 12 + ( h ), "images/speaker.png", rot );
			end
		end
	end

Nem mesmo uma voz ou ruído faz a imagem do auto-falante aumentar, apenas quando há batida. Esses negócios são loucos, mas pelo menos consegui entender de certa forma.

@EDIT: Usei essa mesma linha de raciocínio em um shader no veículo, pra deixar a opacidade da cor mais forte e deu super certo. Quando dá uma batida, a cor fica mais forte, ao contrário fica com menos opacidade. Também consegui realizar alguns algoritmos para os DVOs.

Boa, já testou com outros sons de batidas ou foi só 1? Provavelmente nesse caso foi mais fácil pois o contraste entre os sons da batidas e de fundo são fáceis de se distinguir.

Link to comment
17 minutes ago, DNL291 said:

Mas a questão não vai ser > Como saber quais frequências vai ser necessário remover para chegar ao som ideal? Ou seja, apenas batidas.

Eu sou um leigo nesse assunto também, posso estar dando informação errada, mas acho que pra isso, você vai precisar pegar todas essas frequências e fazer uma análise para julgar aquelas que não fazem parte da batida. E isso não se resume em frequências altas e baixas - cada frequência reproduz certo som (foi o que entendi lendo um pouco sobre o assunto).

Acho que fazer isso de uma forma 100% efetiva pra todos sons é quase impossível, se for para ajustar alguns sons/músicas especificas pode ser mais fácil pra quem não é expert no assunto. Embora tudo isso possa ser mais fácil do que eu imagino, já que hoje em dia encontra-se de tudo na internet xd

Sim, a questão de conseguir separar o vocal das batidas é algo bem complexo. Sugeri ali um meio de conseguir trabalhar apenas com as frequências mais altas (pode ter voz), pois ali no exemplo em que ele coloca 2 (iBands) ocorre essa “junção”, por isso o ícone de auto-falante dele mexe mesmo com frequências não tão altas.

Link to comment
  • Other Languages Moderators
Just now, DNL291 said:

Boa, já testou com outros sons de batidas ou foi só 1? Provavelmente nesse caso foi mais fácil pois o contraste entre os sons da batidas e de fundo são fáceis de se distinguir.

@DNL291 Testei com alguns gêneros músicas. Eletrônica (Psytrance, Hardstyle), Rock e Funk. Algumas músicas desses gêneros não tinham batidas, logo o auto-falante não aumentou de tamanho. No gênero Hardstyle, como há muitas batidas, funcionou perfeitamente.

Link to comment
21 minutes ago, asrzk said:

Valeu pela explicação, @MaligNos. Realmente era necessário aumentar o valor do iBands, também fiz uma modificação que não entendi muito bem o porquê que isso fez dar certo. Removi a função matemática 'math.sqrt', deixei apenas o fft[ 1 ] * largura_máxima_da_imagem. Agora o código tá dessa forma:


-- // rodapé - ícone do auto-falante
	if ( theSound ) then
		local fft = getSoundFFTData( theSound, 2048, 512 );
		
		if ( fft ) then
			rot = rot + 8;
			
			local h = fft[ 1 ] * 20;
			
			if ( h > 0 ) then				
				dxDrawImage( sX + 180 - ( h / 2 ), sY + panel_size[ 2 ] - 65 - ( h / 2 ), 12 + ( h ), 12 + ( h ), "images/speaker.png", rot );
			end
		end
	end

Nem mesmo uma voz ou ruído faz a imagem do auto-falante aumentar, apenas quando há batida. Esses negócios são loucos, mas pelo menos consegui entender de certa forma.

@EDIT: Usei essa mesma linha de raciocínio em um shader no veículo, pra deixar a opacidade da cor mais forte e deu super certo. Quando dá uma batida, a cor fica mais forte, ao contrário fica com menos opacidade. Também consegui realizar alguns algoritmos para os DVOs.

Seguindo a lógica que imaginei seria utilizado algo como fft[ 512 ] no lugar do fft[ 1 ]. Mas se está pegando como queria então não sei de mais nada kkk

Pois imaginava que conforme fosse aumentando o iBand(n), juntamente com o fft [ n ], fosse perdendo frequências cada vez mais altas

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...