mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Start separating out static track parameters: Move first_.filesize to track_.fileSize
This commit is contained in:
parent
bd84e30553
commit
efd9962c6e
3 changed files with 76 additions and 48 deletions
|
@ -49,7 +49,14 @@ void Atrac::DoState(PointerWrap &p) {
|
|||
}
|
||||
|
||||
Do(p, atracID_);
|
||||
if (p.mode != p.MODE_READ) {
|
||||
first_._filesize_dontuse = track_.fileSize;
|
||||
}
|
||||
Do(p, first_);
|
||||
if (p.mode == p.MODE_READ) {
|
||||
track_.fileSize = first_._filesize_dontuse;
|
||||
}
|
||||
|
||||
Do(p, bufferMaxSize_);
|
||||
Do(p, codecType_);
|
||||
|
||||
|
@ -68,10 +75,10 @@ void Atrac::DoState(PointerWrap &p) {
|
|||
if (p.mode == p.MODE_READ) {
|
||||
if (dataBuf_)
|
||||
delete[] dataBuf_;
|
||||
dataBuf_ = new u8[first_.filesize + overAllocBytes];
|
||||
memset(dataBuf_, 0, first_.filesize + overAllocBytes);
|
||||
dataBuf_ = new u8[track_.fileSize + overAllocBytes];
|
||||
memset(dataBuf_, 0, track_.fileSize + overAllocBytes);
|
||||
}
|
||||
DoArray(p, dataBuf_, first_.filesize);
|
||||
DoArray(p, dataBuf_, track_.fileSize);
|
||||
}
|
||||
Do(p, second_);
|
||||
|
||||
|
@ -212,7 +219,7 @@ void Atrac::WriteContextToPSPMem() {
|
|||
context->info.numChan = channels_;
|
||||
context->info.dataOff = dataOff_;
|
||||
context->info.endSample = endSample_ + firstSampleOffset_ + FirstOffsetExtra();
|
||||
context->info.dataEnd = first_.filesize;
|
||||
context->info.dataEnd = track_.fileSize;
|
||||
context->info.curOff = first_.fileoffset;
|
||||
context->info.decodePos = DecodePosBySample(currentSample_);
|
||||
context->info.streamDataByte = first_.size - dataOff_;
|
||||
|
@ -224,6 +231,9 @@ void Atrac::WriteContextToPSPMem() {
|
|||
}
|
||||
|
||||
int Atrac::Analyze(u32 addr, u32 size) {
|
||||
Track *track = &track_;
|
||||
*track = {};
|
||||
|
||||
struct RIFFFmtChunk {
|
||||
u16_le fmtTag;
|
||||
u16_le channels;
|
||||
|
@ -232,6 +242,7 @@ int Atrac::Analyze(u32 addr, u32 size) {
|
|||
u16_le blockAlign;
|
||||
};
|
||||
|
||||
first_ = {};
|
||||
first_.addr = addr;
|
||||
first_.size = size;
|
||||
|
||||
|
@ -275,10 +286,10 @@ int Atrac::Analyze(u32 addr, u32 size) {
|
|||
}
|
||||
|
||||
// RIFF size excluding chunk header.
|
||||
first_.filesize = Memory::Read_U32(addr + offset - 8) + 8;
|
||||
track->fileSize = Memory::Read_U32(addr + offset - 8) + 8;
|
||||
|
||||
// Even if the RIFF size is too low, it may simply be incorrect. This works on real firmware.
|
||||
u32 maxSize = std::max(first_.filesize, size);
|
||||
u32 maxSize = std::max(track->fileSize, size);
|
||||
|
||||
bool bfoundData = false;
|
||||
u32 dataChunkSize = 0;
|
||||
|
@ -384,9 +395,9 @@ int Atrac::Analyze(u32 addr, u32 size) {
|
|||
bfoundData = true;
|
||||
dataOff_ = offset;
|
||||
dataChunkSize = chunkSize;
|
||||
if (first_.filesize < offset + chunkSize) {
|
||||
if (track->fileSize < offset + chunkSize) {
|
||||
WARN_LOG_REPORT(ME, "Atrac data chunk extends beyond riff chunk");
|
||||
first_.filesize = offset + chunkSize;
|
||||
track->fileSize = offset + chunkSize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -422,13 +433,18 @@ int Atrac::Analyze(u32 addr, u32 size) {
|
|||
return hleReportError(ME, ATRAC_ERROR_BAD_CODEC_PARAMS, "loop after end of data");
|
||||
}
|
||||
|
||||
first_._filesize_dontuse = track->fileSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Atrac::AnalyzeAA3(u32 addr, u32 size, u32 filesize) {
|
||||
Track *track = &track_;
|
||||
*track = {};
|
||||
|
||||
first_.addr = addr;
|
||||
first_.size = size;
|
||||
first_.filesize = filesize;
|
||||
track->fileSize = filesize;
|
||||
first_._filesize_dontuse = filesize;
|
||||
|
||||
AnalyzeReset();
|
||||
|
||||
|
@ -501,7 +517,7 @@ void Atrac::CalculateStreamInfo(u32 *outReadOffset) {
|
|||
// If we're buffering the entire file, just give the same as readOffset.
|
||||
first_.offset = readOffset;
|
||||
// In this case, the bytes writable are just the remaining bytes, always.
|
||||
first_.writableBytes = first_.filesize - readOffset;
|
||||
first_.writableBytes = track_.fileSize - readOffset;
|
||||
} else {
|
||||
u32 bufferEnd = StreamBufferEnd();
|
||||
u32 bufferValidExtended = bufferPos_ + bufferValidBytes_;
|
||||
|
@ -514,7 +530,7 @@ void Atrac::CalculateStreamInfo(u32 *outReadOffset) {
|
|||
first_.writableBytes = bufferPos_ - bufferStartUsed;
|
||||
}
|
||||
|
||||
if (readOffset >= first_.filesize) {
|
||||
if (readOffset >= track_.fileSize) {
|
||||
if (bufferState_ == ATRAC_STATUS_STREAMED_WITHOUT_LOOP) {
|
||||
// We don't need anything more, so all 0s.
|
||||
readOffset = 0;
|
||||
|
@ -525,9 +541,9 @@ void Atrac::CalculateStreamInfo(u32 *outReadOffset) {
|
|||
}
|
||||
}
|
||||
|
||||
if (readOffset + first_.writableBytes > first_.filesize) {
|
||||
if (readOffset + first_.writableBytes > track_.fileSize) {
|
||||
// Never ask for past the end of file, even when the space is free.
|
||||
first_.writableBytes = first_.filesize - readOffset;
|
||||
first_.writableBytes = track_.fileSize - readOffset;
|
||||
}
|
||||
|
||||
// If you don't think this should be here, remove it. It's just a temporary safety check.
|
||||
|
@ -577,7 +593,7 @@ void Atrac::GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample) {
|
|||
// Here the message is: you need to read at least this many bytes to get to that position.
|
||||
// This is because we're filling the buffer start to finish, not streaming.
|
||||
bufferInfo->first.writePosPtr = first_.addr + first_.size;
|
||||
bufferInfo->first.writableBytes = first_.filesize - first_.size;
|
||||
bufferInfo->first.writableBytes = track_.fileSize - first_.size;
|
||||
int minWriteBytes = FileOffsetBySample(sample) - first_.size;
|
||||
if (minWriteBytes > 0) {
|
||||
bufferInfo->first.minWriteBytes = minWriteBytes;
|
||||
|
@ -594,7 +610,7 @@ void Atrac::GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample) {
|
|||
const int needsMoreFrames = FirstOffsetExtra();
|
||||
|
||||
bufferInfo->first.writePosPtr = first_.addr;
|
||||
bufferInfo->first.writableBytes = std::min(first_.filesize - sampleFileOffset, bufSizeAligned);
|
||||
bufferInfo->first.writableBytes = std::min(track_.fileSize - sampleFileOffset, bufSizeAligned);
|
||||
if (((sample + firstSampleOffset_) % (int)SamplesPerFrame()) >= (int)SamplesPerFrame() - needsMoreFrames) {
|
||||
// Not clear why, but it seems it wants a bit extra in case the sample is late?
|
||||
bufferInfo->first.minWriteBytes = bytesPerFrame_ * 3;
|
||||
|
@ -625,8 +641,8 @@ int Atrac::SetData(u32 buffer, u32 readSize, u32 bufferSize, int successCode) {
|
|||
first_.addr = buffer;
|
||||
first_.size = readSize;
|
||||
|
||||
if (first_.size > first_.filesize)
|
||||
first_.size = first_.filesize;
|
||||
if (first_.size > track_.fileSize)
|
||||
first_.size = track_.fileSize;
|
||||
first_.fileoffset = first_.size;
|
||||
|
||||
// got the size of temp buf, and calculate offset
|
||||
|
@ -661,10 +677,10 @@ int Atrac::SetData(u32 buffer, u32 readSize, u32 bufferSize, int successCode) {
|
|||
// Over-allocate databuf to prevent going off the end if the bitstream is bad or if there are
|
||||
// bugs in the decoder. This happens, see issue #15788. Arbitrary, but let's make it a whole page on the popular
|
||||
// architecture that has the largest pages (M1).
|
||||
dataBuf_ = new u8[first_.filesize + overAllocBytes];
|
||||
memset(dataBuf_, 0, first_.filesize + overAllocBytes);
|
||||
dataBuf_ = new u8[track_.fileSize + overAllocBytes];
|
||||
memset(dataBuf_, 0, track_.fileSize + overAllocBytes);
|
||||
if (!ignoreDataBuf_) {
|
||||
u32 copybytes = std::min(bufferSize, first_.filesize);
|
||||
u32 copybytes = std::min(bufferSize, track_.fileSize);
|
||||
Memory::Memcpy(dataBuf_, buffer, copybytes, "AtracSetData");
|
||||
}
|
||||
CreateDecoder();
|
||||
|
@ -673,7 +689,7 @@ int Atrac::SetData(u32 buffer, u32 readSize, u32 bufferSize, int successCode) {
|
|||
|
||||
u32 Atrac::SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) {
|
||||
u32 secondFileOffset = FileOffsetBySample(loopEndSample_ - firstSampleOffset_);
|
||||
u32 desiredSize = first_.filesize - secondFileOffset;
|
||||
u32 desiredSize = track_.fileSize - secondFileOffset;
|
||||
|
||||
// 3 seems to be the number of frames required to handle a loop.
|
||||
if (secondBufferSize < desiredSize && secondBufferSize < (u32)BytesPerFrame() * 3) {
|
||||
|
@ -689,6 +705,19 @@ u32 Atrac::SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) {
|
|||
return hleLogSuccessI(ME, 0);
|
||||
}
|
||||
|
||||
int Atrac::GetSecondBufferInfo(u32 *fileOffset, u32 *desiredSize) {
|
||||
if (BufferState() != ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER) {
|
||||
// Writes zeroes in this error case.
|
||||
*fileOffset = 0;
|
||||
*desiredSize = 0;
|
||||
return hleLogWarning(ME, ATRAC_ERROR_SECOND_BUFFER_NOT_NEEDED, "not needed");
|
||||
}
|
||||
|
||||
*fileOffset = FileOffsetBySample(loopEndSample_ - firstSampleOffset_);
|
||||
*desiredSize = track_.fileSize - *fileOffset;
|
||||
return hleLogSuccessI(ME, 0);
|
||||
}
|
||||
|
||||
void Atrac::UpdateBitrate() {
|
||||
bitrate_ = (bytesPerFrame_ * 352800) / 1000;
|
||||
if (codecType_ == PSP_MODE_AT_3_PLUS)
|
||||
|
@ -705,15 +734,15 @@ int Atrac::AddStreamData(u32 bytesToAdd) {
|
|||
|
||||
if (bytesToAdd > 0) {
|
||||
first_.fileoffset = readOffset;
|
||||
int addbytes = std::min(bytesToAdd, first_.filesize - first_.fileoffset);
|
||||
int addbytes = std::min(bytesToAdd, track_.fileSize - first_.fileoffset);
|
||||
if (!ignoreDataBuf_) {
|
||||
Memory::Memcpy(dataBuf_ + first_.fileoffset, first_.addr + first_.offset, addbytes, "AtracAddStreamData");
|
||||
}
|
||||
first_.fileoffset += addbytes;
|
||||
}
|
||||
first_.size += bytesToAdd;
|
||||
if (first_.size >= first_.filesize) {
|
||||
first_.size = first_.filesize;
|
||||
if (first_.size >= track_.fileSize) {
|
||||
first_.size = track_.fileSize;
|
||||
if (bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER)
|
||||
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
|
||||
WriteContextToPSPMem();
|
||||
|
@ -731,11 +760,11 @@ int Atrac::AddStreamData(u32 bytesToAdd) {
|
|||
}
|
||||
|
||||
u32 Atrac::AddStreamDataSas(u32 bufPtr, u32 bytesToAdd) {
|
||||
int addbytes = std::min(bytesToAdd, first_.filesize - first_.fileoffset - FirstOffsetExtra());
|
||||
int addbytes = std::min(bytesToAdd, track_.fileSize - first_.fileoffset - FirstOffsetExtra());
|
||||
Memory::Memcpy(dataBuf_ + first_.fileoffset + FirstOffsetExtra(), bufPtr, addbytes, "AtracAddStreamData");
|
||||
first_.size += bytesToAdd;
|
||||
if (first_.size >= first_.filesize) {
|
||||
first_.size = first_.filesize;
|
||||
if (first_.size >= track_.fileSize) {
|
||||
first_.size = track_.fileSize;
|
||||
if (bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER)
|
||||
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
|
||||
}
|
||||
|
@ -811,7 +840,7 @@ int Atrac::RemainingFrames() const {
|
|||
}
|
||||
|
||||
u32 currentFileOffset = FileOffsetBySample(currentSample_ - SamplesPerFrame() + FirstOffsetExtra());
|
||||
if (first_.fileoffset >= first_.filesize) {
|
||||
if (first_.fileoffset >= track_.fileSize) {
|
||||
if (bufferState_ == ATRAC_STATUS_STREAMED_WITHOUT_LOOP) {
|
||||
return PSP_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY;
|
||||
}
|
||||
|
@ -932,7 +961,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
if (!gotFrame && currentSample_ < endSample_) {
|
||||
// Never got a frame. We may have dropped a GHA frame or otherwise have a bug.
|
||||
// For now, let's try to provide an extra "frame" if possible so games don't infinite loop.
|
||||
if (FileOffsetBySample(currentSample_) < first_.filesize) {
|
||||
if (FileOffsetBySample(currentSample_) < track_.fileSize) {
|
||||
numSamples = std::min(maxSamples, SamplesPerFrame());
|
||||
u32 outBytes = numSamples * outputChannels_ * sizeof(s16);
|
||||
if (outbuf != nullptr) {
|
||||
|
@ -951,7 +980,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
|
||||
int finishFlag = 0;
|
||||
// TODO: Verify.
|
||||
bool hitEnd = currentSample_ >= endSample_ || (numSamples == 0 && first_.size >= first_.filesize);
|
||||
bool hitEnd = currentSample_ >= endSample_ || (numSamples == 0 && first_.size >= track_.fileSize);
|
||||
int loopEndAdjusted = loopEndSample_ - FirstOffsetExtra() - firstSampleOffset_;
|
||||
if ((hitEnd || currentSample_ > loopEndAdjusted) && loopNum != 0) {
|
||||
SeekToSample(loopStartSample_ - FirstOffsetExtra() - firstSampleOffset_);
|
||||
|
@ -1020,12 +1049,12 @@ u32 Atrac::ResetPlayPosition(int sample, int bytesWrittenFirstBuf, int bytesWrit
|
|||
}
|
||||
|
||||
// Did we transition to a full buffer?
|
||||
if (first_.size >= first_.filesize) {
|
||||
first_.size = first_.filesize;
|
||||
if (first_.size >= track_.fileSize) {
|
||||
first_.size = track_.fileSize;
|
||||
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
|
||||
}
|
||||
} else {
|
||||
if (bufferInfo.first.filePos > first_.filesize) {
|
||||
if (bufferInfo.first.filePos > track_.fileSize) {
|
||||
return hleDelayResult(hleLogError(ME, ATRAC_ERROR_API_FAIL, "invalid file position"), "reset play pos", 200);
|
||||
}
|
||||
|
||||
|
@ -1074,7 +1103,7 @@ void Atrac::InitLowLevel(u32 paramsAddr, bool jointStereo) {
|
|||
|
||||
dataOff_ = 0;
|
||||
first_.size = 0;
|
||||
first_.filesize = bytesPerFrame_;
|
||||
track_.fileSize = bytesPerFrame_; // not really meaningful
|
||||
bufferState_ = ATRAC_STATUS_LOW_LEVEL;
|
||||
currentSample_ = 0;
|
||||
CreateDecoder();
|
||||
|
|
|
@ -72,6 +72,8 @@ const int PSP_ATRAC_ALLDATA_IS_ON_MEMORY = -1;
|
|||
const int PSP_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY = -2;
|
||||
const int PSP_ATRAC_LOOP_STREAM_DATA_IS_ON_MEMORY = -3;
|
||||
|
||||
// This is not a PSP-native struct.
|
||||
// But, it's stored in its entirety in savestates, which makes it awkward to change it.
|
||||
struct InputBuffer {
|
||||
// Address of the buffer.
|
||||
u32 addr;
|
||||
|
@ -84,7 +86,7 @@ struct InputBuffer {
|
|||
// Unused, always 0.
|
||||
u32 neededBytes;
|
||||
// Total size of the entire file data.
|
||||
u32 filesize;
|
||||
u32 _filesize_dontuse;
|
||||
// Offset into the file at which new data is read.
|
||||
u32 fileoffset;
|
||||
};
|
||||
|
@ -104,6 +106,10 @@ inline u32 FirstOffsetExtra(int codecType) {
|
|||
return codecType == PSP_MODE_AT_3_PLUS ? 368 : 69;
|
||||
}
|
||||
|
||||
struct Track {
|
||||
u32 fileSize;
|
||||
};
|
||||
|
||||
struct Atrac {
|
||||
~Atrac() {
|
||||
ResetData();
|
||||
|
@ -111,8 +117,8 @@ struct Atrac {
|
|||
|
||||
void ResetData();
|
||||
void UpdateBufferState() {
|
||||
if (bufferMaxSize_ >= first_.filesize) {
|
||||
if (first_.size < first_.filesize) {
|
||||
if (bufferMaxSize_ >= track_.fileSize) {
|
||||
if (first_.size < track_.fileSize) {
|
||||
// The buffer is big enough, but we don't have all the data yet.
|
||||
bufferState_ = ATRAC_STATUS_HALFWAY_BUFFER;
|
||||
} else {
|
||||
|
@ -185,6 +191,8 @@ struct Atrac {
|
|||
InputBuffer first_{};
|
||||
InputBuffer second_{};
|
||||
|
||||
Track track_{};
|
||||
|
||||
PSPPointer<SceAtracContext> context_{};
|
||||
|
||||
AtracStatus BufferState() const {
|
||||
|
@ -239,6 +247,7 @@ struct Atrac {
|
|||
void GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample);
|
||||
int SetData(u32 buffer, u32 readSize, u32 bufferSize, int successCode = 0);
|
||||
u32 SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize);
|
||||
int GetSecondBufferInfo(u32 *fileOffset, u32 *desiredSize);
|
||||
u32 DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains);
|
||||
void ConsumeFrame();
|
||||
u32 GetNextSamples();
|
||||
|
|
|
@ -462,17 +462,7 @@ static u32 sceAtracGetSecondBufferInfo(int atracID, u32 fileOffsetAddr, u32 desi
|
|||
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid addresses");
|
||||
}
|
||||
|
||||
if (atrac->BufferState() != ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER) {
|
||||
// Writes zeroes in this error case.
|
||||
*fileOffset = 0;
|
||||
*desiredSize = 0;
|
||||
return hleLogWarning(ME, ATRAC_ERROR_SECOND_BUFFER_NOT_NEEDED, "not needed");
|
||||
}
|
||||
|
||||
*fileOffset = atrac->FileOffsetBySample(atrac->loopEndSample_ - atrac->firstSampleOffset_);
|
||||
*desiredSize = atrac->first_.filesize - *fileOffset;
|
||||
|
||||
return hleLogSuccessI(ME, 0);
|
||||
return atrac->GetSecondBufferInfo(fileOffset, desiredSize);
|
||||
}
|
||||
|
||||
static u32 sceAtracGetSoundSample(int atracID, u32 outEndSampleAddr, u32 outLoopStartSampleAddr, u32 outLoopEndSampleAddr) {
|
||||
|
|
Loading…
Add table
Reference in a new issue