📄 mix.cpp
字号:
/****************************************************************************
* *
* (C) Copyright Creative Technology Ltd. 1994-1996. All rights reserved. *
* *
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
* PURPOSE. *
* *
* You have a royalty-free right to use, modify, reproduce and *
* distribute the Sample Files (and/or any modified version) in *
* any way you find useful, provided that you agree that *
* Creative has no warranty obligations or liability for any Sample Files. *
* *
****************************************************************************/
/*
* VOC file object. For reading VOC files.
* Copyright (c) 1993 Creative Labs, Inc.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
* PURPOSE.
*
* You have a royalty-free right to use, modify, reproduce and
* distribute the Sample Files (and/or any modified version) in
* any way you find useful, provided that you agree that
* Creative has no warranty obligations or liability for any Sample Files.
*
* This is an incomplete program, for demonstration purposes only.
*
* by D. Kaden 8/4/93
*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "mix.h"
VOCfile::VOCfile(void)
/* class constructor */
{
stereo=repeat=endoffile=IgnoreBlk1Attr=shifton=false;
TimeConst=SamplesRemaining=0;
touse=tousecount=0xFFFF;
}
void VOCfile::SetShiftAmount(unsigned int ToUse)
/* Sets the number of samples to use before one is thrown out. I recommend
* using a better pitch shifting algorithm. This one can only shift up one
* octave, and shifts up in large steps near its upper limit. To replace
* this, I would probably modify a Bresenham line drawing algorithm and use
* it to decide which samples to use and which to discard.
*/
{
touse=tousecount=ToUse;
}
int VOCfile::open(char *fname)
/* Open a voc file, verify that it is a voc file. Returns 0 if successful,
* error number otherwise. */
{
if ((f=fopen(fname,"rb"))==NULL) {
return VOCFILEOPENERROR;
}
fseek(f,0x16,SEEK_SET); /* seek to version number */
fread(&version, 2, 1, f); /* read it */
fread(&idcode, 2, 1, f); /* read VOC file id code */
/* complement of version + 0x1234 should equal idcode */
if (~version + 0x1234 != idcode) {
return VOCNOTVOCFILE;
}
ResetVOC();
return VOCNOERROR;
}
void VOCfile::ResetVOC(void)
/* Resets the voc file to the first block after the header. Will also
* cause the sound to start over.
*/
{
fseek(f,0x14,SEEK_SET); /* seek to location of offset of first data block */
fread(&DataBlockOffset, 2, 1, f); /* read offset */
fseek(f, DataBlockOffset, SEEK_SET); /* seek to data block */
endoffile=false;
SamplesRemaining=0;
}
boolean VOCfile::ProcessBlock(void)
/* Processes the blocks of data in the voc file. This function is incom-
* plete, but is good enough for simple voc files.
*/
{
boolean DataFound=false;
unsigned long blklen=0;
fread(&blocktype, 1, 1, f); /* read block type */
switch(blocktype) {
case 0: /* terminator */
endoffile=true;
break;
case 1: /* data block */
fread(&blklen, 3, 1, f); /* length of data block */
SamplesRemaining = blklen-2; /* all but first two are samples */
if (IgnoreBlk1Attr)
fseek(f,2,SEEK_CUR); /* skip TC and Pack bytes */
else {
fread(&TimeConst, 1, 1, f);
fread(&pack, 1, 1, f);
}
IgnoreBlk1Attr=false;
DataFound=true;
break;
case 2: /* voice continuation */
fread(&SamplesRemaining, 3, 1, f);
DataFound=true;
break;
/*** CASES 3 - 7 ARE NOT YET SUPPORTED ***/
case 3: /* silence period */
case 4: /* marker block */
case 5: /* ASCII text */
case 6: /* Repeat loop */
case 7: /* End repeat loop */
fread(&blklen, 3, 1, f); /* length of this block */
fseek(f,blklen,SEEK_CUR); /* skip over it */
break;
case 8: /* extended block */
fseek(f, 4, SEEK_CUR); /* Skip to TC high order byte */
fread(&TimeConst, 1, 1, f);
fread(&pack, 1,1,f);
fread(&stereo, 1,1,f);
IgnoreBlk1Attr=true;
break;
}
return DataFound;
}
boolean VOCfile::eof(void)
/* Returns true if the terminator block of the voc file has been processed. */
{
boolean DataFound=false;
if (!endoffile && SamplesRemaining==0)
do {
DataFound=ProcessBlock();
} while (!(DataFound || endoffile));
return endoffile;
}
unsigned char VOCfile::GetSample(void)
/* Returns one sound sample from the voc file. If repeat==true, this func-
* tion will automatically start the file over after it reaches the end.
* If repeat==false, this function will return 0x80 (zero volts) after it
* reaches the end of the file.
*/
{
boolean DataFound=false;
if (SamplesRemaining) { /* still samples in data block */
fread(&sample, 1, 1, f);
SamplesRemaining--;
if (shifton) { /* pitch shifting */
if (0==(tousecount--)) { /* if 0, time to toss a sample */
tousecount=touse;
return GetSample();
} else return sample;
} else return sample;
} else { /* no samples left in data block */
if (endoffile) { /* hit end of file */
return 0x80;
} else { /* not yet eof, see if more data blocks */
do {
DataFound=ProcessBlock();
} while (!(DataFound || endoffile));
if (DataFound)
return GetSample(); /* call myself to get sample */
else if (endoffile && repeat) {
ResetVOC();
return GetSample();
} else return 0x80;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -