Frequência de um acorde

Autor Mensagem
mjcmello
Veterano
# set/12
· votar


Spiderpoison
Estes dias estou tentando descobrir se é possível calcular a frequência de um acorde.

Um exemplo:
Dó = 263.63
Mi = 329.63
Sol = 391.99


Só pra dar um pitaco. O próprio instrumento, quando geramos uma nota apenas, gera uma série de harmónicos múltiplos da frequência. É isso que determina o timbre.

Então, cada uma destas notas vai gerar seus respectivos harmônicos e assim compor o acorde. A forma de onda (no que chamamos domínio do tempo) vai ser a sobrbosição de senóides nestas frequências.

Não existe uma frequência resultante. Todas elas estão lá. O alto falante pode "filtrar" algumas delas (diminuir algumas), mas elas continuarão lá.

Spiderpoison
Veterano
# set/12
· votar


mjcmello - Pois é, eu consegui entender bem o processo quando realizei testes criando tons em faixas distintas no Audacity e mixando as faixas para formar acordes conhecidos, o resultado foi um encapsulamento das frequencias resultando em uma nova periódica com todas elas lá.
Agora estou voltando aos estudos básicos para relembrar um pouco de trigonometria e entender o processo todo de uma forma mais aprofundada.

Spiderpoison
Veterano
# set/12
· votar


Galera, para quem está estudando sobre o assunto também eu achei uma ferramenta bem legal criada pelo MIT ... Com ela é possível simular visualmente a somatória das ondas.

http://ocw.mit.edu/ans7870/18/18.06/javademo/FourierSeries/

Scrutinizer
Veterano
# set/12
· votar


Spiderpoison
Cara, talvez você possa usar uma linguagem específica pra síntese de áudio com o arduino, tipo SuperCollider ou CSound, eles tem as funções para senóides e funções muito mais complexas prontinhas pra você, agora o negócio é achar informações sobre isso, dei uma pesquisada rápida e pelo menos sei que existe essa possibilidade.

Spiderpoison
Veterano
# set/12
· votar


Scrutinizer - acho que não vai dar muito trabalho não, eu tinha imaginado mais ou menos como fazer mas mataram a pau no fórum do Arduino.

http://arduino.cc/forum/index.php/topic,121599.15.html

Ainda não testei mas acho que pode funcionar.

Luiz_RibeiroSP
Veterano
# set/12
· votar


Spiderpoison
Esse programinha em java, feito pelo MIT, é bem legal, mas quanto tentei colocar a equação que passei, o negocio travou 0_o...mas o excel faz isso também. Procura um simulador de circuitos que chama PSpice, vai ajudar.

Spiderpoison
Veterano
# set/12
· votar


Pessoal acho que cheguei a uma solução, ainda preciso acertar algumas coisas no projeto acertar a duração das notas, mas basicamente eu consegui misturar as frequências da seguinte forma.

void toca(int n1, int n2, int n3){
for (int i=0;i<100;i++){
digitalWrite(3,HIGH);
delayMicroseconds(n1);
digitalWrite(3,LOW);
delayMicroseconds(n1);
digitalWrite(3,HIGH);
delayMicroseconds(n2);
digitalWrite(3,LOW);
delayMicroseconds(n2);
digitalWrite(3,HIGH);
delayMicroseconds(n3);
digitalWrite(3,LOW);
delayMicroseconds(n3);
}
}

void setup(){
pinMode(3,OUTPUT);
}

void loop(){
toca(1915,1519,1275);
delay(100);
toca(1915,1607,1275);
delay(1000);
}

o 'n', a duracao do pulso pode ser calculado usando essa referência:
http://arduino.cc/playground/Portugues/LearningMelody

Luiz_RibeiroSP
Veterano
# set/12
· votar


Spiderpoison
Mas a saída vai ser uma onda quadrada, que possui vários harmônicos somados, acho que mai do que um acorde com 3 ou 4 notas.
Considerando que uma nota é uma senoide, agora não sei se esta consideração é valida. Quado pensei no projeto, imaginei o uso de um falante com bobina(indutivo). o buzzers é piezoeléctrico, acho que ele não reproduz senoides.
Preciso pesquisar mais porque não mexi muito com uma aplicação dessas, mas depois gere apenas uma nota e coloca um afinador na saída. se der certo manda reproduzir um acorde.
O ideal era usar um analisador de espectros, para poder ver a decomposição do som e analisar os harmônicos separados para saber se esta saindo um acorde. Mas ai ...

shoyoninja
Veterano
# set/12 · Editado por: shoyoninja
· votar


O alto falante não vibra com uma frequencia por vez, o cone tem sua posição instantanea determinada pela forma de onda do sinal, que é a soma dos 3 sinais no caso.

Desde de que as 3 notas sejam senóides simples, eh relativamente facil simular.

Aliás eh ridiculo simular. Abra o Reaper, crie 3 tracks com o ReaSynth emitindo uma senóide em cada nas notas que você quer e faça um bounce da mix. Eh só dar um zoom na forma de onda, eh isso que seu alto falante vai fazer.

Luiz_RibeiroSP
Veterano
# set/12
· votar


shoyoninja
Sim, o cone tem sua posição instantânea determinada pelo valor da somatória dos sinais....mas não sei se um alto falante piezoelétrico faz isso com a mesma precisão de um indutivo.

shoyoninja
Veterano
# set/12
· votar


Nem um nem o outro são precisos, vai haver distorção.

Spiderpoison
Veterano
# set/12
· votar


pois é o resultado não foi uma onda como a esperada, mas achei uma forma de visualizar a onda gerada pelo microcontrolador, é só gravar em um sampler do som e analisar em um editor de áudio.
O que notei é que da forma que eu montei a onda fica uma serra, aprimorando um pouco mais eu consegui achar uma outra forma de escrever a função e talvez corrigir o desenho da curva.

dentro do while estou testando:

int saida= (((sin(3.1415+f1) + sin(2*3.1415+f2) + sin(3*3.1415+f3))*42)+126);
digitalWrite(3,HIGH);
delayMicroseconds(saida);
digitalWrite(3,LOW);
delayMicroseconds(saida);
digitalWrite(3,HIGH);

confesso que os resultados são interessantes ...

shoyoninja
Veterano
# set/12 · Editado por: shoyoninja
· votar


Ok, maninho vc falou em microcontrolador agora hehe. Me conta o que vc está fazendo e como por favor. Esses digital write que vc está fazendo estão controlando o que?

Se agora vc está modulando o delay com o seno de pi somado a f1 que imagino que seja frequencia, o que vc espera que isso faça?

Vc tem uma função tmb que gera uma determinada frequencia sozinha certo? Vc que havia feito ela? Ou eh parte de alguma lib?

Spiderpoison
Veterano
# set/12
· votar


shoyoninja - A idéia é um projeto que gere notas e acordes aleatórios para treino de ouvido absoluto. Estou usando o Arduino (www.arduino.cc) Barateei muito o projeto, por isso a qualidade do som é meio limitada. Os digitalWrite estao controlando os pulso da porta PWM.

Neste link tem um exemplo da função que estou usando como modelo para gerar as notas: http://arduino.cc/playground/Portugues/LearningMelody

Para gerar uma frequência no Arduino você pode usra uma função nativa tone(pino,frequencia Hz,duracao ms).
Mas também da para simular como o tutorial que passei.

Na minha logica, a cada ciclo do micro ele toca uma das 3 notas do acorde por milésimos de segundo, isso simula uma somatória das notas formando uma onda triangular (isso se eu tiver certo).

El_Cabong
Veterano
# set/12
· votar


Um acorde consiste NO MÍNIMO de três ondas senóides de frequências diferentes (que juntas resultam num som "agradável" aos ouvidos). As notas se somam vetorialmente, e isso resulta numa onda complexa.

Se considerar que as notas deste acorde não são senóides simples e sim algo mais complexo cheio de harmônicas (como é o caso real dos instrumentos acústicos) o resultado final só tende a ficar mais complexo.

Eu diria que um acorde, é uma onda contendo inúmeras frequências (não existe A FREQUENCIA do acorde).

Spiderpoison
Veterano
# set/12
· votar


El_Cabong - a sim, essa conclusão já ficou para trás quando li sobre a Serie de Fourier, o que resta agora é achar uma forma de somar as senóides para formar o encapsulamento de frequências.

A onda não necessita ser necessariamente uma senóide, pode ser uma onda retangular, dente de serra ou triangular também.

Luiz_RibeiroSP
Veterano
# set/12
· votar


Spiderpoison
porque colocou um 3 multiplicando no seno? -> sin(3*3.1415+f3)
e em outra equação colou sói o pi?

esta usando um conversor D/A na saída?

shoyoninja
Veterano
# set/12 · Editado por: shoyoninja
· votar


Ta agora entendi... Nao vai dar certo dessa forma, esse metodo que vc esta usando esta apenas emitindo pulsos em uma determinada frequencia. Pra fazer o que vc quer, vc precisaria usar modulacao pwm, nao eh a mesma coisa. Cada pulso desses tem um monte de harmonicos, gera um sinal assimétrico, muito longe de senoidal.

A função pwm desse modulo usa 500hz como frequencia de base para modulação, Isso eh muito baixo... Vc vai ficar limitado a 200hz e com muita degradação de qualidade.

Vc poderia montar um algoritmo para fazer o pwm usando o digitalwrite, se ele consegue chavear com esse delay de microsegundos. Mas eu acho que nao eh o caso.

Nao vai rolar velhinho. Eh como tentar simular polifonia com uma bexiga, estreitando a ponta.

Spiderpoison
Veterano
# set/12
· votar


Luiz_RibeiroSP - Coloquei os números para teste, estou fazendo experimentações para ver os resultados baseados em algumas ideias que tive estudando as teorias.
A saída não está usando um conversor digital ... vou ver se se faço um sampler do meu teste e disponibilizo.

Spiderpoison
Veterano
# set/12
· votar


shoyoninja - Então eu até consegui gerar os acordes usando o 1 método, mas o som está ruim. Vou voltar a dar uma lida e ver se acho alguma outra forma.

Como está até da para identificar o acorde, mas ainda não vi se está batendo 100%.

shoyoninja
Veterano
# set/12
· votar


Então, se vc trabalhar com pulsos esquecer a senoide da pra fazer algo sim.

Quantize tudo usando duração minima que um pulso possa ter, e monte uma função para fazer um stream desses dados parAa a portA de saida.

Da forma que esta, vc esta alternando os pulsos ao inves de gerar todos ao mesmo tempo.

Ou ainda melhor.

Calcule a distancia e monte o padrao de pulsos de uma vez soh, usando soh o desvio de um para o outro.

Luiz_RibeiroSP
Veterano
# set/12 · Editado por: Luiz_RibeiroSP
· votar


shoyoninja
Mas sem um A/D essa equação que passei não vai ter efeito. A ideia é o arduino calcular o valor instantâneo da função e enviar os valores com 8 bits, para a porta de saída, depois o conversor vai transformar esses números binários em um valor de tensão. O que você esta fazendo é modular em PWM, um sinal na saída, mas pelo que passou da programação, esse sinal não vai variar com a equação


void toca(int n1, int n2, int n3){
for (int i=0;i<100;i++){ // faz essa rotina 100 vezes
digitalWrite(3,HIGH); // nivel logico 1(5V) no pino 3
delayMicroseconds(n1); // espera n1 microssegundos
digitalWrite(3,LOW); // nivel logico 0 no pino 3
delayMicroseconds(n1); // espera n1 microssegundos

//mesma analogia para o resto do programa
digitalWrite(3,HIGH);
delayMicroseconds(n2);
digitalWrite(3,LOW);
delayMicroseconds(n2);

digitalWrite(3,HIGH);
delayMicroseconds(n3);
digitalWrite(3,LOW);
delayMicroseconds(n3);
}
}
Vamos supor de n1=1, n2=2, e n3=3 na saida do pino você vai ter uma onda quadrada assim

--_----__------___ se repetindo 100x
11 2__2__3__3

shoyoninja
Veterano
# set/12 · Editado por: shoyoninja
· votar


Huummm nao, nao funciona.

Pensei no seguinte, fazer a funcao (sen(Pi F1 t)+sen(Pi F2 t)+sen(pi f3 t)) em funçao de t, em segundos, e toda a vez que o resultado passar pelo 0, inverter a saída. Quantizando em microsegundos.

Isso vai plotar um cópia, digamos preto e branco, do sinal.

O pwm não seria rápido o suficiente para alimentar o DAC.

Assim vc elimina o elemento supresa de saber o delay de chaveamento do DAC, mas fica com um problema sério de timming, vc precisaria ter acesso a algum tipo de relógio para referenciar o loop principal.

Spiderpoison
Veterano
# set/12
· votar


Então Luiz_RibeiroSP, foi exatamente uma das conclusões que cheguei, a única diferença da minha fórmula final é que eu oitavei a terça e a quinta para pegar a frequência harmônica dessa notas. Meu 'i' está sendo calculado pelo ciclo do arduino, sendo assim não precisa do for. Da uma olhada, coloquei link para o audio também.

#define C 1897
#define Ds 1607
#define E 1517
#define G 1276

void toca(int f1, int f2, int f3, int duracao){
duracao=duracao/10;
int i=0;
while (i<duracao){
digitalWrite(3,HIGH);
delayMicroseconds(f1/2);
digitalWrite(3,LOW);
delayMicroseconds(f1/2);
digitalWrite(3,HIGH);
delayMicroseconds(((f2+f1)/2)^2);
digitalWrite(3,LOW);
delayMicroseconds(((f2+f1)/2)^2);
digitalWrite(3,HIGH);
delayMicroseconds(((f3+f2)/2)^3);
digitalWrite(3,LOW);
delayMicroseconds(((f3+f2)/2)^3);
i++;
}
}

void setup(){
pinMode(3,OUTPUT);
Serial.begin(9600);
}

void loop(){
toca(C,E,G,1000);
toca(C,Ds,G,1000);
}

resultados:

Dó maior - http://flxsys.com.br/do_maior_arduino.mp3
Dó maior e dó menor - http://flxsys.com.br/arduino_teste.mp3
440Hz -referência - http://flxsys.com.br/la_arduino.mp3

esperado:
http://flxsys.com.br/do_maior_gerador.mp3

shoyoninja
Veterano
# set/12
· votar


Está errado... A soma dos tres sinais nao eh um periodo de cada frequencia depois do outro. A interação dos três leva bem mais do que a soma dos três periodos pra se resolver. Além de não resultar em polifonia, ainda está gerando um sinal com freqüência diferente das 3 iniciais.

Spiderpoison
Veterano
# set/12
· votar


shoyoninja - Sim, eu consegui entender isso, que não é um período de cada frequência, mas foi o mais próximo que consegui chegar até o momento, o que eu estou buscando é justamente a formula para juntar estas 3 notas gerando um acorde.
Segundo eu entendi a frequência no momento X deve ser a resultante da Serie de Fourier?

shoyoninja
Veterano
# set/12
· votar


Eu escrevi a formula ali... eh a soma das funções seno em função do tempo, soh isso.

Spiderpoison
Veterano
# set/12
· votar


shoyoninja - Hum, eu via formula (sen(Pi F1 t)+sen(Pi F2 t)+sen(pi f3 t)), até testei, mas acho que o problema é o PWM não ser rápido como você comentou.

Spiderpoison
Veterano
# set/12
· votar


Pode ser feito, só vou demorar para entender.

http://www.cs.nott.ac.uk/~jqm/?p=605

shoyoninja
Veterano
# set/12
· votar


Tem que dar na mesma....

Vc monta função f(t) = sen(2π•f1•t)+sen(2π•f2•t)+..., detecta se f(t) eh maior que zero, digitalwrite HIGH, senão digitalwrite LOW.

Ou caso isso gere ruído, estabeleça um controle e faça o digitalwrite apenas quando for necessário.

O loop deve ocorrer em um timming específico, seria bom usar um timer.

Se cada iteração tiver um frame de 10microssegundos, t sendo incrementado como contador unitário, adeque a função, sen(2π•f•t÷100000). Entendeu?

Ai basta vc achar um jeito de garantir que cada iteração vai durar exatos 10 microssegundos, se vc tem a função de delay, deve ter acesso a alguma variável de timer também.

Enviar sua resposta para este assunto
        Tablatura   
Responder tópico na versão original
 

Tópicos relacionados a Frequência de um acorde