Fixed PSP trying to load entirely into memory
This commit is contained in:
@@ -128,7 +128,7 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
||||
}
|
||||
stream->platform.playRequested = false;
|
||||
|
||||
const size_t totalFrames = stream->dataSize / frameSize;
|
||||
const size_t totalFrames = audioStreamPcmGetTotalFrames(stream);
|
||||
|
||||
// loopEndFrame/loopToFrame define the loop segment [loopToFrame,
|
||||
// loopEndFrame) that a looping pass wraps within, once it's reached -
|
||||
@@ -147,6 +147,14 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
||||
size_t position = stream->platform.startFrame;
|
||||
bool_t reachedEnd = false;
|
||||
|
||||
// Samples are read on demand from the asset (via audioStreamPcmRead(),
|
||||
// sequentially, plus an explicit audioStreamPcmSeek() whenever jumping
|
||||
// backward for a loop wrap) rather than indexed out of a fully
|
||||
// resident buffer - a read/seek failure here (a corrupt or truncated
|
||||
// asset, an I/O error) stops playback cleanly instead of crashing the
|
||||
// thread on bad data.
|
||||
bool_t readFailed = errorIsNotOk(audioStreamPcmSeek(stream, position));
|
||||
|
||||
// Every call always sends a full, constant-size AUDIO_PSP_CHUNK_FRAMES
|
||||
// buffer - the channel is never re-declared to a different length, to
|
||||
// avoid relying on sceAudioSetChannelDataLen's undocumented behavior
|
||||
@@ -157,7 +165,7 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
||||
// engine's finished+looping path is designed for platforms with no
|
||||
// better option (see audiostream.c), but here the thread can just
|
||||
// keep going and call onLoop itself instead.
|
||||
while(!threadShouldStop(thread) && !reachedEnd) {
|
||||
while(!readFailed && !threadShouldStop(thread) && !reachedEnd) {
|
||||
// Normally bounded by loopEndFrame (the loop segment's end), but a
|
||||
// seek can legitimately land past it (e.g. into an outro after the
|
||||
// loop point) - in that case play out to the true end of the buffer
|
||||
@@ -173,9 +181,22 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
||||
const bool_t willLoop = reachesEndThisChunk &&
|
||||
(stream->state & AUDIO_STREAM_STATE_LOOPING);
|
||||
|
||||
memoryCopy(
|
||||
chunk, stream->data + (position * frameSize), framesThisChunk * frameSize
|
||||
);
|
||||
size_t framesRead = 0;
|
||||
if(errorIsNotOk(
|
||||
audioStreamPcmRead(stream, chunk, framesThisChunk, &framesRead)
|
||||
)) {
|
||||
readFailed = true;
|
||||
break;
|
||||
}
|
||||
if(framesRead < framesThisChunk) {
|
||||
// The asset is shorter than its declared header size (corrupt or
|
||||
// truncated) - pad what's missing with silence rather than play
|
||||
// whatever was left in `chunk` from a previous pass.
|
||||
memoryZero(
|
||||
chunk + (framesRead * channels),
|
||||
(framesThisChunk - framesRead) * frameSize
|
||||
);
|
||||
}
|
||||
|
||||
const size_t remainderFrames = AUDIO_PSP_CHUNK_FRAMES - framesThisChunk;
|
||||
size_t wrapFrames = 0;
|
||||
@@ -205,15 +226,22 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
||||
wrapFrames = remainderFrames < loopSegmentFrames
|
||||
? remainderFrames
|
||||
: loopSegmentFrames;
|
||||
memoryCopy(
|
||||
chunk + (framesThisChunk * channels),
|
||||
stream->data + (loopToFrame * frameSize),
|
||||
wrapFrames * frameSize
|
||||
);
|
||||
if(wrapFrames < remainderFrames) {
|
||||
|
||||
if(errorIsNotOk(audioStreamPcmSeek(stream, loopToFrame))) {
|
||||
readFailed = true;
|
||||
break;
|
||||
}
|
||||
size_t wrapRead = 0;
|
||||
if(errorIsNotOk(audioStreamPcmRead(
|
||||
stream, chunk + (framesThisChunk * channels), wrapFrames, &wrapRead
|
||||
))) {
|
||||
readFailed = true;
|
||||
break;
|
||||
}
|
||||
if(wrapRead < remainderFrames) {
|
||||
memoryZero(
|
||||
chunk + ((framesThisChunk + wrapFrames) * channels),
|
||||
(remainderFrames - wrapFrames) * frameSize
|
||||
chunk + ((framesThisChunk + wrapRead) * channels),
|
||||
(remainderFrames - wrapRead) * frameSize
|
||||
);
|
||||
}
|
||||
} else if(reachesEndThisChunk) {
|
||||
|
||||
Reference in New Issue
Block a user