|
RealTime Sound FX Mixing Structures Example 7 |
Mission :Let's change a little of how we fill in our DMA buffer and achieve seamless
Realtime Sound FX Mixing!
Download the Expansion Pack!
Introtypedef struct SampleHeader
{unsigned long Position;
unsigned long Length;
unsigned short SoundNumber;
SampleHeader *Next;
SampleHeader *Previous;
SampleHeader()
{Position=Length=SoundNumber=0;
Next=Previous=NULL;
}
}Sampler,*Sample_ptr;
|
void SB16::Play
(unsigned int sound_num)
{SampleTail->Next = new SampleHeader();
SampleTail->Next->Previous=SampleTail;
SampleTail->Next->Length= Sounds[sound_num].Length;
SampleTail->Next->SoundNumber = sound_num;
SampleTail = SampleTail->Next;
} |
void SB16::FillBuffer()
{unsigned short i;
unsigned char *start=(unsigned char*)dma.MK_FP(dma.SegInfo.rm_segment,0);
SideToFill^=1;
if(SideToFill)
{ start+=HALFBUFFSIZE;
}
for(i=0;i<HALFBUFFSIZE;i++,start++)
{*start=MixSamples()+128;
}
} |
char SB16::MixSamples()
{long Total=0,SoundCount;
CurrentSample = SampleHead;
if(CurrentSample == SampleTail)
{return 0; //silence.....
}
CurrentSample = CurrentSample->Next; //go 1 past head nod
// 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 ClipChar(Total);
}
Total+=GetSample(CurrentSample);
CurrentSample=CurrentSample->Next;
SoundCount++;
}
}
}
return ClipChar(Total);
}
|
char SB16::GetSample(Sample_ptr S)
{ S->Position++;
return Sounds[S->SoundNumber].Sound[S->Position-1]-128;
}
char SB16::ClipChar(long num)
{
if(num > 127)
{num = 127;
}
if(num < -128)
{num = -128;
}
return (char)num;
}
|