Skip to content

Commit

Permalink
preliminary audio. only supports PSG (and handles all channels as suc…
Browse files Browse the repository at this point in the history
…h). drops out every once in a while.
  • Loading branch information
Arisotura committed Apr 6, 2017
1 parent 8d66beb commit 76c4e57
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 6 deletions.
89 changes: 84 additions & 5 deletions src/SPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,11 @@ void Reset()

Channel::Channel(u32 num)
{
//
Num = num;
}

Channel::~Channel()
{
//
}

void Channel::Reset()
Expand All @@ -88,28 +87,108 @@ void Channel::Reset()
Length = 0;
}

void Channel::Start()
{
Timer = TimerReload;
Pos = 0;

// hax
NextSample_PSG();
}

void Channel::NextSample_PSG()
{
s16 psgtable[8][8] =
{
{-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF},
{-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF},
{-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF},
{-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF},
{-0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF},
{-0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF},
{-0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF},
{ 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF}
};

CurSample = psgtable[(Cnt >> 24) & 0x7][Pos & 0x7];
}

void Channel::Run(s32* buf, u32 samples)
{
for (u32 s = 0; s < samples; s++)
buf[s] = 0;

if (!(Cnt & (1<<31))) return;
if (Num < 8) return;
if (!(Cnt & 0x7F)) return;

for (u32 s = 0; s < samples; s++)
{
Timer += 512; // 1 sample = 512 cycles at 16MHz
// will probably shit itself for very high-pitched sounds
while (Timer >> 16)
{
Timer = TimerReload + (Timer - 0x10000);
Pos++;
NextSample_PSG();
}

buf[s] = (s32)CurSample;
}
}


void Mix(u32 samples)
{
s32 channelbuf[32];
s32 finalbuf[32];

for (u32 s = 0; s < samples; s++)
finalbuf[s] = 0;

for (int i = 0; i < 16; i++)
//int i = 8;
{
Channel* chan = Channels[i];
chan->Run(channelbuf, samples);

for (u32 s = 0; s < samples; s++)
{
finalbuf[s] += channelbuf[s];
}
}

//

for (u32 s = 0; s < samples; s++)
{
s16 val = (s16)(finalbuf[s] >> 4);
// TODO panning! also volume and all

OutputBuffer[OutputWriteOffset] = val;
OutputBuffer[OutputWriteOffset + 1] = val;
OutputWriteOffset += 2;
OutputWriteOffset &= ((2*OutputBufferSize)-1);
}


NDS::ScheduleEvent(NDS::Event_SPU, true, 1024*16, Mix, 16);
}


void ReadOutput(s16* data, int samples)
{
{u32 zarp = 0;
for (int i = 0; i < samples; i++)
{
*data++ = OutputBuffer[OutputReadOffset];
*data++ = OutputBuffer[OutputReadOffset + 1];

if (OutputReadOffset != OutputWriteOffset)
{
{zarp += 2;
OutputReadOffset += 2;
OutputReadOffset &= ((2*OutputBufferSize)-1);
}
}
}printf("read %d samples, took %d\n", samples, zarp);
}


Expand Down
20 changes: 19 additions & 1 deletion src/SPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,39 @@ class Channel
~Channel();
void Reset();

u32 Num;

u32 Cnt;
u32 SrcAddr;
u16 TimerReload;
u32 LoopPos;
u32 Length;

u32 Timer;
u32 Pos;
s16 CurSample;

void SetCnt(u32 val)
{
if ((val & (1<<31)) && !(Cnt & (1<<31)))
{
Start();
}

Cnt = val & 0xFF7F837F;
//if(Num==8)printf("chan %d volume: %d\n", Num, val&0x7F);
}

void SetSrcAddr(u32 val) { SrcAddr = val & 0x07FFFFFF; }
void SetTimerReload(u32 val) { TimerReload = val & 0xFFFF; }
void SetTimerReload(u32 val) { TimerReload = val & 0xFFFF;if(Num==8) printf("chan8 timer %04X\n", TimerReload);}
void SetLoopPos(u32 val) { LoopPos = (val & 0xFFFF) << 2; }
void SetLength(u32 val) { Length = (val & 0x001FFFFF) << 2; }

void Start();

void NextSample_PSG();

void Run(s32* buf, u32 samples);
};

}
Expand Down

0 comments on commit 76c4e57

Please sign in to comment.