Moderadores: andre_luis, 51, guest2003, Renie
O La de um violao equivale o lá da 5° oitava de um piano.. 440hz...
Ja o da guitarra esta ainda mais alto, e do violino ainda mais alto..
tem que partir para ponto flutuante mesmo...e isso prova definitivamente que nao tem como fazer usando um pic programado em asm!
void timer1 (void) interrupt 1
{
#define TABLE_SIZE (sizeof(bin_data))
#define MAX_INDEX (TABLE_SIZE-1)
#define FA (TAXA_AMOSTRAGEM-1)
#define QTD_FREQ (3)
static u16 u16_count;
static u16 u16_fi[QTD_FREQ];
static u16 u16_f[QTD_FREQ] = {
60,
697,
1209
};
u8 u8_i;
u16 u16_sum = 0;
TL0 = RELOAD_LO;
TH0 = RELOAD_HI;
/* 0...(TAXA_AMOSTRAGEM - 1) */
++u16_count;
u16_count &= FA;
for (u8_i = 0; u8_i < QTD_FREQ; u8_i++)
{
u16_fi[u8_i] = (u16) (((u32) (u16_count * u16_f[u8_i])) & MAX_INDEX);
u16_sum += bin_data[u16_fi[u8_i]];
}
P0 = bin_data[u16_fi[0]];
P1 = bin_data[u16_fi[1]];
P2 = bin_data[u16_fi[2]];
P3 = (u8) (u16_sum / QTD_FREQ);
}
Marcelo Samsoniuk escreveu:vou colocar uma versao com comentarios e testada no linux:
- Código: Selecionar todos
#include <stdio.h>
#include <math.h>
int main()
{
FILE *fp; // file descriptor para placa de som no linux
int i, s0, s1, k1, k2; // variaveis todas int de 32 bits
char saida, table[256]; // wavetable qq, no exemplo uma senoide
for(i=0;i!=256;i++) // inicializa wavetable com senoide
{
table[i] = (char)(127*sin(i*2.0*M_PI/256.0));
}
fp = fopen("/dev/dsp", "w"); // abre a placa de som
if(fp) // se abrir, roda o codigo, senao vai embora
{
k1 = (256*697)/8000; // k1 de linha 1 697hz
k2 = (256*1209)/8000; // k2 de coluna 1 1209hz
// 1,1 corresponde ao DTMF "1"
printf("coeficientes: 697Hz => %d, 1209Hz => %d\n",k1,k2);
for (i = 0;; i++) // loop eterno
{
s0 = table[(unsigned char) (i*k1)]; // primeiro resultado
s1 = table[(unsigned char) (i*k2)]; // segundo resultado
saida = (s0 + s1) / 2; // mixer simples
fputc(saida+128, fp); // envia para a placa de som
// a soma +128 no envio eh necessario
// pq a placa trabalha com pcm nao
// sinalizado, mas para processar audio
// *sempre* use sinalizado
}
}
return -1; // retorna erro se nao conseguir abrir o arquivo
}
para minimizar o problema de overflow, eu calculei o coeficiente antes e multipliquei depois... o problema eh que a menor frequencia vai ser 32Hz (coeficiente 1), enquanto que na maior frequencia (1/4 do sample rate) vc vai ter coeficiente 64, ou seja, na pratica vc soh gera 64 frequencias diferentes na faixa de 32 a 2000Hz.
trocando para:
- Código: Selecionar todos
k1 = (256*697); // k1 de linha 1 697hz
k2 = (256*1209); // k2 de coluna 1 1209hz
e tambem:
- Código: Selecionar todos
s0 = table[(unsigned char)((i*k1)/8000)]; // primeiro resultado
s1 = table[(unsigned char)((i*k2)/8000)]; // segundo resultado
voce garante capacidade de gerar corretamente de 1 a 2000Hz. porem comeca a ocorrer um overflow periodico, pois os coeficientes variam de 256 a 512000, ou seja, o coeficiente consome 19 bits, sobrando entao apenas 12 bits para o contador i, de modo que ele faz overflow em apenas 4096 contagens (quase 2x por segundo!). mas se vc declarar i como uma variavel long long de 64 bits, o overflow ira demorar alguns anos para ocorrer.
outra alternativa eh usar ponto flutuante:
- Código: Selecionar todos
float k1,k2;
...
k1 = 256.0*697.0/8000.0; // k1 de linha 1 697hz
k2 = 256.0*1209.0/8000.0; // k2 de coluna 1 1209hz
...
s0 = table[(unsigned char)((int)(i*k1))]; // primeiro resultado
s1 = table[(unsigned char)((int)(i*k2))]; // segundo resultado
daih fica similar ao primeiro caso lah em cima, soh que agora os coeficientes variam de 0.032 a 64 com grande precisao. usando ponto flutuante de precisao simples, vc consegue sintetizar qq frequencia corretamente e o overflow do inteiro i vai ocorrer apenas depois de 2h de sintese continua da frequencia maxima.
uma forma de resolver o problema de overflow dos indices seria tambem usar um indice separado para cada canal, porem todos incrementando de forma sincronizada de acordo com o sample rate... fica como licao de casa para vc testar issohehehe
só pra esquentar a "briga lá é lá"
a frequencia fundamental de uma nota é mesma em qualquer instrumento.
oque muda é o timbre(ou se quiser chamar forma de onda, serie de harmonicos, componentes como: atack, decay, etc.)
Agora, o lá da guitarra, equivale a frequencia de qual 8° do piano
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante