406 lines
9.4 KiB
C++
406 lines
9.4 KiB
C++
#include <stdio.h>
|
||
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <conio.h>
|
||
|
||
#include <alloc.h>
|
||
#include <dos.h>
|
||
#include <io.h>
|
||
|
||
#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));
|
||
|
||
} |