#include #include #include #include #include #include #include #include "sb.h" #include "dac.h" #include "speaker.h" #include "Wavplay.h" #define FALSE 0 #define TRUE 1 #define ERROR_ABRIENDO 2 #define SIN_MEMORIA 3 #define FICHERO_ENORME 4 char huge *pWav, /* Puntero a la digitalizaci¢n */ huge *pMuestra; /* Puntero a la muestra que suena */ long Tamanyo, /* Tama¤o de los datos */ T_Real; unsigned Divisor, /* Valor del divisor del Timer 0 */ Frec=11000; /* Frecuencia de muestreo */ char FinVoz; /* Indica si la digitalizaci¢n ha terminado de sonar */ void interrupt (*Antigua8)(...); /* Antigua INT 8 */ void (*ByteAlDAC)(unsigned char); /* Puntero a la funci¢n que env¡a el byte al DAC */ char Wav_Mem = 0, Init = 0, SB_SPK = 0, Old_File[80]; int CargaWav(char *Nombre, long Pos, long Len); void DeInitSB(void); int InitSB(void); int Condicion_S00(void); int PlayWav(char far *File, long Pos, long Len ); int PlayLongWav(char far *File, long Pos, long Len); void ProgFrec(unsigned *Frecuencia); void interrupt Nuestra8(...); void ProgTimer0(unsigned Divisor); //int far TeclaPulsada(void); /* int main(int argc, char *argv[]) { if (argc<2) { printf("Error: falta par metro necesario.\n"); printf(" Fichero Salida\n"); printf(" Salida --> 0 Speaker\n"); printf(" --> 1 SB\n"); printf(" --> 2 Dac\n"); return(1); } InitSB(); if ( argc == 3 ) SB_SPK = atoi(argv[2]); if ( PlayWav(argv[1],TeclaPulsada) != 0 ) PlayLongWav(argv[1],TeclaPulsada); return 0; } */ /* *//* *//**/ /* *//* Ûßß ÜßßÜ ÛßßÜ Ûßßß ÜßßÜ Û Û ÛßßÛ Ûßß Û Û ÜßßÜ Û Û *//**/ /* *//* Û ÛÜÜÛ ÛÜÜß Û ÜÜ ÛÜÜÛ Û Û Û Û Û Û Û ÛÜÜÛ Û Û *//**/ /* *//* ÛÜÜ Û Û Û ßÜ ÛÜÜÛ Û Û ßÜß ÛÜÜÛ ÛÜÜ ÜÜÜÜ ßÜßÜß Û Û ßÜß *//**/ /* *//* JD*//**/ int CargaWav(char *Nombre, long Pos, long Len) { FILE *handle_sonido; long tam = 0; if( Wav_Mem == 1 ) { farfree( pWav ); Wav_Mem = 0; } if((handle_sonido = fopen(Nombre, "rb"))==NULL) { return ERROR_ABRIENDO; } if( (Tamanyo = ( (Len==-1) ? filelength(fileno(handle_sonido))-32 : Len - 32 ) ) < 1 ) { T_Real = 0; return ERROR_ABRIENDO; } fseek( handle_sonido, Pos, SEEK_SET ); T_Real = Tamanyo; if ( (pWav = (char huge *)farmalloc(Tamanyo+32) ) == NULL ) { fclose(handle_sonido); return SIN_MEMORIA; } Wav_Mem = 1; pMuestra = pWav; fread(pMuestra, sizeof(char), 24, handle_sonido); // C A B E C E R A . . . fread(&Frec, sizeof(unsigned int), 1, handle_sonido); // C A B E C E R A . . . if ( Frec <2000 ) Frec = 11025; fread(pMuestra, sizeof(char), 6, handle_sonido); // C A B E C E R A . . . pMuestra = pWav; while( tam < (Tamanyo + 1)) { tam++; *pMuestra++ = getc(handle_sonido); //if(pWav == pMuestra) printf("\nEl puntero esta en el origen o dio la vuelta durante la carga... %ld\n", tam); } pMuestra = pWav; fclose(handle_sonido); return 1; } void ProgTimer0(unsigned Divisor) /* Programa el Timer 0 para que cuente desde Divisor hasta 0 */ { asm CLI; /* Inhabilitamos interrupciones: secci¢n cr¡tica */ outportb(0x43,0x36); /* 00111010: Timer 0, acceso secuencial y modo cont¡nuo */ outportb(0x40,Divisor & 0xFF); /* Byte bajo del contador */ outportb(0x40,Divisor >> 8); /* Byte alto del contador */ asm STI; /* Fin de secci¢n cr¡tica */ } void ProgFrec(unsigned *Frecuencia) /* Programa el Timer 0 para que genere "Frecuencia" interrupciones por segundo */ { Divisor = 1193180 / *Frecuencia; *Frecuencia = 1193180 / Divisor; ProgTimer0(Divisor); } void interrupt Nuestra8(...) { if (!FinVoz) { (*ByteAlDAC)(*pMuestra); pMuestra++; Tamanyo--; if (Tamanyo<=1) FinVoz = TRUE; } outportb(0x20,0x20); /* Indicamos al controlador de interrupciones */ } /* que la interrupci¢n ha sido atendida */ void DeInitSB(void){ if ( Wav_Mem == 1 ) { farfree( pWav ); Wav_Mem = 0; } } int InitSB(void){ if ( Init == 0 ) atexit( DeInitSB ); Init = 1; return ( ( SBDetect() != -1 ) ? ( SB_SPK = 1 ) : ( SB_SPK = 0 ) ); } /**//* *//**/ /**//* ÛßßÜ Û ÜßßÜ Û Û Û Û ÛßßÛ Ûßß Û Û ÜßßÜ Û Û *//**/ /**//* ÛÜÜß Û ÛÜÜÛ ßÜß Û Û Û Û Û Û Û ÛÜÜÛ Û Û *//**/ /**//* Û ÛÜÜ Û Û Û ßÜß ÛÜÜÛ ÛÜÜ ÜÜÜÜ ßÜßÜß Û Û ßÜß *//**/ /**//* JD*//**/ int PlayWav(char far *File, long Pos, long Len) { static long Old_Pos = -1; if( Len == -1 ) { if ( strcmpi( File, Old_File ) != 0 || !Wav_Mem ) { if ( CargaWav(File, Pos, Len) != 1 ) { strcpy( Old_File, "\0" ); return (-1); } strcpy( Old_File, File ); } else { pMuestra = pWav; Tamanyo = T_Real; } } else { if ( Old_Pos != Pos || !Wav_Mem ) { if ( CargaWav(File, Pos, Len) != 1 ) { strcpy( Old_File, "\0" ); return (-1); } Old_Pos = Pos; } else { pMuestra = pWav; Tamanyo = T_Real; } } switch ( SB_SPK ) { case 0: InitSpeaker(); FinVoz = TRUE; ByteAlDAC = SpkSendByte; break; case 1: FinVoz = TRUE; ByteAlDAC = SBSendByte; break; case 2: InitDAC(); FinVoz = TRUE; ByteAlDAC = LPT1DAC; break; default: return -1; } Antigua8 = getvect(8); /* Guardamos el puntero a la antigua INT 8 */ setvect(8,Nuestra8); /* Colocamos el puntero a nuestra rutina */ ProgFrec(&Frec); FinVoz = FALSE; while (!FinVoz && !Condicion_S00() ); // /* if ( !*/Condicion_S00() /*) while (!FinVoz)*/; ProgTimer0(0); CloseSpeaker(); setvect(8,Antigua8); return(0); } int PlayLongWav(char far *File, long Pos, long Len) { const int Buff = 4096; FILE *handle_sonido; long n_lecturas, pico_lectr; char parte=0, key; if( Wav_Mem == 1 ) { farfree( pWav ); Wav_Mem = 0; } if((handle_sonido = fopen(File, "rb"))==NULL) { return ERROR_ABRIENDO; } if( (Tamanyo = ( (Len==-1) ? filelength(fileno(handle_sonido))-32 : Len - 32 ) ) < 1 ) { T_Real = 0; return ERROR_ABRIENDO; } fseek( handle_sonido, Pos, SEEK_SET ); T_Real = Tamanyo; n_lecturas = Tamanyo / Buff; pico_lectr = Tamanyo - ( n_lecturas * Buff ); if ( (pWav = (char huge *)farmalloc(Buff*2) ) == NULL ) { fclose(handle_sonido); return SIN_MEMORIA; } Wav_Mem = 1; pMuestra = pWav; // fread(pMuestra, sizeof(char), 32, handle_sonido); // C A B E C E R A . . . fread(pMuestra, sizeof(char), 24, handle_sonido); // C A B E C E R A . . . fread(&Frec, sizeof(unsigned int), 1, handle_sonido); // C A B E C E R A . . . if ( Frec <2000 ) Frec = 8050; fread(pMuestra, sizeof(char), 6, handle_sonido); // C A B E C E R A . . . if(n_lecturas) { fread(pWav, sizeof(char), Buff, handle_sonido); Tamanyo = Buff; } else { fread(pWav, sizeof(char), pico_lectr, handle_sonido); Tamanyo = pico_lectr; } switch ( SB_SPK ) { case 0: InitSpeaker(); FinVoz = TRUE; ByteAlDAC = SpkSendByte; break; case 1: FinVoz = TRUE; ByteAlDAC = SBSendByte; break; case 2: InitDAC(); FinVoz = TRUE; ByteAlDAC = LPT1DAC; break; default: return -1; } Antigua8 = getvect(8); /* Guardamos el puntero a la antigua INT 8 */ setvect(8,Nuestra8); /* Colocamos el puntero a nuestra rutina */ ProgFrec(&Frec); FinVoz = FALSE; parte = 1; if ( n_lecturas > 0 ) { while( n_lecturas > 0 ){ // Ejecutamos tantas veces con Lecturas Buff se // puedan hacer... n_lecturas--; // Vaya se nos fue una lectura... if ( n_lecturas > 0 ) { // Si quedan lecturas... llenamos el Doble Buffer if( parte ) fread( (pWav+4096), sizeof(char), Buff, handle_sonido ); else fread( (pWav ), sizeof(char), Buff, handle_sonido ); } else if ( pico_lectr > 0) { if( parte ) fread( (pWav+4096), sizeof(char), pico_lectr, handle_sonido ); else fread( (pWav ), sizeof(char), pico_lectr, handle_sonido ); } while (!FinVoz && !(key = Condicion_S00() ) ); // if ( !(key = Condicion()) ) while (!FinVoz); if ( key ) { FinVoz = TRUE; break; } if ( (n_lecturas > 0 || pico_lectr !=0) && !key ) { if( parte ){ parte = 0; /* Ya colocado */} else { parte = 1; pMuestra = pWav; } if (n_lecturas > 0) Tamanyo = Buff; else Tamanyo = pico_lectr; FinVoz = FALSE; } } while (!FinVoz && !Condicion_S00()); // if ( !(Condicion()) ) while (!FinVoz); } else while (!FinVoz && !Condicion_S00()); // if ( !(Condicion()) ) while (!FinVoz); ProgTimer0(0); CloseSpeaker(); setvect(8,Antigua8); fclose(handle_sonido); DeInitSB(); return(0); } // int far TeclaPulsada(void) /* Esta funci¢n mira si se ha pulsado una tecla pero SIN llamadas a la BIOS, de forma que no se inhabilitan las interrupciones en cada llamada, cosa que bajar¡a mucho la calidad de reproducci¢n con el altavoz interno. */ // { // return ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ); // } int Condicion_S00(void) { union REGS RaT; RaT.x.ax = 3; int86(0x33, &RaT, &RaT); return (( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ) || (RaT.x.bx & 1)); }