home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
msdos
/
sndbords
/
proaudio
/
pas_sdk1
/
pas
/
pcm
/
playfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-24
|
22KB
|
1,073 lines
/*$Author: DCODY $*/
/*$Date: 24 Sep 1992 08:59:20 $*/
/*$Header: X:/sccs/pcmapps/playfile.c_v 1.9 24 Sep 1992 08:59:20 DCODY $*/
/*$Log: X:/sccs/pcmapps/playfile.c_v $
*
* Rev 1.9 24 Sep 1992 08:59:20 DCODY
* changed MVGetHardware to mvGetHardware
*
* Rev 1.8 14 Sep 1992 17:22:38 SHAO_M
* Put all the text strings used in printf into playtext.h
*
* Rev 1.0 14 Sep 1992 17:01:30 unknown
* Initial revision.
*
* Rev 1.7 13 Aug 1992 08:26:18 DCODY
* corrected #if/#endif and } placement for TB stuff...
*
* Rev 1.6 04 Aug 1992 11:39:54 DCODY
* corrected t&l spelling
*
* Rev 1.5 28 Jul 1992 14:29:06 DCODY
* updated for Thunderboard and Thunder&Lightning
*
* Rev 1.4 20 Jul 1992 11:39:02 DCODY
* call to mvGetHWVersion now uses active I/O address detection.
*
* Rev 1.3 13 Jul 1992 18:54:14 DCODY
* removed initmvsound call
*
* Rev 1.2 01 Jul 1992 11:55:16 DCODY
* GaryL: Added OEM compiler flag checking for Welcome()
* to use the generic board name and to not display the MVI copyright.
* Note that the copyright is still present, as an imbedded static string.
*
* Rev 1.1 23 Jun 1992 16:09:50 DCODY
* pas2 update...
*
* Rev 1.0 15 Jun 1992 09:26:40 BCRANE
* Initial revision.
*/
/*$Logfile: X:/sccs/pcmapps/playfile.c_v $*/
/*$Modtimes$*/
/*$Revision: 1.9 $*/
/*$Workfile: playfile.c $*/
/*\
|*|----====< PLAYFILE.C >====----
|*|
|*| Play the voice file from disk to the PCM hardware
|*|
|*| Copyright (c) 1991, Media Vision, Inc. All rights reserved.
|*|
\*/
#ifndef OEM
#define OEM 0 /* OEM compile flag */
#endif
#ifndef PROAS
#define PROAS 0 /* Pro Audio Spectrum compile flag */
#endif
#ifndef THUNDER
#define THUNDER 0 /* Thunder Board compile flag */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <signal.h>
#include "playtext.h"
#if PROAS
#include "play.h"
#include "common.h"
#include "pcmio.h"
#endif
#if THUNDER
#include "proto.h"
#include "play.h"
#include "common.h"
#include "pcmio.h"
#include "mvsound.h"
#endif
/*\
|*|----====< Global Variables >====----
\*/
extern int DMARunning;
long mvGetHWVersion (int);
/*\
|*|----====< Local Variables >====----
\*/
static FILE *inf; /* user input file */
static long SampleRate = 11025L;/* default sample rate */
static int StereoMono = 0; /* default to mono */
static int Filter = -1; /* filter override # */
static int Compression= FALSE; /* compressed data */
static int DMAChannel = -1; /* default to standard DMA */
static int IRQChannel = -1; /* default to standard IRQ */
static int speed = 100; /* 100 percent */
static int UserStereoMono = -1;/* user's override flag = mono */
static long UserSampleRate = -1;/* user's override = 11k */
static long DataLength = -1;/* -1 goes to EOF */
static int maxsize = 16; /* 16k DMA buffer size */
static int maxdiv = 4; /* 4k divisions on the DMA */
static int datasize = 8; /* 8 bit or 16 bit pcm */
static int dsoverride = FALSE; /* data size override */
#define ALLOTHERS 0 /* assume an 8 bit data file */
#define WAVEFILE 1 /* wave type of file */
#define VOCFILE 2 /* .voc 8 bit pcm file */
static int FileType; /* type of source file */
#define BUFFLEN 4096
static char vocbuffer[BUFFLEN]; /* 4k worth of data */
static long VOCBlockLength; /* current block length */
static char VOCBlockType; /* current block type */
static char VOCPackType;
int CommandLine ( int, char *[] );
int DoExit ( int );
int FetchVOCData ( char * ); /* buffer of PCM data */
int PreProcessFile ( char * );
int SetupPlayRate ( );
void SetupSound ( );
/*\
|*|----====< Main >====----
|*|
|*| Play the voice file out to the PCM hardware
|*|
\*/
main(argc,argv)
int argc;
char *argv[];
{
char c;
/* give the opening welcome & checkout the hardware */
Welcome();
/* set the runtime switches */
CommandLine (argc,argv);
/* disable the ^C */
signal (SIGINT,SIG_IGN);
/* need a file name to play, exit if not found */
PreProcessFile (argv[1]);
if (OpenPCMBuffering(DMAChannel,IRQChannel,maxsize,maxdiv)) {
printf (TXT_MSG1);
DoExit (-1);
}
/* setup how this file sounds */
SetupSound();
/* Start the DMA & wait till an ESC is typed or data ends */
printf (TXT_MSG2);
if (FileType <= WAVEFILE) {
/* .WAV & all other files can go out using normal file I/O */
if (StartFileOutput( inf, DataLength )) {
while (1) {
/* if all done, then just break */
if (!ContinueFileOutput())
break;
/* if ESC typed, kill the DMA & exit */
if (kbhit()) {
if ((c = getch()) == 0x1b) {
StopDMAIO();
break;
}
if (c == ' ') {
PausePCM();
printf (TXT_MSG3);
GetKey();
printf (TXT_MSG4);
ResumePCM();
}
}
}
}
}
else {
/* if there is data available, play it... */
if (FetchVOCData(vocbuffer)) {
/* start the output with the first block of data */
if (StartBlockOutput( vocbuffer )) {
/* fetch the next block of data */
FetchVOCData(vocbuffer);
while (1) {
/* if the block can be passed, reload it */
if (ContinueBlockOutput(vocbuffer)) {
if (!FetchVOCData(vocbuffer))
break;
}
/* if ESC typed, kill the DMA & exit */
if (kbhit()) {
if ((c = getch()) == 0x1b) {
StopDMAIO();
DoExit(0);
}
if (c == ' ') {
PausePCM();
printf (TXT_MSG5);
GetKey();
printf (TXT_MSG6);
ResumePCM();
}
}
}
/* wait till the DMA finishes */
while (DMARunning) ;
}
}
}
/* exit to DOS */
DoExit(0);
}
/*\
|*|----====< CommandLine >====----
|*|
|*| process the command line switches
|*|
\*/
int CommandLine(argc,argv)
int argc;
char *argv[];
{
char *s;
int n,temp;
long longtemp;
/* exit if no additional parameters */
if (argc < 2) {
GiveHelps();
DoExit (-1);
}
n = 2;
while (n < argc) {
s = argv[n++];
if (*s == '/') s++;
if (*s == '-') s++;
switch (*s & 0x5f) {
#if PROAS
case '1' & 0x5f:
case '8' & 0x5f:
if (*++s == '6')
datasize = 16;
dsoverride = TRUE;
break;
case 'F':
Filter = *++s - 0x30;
if ((Filter > 6) || (Filter < 0))
Filter = -1;
break;
#endif
case 'D':
temp = *++s - 0x30;
if ((temp <= 7) && (temp >= 1)) {
if (temp == 4) temp = 0;
DMAChannel = temp;
}
break;
case 'I':
if (sscanf (++s,"%d",&temp) == 1) {
if ((1 << temp) & 0x9CBC)
IRQChannel = temp;
}
break;
case 'M':
maxsize = 64;
maxdiv = 16;
break;
case 'R':
if (sscanf (++s,"%ld",&longtemp) == 1) {
if ((longtemp >4000L) && (longtemp < 88200L))
UserSampleRate = longtemp;
}
break;
case 'S':
s++;
if (*s == '\0')
UserStereoMono = 1;
else {
if (sscanf (s,"%d",&temp) == 1) {
if ((temp >= 0) && ( temp <= 200))
speed = temp;
}
}
break;
default:
break;
}
}
}
/*\
|*|----====< DoExit() >====----
|*|
|*| Exit to DOS
|*|
\*/
int DoExit(cc)
int cc;
{
ClosePCMBuffering();
exit (cc);
}
/*\
|*|----====< GiveHelps() >====----
|*|
|*| print text helps & return
|*|
\*/
int GiveHelps()
{
/* print & return... */
#if PROAS
printf (TXT_MSG7);
printf (TXT_MSG8);
printf (TXT_MSG9);
printf (TXT_MSG10);
printf (TXT_MSG11);
printf (TXT_MSG12);
printf (TXT_MSG13);
printf (TXT_MSG14);
printf (TXT_MSG15);
printf (TXT_MSG16);
printf (TXT_MSG17);
#endif
#if THUNDER
printf (TXT_MSG18);
printf (TXT_MSG19);
printf (TXT_MSG20);
#if THUNDER==2
printf (TXT_MSG21);
printf (TXT_MSG22);
#else
printf (TXT_MSG23);
#endif
printf (TXT_MSG24);
printf (TXT_MSG25);
printf (TXT_MSG26);
#endif
}
/*\
|*|----====< FetchVOCData >====----
|*|
|*| Get a new key
|*|
\*/
int FetchVOCData(buff)
char *buff;
{
int loaded = 0, n;
int looping = TRUE;
int remaining = BUFFLEN;
/* grab the next block of data */
looping = 1;
while (looping) {
/* process the header */
switch (VOCBlockType) {
case TERMINATOR:
for (;remaining;remaining--)
*buff++ = 0x80;
remaining = 0;
looping = 0; /* this will knock us out */
break;
case VOICECONTINUE:
case VOICEDATA:
/* load the data, try to span blocks */
if (VOCBlockLength < remaining) {
remaining -= VOCBlockLength;
n = fread (buff,1,(size_t)VOCBlockLength,inf);
loaded += n;
buff += n;
VOCBlockLength = 0;
}
else {
n = fread(buff,1,remaining,inf);
loaded += n;
VOCBlockLength -= n;
looping = remaining = 0;
}
break;
case SILENCE:
/* load the data, try to span blocks */
if (VOCBlockLength < remaining) {
remaining -= VOCBlockLength;
loaded += VOCBlockLength;
for (;VOCBlockLength;VOCBlockLength--)
*buff++ = 0x80;
}
else {
loaded = remaining;
VOCBlockLength -= remaining;
for (;remaining;remaining--)
*buff++ = 0x80;
looping = remaining = 0;
}
break;
case MARKER:
case REPEAT:
case ENDREPEAT:
case ASCIITEXT:
/* all the rest of the header were eaten by the */
/* "GetNextBlock" routine. We will continue till we */
/* find data, or the terminating record */
default:
break;
}
/* span blocks, but exit on EOF */
if (remaining) {
if (!GetNextBlock()) {
for (;remaining;remaining--)
*buff++ = 0x80;
looping = FALSE;
}
}
}
/* return with data data block */
return(loaded);
}
/*\
|*|----====< GetKey() >====----
|*|
|*| Get a new key
|*|
\*/
int GetKey()
{
char c;
while (kbhit()) getch();
while (!kbhit()) ;
if (getch() == 0) getch();
}
/*\
|*|----====< GetNextBlock() >====----
|*|
|*| Process the header to the next block, & return TRUE if data is
|*| pointed to.
|*|
\*/
int GetNextBlock()
{
int looping = TRUE;
long l;
/* get the record type & process to get the sample rate */
VOCBlockLength = 0; /* we must end up with data! */
while (looping) {
switch (VOCBlockType = fgetc(inf)) {
case TERMINATOR:
return(0); /* if at the end, just exit */
case SILENCE:
fgetc(inf);fgetc(inf);fgetc(inf);
VOCBlockLength = fgetc(inf) & 0xff;
VOCBlockLength += ((long)(fgetc(inf) & 0xff)) << 8;
SetupPlayRate(fgetc(inf) & 0xff);
VOCBlockLength -= 3; /* 3 less for header data */
looping = FALSE;
break;
case VOICEDATA:
VOCBlockLength = fgetc(inf) & 0xff;
VOCBlockLength += ((long)(fgetc(inf) & 0xff)) << 8;
VOCBlockLength += ((long)(fgetc(inf) & 0xff)) << 16;
SetupPlayRate(fgetc(inf) & 0xff);
/* determine mono/stereo */
StereoMono = 0;
if (((VOCPackType = fgetc(inf)) & 0xff) == 5) {
StereoMono = 1;
VOCPackType = 0;
}
#if THUNDER
/* determine compression */
if (VOCPackType <= 3) /* types 0 - 3 */
Compression = VOCPackType;
#endif
VOCBlockLength -= 2; /* 2 less for header data */
looping = FALSE;
break;
case ASCIITEXT:
l = fgetc(inf) & 0xff;
l += ((long)(fgetc(inf) & 0xff)) << 8;
l += ((long)(fgetc(inf) & 0xff)) << 16;
for (;l;l--)
fgetc(inf);
break;
case MARKER:
case REPEAT:
fgetc(inf);fgetc(inf);
case ENDREPEAT:
fgetc(inf);fgetc(inf);fgetc(inf);
break;
default:
printf (TXT_MSG27);
DoExit(-1);
break;
}
}
/* we leave the file pointing to the first data byte */
return(1);
}
/*\
|*|----====< PreProcessFile >====----
|*|
|*| Fill the play buffer with the contents of the disk file
|*|
\*/
int PreProcessFile (fn)
char *fn;
{
char buff[100];
int n,looping;
long psize,l;
char *p,*b;
long* ptr;
FILE *wf;
/* attempt to open the users disk file */
if ((inf = fopen(fn,"rb")) == 0) {
strcpy (buff,fn);
strcat (buff,".WAV");
if ((inf = fopen(buff,"rb")) == 0) {
strcpy (buff,fn);
strcat (buff,".VOC");
if ((inf = fopen(buff,"rb")) == 0) {
printf (TXT_MSG28,fn);
DoExit (-1);
}
}
}
/* get the 1st 2 characters in the file */
n = fgetc(inf) & 0xff;
n = n + ((fgetc(inf) & 0xff) << 8);
fseek (inf,0L,SEEK_SET); /* rewind to the start */
/* special case a .WAV file */
if (n == 0x4952) {
ProcessWAVFile();
return(0);
}
/* special case anything else than a .VOC file */
if (n != 0x7243) { /* if NE to Creative..., then it's PCM */
ProcessPCMFile();
return(0);
}
/* .VOC type of source file */
FileType = VOCFILE;
/* get the header of the voice file */
b = &buff[0];
fseek(inf,0L,SEEK_SET); /* move to the first byte */
for (n=0;n<(sizeof (VOCHDR));n++)
*b++ = fgetc(inf);
if (feof(inf)) {
printf (TXT_MSG29);
DoExit (-1);
}
/* Make sure it's a legit file */
if (strncmp (buff,"Creative Voice File",0x13) != 0) {
printf (TXT_MSG30);
DoExit (-1);
}
p = &buff[0x14]; /* get a pointer to the offset */
psize = LONG(*p) & 0xffff; /* get the 16 bit word */
fseek(inf,psize,SEEK_SET); /* move to the first byte */
if (!GetNextBlock()) /* process the next header */
DoExit(0);
}
/*\
|*|----====< ProcessWAVFile >====----
|*|
|*| load the header from our WAV file format
|*|
\*/
int ProcessWAVFile(f)
{
int n;
char *b,c;
WaveInfo whd;
DataHeader dhd;
/* We are a WAVE file */
FileType = WAVEFILE; /* type of source file */
/* eat the RIFF portion of the header */
c = fgetc(inf);
if (c == 'R') {
for (n=7;n;n--)
fgetc(inf);
c = fgetc(inf);
}
/* pas up the wave block header name */
if (c != 'W') {
printf (TXT_MSG31);
DoExit(-1);
}
fgetc(inf); fgetc(inf); fgetc(inf); /* move past the data */
/* pass up the format section name */
c = fgetc(inf);
if (c != 'f') {
printf (TXT_MSG32);
DoExit(-1);
}
for (n=7;n;n--)
fgetc(inf); /* move past the data */
/* load the actual header data */
b = (char *) &whd;
for (n=0;n<sizeof (WaveInfo);n++)
*b++ = fgetc(inf);
/* grab the sample rate */
StereoMono = whd.nChannels - 1;
SampleRate = whd.nSamplesPerSec;
/* setup the data size only if no override has been requested */
if (!dsoverride)
datasize = whd.nBitsPerSample;
/* go to the data section and get the data length */
b = (char *) &dhd;
for (n=0;n<sizeof(DataHeader);n++)
*b++ = fgetc(inf); /* move past the data */
if (dhd.name[0] != 'd') {
printf (TXT_MSG33);
DoExit(-1);
}
DataLength = dhd.length;
}
/*\
|*|----====< ProcessPCMFile >====----
|*|
|*| load the header from our PCM file format
|*|
\*/
int ProcessPCMFile()
{
int n;
char *b;
/* we are some unknown data type */
FileType = ALLOTHERS; /* type of source file */
/* ask for the sample rate */
if (UserSampleRate != -1) {
SampleRate = UserSampleRate;
if (UserStereoMono == -1)
UserStereoMono = 0;
StereoMono = UserStereoMono;
}
else {
SampleRate = 11025L;
printf (TXT_MSG34);
while (1) {
if (scanf ("%ld",&SampleRate) == 1)
break;
}
printf (TXT_MSG35);
while (1) {
if (scanf ("%d",&StereoMono) == 1) {
StereoMono--; /* make it zero based */
break;
}
}
}
if ((StereoMono < 0) || (StereoMono > 1))
StereoMono = 0;
}
/*\
|*|----====< SetupPlayRate >====----
|*|
|*| Setup the playing rate of the interrupt routine.
|*|
\*/
int SetupPlayRate(n)
int n;
{
/* we will use a default rate */
SampleRate = 11025L;
/* search for the real rate */
while (1) {
if (n <= 6) {
SampleRate = 4000L; /* 4000 kh sampling */
break;
}
if (n <= 56) {
SampleRate = 5000L; /* 5000 kh sampling */
break;
}
if (n <= 90) {
SampleRate = 6000L; /* 6000 kh sampling */
break;
}
if (n <= 114) {
SampleRate = 7000L; /* 7000 kh sampling */
break;
}
if (n <= 131) {
SampleRate = 8000L; /* 8000 kh sampling */
break;
}
if (n <= 145) {
SampleRate = 9000L; /* 9000 kh sampling */
break;
}
if (n <= 156) {
SampleRate = 10000L; /* 10000 kh sampling */
break;
}
if (n <= 166) {
SampleRate = 11000L; /* 11000 kh sampling */
break;
}
if (n <= 173) {
SampleRate = 12000L; /* 11000 kh sampling */
break;
}
if (n <= 180) {
SampleRate = 13000L; /* 11000 kh sampling */
break;
}
if (n <= 185) {
SampleRate = 14000L; /* 11000 kh sampling */
break;
}
if (n <= 190) {
SampleRate = 15000L; /* 11000 kh sampling */
break;
}
if (n <= 194) {
SampleRate = 16000L; /* 11000 kh sampling */
break;
}
if (n <= 198) {
SampleRate = 17000L; /* 11000 kh sampling */
break;
}
if (n <= 201) {
SampleRate = 18000L; /* 11000 kh sampling */
break;
}
if (n <= 204) {
SampleRate = 19000L; /* 11000 kh sampling */
break;
}
if (n <= 206) {
SampleRate = 20000L; /* 11000 kh sampling */
break;
}
if (n <= 209) {
SampleRate = 21000L; /* 11000 kh sampling */
break;
}
if (n <= 211) {
SampleRate = 22000L; /* 11000 kh sampling */
break;
}
if (n <= 215) {
SampleRate = 23000L; /* 11000 kh sampling */
break;
}
/* if unknown value, bomb out... */
printf (TXT_MSG36);
DoExit(0);
}
}
/*\
|*|----====< SetupSound() >====----
|*|
|*| Setup the sample rate, stereo/mono.
|*|
\*/
void SetupSound()
{
/* if the user wants it different... */
if (UserSampleRate != -1)
SampleRate = UserSampleRate;
if (UserStereoMono != -1)
StereoMono = UserStereoMono;
/* speed is the user's %. from 0 to 200 % */
SampleRate = ((SampleRate * speed) + 50) / 100;
#if PROAS
ChooseFilter( SampleRate, Filter );
#endif
PCMState (SampleRate, StereoMono, Compression, datasize );
}
/*\
|*|----====< Welcome >====----
|*|
|*| Print the logo & check for the appropriate hardware
|*|
\*/
Welcome()
{
long ver;
/* give the normal stuff... */
#if OEM
#if PROAS
printf (TXT_MSG37);
#endif
#if THUNDER
printf (TXT_MSG38);
#endif
{
static char zsCopyright[] = "Copyright (c) 1991,1992 Media Vision, Inc. All Rights Reserved\n\n";
}
#else
#if PROAS
printf (TXT_MSG39);
#endif
#if THUNDER
#if THUNDER==2
printf (TXT_MSG40);
#else
printf (TXT_MSG41);
#endif
#endif
printf (TXT_MSG42);
#endif //OEM
/* check for the hardware */
#if PROAS
ver = mvGetHWVersion(USE_ACTIVE_ADDR); /* get the version */
if (ver == -1) {
#if OEM
printf (TXT_MSG43);
#else //OEM
printf (TXT_MSG44);
#endif //OEM
GiveHelps();
exit(-1);
}
#endif
#if THUNDER
ver = mvGetHWVersion(0); /* get the version, or something.. */
if ((ver < 0) || ((ver & 0xffff0000) != 0x00010000)) {
#if OEM
printf (TXT_MSG45);
#else //OEM
#if THUNDER==2
printf (TXT_MSG46);
#else
printf (TXT_MSG47);
#endif
#endif
GiveHelps();
exit(-1);
}
#endif //THUNDER
}
/*\
|*| end of PLAYFILE.C
\*/