|
Realtime Sound FX Example 9 |
Mission :Let's change a little more of our source code to create Realtime Sound FX!!
Download the Expansion Pack!!
Intro
Phase Shift Delay
#define PSDMAX 16384
class SB16
{ public:
typedef struct SampleHeader
{unsigned long Position; //positional pointers for where the sound is.
unsigned long Length; //length of the sample.
unsigned short SoundNumber; //sound number
XYZLocation *Location; // used for 3d sound
long OldSample; //used for stereo mode
long PSD,PSDCounter;
long (SB16::*MixingRoutine)(SampleHeader*);
long SampleList[PSDMAX];
SampleHeader *Next;
SampleHeader *Previous;
SampleHeader()
{Position=Length=SoundNumber=PSD=PSDCounter=0;
memset((long*)SampleList,0,PSDMAX);
Next=Previous=NULL;
}Sampler,*Sample_ptr;
}
...
long GetSamplePSD(Sample_ptr);
void Play(int,long);
long (SB16::*GetSamplePSDptr)(Sample_ptr);
|
void SB16::SetPtrFunctions()
{ GetSamplePSDptr = &SB16::GetSamplePSD;
if(ModeBits==16)
{MixingFunction=&SB16::FillBuffer16;
GetSample=&SB16::GetSample16;
if(Sound3d)
{if(ModeStereoMono)
{GrabSample=&SB16::Get3dSampleStereo; //3d 16 Stereo
}
else
{GrabSample=&SB16::Get3dSampleMono; //3d 16 Mono
}
}
}
else
{MixingFunction=&SB16::FillBuffer8; //default 8 bit mixing scheme
GetSample=&SB16::GetSample8;
if(Sound3d)
{if(ModeStereoMono)
{GrabSample=&SB16::Get3dSampleStereo; //3d 8 Stereo
}
else
{GrabSample=&SB16::Get3dSampleMono; //3d 8 Mono
}
}
}
}
|
long SB16::MixSamples()
{//go through linked list and average the outgoing signal
long Total=0,SoundCount;
CurrentSample = SampleHead;
if(CurrentSample == SampleTail)
{return 0; //silence.....
}
CurrentSample = CurrentSample->Next;
// there is at least 1 sound needed to play
while(CurrentSample != NULL)
{
if(CurrentSample->Position == CurrentSample->Length )
{FrontLink = CurrentSample->Previous;
EndLink = CurrentSample->Next;
if(EndLink == NULL)
{//this is the last item in the list
FrontLink->Next = NULL;
delete CurrentSample;
CurrentSample = NULL; //trigger exit
SampleTail = FrontLink; //only true if last item.
}
else
{FrontLink->Next = EndLink;
EndLink->Previous = FrontLink;
delete CurrentSample;
CurrentSample = EndLink;
}
}
else
{if(SoundCount == MaxNumberToMix)
{ return Total;
}
Total+=(this->*CurrentSample->MixingRoutine)(CurrentSample);
CurrentSample=CurrentSample->Next;
SoundCount++;
}
}
return Total;
} |
void SB16::Play(int sound_num,long PSD)
{SampleTail->Next = new SampleHeader();
SampleTail->Next->Previous=SampleTail;
SampleTail->Next->Next = NULL;
SampleTail->Next->Position=0;
SampleTail->Next->Length = Sounds[sound_num].Length+PSD;
SampleTail->Next->SoundNumber = sound_num;
SampleTail->Next->PSD=PSD;
SampleTail->Next->MixingRoutine=(this->*&SB16::GetSamplePSDptr);
SampleTail = SampleTail->Next;
} |
long SB16::GetSamplePSD(Sample_ptr S)
{long sample=0;
if(LeftChannel)
{// length is acutally length-psd, so should be attempt at new sample?
if(S->PSDCounter < ((S->Length>>1)-S->PSD))
{sample=(this->*GetSample)(S);
}
else
{S->SampleList[S->PSDCounter&(PSDMAX-1)]=0; //return 0 on other side!
return 0;
}
//MARKER
S->SampleList[S->PSDCounter&(PSDMAX-1)]=sample<<16;
return sample<<16;
}
else
{//don't need to see if position-psd is positive because a negative number
//raps over to the end of our buffer since we are and'ing PSDMAX-1. since we
//initialized all the buffer to 0, we could care less!!
S->PSDCounter++;
return S->SampleList[((S->PSDCounter-1)-S->PSD)&(PSDMAX-1)];
}
}
|
