ndsp: Make wavebuf handling more robust (and fix glaring omissions...)

This commit is contained in:
fincs 2020-06-22 22:47:53 +02:00
parent 2ff08fbac8
commit 03c41754e8
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60

View File

@ -53,7 +53,11 @@ void ndspChnReset(int id)
chn->syncCount ++; chn->syncCount ++;
chn->waveBufSeqPos = 0; chn->waveBufSeqPos = 0;
chn->samplePos = 0; chn->samplePos = 0;
chn->waveBuf = NULL; while (chn->waveBuf)
{
chn->waveBuf->status = NDSP_WBUF_DONE;
chn->waveBuf = chn->waveBuf->next;
}
chn->wavBufCount = 0; chn->wavBufCount = 0;
chn->wavBufIdNext = 0; chn->wavBufIdNext = 0;
chn->wavBufSeq = 0; chn->wavBufSeq = 0;
@ -150,7 +154,11 @@ void ndspChnWaveBufClear(int id)
{ {
ndspChnSt* chn = &ndspChn[id]; ndspChnSt* chn = &ndspChn[id];
LightLock_Lock(&chn->lock); LightLock_Lock(&chn->lock);
chn->waveBuf = NULL; while (chn->waveBuf)
{
chn->waveBuf->status = NDSP_WBUF_DONE;
chn->waveBuf = chn->waveBuf->next;
}
chn->waveBufSeqPos = 0; chn->waveBufSeqPos = 0;
chn->wavBufCount = 0; chn->wavBufCount = 0;
chn->wavBufIdNext = 0; chn->wavBufIdNext = 0;
@ -167,6 +175,12 @@ void ndspChnWaveBufAdd(int id, ndspWaveBuf* buf)
if (!buf->nsamples) return; if (!buf->nsamples) return;
LightLock_Lock(&chn->lock); LightLock_Lock(&chn->lock);
if (buf->status == NDSP_WBUF_QUEUED || buf->status == NDSP_WBUF_PLAYING)
{
// Wavebuf is already queued, avoid requeuing it...
LightLock_Unlock(&chn->lock);
return;
}
buf->next = NULL; buf->next = NULL;
buf->status = NDSP_WBUF_QUEUED; buf->status = NDSP_WBUF_QUEUED;
ndspWaveBuf* cb = chn->waveBuf; ndspWaveBuf* cb = chn->waveBuf;
@ -275,6 +289,7 @@ void ndspiInitChn(void)
{ {
LightLock_Init(&ndspChn[i].lock); LightLock_Init(&ndspChn[i].lock);
ndspChn[i].syncCount = 0; ndspChn[i].syncCount = 0;
ndspChn[i].waveBuf = NULL;
ndspChnReset(i); ndspChnReset(i);
} }
} }
@ -464,31 +479,37 @@ void ndspiReadChnState(void)
if (wb) if (wb)
{ {
ndspWaveBuf* doneList = NULL; ndspWaveBuf* doneList = NULL;
if (chn->wavBufCount) while (chn->wavBufCount)
{ {
while (wb->sequence_id != seqId) u16 wbSeqId = wb->sequence_id;
if (wbSeqId == seqId)
{ {
wb->status = NDSP_WBUF_PLAYING;
break;
}
chn->wavBufCount--; chn->wavBufCount--;
bool shouldBreak = seqId == 0 && (wb->sequence_id == st->lastSeqId || st->lastSeqId == 0);
ndspWaveBuf* next = wb->next; ndspWaveBuf* next = wb->next;
wb->next = doneList; wb->next = doneList;
doneList = wb; doneList = wb;
wb = next; wb = next;
if (!wb || shouldBreak || chn->wavBufCount == 0)
if (seqId == 0 && (wbSeqId == st->lastSeqId || st->lastSeqId == 0))
break; break;
} }
if (wb)
wb->status = NDSP_WBUF_PLAYING;
}
if (seqId == 0) if (seqId == 0)
chn->wavBufCount = 0; chn->wavBufCount = 0;
__dmb();
chn->waveBuf = wb; chn->waveBuf = wb;
for (; doneList; doneList = doneList->next) for (; doneList; doneList = doneList->next)
doneList->status = NDSP_WBUF_DONE; doneList->status = NDSP_WBUF_DONE;
} }
LightLock_Unlock(&chn->lock); LightLock_Unlock(&chn->lock);
} }
chn->playing = (st->flags & 0xFF) ? true : false; chn->playing = (st->flags & 0xFF) == 1;
} }
} }
} }