Pergunta
Estou pensando em escrever um sintetizador de áudio em Java e gostaria de saber se alguém tem algum conselho ou bons recursos para escrever tal programa.Estou procurando informações sobre como gerar ondas sonoras brutas, como produzi-las em uma forma utilizável (tocando em alto-falantes), bem como teoria geral sobre o assunto.Obrigado rapazes.
Solução
Este problema é basicamente sobre o mapeamento de funções para matrizes de números.Uma linguagem que suporte funções de primeira classe seria muito útil aqui.
Confirahttp://www.harmony-central.com/Computer/Programming ehttp://www.developer.com/java/other/article.php/3071021 para obter algumas informações relacionadas ao Java.
Se você não conhece os conceitos básicos de codificação de dados sonoros, leia http://en.wikipedia.org/wiki/Sampling_rate
O formato canônico WAVE é muito simples, veja http://www.lightlink.com/tjweber/StripWav/Canon.html.Um cabeçalho (primeiros 44 bytes) + os dados da onda.Você não precisa de nenhuma biblioteca para implementar isso.
Em C/C++, a estrutura de dados correspondente seria mais ou menos assim:
typedef struct _WAVstruct
{
char headertag[4];
unsigned int remnantlength;
char fileid[4];
char fmtchunktag[4];
unsigned int fmtlength;
unsigned short fmttag;
unsigned short channels;
unsigned int samplerate;
unsigned int bypse;
unsigned short ba;
unsigned short bipsa;
char datatag[4];
unsigned int datalength;
void* data; //<--- that's where the raw sound-data goes
}* WAVstruct;
Não tenho certeza sobre Java.Eu acho que você terá que substituir "struct" por "class" e "void* data" por "char[] data" ou "short[] data" ou "int[] data", correspondente ao número de bits por amostra, conforme definido no campo bipsa.
Para preenchê-lo com dados, você usaria algo assim em C/C++:
int data2WAVstruct(unsigned short channels, unsigned short bipsa, unsigned int samplerate, unsigned int datalength, void* data, WAVstruct result)
{
result->headertag[0] = 'R';
result->headertag[1] = 'I';
result->headertag[2] = 'F';
result->headertag[3] = 'F';
result->remnantlength = 44 + datalength - 8;
result->fileid[0] = 'W';
result->fileid[1] = 'A';
result->fileid[2] = 'V';
result->fileid[3] = 'E';
result->fmtchunktag[0] = 'f';
result->fmtchunktag[1] = 'm';
result->fmtchunktag[2] = 't';
result->fmtchunktag[3] = ' ';
result->fmtlength = 0x00000010;
result->fmttag = 1;
result->channels = channels;
result->samplerate = samplerate;
result->bipsa = bipsa;
result->ba = channels*bipsa / 8;
result->bypse = samplerate*result->ba;
result->datatag[0] = 'd';
result->datatag[1] = 'a';
result->datatag[2] = 't';
result->datatag[3] = 'a';
result->datalength = datalength;
result->data = data; // <--- that's were the data comes in
return 0; // an error code, not implemented, yet ...; in Java: return result
}
Novamente, não tenho certeza sobre Java, mas a conversão deve ser direta se você converter o ponteiro vazio em uma matriz correspondente à taxa de bits.
Em seguida, basta gravar toda a estrutura em um arquivo para obter um arquivo wave reproduzível.
Outras dicas
Confira Frinica.É uma estação de trabalho musical completa implementada em Java (código aberto).Usando a API, você pode executar eventos midi através do sintetizador, ler a saída de som bruta e gravá-la em um arquivo WAV (veja o link do código-fonte abaixo).
Informações adicionais:
Enquanto estudava para me formar, meu projeto de dissertação foi a criação de um sintetizador modular baseado em Java, e a universidade onde estudei achou por bem disponibilizar meu relatório publicamente:
Não sei se isso ajuda, mas se você pode usar MIDI para alguma coisa, dê uma olhada JFuge.