Skip to content

Commit

Permalink
Audio streaming change + gaussian interpolation fix
Browse files Browse the repository at this point in the history
No more clicking and smoother playback? Yes please! Possible playback
corruption because timing is not perfect (but should be good for a
couple of hours of playback with no problems).
  • Loading branch information
DiscostewSM committed Jan 3, 2015
1 parent a7a507d commit c14b0ac
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 100 deletions.
82 changes: 36 additions & 46 deletions source/audio.c
Expand Up @@ -25,14 +25,11 @@
// 0 = none, 1 = CSND, 2 = DSP
int Audio_Type;

s16* Audio_Buffer0;
s16* Audio_Buffer1;

s16* Audio_Buffer;

u8 curbuffer = 0;
u32 cursample = 0;
u32 curpos = 0;

bool isPlaying = false;


void Audio_Init()
Expand All @@ -41,23 +38,19 @@ void Audio_Init()

Audio_Type = 0;

Audio_Buffer0 = (s16*)linearAlloc(MIXBUFSIZE*4*4);
Audio_Buffer1 = &Audio_Buffer0[MIXBUFSIZE*4];

memset(Audio_Buffer0, 0, MIXBUFSIZE*4*4);

curbuffer = 0;
Audio_Buffer = Audio_Buffer0;
Audio_Buffer = (s16*)linearAlloc(MIXBUFSIZE*4*2);
memset(Audio_Buffer, 0, MIXBUFSIZE*4*2);

cursample = 0;
curpos = 0;

// try using CSND
res = CSND_initialize(NULL);
if (!res)
{
Audio_Type = 1;
}

isPlaying = false;

// TODO: DSP black magic
}
Expand All @@ -75,23 +68,28 @@ void Audio_DeInit()

CSND_shutdown();
}
isPlaying = false;
}

void Audio_Pause()
{
// stop
if (Audio_Type == 1)
if(isPlaying)
{
CSND_setchannel_playbackstate(8, 0);
CSND_setchannel_playbackstate(9, 0);
CSND_setchannel_playbackstate(10, 0);
CSND_setchannel_playbackstate(11, 0);
// stop
if (Audio_Type == 1)
{
CSND_setchannel_playbackstate(8, 0);
CSND_setchannel_playbackstate(9, 0);
CSND_setchannel_playbackstate(10, 0);
CSND_setchannel_playbackstate(11, 0);

CSND_sharedmemtype0_cmdupdatestate(0);
}
CSND_sharedmemtype0_cmdupdatestate(0);
}

memset(Audio_Buffer0, 0, MIXBUFSIZE*4*4);
GSPGPU_FlushDataCache(NULL, Audio_Buffer0, MIXBUFSIZE*4*4);
memset(Audio_Buffer, 0, MIXBUFSIZE*4*2);
GSPGPU_FlushDataCache(NULL, Audio_Buffer, MIXBUFSIZE*4*2);
isPlaying = false;
}
}

void Audio_Mix()
Expand Down Expand Up @@ -137,28 +135,20 @@ void myCSND_playsound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u3
CSND_setchannel_playbackstate(channel, 1);
}

void Audio_MixFinish()
bool Audio_Begin()
{
GSPGPU_FlushDataCache(NULL, Audio_Buffer, MIXBUFSIZE*4*4);

curpos++;
if (curpos >= (MIXBUFSIZE/256))
{
if (Audio_Type == 1)
{
int newbuffer = curbuffer^1;

myCSND_playsound(8+newbuffer, 1, CSND_ENCODING_PCM16, 32000, (u32*)&Audio_Buffer[0], (u32*)&Audio_Buffer[(MIXBUFSIZE*2)-1], MIXBUFSIZE*4, 0xFFFF, 0);
myCSND_playsound(10+newbuffer, 1, CSND_ENCODING_PCM16, 32000, (u32*)&Audio_Buffer[MIXBUFSIZE*2], (u32*)&Audio_Buffer[(MIXBUFSIZE*4)-1], MIXBUFSIZE*4, 0, 0xFFFF);

CSND_setchannel_playbackstate(8+curbuffer, 0);
CSND_setchannel_playbackstate(10+curbuffer, 0);

CSND_sharedmemtype0_cmdupdatestate(0);
}

curbuffer ^= 1;
Audio_Buffer = curbuffer ? Audio_Buffer1 : Audio_Buffer0;
curpos = 0;
}
if(isPlaying)
return 0;

memset(Audio_Buffer, 0, MIXBUFSIZE*4*2);
GSPGPU_FlushDataCache(NULL, Audio_Buffer, MIXBUFSIZE*4*2);

myCSND_playsound(8, 1, CSND_ENCODING_PCM16, 32000, (u32*)&Audio_Buffer[0], (u32*)&Audio_Buffer[0], MIXBUFSIZE*4, 0xFFFF, 0);
myCSND_playsound(9, 1, CSND_ENCODING_PCM16, 32000, (u32*)&Audio_Buffer[MIXBUFSIZE*2], (u32*)&Audio_Buffer[MIXBUFSIZE*2], MIXBUFSIZE*4, 0, 0xFFFF);

CSND_sharedmemtype0_cmdupdatestate(0);

cursample = MIXBUFSIZE;//(MIXBUFSIZE * 3) >> 1;
isPlaying = true;
return 1;
}
3 changes: 2 additions & 1 deletion source/audio.h
Expand Up @@ -24,7 +24,8 @@ void Audio_DeInit();

void Audio_Pause();

bool Audio_Begin();

void Audio_Mix();
void Audio_MixFinish();

#endif
4 changes: 4 additions & 0 deletions source/dsp.c
Expand Up @@ -369,6 +369,10 @@ void DspKeyOnChannel(u32 i) {
channels[i].prevSamp1 = 0;
channels[i].prevSamp2 = 0;

channels[i].decoded[13] = 0;
channels[i].decoded[14] = 0;
channels[i].decoded[15] = 0;

channels[i].envCount = ENVCNT_START;
channels[i].active = true;

Expand Down
33 changes: 7 additions & 26 deletions source/dspMixer.s
Expand Up @@ -48,7 +48,8 @@ DecodeSampleBlockAsm:
ldrh r4, [r14, #52]
strh r4, [r14, #20]
ldrh r4, [r14, #54]
strh r4, [r14, #22]
strh r4, [r14, #22]


@ Load prev0 and prev1
ldrsh PREV0, [r14, #62]
Expand All @@ -61,8 +62,8 @@ DecodeSampleBlockAsm:
add r8, r8, r9, lsl #5 @ brrTabPtr = brrTab + (r4 * 32)

mov CONST_F, #0xf << 1
ldr r11, =0xffff8000
ldr r12, =0x7fff
ldr r11, =0xffff800c
ldr r12, =0x7ff0

@ 16 samples to decode, but do two at a time
mov ITER_LEFT, #8
Expand Down Expand Up @@ -588,21 +589,21 @@ gaussianInterpolation:
@ out = out + ((gauss[000h+i] * new) SAR 10) ;-with 16bit overflow handling
@ out = out SAR 1 ;-convert 16bit result to 15bit

ldrh r9, [r14, #-6] /* 0FFh */
ldr r9, =0x1FE /* 0FFh ( << 1) */
rsb r9, r6, r9 /* 0FFh-i */
ldrh r7, [r14, r9] /* gauss[0FFh-i] */
ldrsh r11, [r12], #2 /* oldest */
mul r8, r11, r7 /* gauss[0FFh-i] * oldest */
asr r8, #10 /* (gauss[0FFh-i] * oldest) SAR 10 */

ldrh r9, [r14, #-4]
ldr r9, =0x3FE
rsb r9, r6, r9
ldrh r7, [r14, r9]
ldrsh r11, [r12], #2
mul r9, r11, r7
add r8, r9, asr #10

ldrh r9, [r14, #-2]
ldrh r9, =0x200
add r9, r6
ldrh r7, [r14, r9]
ldrsh r11, [r12], #2
Expand All @@ -620,25 +621,7 @@ gaussianInterpolation:
ldmfd sp!, {r6-r7,r9-r12,r14}

b mixEchoDisabled

/*
linearIntpolation:
mov r12, SAMPLE_POS, lsr #12
add r12, r0, r12, lsl #1
ldrsh r8, [r12, #DECODED_OFFSET]

@ interpolate
@ final = ((final * pos4-11) + (finalprev * (255 - pos4-11))) >> 8
and r9, SAMPLE_POS, #0xFF0
sub r12, r12, #2
ldrsh r12, [r12, #DECODED_OFFSET]
mul r14, r8, r9
rsb r9, r9, #0xFF0
mla r14, r12, r9, r14
mov r8, r14, asr #12
b mixEchoDisabled
*/

useNoise:
@ Noise is already computed, so grab from the noise table

Expand Down Expand Up @@ -789,8 +772,6 @@ channelNum:
.byte 0
echoEnabled:
.byte 0
gaussianext:
.hword 0x01FE,0x03FE,0x0200
gaussian:
.hword 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000
.hword 0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x002,0x002,0x002,0x002,0x002
Expand Down
71 changes: 44 additions & 27 deletions source/main.c
Expand Up @@ -97,51 +97,68 @@ int exitspc = 0;
// +1 sample every 32 second
void SPCThread(u32 blarg)
{
//const double samplerate = 67027964.0 / (double)((u32)(67027964.0 / 32000.0));
const double samplerate = 67030870.0 / (double)((u32)(67030870.0 / 32000.0));
const double SAMPLE512TICK = 268123480.0 / (double)(samplerate / 512.0);
const double SAMPLE16TICK = 268123480.0 / (double)(samplerate / 16.0);
int audCnt = 32;
int audExt = 0;
u64 lastmixtime = svcGetSystemTick();
double mixtimediff = 0.0f;
int i;
/*u64 lastmixtime = svcGetSystemTick();
u32 mixtimes[2048];
memset(mixtimes, 0, 2048*4);
int k = 0;*/
while (!exitspc)
{
svcWaitSynchronization(SPCSync, U64_MAX);
svcClearEvent(SPCSync);

if (!pause)
{
for (i = 0; i < 32; i++)
bool started = Audio_Begin();
if(started)
{
audCnt = 32;
audExt = 0;
mixtimediff = 0.0f;
}
for (i = 0; i < audCnt; i++)
{
DSP_ReplayWrites(i);
Audio_Mix();
}

Audio_MixFinish();
/*if (k < 2048)
for(i = audCnt; i < 32; i++)
DSP_ReplayWrites(i);
audCnt = 32;
for(i = 0; i < audExt; i++)
Audio_Mix();
audExt = 0;

u64 curmixtime = svcGetSystemTick();
double diff = (double)(curmixtime - lastmixtime);
lastmixtime = curmixtime;
if(!started)
{
u64 t = svcGetSystemTick();
u32 diff = (u32)(t-lastmixtime);
lastmixtime = t;
mixtimes[k] = diff;
k++;
if (k >= 2048)
mixtimediff += diff - SAMPLE512TICK;
if(mixtimediff >= SAMPLE16TICK)
{
double avg = 0;
int m;
for (m = 0; m < 2048; m++) avg += (double)mixtimes[m];
avg /= 2048.0f;
avg = (avg * 1000.0f) / 268123480.0f;
// avg = time in ms for 512 samples
double freq = (1000.0f * 512.0f) / avg;
bprintf("time: %f | freq: %f\n", avg, freq);
k = 0;
while(mixtimediff >= SAMPLE16TICK)
{
mixtimediff -= SAMPLE16TICK;
audExt++;
}
}
}*/
else
{
while(mixtimediff < 0)
{
mixtimediff += SAMPLE16TICK;
audCnt--;
}
}
}
}
else
Audio_Pause();
}

}
svcExitThread();
}

Expand Down

0 comments on commit c14b0ac

Please sign in to comment.