mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Atrac2 track_ removal, part 1
This commit is contained in:
parent
5363159610
commit
02f06faad1
5 changed files with 54 additions and 72 deletions
|
@ -230,7 +230,7 @@ void Atrac::WriteContextToPSPMem() {
|
|||
NotifyMemInfo(MemBlockFlags::WRITE, context_.ptr, sizeof(SceAtracContext), "AtracContext");
|
||||
}
|
||||
|
||||
void Track::DebugLog() {
|
||||
void Track::DebugLog() const {
|
||||
DEBUG_LOG(Log::ME, "ATRAC analyzed: %s channels: %d filesize: %d bitrate: %d kbps jointStereo: %d",
|
||||
codecType == PSP_MODE_AT_3 ? "AT3" : "AT3Plus", channels, fileSize, bitrate / 1024, jointStereo);
|
||||
DEBUG_LOG(Log::ME, "dataoff: %d firstSampleOffset: %d endSample: %d", dataByteOffset, firstSampleOffset, endSample);
|
||||
|
@ -691,9 +691,9 @@ int Atrac::SetData(const Track &track, u32 buffer, u32 readSize, u32 bufferSize,
|
|||
bufferPos_ = 0;
|
||||
outputChannels_ = outputChannels;
|
||||
|
||||
track.DebugLog();
|
||||
track_ = track;
|
||||
first_._filesize_dontuse = track_.fileSize;
|
||||
track_.DebugLog();
|
||||
|
||||
if (outputChannels != track_.channels) {
|
||||
WARN_LOG(Log::ME, "Atrac::SetData: outputChannels %d doesn't match track_.channels %d", outputChannels, track_.channels);
|
||||
|
|
|
@ -161,7 +161,7 @@ struct Track {
|
|||
return (u32)(dataByteOffset + bytesPerFrame + frameOffset * bytesPerFrame);
|
||||
}
|
||||
|
||||
void DebugLog();
|
||||
void DebugLog() const;
|
||||
};
|
||||
|
||||
int AnalyzeAA3Track(u32 addr, u32 size, u32 filesize, Track *track);
|
||||
|
|
|
@ -437,10 +437,13 @@ u32 Atrac2::GetNextSamples() {
|
|||
|
||||
int Atrac2::GetNextDecodePosition(int *pos) const {
|
||||
const SceAtracIdInfo &info = context_->info;
|
||||
const int currentSample = info.decodePos - track_.FirstSampleOffsetFull();
|
||||
// Check if we reached the end.
|
||||
int firstSampleOffsetFull = track_.FirstSampleOffsetFull();
|
||||
const int currentSample = info.decodePos - info.firstValidSample;
|
||||
if (currentSample >= track_.endSample) {
|
||||
return SCE_ERROR_ATRAC_ALL_DATA_DECODED;
|
||||
}
|
||||
// Check if remaining data in the file is smaller than a frame.
|
||||
if (info.fileDataEnd - info.curFileOff < info.sampleSize) {
|
||||
return SCE_ERROR_ATRAC_ALL_DATA_DECODED;
|
||||
}
|
||||
|
@ -675,7 +678,7 @@ u32 Atrac2::DecodeInternal(u32 outbufAddr, u32 *SamplesNum, u32 *finish) {
|
|||
|
||||
int bytesConsumed = 0;
|
||||
int outSamples = 0;
|
||||
if (!decoder_->Decode(Memory::GetPointer(inAddr), track_.bytesPerFrame, &bytesConsumed, outputChannels_, outPtr, &outSamples)) {
|
||||
if (!decoder_->Decode(Memory::GetPointer(inAddr), info.sampleSize, &bytesConsumed, outputChannels_, outPtr, &outSamples)) {
|
||||
// Decode failed.
|
||||
*finish = 0;
|
||||
// TODO: The error code here varies based on what the problem is, but not sure of the right values.
|
||||
|
@ -775,29 +778,29 @@ int Atrac2::SetData(const Track &track, u32 bufferAddr, u32 readSize, u32 buffer
|
|||
}
|
||||
|
||||
// TODO: Remove track_.
|
||||
track.DebugLog();
|
||||
track_ = track;
|
||||
track_.DebugLog();
|
||||
|
||||
SceAtracIdInfo &info = context_->info;
|
||||
|
||||
if (track_.codecType != PSP_MODE_AT_3 && track_.codecType != PSP_MODE_AT_3_PLUS) {
|
||||
if (track.codecType != PSP_MODE_AT_3 && track.codecType != PSP_MODE_AT_3_PLUS) {
|
||||
// Shouldn't have gotten here, Analyze() checks this.
|
||||
ERROR_LOG(Log::ME, "unexpected codec type %d in set data", track_.codecType);
|
||||
ERROR_LOG(Log::ME, "unexpected codec type %d in set data", track.codecType);
|
||||
return SCE_ERROR_ATRAC_UNKNOWN_FORMAT;
|
||||
}
|
||||
|
||||
if (outputChannels != track_.channels) {
|
||||
INFO_LOG(Log::ME, "Atrac2::SetData: outputChannels %d doesn't match track_.channels %d, decoder will expand.", outputChannels, track_.channels);
|
||||
if (outputChannels != track.channels) {
|
||||
INFO_LOG(Log::ME, "Atrac2::SetData: outputChannels %d doesn't match track_.channels %d, decoder will expand.", outputChannels, track.channels);
|
||||
}
|
||||
|
||||
CreateDecoder();
|
||||
|
||||
outputChannels_ = outputChannels;
|
||||
|
||||
if (!track_.loopinfo.empty()) {
|
||||
info.loopNum = track_.loopinfo[0].playCount;
|
||||
info.loopStart = track_.loopStartSample;
|
||||
info.loopEnd = track_.loopEndSample;
|
||||
if (!track.loopinfo.empty()) {
|
||||
info.loopNum = track.loopinfo[0].playCount;
|
||||
info.loopStart = track.loopStartSample;
|
||||
info.loopEnd = track.loopEndSample;
|
||||
} else {
|
||||
info.loopNum = 0;
|
||||
info.loopStart = 0;
|
||||
|
@ -805,20 +808,20 @@ int Atrac2::SetData(const Track &track, u32 bufferAddr, u32 readSize, u32 buffer
|
|||
}
|
||||
|
||||
if (!decodeTemp_) {
|
||||
_dbg_assert_(track_.channels <= 2);
|
||||
decodeTemp_ = new int16_t[track_.SamplesPerFrame() * outputChannels + 1];
|
||||
decodeTemp_[track_.SamplesPerFrame() * outputChannels] = 1337; // Sentinel
|
||||
_dbg_assert_(track.channels <= 2);
|
||||
decodeTemp_ = new int16_t[track.SamplesPerFrame() * outputChannels + 1];
|
||||
decodeTemp_[track.SamplesPerFrame() * outputChannels] = 1337; // Sentinel
|
||||
}
|
||||
|
||||
context_->codec.inBuf = bufferAddr;
|
||||
|
||||
if (readSize > track_.fileSize) {
|
||||
if (readSize > track.fileSize) {
|
||||
// This is seen in Tekken 6.
|
||||
WARN_LOG(Log::ME, "readSize %d > track_.fileSize", readSize, track_.fileSize);
|
||||
readSize = track_.fileSize;
|
||||
WARN_LOG(Log::ME, "readSize %d > track_.fileSize", readSize, track.fileSize);
|
||||
readSize = track.fileSize;
|
||||
}
|
||||
|
||||
if (bufferSize >= track_.fileSize) {
|
||||
if (bufferSize >= track.fileSize) {
|
||||
// Buffer is big enough to fit the whole track.
|
||||
if (readSize < bufferSize) {
|
||||
info.state = ATRAC_STATUS_HALFWAY_BUFFER;
|
||||
|
@ -827,10 +830,10 @@ int Atrac2::SetData(const Track &track, u32 bufferAddr, u32 readSize, u32 buffer
|
|||
}
|
||||
} else {
|
||||
// Streaming cases with various looping types.
|
||||
if (track_.loopEndSample <= 0) {
|
||||
if (track.loopEndSample <= 0) {
|
||||
// There's no looping, but we need to stream the data in our buffer.
|
||||
info.state = ATRAC_STATUS_STREAMED_WITHOUT_LOOP;
|
||||
} else if (track_.loopEndSample == track_.endSample + track_.FirstSampleOffsetFull()) {
|
||||
} else if (track.loopEndSample == track.endSample + track.FirstSampleOffsetFull()) {
|
||||
info.state = ATRAC_STATUS_STREAMED_LOOP_FROM_END;
|
||||
} else {
|
||||
info.state = ATRAC_STATUS_STREAMED_LOOP_WITH_TRAILER;
|
||||
|
@ -839,35 +842,25 @@ int Atrac2::SetData(const Track &track, u32 bufferAddr, u32 readSize, u32 buffer
|
|||
|
||||
INFO_LOG(Log::ME, "Atrac mode setup: %s", AtracStatusToString(info.state));
|
||||
|
||||
int retval = InitContext(bufferAddr, readSize, bufferSize);
|
||||
if (retval != 0) {
|
||||
ERROR_LOG(Log::ME, "InitContext failed, bad data?");
|
||||
return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 Atrac2::InitContext(u32 bufferAddr, u32 readSize, u32 bufferSize) {
|
||||
SceAtracIdInfo &info = context_->info;
|
||||
// Copy parameters into struct.
|
||||
info.codec = track_.codecType;
|
||||
info.numChan = track_.channels;
|
||||
info.sampleSize = track_.bytesPerFrame;
|
||||
// Copy parameters into state struct.
|
||||
info.codec = track.codecType;
|
||||
info.numChan = track.channels;
|
||||
info.sampleSize = track.bytesPerFrame;
|
||||
info.buffer = bufferAddr;
|
||||
info.bufferByte = bufferSize;
|
||||
info.firstValidSample = track_.FirstSampleOffsetFull();
|
||||
info.endSample = track_.endSample + info.firstValidSample;
|
||||
if (track_.loopStartSample != 0xFFFFFFFF) {
|
||||
info.loopStart = track_.loopStartSample;
|
||||
info.loopEnd = track_.loopEndSample;
|
||||
info.firstValidSample = track.FirstSampleOffsetFull();
|
||||
info.endSample = track.endSample + info.firstValidSample;
|
||||
if (track.loopStartSample != 0xFFFFFFFF) {
|
||||
info.loopStart = track.loopStartSample;
|
||||
info.loopEnd = track.loopEndSample;
|
||||
// Sanity check the loop points, useful for testing.
|
||||
}
|
||||
info.dataOff = track_.dataByteOffset;
|
||||
info.curFileOff = track_.dataByteOffset;
|
||||
info.streamOff = track_.dataByteOffset;
|
||||
info.dataOff = track.dataByteOffset;
|
||||
info.curFileOff = track.dataByteOffset;
|
||||
info.streamOff = track.dataByteOffset;
|
||||
info.streamDataByte = readSize - info.dataOff;
|
||||
info.fileDataEnd = track_.fileSize;
|
||||
info.decodePos = track_.FirstSampleOffsetFull();
|
||||
info.fileDataEnd = track.fileSize;
|
||||
info.decodePos = track.FirstSampleOffsetFull();
|
||||
info.numSkipFrames = info.firstValidSample / info.SamplesPerFrame();
|
||||
// NOTE: we do not write into secondBuffer/secondBufferByte! they linger...
|
||||
|
||||
|
@ -966,34 +959,24 @@ int Atrac2::Bitrate() const {
|
|||
void Atrac2::InitLowLevel(u32 paramsAddr, bool jointStereo, int codecType) {
|
||||
// TODO: We shouldn't need to look at track_ later, so we shouldn't need to init it here.
|
||||
// Not true yet.
|
||||
track_ = Track();
|
||||
track_.codecType = codecType;
|
||||
track_.channels = Memory::Read_U32(paramsAddr);
|
||||
outputChannels_ = Memory::Read_U32(paramsAddr + 4);
|
||||
track_.bytesPerFrame = Memory::Read_U32(paramsAddr + 8);
|
||||
if (track_.codecType == PSP_MODE_AT_3) {
|
||||
track_.bitrate = (track_.bytesPerFrame * 352800) / 1000;
|
||||
track_.bitrate = (track_.bitrate + 511) >> 10;
|
||||
track_.jointStereo = false;
|
||||
} else if (track_.codecType == PSP_MODE_AT_3_PLUS) {
|
||||
track_.bitrate = (track_.bytesPerFrame * 352800) / 1000;
|
||||
track_.bitrate = ((track_.bitrate >> 11) + 8) & 0xFFFFFFF0;
|
||||
track_.jointStereo = false;
|
||||
}
|
||||
track_.dataByteOffset = 0;
|
||||
|
||||
context_->info.decodePos = 0;
|
||||
context_->info.state = ATRAC_STATUS_LOW_LEVEL;
|
||||
context_->info.sampleSize = track_.BytesPerFrame();
|
||||
context_->info.numChan = track_.channels;
|
||||
|
||||
SceAtracIdInfo &info = context_->info;
|
||||
info.codec = codecType;
|
||||
info.numChan = Memory::ReadUnchecked_U32(paramsAddr);
|
||||
outputChannels_ = Memory::ReadUnchecked_U32(paramsAddr + 4);
|
||||
info.sampleSize = Memory::ReadUnchecked_U32(paramsAddr + 8);
|
||||
info.dataOff = 0;
|
||||
info.decodePos = 0;
|
||||
info.state = ATRAC_STATUS_LOW_LEVEL;
|
||||
info.numChan = 2;
|
||||
CreateDecoder();
|
||||
}
|
||||
|
||||
int Atrac2::DecodeLowLevel(const u8 *srcData, int *bytesConsumed, s16 *dstData, int *bytesWritten) {
|
||||
SceAtracIdInfo &info = context_->info;
|
||||
|
||||
const int channels = outputChannels_;
|
||||
int outSamples = 0;
|
||||
decoder_->Decode(srcData, track_.BytesPerFrame(), bytesConsumed, channels, dstData, &outSamples);
|
||||
decoder_->Decode(srcData, info.sampleSize, bytesConsumed, channels, dstData, &outSamples);
|
||||
*bytesWritten = outSamples * channels * sizeof(int16_t);
|
||||
// TODO: Possibly return a decode error on bad data.
|
||||
return 0;
|
||||
|
|
|
@ -60,7 +60,6 @@ private:
|
|||
void GetResetBufferInfoInternal(AtracResetBufferInfo *bufferInfo, int sample);
|
||||
u32 ResetPlayPositionInternal(int seekPos, int bytesWrittenFirstBuf, int bytesWrittenSecondBuf);
|
||||
|
||||
u32 InitContext(u32 bufferAddr, u32 readSize, u32 bufferSize);
|
||||
u32 SkipFrames(int *skippedCount);
|
||||
void WrapLastPacket();
|
||||
|
||||
|
|
|
@ -969,8 +969,8 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) {
|
|||
return hleLogError(Log::ME, SCE_ERROR_ATRAC_BAD_ATRACID, "bad atrac ID");
|
||||
}
|
||||
|
||||
if (!Memory::IsValidAddress(paramsAddr)) {
|
||||
// TODO: Returning zero as code was before. Needs testing.
|
||||
if (!Memory::IsValidRange(paramsAddr, 12)) {
|
||||
// The real library will probably just crash here.
|
||||
return hleReportError(Log::ME, 0, "invalid pointers");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue