home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
m
/
muldisk1.zip
/
PAS
/
PCM
/
RECFILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-06
|
19KB
|
870 lines
/*$Author: DCODY $*/
/*$Date: 06 Oct 1992 15:21:10 $*/
/*$Header: X:/sccs/pcmapps/recfile.c_v 1.12 06 Oct 1992 15:21:10 DCODY $*/
/*$Log: X:/sccs/pcmapps/recfile.c_v $
*
* Rev 1.12 06 Oct 1992 15:21:10 DCODY
* corrected a bug in writing the RIFF data size
*
* Rev 1.11 24 Sep 1992 08:59:04 DCODY
* changed MVGetHardware to mvGetHardware
*
* Rev 1.10 18 Sep 1992 08:47:58 DCODY
* added '+' option to the 'M' switch.
*
* Rev 1.9 14 Sep 1992 17:23:50 SHAO_M
* Put all the text strings used in printf into rectext.h
*
* Rev 1.0 14 Sep 1992 17:02:20 unknown
* Initial revision.
*
* Rev 1.8 02 Sep 1992 12:48:52 DCODY
* made one simple change that now allows 44khz stereo 16bit recordings.
* Took out the writting of the WAV header before starting the record
* process. It is now done after the recording is finished. This allows
* the data blocks to be written on sector boundaries.
*
* Rev 1.7 20 Aug 1992 14:36:28 DCODY
* error exit now reports proper T&L product name.
*
* Rev 1.6 04 Aug 1992 11:39:42 DCODY
* corrected t&l spelling
*
* Rev 1.5 28 Jul 1992 14:29:30 DCODY
* updated for Thunderboard and Thunder&Lightning
*
* Rev 1.4 20 Jul 1992 11:39:18 DCODY
* call to mvGetHWVersion now uses active I/O address detection.
*
* Rev 1.3 13 Jul 1992 18:54:00 DCODY
* removed initmvsound call
*
* Rev 1.2 01 Jul 1992 11:57:16 DCODY
* GaryL: Added OEM compiler flag checking for Welcome()
* to use the generic board name and to not displau the MVI copyright.
* Note that the copyright is still present, as an imbedded static string.
*
* Rev 1.1 23 Jun 1992 16:10:02 DCODY
* pas2 update...
*
* Rev 1.0 15 Jun 1992 09:26:48 BCRANE
* Initial revision.
*/
/*$Logfile: X:/sccs/pcmapps/recfile.c_v $*/
/*$Modtimes$*/
/*$Revision: 1.12 $*/
/*$Workfile: recfile.c $*/
/*\
|*|----====< RECFILE.C >====----
|*|
|*| Record 8 bit PCM to disk in .WAV format
|*|
|*| Copyright (c) 1991, Media Vision, Inc. All rights reserved.
|*|
\*/
#ifndef OEM
#define OEM 0
#endif
#ifndef PROAS
#define PROAS 0
#endif
#ifndef THUNDER
#define THUNDER 0
#endif
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <signal.h>
#include "rectext.h"
#if PROAS
#include "play.h"
#include "common.h"
#include "pcmio.h"
#include "binary.h"
#endif
#if THUNDER
#include "proto.h"
#include "play.h"
#include "common.h"
#include "pcmio.h"
#endif
/*\
|*|----====< Global Variables >====----
\*/
extern int ProcessedBlockCount;
long mvGetHWVersion (int);
/*\
|*|----====< Local Variables >====----
\*/
static FILE *ouf = 0; /* temp output file */
static long SampleRate = 11025L;/* default sample rate */
static int StereoMono = 0; /* default to mono */
static char TargetFile[100]; /* holds output file name */
static int FilterIndex = -1; /* -1 means no override */
static int DMAChannel = -1; /* default to standard DMA */
static int IRQChannel = -1; /* default to standard IRQ */
static int DebugFlag = FALSE;
static int Compression = 0; /* no compression - 8 bits */
static int VoiceActivated = FALSE;
static int VoiceActivatedNonStop = FALSE;
static int NoiseLevel = 5;
static int maxsize = 16; /* 16k DMA buffer size */
static int maxdiv = 4; /* 4k divisions on the DMA */
static int datasize= 8; /* 8 or 16 bit samples */
#define WAVEFILE 1
#define VOCFILE 2
static int FileType;
/*\
|*|----====< Data Structures >====----
\*/
RiffWave fhd = {
{ "RIFF", 0L },
{ "WAVE",
{ "fmt ", sizeof(WaveInfo) , { 1, 1, 11025L, 11025L, 1, 8}, },
{ "data", 0L },
}
};
/* .VOC simple (cheat) header definition */
typedef struct {
VOCHDR vhdr;
bVOCDATA vdta;
} VOCHeader;
/* our pre-defined data block */
static VOCHeader vhd = {
{ "Creative Voice File\x1a", 0x001a, 0x010a, 0x1129 },
{ 0x01, 0x0,0x0,0x0, 0xa5, 0x0 }
};
/*\
|*|-----------------=============================-------------------
|*|-----------------====< Start of Exection >====-------------------
|*|-----------------=============================-------------------
\*/
/*\
|*|----====< Main >====----
|*|
|*| Play the voice file out to the PCM hardware
|*|
\*/
main(argc,argv)
int argc;
char *argv[];
{
char c;
/* Give the welcome & checkout the hardware */
Welcome();
/* disable the ^C */
signal(SIGINT,SIG_IGN);
/* set the runtime switches */
CommandLine (argc,argv);
/* need a file name to play, exit if not found */
PreProcessFile (TargetFile);
#if THUNDER
/* last minute weirdness check... */
LastChanceStop();
#endif
#if PROAS
/* turn off the digital input mixer channel to avoid feedback */
TurnItOff();
#endif
/* setup the DMA operations */
if (OpenPCMBuffering(DMAChannel,IRQChannel,maxsize,maxdiv)) {
printf (TXT_MSG1);
DoExit (-1);
}
/* setup how this file sounds */
#if PROAS
ChooseFilter( SampleRate, FilterIndex );
#endif
PCMState (SampleRate, StereoMono, Compression, datasize);
/* Start the DMA & wait till an ESC is typed or data ends */
printf (TXT_MSG2);
if (StartFileInput( ouf )) {
while (1) {
/* process some PCM data, if available */
if (VoiceActivated) {
if (!ASpecialContinueFileInput(NoiseLevel,VoiceActivatedNonStop))
DoExit(PCMIOERR_FILEFULL);
}
else {
if (!ContinueFileInput())
DoExit(PCMIOERR_FILEFULL);
}
/* 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
DoExit (PCMIOERR_OPENPCM);
/* exit to DOS */
DoExit(0);
}
/*\
|*|--------------------=======================----------------------
|*|--------------------====< Subroutines >====----------------------
|*|--------------------=======================----------------------
\*/
/*\
|*|----====< BuildFileName( char *, char *, char *, int ); >====----
|*|
|*| This routine takes the source name, scans it for an extension,
|*| then may append the new extension. The entire file name is
|*| returned in the callers target string.
|*|
\*/
void BuildFileName(trg,src,ext,force)
char *trg;
char *src;
char *ext;
int force;
{
int n;
char *t,*o;
// save a copy of the starting target address
o = trg;
// copy the source over to the target
while ((*trg++ = *src++)) ;
// move back to the terminator and save the pointer
t = --trg;
// search for an extension, if found, just return, we're all done...
for (n=0;n<=4;n++) {
// if no extension, go add one...
if (o == trg)
break;
// if an extension...
if (*trg == '.') {
// and do not force it, just return.
if (!force)
return;
// else point to this extension, and break out...
else {
t = trg;
break;
}
}
// move back to the prior character
trg--;
}
// add the extension
strcpy (t,ext);
}
/*\
|*|----====< CommandLine >====----
|*|
|*| process the command line switches
|*|
\*/
int CommandLine(argc,argv)
int argc;
char *argv[];
{
char *s;
int n,temp;
long l;
/* 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 THUNDER
case 'C':
Compression = 01; /* 4 bit compression */
break;
#endif
#if PROAS
case '8' & 0x5f:
case '1' & 0x5f:
if (*++s == '6')
datasize = 16;
break;
case 'F':
FilterIndex = *++s - 0x30;
if ((FilterIndex<0) || (FilterIndex>6))
FilterIndex = -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;
if (*++s == '+')
maxdiv = 4;
break;
case 'R':
if (sscanf (++s,"%ld",&SampleRate) != 1) {
printf (TXT_MSG5,s);
SampleRate = 11025L;
}
#if PROAS
if ((SampleRate < 4000L) || (SampleRate > 44100L)) {
printf (TXT_MSG5,s);
SampleRate = 11025L;
}
#endif
#if THUNDER
if ((SampleRate < 4000L) || (SampleRate > 23300L)) {
printf (TXT_MSG5,s);
SampleRate = 11025L;
}
#endif
break;
case 'S':
StereoMono = 1;
break;
case 'V':
VoiceActivated = TRUE;
if (*(s+1) == '+') {
VoiceActivatedNonStop = TRUE;
s++;
}
if (sscanf (++s,"%d",&temp) == 1)
NoiseLevel = temp;
break;
case '+' & 0x5f:
DebugFlag = TRUE;
break;
default:
break;
}
}
/* determine the type of output file */
BuildFileName (TargetFile,argv[1],".WAV",FALSE);
/* scan the last portion of the name for the type */
FileType = WAVEFILE;
s = TargetFile;
while (*s) s++;
if ((*(s-1) & 0x5f) == 'C')
if ((*(s-2) & 0x5f) == 'O')
if ((*(s-3) & 0x5f) == 'V')
FileType = VOCFILE;
/* if a bad sample rate, time to bomb out... */
if (FileType == WAVEFILE) {
if ((SampleRate<<StereoMono) > 88200L) {
printf (TXT_MSG6);
DoExit(-1);
}
}
else {
if ((SampleRate<<StereoMono) > 23300L) {
printf (TXT_MSG7,l);
DoExit(-1);
}
}
}
/*\
|*|----====< DoExit() >====----
|*|
|*| Exit to DOS
|*|
\*/
int DoExit(cc)
int cc;
{
#if PROAS
/* restore the PCM mixer channel */
TurnItOn();
#endif
/* print any error messages */
switch (cc) {
case PCMIOERR_SAMPLERATE:
printf (TXT_MSG8);
break;
case PCMIOERR_OPENFILE:
printf (TXT_MSG9);
break;
case PCMIOERR_OPENPCM:
printf (TXT_MSG10);
break;
case PCMIOERR_NOMEM:
printf (TXT_MSG11);
break;
case PCMIOERR_BADDMA:
printf (TXT_MSG12);
break;
case PCMIOERR_BADIRQ:
printf (TXT_MSG13);
break;
case PCMIOERR_FILEFULL:
printf (TXT_MSG14);
printf (TXT_MSG15);
break;
default:
case PCMIOERR_HELPS:
break;
}
/* if there is data, flush it and zip up the file */
if (ouf) {
if (ProcessedBlockCount) {
if (FileType == VOCFILE)
fputc (0x00,ouf); /* set the terminating record */
fclose (ouf);
if ((ouf = fopen(TargetFile,"r+b")) == 0) {
printf (TXT_MSG16,TargetFile);
ClosePCMBuffering();
exit(cc);
}
SetupHeader();
WriteBlockHeader();
}
fclose (ouf);
}
/* shut down the hardware */
ClosePCMBuffering();
exit (cc);
}
/*\
|*|----====< GetKey() >====----
|*|
|*| Get a new key
|*|
\*/
int GetKey()
{
char c;
while (kbhit()) getch();
while (!kbhit()) ;
if (getch() == 0) getch();
}
/*\
|*|----====< GiveHelps >====----
|*|
|*| Print the Help messages & returen
|*|
\*/
int GiveHelps()
{
/* print & return... */
#if PROAS
printf (TXT_MSG17);
printf (TXT_MSG18);
printf (TXT_MSG19);
printf (TXT_MSG20);
printf (TXT_MSG21);
printf (TXT_MSG22);
printf (TXT_MSG23);
printf (TXT_MSG24);
printf (TXT_MSG25);
printf (TXT_MSG26);
printf (TXT_MSG27);
printf (TXT_MSG28);
#endif
#if THUNDER
printf (TXT_MSG29);
printf (TXT_MSG30);
printf (TXT_MSG31);
printf (TXT_MSG32);
#if THUNDER==2
printf (TXT_MSG33);
printf (TXT_MSG34);
#else
printf (TXT_MSG35);
#endif
printf (TXT_MSG36);
printf (TXT_MSG37);
printf (TXT_MSG38);
printf (TXT_MSG39);
#endif
}
#if THUNDER
/*\
|*|----====< LastChanceStop() >====----
|*|
|*| Stop if there are some illegal setups
|*|
\*/
LastChanceStop()
{
/* .WAV cannot support compression... */
if ((FileType == WAVEFILE) && (Compression)) {
printf (TXT_MSG40);
GiveHelps();
DoExit(-1);
}
}
#endif
/*\
|*|----====< PreProcessFile >====----
|*|
|*| Validate the User's output file & load the 1st header block
|*|
\*/
int PreProcessFile (fn)
char *fn;
{
/* see if the file already exists */
if ((ouf = fopen(fn,"rb"))) {
printf (TXT_MSG41,fn);
while (!kbhit()) ;
if ((getchar() & 0x5f) != 'Y') {
#if PROAS
TurnItOn();
#endif
exit(1);
}
fclose (ouf);
}
/* attempt to open the users disk file */
if ((ouf = fopen(fn,"wb")) == 0) {
printf (TXT_MSG42,fn);
DoExit (-1);
}
/* send the header to disk */
////////WriteBlockHeader();
}
/*\
|*|----====< SetupHeader >====----
|*|
|*| Load the RIFF header with the critical data
|*|
\*/
int SetupHeader()
{
long l,n;
/* calculate the block size of each buffer division */
n = maxsize / maxdiv * 1024;
/* get the # of processed blocks */
l = LONG(ProcessedBlockCount) * n - sizeof(RiffWave);
/* set the data size */
fhd.wave.data.length = l;
/* set the RIFF length */
fhd.riff.length = l + sizeof(WaveHeader);
/* set the length of the FORMAT block */
fhd.wave.fmt.length = sizeof(WaveInfo);
/* set up the sample rate, etc... */
fhd.wave.fmt.info.nChannels = StereoMono + 1;
fhd.wave.fmt.info.nSamplesPerSec = SampleRate;
fhd.wave.fmt.info.nAvgBytesPerSec = (SampleRate << StereoMono) <<
((datasize == 8) ? 0 : 1);
fhd.wave.fmt.info.nBlockAlign = (1 + ((datasize == 8) ? 0 : 1))
<< StereoMono;
fhd.wave.fmt.info.nBitsPerSample = datasize;
/* setup the .VOC header */
l += 2; // .VOC wants a block length 2 bytes too long!
vhd.vdta.bsize[0] = (char) (l & 0xff);
vhd.vdta.bsize[1] = (char)((l>>8) & 0xff);
vhd.vdta.bsize[2] = (char)((l>>16) & 0xff);
vhd.vdta.sampler = (char)(256-(1000000L/SampleRate)) & 0xff;
vhd.vdta.packtype = Compression;
if (StereoMono)
vhd.vdta.packtype = 5;
}
/*\
|*|----====< Welcome >====----
|*|
|*| Print the logo & check for the appropriate hardware
|*|
\*/
Welcome()
{
long ver;
/* give the normal stuff... */
#if OEM
#if PROAS
printf (TXT_MSG43);
{
static char zsCopyright[] = "Copyright (c) 1991,1992 Media Vision, Inc. All Rights Reserved\n\n";
}
ver = mvGetHWVersion(USE_ACTIVE_ADDR);/* get the version */
if (ver == -1) {
printf (TXT_MSG44);
GiveHelps();
exit(-1);
}
#endif
#if THUNDER
printf (TXT_MSG45);
{
static char zsCopyright[] = "Copyright (c) 1991,1992 Media Vision, Inc. All Rights Reserved\n\n";
}
ver = InitMVHardware(); /* get the version, or something.. */
if ((ver < 0) || ((ver & 0xffff0000) != 0x00010000)) {
printf (TXT_MSG46);
GiveHelps();
exit(-1);
}
#endif
#else //OEM
#if PROAS
printf (TXT_MSG47);
printf (TXT_MSG48);
ver = mvGetHWVersion(USE_ACTIVE_ADDR);/* get the version */
if (ver == -1) {
printf (TXT_MSG49);
GiveHelps();
exit(-1);
}
#endif
#if THUNDER
#if THUNDER==2
printf (TXT_MSG50);
#else
printf (TXT_MSG51);
#endif
printf (TXT_MSG52);
ver = mvGetHWVersion(0); /* get the version, or something.. */
if ((ver < 0) || ((ver & 0xffff0000) != 0x00010000)) {
#if THUNDER==2
printf (TXT_MSG53);
#else
printf (TXT_MSG54);
#endif
GiveHelps();
exit(-1);
}
#endif
#endif //OEM
}
/*\
|*|----====< WriteBlockHeader >====----
|*|
|*| Output the one and only voice block header
|*|
\*/
int WriteBlockHeader()
{
long l;
char *s;
int n;
WaveFormat wf;
/* point to the start of the file */
fseek (ouf,0L,SEEK_SET);
/* depending on the type of file, output the data... */
if (FileType == WAVEFILE) {
s = (char*) &fhd;
for (n=sizeof(RiffWave);n;n--)
fputc(*s++,ouf);
}
else {
s = (char*) &vhd;
for (n=sizeof(VOCHeader);n;n--)
fputc(*s++,ouf);
}
}
/*\
|*| end of RECFILE.C
\*/