#pragma once
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/Swap.h"
#include "Core/MemMap.h"
#include "Core/HLE/AtracBase.h"
#include "Core/Util/AtracTrack.h"
class Atrac : public AtracBase {
public:
Atrac(int atracID, int codecType = 0) : atracID_(atracID) {
if (codecType) {
track_.codecType = codecType;
}
}
~Atrac();
uint32_t CurBufferAddress(int adjust = 0) const {
u32 off = track_.FileOffsetBySample(currentSample_ + adjust);
if (off < first_.size && ignoreDataBuf_) {
return first_.addr + off;
}
return 0;
}
u8 *BufferStart();
AtracStatus BufferState() const override {
return bufferState_;
}
void DoState(PointerWrap &p) override;
int GetNextDecodePosition(int *pos) const override;
int RemainingFrames() const override;
int CodecType() const override {
return track_.codecType;
}
bool HasSecondBuffer() const override {
return second_.size != 0;
}
int Channels() const override {
return track_.channels;
}
int LoopNum() const override {
return loopNum_;
}
int LoopStatus() const override {
if (track_.loopinfo.size() > 0)
return 1;
else
return 0;
}
int Bitrate() const override {
return track_.Bitrate();
}
int BytesPerFrame() const override {
return track_.BytesPerFrame();
}
int SamplesPerFrame() const override {
return track_.SamplesPerFrame();
}
Track &GetTrackMut() {
return track_;
}
int SetLoopNum(int loopNum) override;
void GetStreamDataInfo(u32 *writePtr, u32 *writableBytes, u32 *readOffset) override;
int AddStreamData(u32 bytesToAdd) override;
int ResetPlayPosition(int sample, int bytesWrittenFirstBuf, int bytesWrittenSecondBuf, bool *delay) override;
int GetBufferInfoForResetting(AtracResetBufferInfo *bufferInfo, int sample, bool *delay) override;
int SetData(const Track &track, u32 buffer, u32 readSize, u32 bufferSize, u32 fileSize, int outputChannels, bool isAA3) override;
int GetSecondBufferInfo(u32 *fileOffset, u32 *desiredSize) const override;
int SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) override;
u32 DecodeData(u8 *outbuf, u32 outbufPtr, int *SamplesNum, int *finish, int *remains) override;
int DecodeLowLevel(const u8 *srcData, int *bytesConsumed, s16 *dstData, int *bytesWritten) override;
void CheckForSas() override;
int EnqueueForSas(u32 address, u32 ptr) override;
void DecodeForSas(s16 *dstData, int *bytesWritten, int *finish) override;
u32 GetNextSamples() override;
void InitLowLevel(const Atrac3LowLevelParams ¶ms, int codecType) override;
int GetSoundSample(int *endSample, int *loopStartSample, int *loopEndSample) const override;
void NotifyGetContextAddress() override;
void UpdateContextFromPSPMem() override;
void WriteContextToPSPMem();
int GetContextVersion() const override { return 1; }
private:
void UpdateBufferState();
void ResetData();
void SeekToSample(int sample);
void ForceSeekToSample(int sample);
u32 StreamBufferEnd() const {
u32 framesAfterHeader = (bufferMaxSize_ - bufferHeaderSize_) / track_.bytesPerFrame;
return framesAfterHeader * track_.bytesPerFrame + bufferHeaderSize_;
}
void ConsumeFrame();
void CalculateStreamInfo(u32 *readOffset);
Track track_{};
InputBuffer first_{};
InputBuffer second_{};
u8 *dataBuf_ = nullptr;
bool ignoreDataBuf_ = false;
int currentSample_ = 0;
u32 decodePos_ = 0;
u32 bufferMaxSize_ = 0;
int loopNum_ = 0;
u32 bufferPos_ = 0;
u32 bufferValidBytes_ = 0;
u32 bufferHeaderSize_ = 0;
int atracID_ = -1;
AtracStatus bufferState_ = ATRAC_STATUS_NO_DATA;
};