mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Slim down the AtracBase class
This commit is contained in:
parent
6c648a2cdd
commit
5e8a46fde0
3 changed files with 70 additions and 75 deletions
|
@ -217,7 +217,7 @@ void Atrac::WriteContextToPSPMem() {
|
|||
context->info.endSample = track_.endSample + track_.firstSampleOffset + FirstOffsetExtra();
|
||||
context->info.dataEnd = track_.fileSize;
|
||||
context->info.curOff = first_.fileoffset;
|
||||
context->info.decodePos = DecodePosBySample(currentSample_);
|
||||
context->info.decodePos = track_.DecodePosBySample(currentSample_);
|
||||
context->info.streamDataByte = first_.size - track_.dataOff;
|
||||
|
||||
u8 *buf = (u8 *)context;
|
||||
|
@ -537,7 +537,7 @@ void Atrac::CalculateStreamInfo(u32 *outReadOffset) {
|
|||
first_.offset = 0;
|
||||
first_.writableBytes = 0;
|
||||
} else {
|
||||
readOffset = FileOffsetBySample(track_.loopStartSample - FirstOffsetExtra() - track_.firstSampleOffset - track_.SamplesPerFrame() * 2);
|
||||
readOffset = track_.FileOffsetBySample(track_.loopStartSample - FirstOffsetExtra() - track_.firstSampleOffset - track_.SamplesPerFrame() * 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -592,7 +592,7 @@ void Atrac::GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample) {
|
|||
// This is because we're filling the buffer start to finish, not streaming.
|
||||
bufferInfo->first.writePosPtr = first_.addr + first_.size;
|
||||
bufferInfo->first.writableBytes = track_.fileSize - first_.size;
|
||||
int minWriteBytes = FileOffsetBySample(sample) - first_.size;
|
||||
int minWriteBytes = track_.FileOffsetBySample(sample) - first_.size;
|
||||
if (minWriteBytes > 0) {
|
||||
bufferInfo->first.minWriteBytes = minWriteBytes;
|
||||
} else {
|
||||
|
@ -601,7 +601,7 @@ void Atrac::GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample) {
|
|||
bufferInfo->first.filePos = first_.size;
|
||||
} else {
|
||||
// This is without the sample offset. The file offset also includes the previous batch of samples?
|
||||
int sampleFileOffset = FileOffsetBySample(sample - track_.firstSampleOffset - track_.SamplesPerFrame());
|
||||
int sampleFileOffset = track_.FileOffsetBySample(sample - track_.firstSampleOffset - track_.SamplesPerFrame());
|
||||
|
||||
// Update the writable bytes. When streaming, this is just the number of bytes until the end.
|
||||
const u32 bufSizeAligned = (bufferMaxSize_ / track_.bytesPerFrame) * track_.bytesPerFrame;
|
||||
|
@ -688,7 +688,7 @@ int Atrac::SetData(u32 buffer, u32 readSize, u32 bufferSize, int outputChannels,
|
|||
}
|
||||
|
||||
u32 Atrac::SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) {
|
||||
u32 secondFileOffset = FileOffsetBySample(track_.loopEndSample - track_.firstSampleOffset);
|
||||
u32 secondFileOffset = track_.FileOffsetBySample(track_.loopEndSample - track_.firstSampleOffset);
|
||||
u32 desiredSize = track_.fileSize - secondFileOffset;
|
||||
|
||||
// 3 seems to be the number of frames required to handle a loop.
|
||||
|
@ -713,7 +713,7 @@ int Atrac::GetSecondBufferInfo(u32 *fileOffset, u32 *desiredSize) {
|
|||
return hleLogWarning(ME, ATRAC_ERROR_SECOND_BUFFER_NOT_NEEDED, "not needed");
|
||||
}
|
||||
|
||||
*fileOffset = FileOffsetBySample(track_.loopEndSample - track_.firstSampleOffset);
|
||||
*fileOffset = track_.FileOffsetBySample(track_.loopEndSample - track_.firstSampleOffset);
|
||||
*desiredSize = track_.fileSize - *fileOffset;
|
||||
return hleLogSuccessI(ME, 0);
|
||||
}
|
||||
|
@ -728,6 +728,26 @@ void Atrac::GetStreamDataInfo(u32 *writePtr, u32 *writableBytes, u32 *readOffset
|
|||
*readOffset = calculatedReadOffset;
|
||||
}
|
||||
|
||||
void Atrac::UpdateBufferState() {
|
||||
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 {
|
||||
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
|
||||
}
|
||||
} else {
|
||||
if (track_.loopEndSample <= 0) {
|
||||
// There's no looping, but we need to stream the data in our buffer.
|
||||
bufferState_ = ATRAC_STATUS_STREAMED_WITHOUT_LOOP;
|
||||
} else if (track_.loopEndSample == track_.endSample + track_.firstSampleOffset + (int)FirstOffsetExtra()) {
|
||||
bufferState_ = ATRAC_STATUS_STREAMED_LOOP_FROM_END;
|
||||
} else {
|
||||
bufferState_ = ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Atrac::AddStreamData(u32 bytesToAdd) {
|
||||
u32 readOffset;
|
||||
CalculateStreamInfo(&readOffset);
|
||||
|
@ -819,7 +839,7 @@ void Atrac::SeekToSample(int sample) {
|
|||
int offsetSamples = track_.firstSampleOffset + FirstOffsetExtra();
|
||||
adjust = -(int)(offsetSamples % track_.SamplesPerFrame());
|
||||
}
|
||||
const u32 off = FileOffsetBySample(sample + adjust);
|
||||
const u32 off = track_.FileOffsetBySample(sample + adjust);
|
||||
const u32 backfill = track_.bytesPerFrame * 2;
|
||||
const u32 start = off - track_.dataOff < backfill ? track_.dataOff : off - backfill;
|
||||
|
||||
|
@ -837,7 +857,7 @@ int Atrac::RemainingFrames() const {
|
|||
return PSP_ATRAC_ALLDATA_IS_ON_MEMORY;
|
||||
}
|
||||
|
||||
u32 currentFileOffset = FileOffsetBySample(currentSample_ - track_.SamplesPerFrame() + FirstOffsetExtra());
|
||||
u32 currentFileOffset = track_.FileOffsetBySample(currentSample_ - track_.SamplesPerFrame() + FirstOffsetExtra());
|
||||
if (first_.fileoffset >= track_.fileSize) {
|
||||
if (bufferState_ == ATRAC_STATUS_STREAMED_WITHOUT_LOOP) {
|
||||
return PSP_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY;
|
||||
|
@ -921,7 +941,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
SeekToSample(currentSample_);
|
||||
|
||||
bool gotFrame = false;
|
||||
u32 off = FileOffsetBySample(currentSample_ - skipSamples);
|
||||
u32 off = track_.FileOffsetBySample(currentSample_ - skipSamples);
|
||||
if (off < first_.size) {
|
||||
uint8_t *indata = BufferStart() + off;
|
||||
int bytesConsumed = 0;
|
||||
|
@ -957,7 +977,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
if (!gotFrame && currentSample_ < track_.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_) < track_.fileSize) {
|
||||
if (track_.FileOffsetBySample(currentSample_) < track_.fileSize) {
|
||||
numSamples = std::min(maxSamples, track_.SamplesPerFrame());
|
||||
u32 outBytes = numSamples * outputChannels_ * sizeof(s16);
|
||||
if (outbuf != nullptr) {
|
||||
|
@ -970,7 +990,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
*SamplesNum = numSamples;
|
||||
// update current sample and decodePos
|
||||
currentSample_ += numSamples;
|
||||
decodePos_ = DecodePosBySample(currentSample_);
|
||||
decodePos_ = track_.DecodePosBySample(currentSample_);
|
||||
|
||||
ConsumeFrame();
|
||||
|
||||
|
@ -986,11 +1006,11 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
}
|
||||
if ((bufferState_ & ATRAC_STATUS_STREAMED_MASK) == ATRAC_STATUS_STREAMED_MASK) {
|
||||
// Whatever bytes we have left were added from the loop.
|
||||
u32 loopOffset = FileOffsetBySample(track_.loopStartSample - FirstOffsetExtra() - track_.firstSampleOffset - track_.SamplesPerFrame() * 2);
|
||||
u32 loopOffset = track_.FileOffsetBySample(track_.loopStartSample - FirstOffsetExtra() - track_.firstSampleOffset - track_.SamplesPerFrame() * 2);
|
||||
// TODO: Hmm, need to manage the buffer better. But don't move fileoffset if we already have valid data.
|
||||
if (loopOffset > first_.fileoffset || loopOffset + bufferValidBytes_ < first_.fileoffset) {
|
||||
// Skip the initial frame at the start.
|
||||
first_.fileoffset = FileOffsetBySample(track_.loopStartSample - FirstOffsetExtra() - track_.firstSampleOffset - track_.SamplesPerFrame() * 2);
|
||||
first_.fileoffset = track_.FileOffsetBySample(track_.loopStartSample - FirstOffsetExtra() - track_.firstSampleOffset - track_.SamplesPerFrame() * 2);
|
||||
}
|
||||
}
|
||||
} else if (hitEnd) {
|
||||
|
|
|
@ -141,6 +141,16 @@ struct Track {
|
|||
bitrate = (bitrate + 511) >> 10;
|
||||
}
|
||||
|
||||
u32 DecodePosBySample(int sample) const {
|
||||
return (u32)(firstSampleOffset + sample / (int)SamplesPerFrame() * bytesPerFrame);
|
||||
}
|
||||
|
||||
u32 FileOffsetBySample(int sample) const {
|
||||
int offsetSample = sample + firstSampleOffset;
|
||||
int frameOffset = offsetSample / (int)SamplesPerFrame();
|
||||
return (u32)(dataOff + bytesPerFrame + frameOffset * bytesPerFrame);
|
||||
}
|
||||
|
||||
void AnalyzeReset() {
|
||||
endSample = -1;
|
||||
loopinfo.clear();
|
||||
|
@ -157,20 +167,9 @@ int AnalyzeAtracTrack(u32 addr, u32 size, Track *track);
|
|||
class AtracBase {
|
||||
public:
|
||||
virtual ~AtracBase() {}
|
||||
virtual void UpdateBufferState() = 0;
|
||||
|
||||
virtual void DoState(PointerWrap &p) = 0;
|
||||
|
||||
u32 DecodePosBySample(int sample) const {
|
||||
return (u32)(track_.firstSampleOffset + sample / (int)track_.SamplesPerFrame() * track_.bytesPerFrame);
|
||||
}
|
||||
|
||||
u32 FileOffsetBySample(int sample) const {
|
||||
int offsetSample = sample + track_.firstSampleOffset;
|
||||
int frameOffset = offsetSample / (int)track_.SamplesPerFrame();
|
||||
return (u32)(track_.dataOff + track_.bytesPerFrame + frameOffset * track_.bytesPerFrame);
|
||||
}
|
||||
|
||||
const Track &GetTrack() const {
|
||||
return track_;
|
||||
}
|
||||
|
@ -179,21 +178,11 @@ public:
|
|||
return track_;
|
||||
}
|
||||
|
||||
int Bitrate() const {
|
||||
return track_.bitrate;
|
||||
}
|
||||
int Channels() const {
|
||||
return track_.channels;
|
||||
}
|
||||
|
||||
int GetOutputChannels() const {
|
||||
return outputChannels_;
|
||||
}
|
||||
|
||||
int atracID_ = -1;
|
||||
u16 outputChannels_ = 2;
|
||||
int loopNum_ = 0;
|
||||
Track track_{};
|
||||
|
||||
PSPPointer<SceAtracContext> context_{};
|
||||
|
||||
|
@ -201,15 +190,19 @@ public:
|
|||
return bufferState_;
|
||||
}
|
||||
|
||||
int LoopNum() const {
|
||||
return loopNum_;
|
||||
}
|
||||
u32 CodecType() const {
|
||||
return track_.codecType;
|
||||
}
|
||||
AudioDecoder *GetDecoder() const {
|
||||
AudioDecoder *Decoder() const {
|
||||
return decoder_;
|
||||
}
|
||||
u32 FirstOffsetExtra() const {
|
||||
return ::FirstOffsetExtra(track_.codecType);
|
||||
}
|
||||
|
||||
void CreateDecoder();
|
||||
|
||||
virtual uint32_t CurBufferAddress(int adjust = 0) const = 0;
|
||||
|
@ -232,8 +225,6 @@ public:
|
|||
virtual int SetData(u32 buffer, u32 readSize, u32 bufferSize, int outputChannels, int successCode) = 0;
|
||||
virtual u32 SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) = 0;
|
||||
virtual int GetSecondBufferInfo(u32 *fileOffset, u32 *desiredSize) = 0;
|
||||
virtual void ForceSeekToSample(int sample) = 0;
|
||||
virtual void SeekToSample(int sample) = 0;
|
||||
virtual u32 DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains) = 0;
|
||||
virtual u32 GetNextSamples() = 0;
|
||||
virtual void InitLowLevel(u32 paramsAddr, bool jointStereo) = 0;
|
||||
|
@ -241,6 +232,10 @@ public:
|
|||
protected:
|
||||
virtual void AnalyzeReset() = 0;
|
||||
|
||||
Track track_{};
|
||||
u16 outputChannels_ = 2;
|
||||
int loopNum_ = 0;
|
||||
|
||||
// TODO: Save the internal state of this, now technically possible.
|
||||
AudioDecoder *decoder_ = nullptr;
|
||||
AtracStatus bufferState_ = ATRAC_STATUS_NO_DATA;
|
||||
|
@ -251,30 +246,9 @@ public:
|
|||
~Atrac() {
|
||||
ResetData();
|
||||
}
|
||||
void ResetData();
|
||||
|
||||
virtual void UpdateBufferState() {
|
||||
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 {
|
||||
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
|
||||
}
|
||||
} else {
|
||||
if (track_.loopEndSample <= 0) {
|
||||
// There's no looping, but we need to stream the data in our buffer.
|
||||
bufferState_ = ATRAC_STATUS_STREAMED_WITHOUT_LOOP;
|
||||
} else if (track_.loopEndSample == track_.endSample + track_.firstSampleOffset + (int)FirstOffsetExtra()) {
|
||||
bufferState_ = ATRAC_STATUS_STREAMED_LOOP_FROM_END;
|
||||
} else {
|
||||
bufferState_ = ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CurBufferAddress(int adjust = 0) const override {
|
||||
u32 off = FileOffsetBySample(currentSample_ + adjust);
|
||||
u32 off = track_.FileOffsetBySample(currentSample_ + adjust);
|
||||
if (off < first_.size && ignoreDataBuf_) {
|
||||
return first_.addr + off;
|
||||
}
|
||||
|
@ -309,22 +283,18 @@ public:
|
|||
int SetData(u32 buffer, u32 readSize, u32 bufferSize, int outputChannels, int successCode) override;
|
||||
u32 SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) override;
|
||||
int GetSecondBufferInfo(u32 *fileOffset, u32 *desiredSize) override;
|
||||
void ForceSeekToSample(int sample) override;
|
||||
void SeekToSample(int sample) override;
|
||||
u32 DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains) override;
|
||||
u32 GetNextSamples() override;
|
||||
void InitLowLevel(u32 paramsAddr, bool jointStereo);
|
||||
|
||||
// Indicates that the dataBuf_ array should not be used.
|
||||
u8 *dataBuf_ = nullptr;
|
||||
|
||||
InputBuffer first_{};
|
||||
InputBuffer second_{};
|
||||
|
||||
protected:
|
||||
void AnalyzeReset();
|
||||
|
||||
private:
|
||||
void UpdateBufferState();
|
||||
void ResetData();
|
||||
void SeekToSample(int sample);
|
||||
void ForceSeekToSample(int sample);
|
||||
u32 StreamBufferEnd() const {
|
||||
// The buffer is always aligned to a frame in size, not counting an optional header.
|
||||
// The header will only initially exist after the data is first set.
|
||||
|
@ -334,6 +304,11 @@ private:
|
|||
void ConsumeFrame();
|
||||
void CalculateStreamInfo(u32 *readOffset);
|
||||
|
||||
InputBuffer first_{};
|
||||
InputBuffer second_{};
|
||||
|
||||
u8 *dataBuf_ = nullptr;
|
||||
// Indicates that the dataBuf_ array should not be used.
|
||||
bool ignoreDataBuf_ = false;
|
||||
|
||||
int currentSample_ = 0;
|
||||
|
|
|
@ -176,7 +176,7 @@ static u32 sceAtracGetAtracID(int codecType) {
|
|||
}
|
||||
|
||||
AtracBase *atrac = new Atrac();
|
||||
atrac->track_.codecType = codecType;
|
||||
atrac->GetTrackMut().codecType = codecType;
|
||||
int atracID = createAtrac(atrac);
|
||||
if (atracID < 0) {
|
||||
delete atrac;
|
||||
|
@ -310,7 +310,7 @@ static u32 sceAtracGetBitrate(int atracID, u32 outBitrateAddr) {
|
|||
atrac->GetTrackMut().UpdateBitrate();
|
||||
|
||||
if (Memory::IsValidAddress(outBitrateAddr)) {
|
||||
Memory::WriteUnchecked_U32(atrac->Bitrate(), outBitrateAddr);
|
||||
Memory::WriteUnchecked_U32(atrac->GetTrack().bitrate, outBitrateAddr);
|
||||
return hleLogSuccessI(ME, 0);
|
||||
} else {
|
||||
return hleLogError(ME, 0, "invalid address");
|
||||
|
@ -326,7 +326,7 @@ static u32 sceAtracGetChannel(int atracID, u32 channelAddr) {
|
|||
}
|
||||
|
||||
if (Memory::IsValidAddress(channelAddr)){
|
||||
Memory::WriteUnchecked_U32(atrac->Channels(), channelAddr);
|
||||
Memory::WriteUnchecked_U32(atrac->GetTrack().channels, channelAddr);
|
||||
return hleLogSuccessI(ME, 0);
|
||||
} else {
|
||||
return hleLogError(ME, 0, "invalid address");
|
||||
|
@ -342,7 +342,7 @@ static u32 sceAtracGetLoopStatus(int atracID, u32 loopNumAddr, u32 statusAddr) {
|
|||
}
|
||||
|
||||
if (Memory::IsValidAddress(loopNumAddr))
|
||||
Memory::WriteUnchecked_U32(atrac->loopNum_, loopNumAddr);
|
||||
Memory::WriteUnchecked_U32(atrac->LoopNum(), loopNumAddr);
|
||||
// return audio's loopinfo in at3 file
|
||||
if (Memory::IsValidAddress(statusAddr)) {
|
||||
if (atrac->GetTrack().loopinfo.size() > 0)
|
||||
|
@ -603,7 +603,7 @@ static u32 sceAtracSetData(int atracID, u32 buffer, u32 bufferSize) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (atrac->track_.codecType != atracContextTypes[atracID]) {
|
||||
if (atrac->GetTrack().codecType != atracContextTypes[atracID]) {
|
||||
// TODO: Should this not change the buffer size?
|
||||
return hleReportError(ME, ATRAC_ERROR_WRONG_CODECTYPE, "atracID uses different codec type than data");
|
||||
}
|
||||
|
@ -883,7 +883,7 @@ struct At3HeaderMap {
|
|||
u8 jointStereo;
|
||||
|
||||
bool Matches(const AtracBase *at) const {
|
||||
return bytes == at->GetTrack().BytesPerFrame() && channels == at->Channels();
|
||||
return bytes == at->GetTrack().BytesPerFrame() && channels == at->GetTrack().channels;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -919,7 +919,7 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) {
|
|||
}
|
||||
}
|
||||
if (!found) {
|
||||
ERROR_LOG_REPORT(ME, "AT3 header map lacks entry for bpf: %i channels: %i", atrac->GetTrack().BytesPerFrame(), atrac->Channels());
|
||||
ERROR_LOG_REPORT(ME, "AT3 header map lacks entry for bpf: %i channels: %i", atrac->GetTrack().BytesPerFrame(), atrac->GetTrack().channels);
|
||||
// TODO: Should we return an error code for these values?
|
||||
}
|
||||
}
|
||||
|
@ -949,7 +949,7 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo
|
|||
|
||||
int bytesConsumed = 0;
|
||||
int bytesWritten = 0;
|
||||
atrac->GetDecoder()->Decode(srcp, atrac->GetTrack().BytesPerFrame(), &bytesConsumed, 2, outp, &bytesWritten);
|
||||
atrac->Decoder()->Decode(srcp, atrac->GetTrack().BytesPerFrame(), &bytesConsumed, 2, outp, &bytesWritten);
|
||||
*srcConsumed = bytesConsumed;
|
||||
*outWritten = bytesWritten;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue