Até o início dos anos 90, os micro-computadores compatíveis com o IBM PC utilizavam o PC speaker para reproduzir músicas polifônicas ou efeitos sonoros. Com a criação das placas de som, capazes de reproduzirem sons complexos independentemente da CPU, o PC speaker ficou com seu uso basicamente no processo de inicialização da máquina ou em terminais em modo texto, para comunicação de códigos de erro, avisos etc.
O PC speaker cria ondas sonoras usando o Intel 8253/8254, um chip Temporizador de Intervalo Programável (Programmable Interval Timer, PIT). O PIT é o mais antigo temporizador usado nos IBM PC compatíveis. É usado para execução de funções de contagem e cronometragem através de um oscilador de cristal de 1,193182 MHz e contém três contadores: o contador 0 é usado pelo sistema operacional para o tempo do sistema; o contador 1 foi usado historicamente para a RAM; e o contador 2 é usado pelo PC speaker. Nos PCs x86 modernos o PIT não está mais incluído em um chip separado, sua funcionalidade está incluída no chipset "southbridge" da placa mãe.
O programa abaixo explora um recurso disponível nos terminais que é a reprodução de "beep" pelo PC speaker. A função ioctl(), da linguagem C, fornece uma interface para a manipulação do terminal e o argumento "KIOCSOUND" desta função gera um som no PC speaker.
O código fonte apresentado a seguir é uma versão bem simplificada e foi baseado no programa Beep (http://www.johnath.com/beep/). Contém apenas o necessário para a reprodução dos sons e com uma interface básica para o usuário. Está adequado para ser compilado no ambiente Linux. Por razões de segurança do sistema, provavelmente somente o root tem permissão de acesso ao dispositivo "/dev/sonsole", sendo assim, um usuário comum não conseguirá reproduzir som, a não ser que faça algumas alterações no ambiente. Segue o código:
A função meugetch() não é necessária para a reprodução de som pelo PC speaker, o que ela faz é tratar a entrada pelo teclado para que não seja necessário pressionar a tecla Enter em cada nota. Caso prefira, com a biblioteca ncurses também é possível aprimorar esta entrada pelo teclado.
O PC speaker cria ondas sonoras usando o Intel 8253/8254, um chip Temporizador de Intervalo Programável (Programmable Interval Timer, PIT). O PIT é o mais antigo temporizador usado nos IBM PC compatíveis. É usado para execução de funções de contagem e cronometragem através de um oscilador de cristal de 1,193182 MHz e contém três contadores: o contador 0 é usado pelo sistema operacional para o tempo do sistema; o contador 1 foi usado historicamente para a RAM; e o contador 2 é usado pelo PC speaker. Nos PCs x86 modernos o PIT não está mais incluído em um chip separado, sua funcionalidade está incluída no chipset "southbridge" da placa mãe.
O programa abaixo explora um recurso disponível nos terminais que é a reprodução de "beep" pelo PC speaker. A função ioctl(), da linguagem C, fornece uma interface para a manipulação do terminal e o argumento "KIOCSOUND" desta função gera um som no PC speaker.
O código fonte apresentado a seguir é uma versão bem simplificada e foi baseado no programa Beep (http://www.johnath.com/beep/). Contém apenas o necessário para a reprodução dos sons e com uma interface básica para o usuário. Está adequado para ser compilado no ambiente Linux. Por razões de segurança do sistema, provavelmente somente o root tem permissão de acesso ao dispositivo "/dev/sonsole", sendo assim, um usuário comum não conseguirá reproduzir som, a não ser que faça algumas alterações no ambiente. Segue o código:
/* Teclado musical para o speaker interno, em ambiente Linux. Compilar com o camando: gcc teclado-musical.c -o teclado-musical */ #include <fcntl.h> /* O_WRONLY */ #include <stdio.h> /* fprintf, stderr, printf */ #include <stdlib.h> /* exit */ #include <unistd.h> /* STDIN_FILENO */ #include <linux/kd.h> /* KIOCSOUND */ #include <termios.h> /* ICANON, ECHO, TCSANOW */ #define CLOCK_TICK_RATE 1193182 /* Frequência do oscilador do chip i8254 da placa mãe, em Hz */ #define DURACAO_PADRAO 200 /* Em milisegundos */ #define DO 262 /* Frequências das notas */ #define RE 294 #define MI 330 #define FA 349 #define SOL 392 #define LA 440 #define SI 494 #define ESC 27 /* Valor decimal ASCII da tecla de saída do programa */ char meugetch() { /* Função que substitui o getchar() para não emitir echo na tela e ser necessário o <enter> */ struct termios tant, tnovo; /* Cria as variáveis com a estrutura termios */ char ch; tcgetattr( STDIN_FILENO, &tant ); /* Backup dos atributos do terminal atual */ tnovo = tant; /* Cópia dos atributos atuais para um novo terminal */ tnovo.c_lflag &= ~( ICANON | ECHO ); /* Desativa caracteres especiais e o echo no modo local */ tcsetattr( STDIN_FILENO, TCSANOW, &tnovo ); /* Usa imediatamente os novos atributos */ ch = getchar(); /* Lê um caractere do teclado */ tcsetattr( STDIN_FILENO, TCSANOW, &tant ); /* Usa de volta os atributos anteriores */ return ch; } void toca_nota(int freq, int duracao) { /* Reproduz o som no console */ int console_fd; /* Se a variável receber -1 significa que o arquivo não pode ser aberto */ if((console_fd = open("/dev/console", O_WRONLY)) == -1) { /* Abre o console para somente escrita e checa se não houve erro */ fprintf(stderr, "Impossivel abrir /dev/console para escrita.\n"); /* Imprime na saída de erro */ perror("open"); /* Imprime a mensagem de erro na saída de erro padrão */ exit(1); /* Saída com erro */ } if(ioctl(console_fd, KIOCSOUND, (int)(CLOCK_TICK_RATE/freq)) < 0) { /* Gera o som no console */ perror("ioctl"); /* Imprime a mensagem de erro na saída de erro padrão */ } usleep(1000*duracao); /* Tempo de espera para a duração do som */ ioctl(console_fd, KIOCSOUND, 0); /* Encerra o som */ close(console_fd); /* Fecha o uso da escrita no console */ } int main() { char tecla; printf("Digite teclas zxcvbnm para notas\nou ESC para sair\n"); do{ tecla = meugetch(); switch(tecla){ case 'z': toca_nota(DO,DURACAO_PADRAO); break; case 'x': toca_nota(RE,DURACAO_PADRAO); break; case 'c': toca_nota(MI,DURACAO_PADRAO); break; case 'v': toca_nota(FA,DURACAO_PADRAO); break; case 'b': toca_nota(SOL,DURACAO_PADRAO); break; case 'n': toca_nota(LA,DURACAO_PADRAO); break; case 'm': toca_nota(SI,DURACAO_PADRAO); break; } }while(tecla != ESC); return 0; }
A função meugetch() não é necessária para a reprodução de som pelo PC speaker, o que ela faz é tratar a entrada pelo teclado para que não seja necessário pressionar a tecla Enter em cada nota. Caso prefira, com a biblioteca ncurses também é possível aprimorar esta entrada pelo teclado.
Nenhum comentário:
Postar um comentário