CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/HLE/AtracCtx2.cpp
Views: 1401
1
#include "Common/Log.h"
2
#include "Core/MemMapHelpers.h"
3
#include "Core/HLE/HLE.h"
4
#include "Core/HLE/FunctionWrappers.h"
5
#include "Core/HLE/AtracCtx2.h"
6
#include "Core/HW/Atrac3Standalone.h"
7
8
// Convenient command line:
9
// Windows\x64\debug\PPSSPPHeadless.exe --root pspautotests/tests/../ --compare --timeout=5 --new-atrac --graphics=software pspautotests/tests/audio/atrac/decode.prx
10
11
// See the big comment in sceAtrac.cpp for an overview of the different modes of operation.
12
//
13
// Test cases
14
//
15
// Halfway buffer
16
//
17
// * None found yet
18
//
19
// All-data-loaded
20
//
21
// * MotoGP (menu music with specified loop). Simple repeated calls to sceAtracDecodeData
22
// * Archer MacLean's Mercury (in-game, not menu)
23
// * Crisis Core
24
//
25
// Streaming
26
//
27
// - Good ones (early)
28
// * Everybody's Golf 2 (0x2000 buffer size, loop from end)
29
// * Burnout Legends (no loop, 0x1800 buffer size)
30
// * Suicide Barbie
31
// - Others
32
// * Bleach
33
// * God of War: Chains of Olympus
34
// * Ape Academy 2 (bufsize 8192)
35
// * Half Minute Hero (bufsize 65536)
36
// * Flatout (tricky! needs investigation)
37
38
void Atrac2::DoState(PointerWrap &p) {
39
_assert_msg_(false, "Savestates not yet support with new Atrac implementation.\n\nTurn it off in Developer settings.\n\n");
40
}
41
42
void Atrac2::WriteContextToPSPMem() {
43
if (!context_.IsValid()) {
44
return;
45
}
46
// context points into PSP memory.
47
SceAtracContext *context = context_;
48
context->info.buffer = 0; // bufferAddr_; // first_.addr;
49
context->info.bufferByte = 0; // bufferMaxSize_;
50
context->info.secondBuffer = 0; // TODO
51
context->info.secondBufferByte = 0; // TODO
52
context->info.codec = track_.codecType;
53
context->info.loopNum = loopNum_;
54
context->info.loopStart = track_.loopStartSample > 0 ? track_.loopStartSample : 0;
55
context->info.loopEnd = track_.loopEndSample > 0 ? track_.loopEndSample : 0;
56
57
// Note that we read in the state when loading the atrac object, so it's safe
58
// to update it back here all the time. Some games, like Sol Trigger, change it.
59
// TODO: Should we just keep this in PSP ram then, or something?
60
context->info.state = bufferState_;
61
if (track_.firstSampleOffset != 0) {
62
context->info.samplesPerChan = track_.FirstSampleOffsetFull();
63
} else {
64
context->info.samplesPerChan = (track_.codecType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
65
}
66
context->info.sampleSize = track_.bytesPerFrame;
67
context->info.numChan = track_.channels;
68
context->info.dataOff = track_.dataByteOffset;
69
context->info.endSample = track_.endSample + track_.FirstSampleOffsetFull();
70
context->info.dataEnd = track_.fileSize;
71
context->info.curOff = 0; // first_.fileoffset;
72
context->info.decodePos = track_.DecodePosBySample(currentSample_);
73
context->info.streamDataByte = 0; // first_.size - track_.dataOff;
74
75
u8 *buf = (u8 *)context;
76
*(u32_le *)(buf + 0xfc) = atracID_;
77
78
NotifyMemInfo(MemBlockFlags::WRITE, context_.ptr, sizeof(SceAtracContext), "AtracContext");
79
}
80
81
int Atrac2::Analyze(u32 addr, u32 size) {
82
int retval = AnalyzeAtracTrack(addr, size, &track_);
83
if (retval < 0) {
84
return retval;
85
}
86
return 0;
87
}
88
int Atrac2::AnalyzeAA3(u32 addr, u32 size, u32 filesize) {
89
int retval = AnalyzeAA3Track(addr, size, filesize, &track_);
90
if (retval < 0) {
91
return retval;
92
}
93
94
return 0;
95
}
96
97
int Atrac2::RemainingFrames() const {
98
return 0;
99
}
100
101
u32 Atrac2::SecondBufferSize() const {
102
return 0;
103
}
104
105
void Atrac2::GetStreamDataInfo(u32 *writePtr, u32 *writableBytes, u32 *readOffset) {
106
107
}
108
109
int Atrac2::AddStreamData(u32 bytesToAdd) {
110
return 0;
111
}
112
113
u32 Atrac2::AddStreamDataSas(u32 bufPtr, u32 bytesToAdd) {
114
return 0;
115
}
116
117
u32 Atrac2::ResetPlayPosition(int sample, int bytesWrittenFirstBuf, int bytesWrittenSecondBuf) {
118
return 0;
119
}
120
121
void Atrac2::GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample) {
122
123
}
124
125
int Atrac2::SetData(u32 buffer, u32 readSize, u32 bufferSize, int outputChannels, int successCode) {
126
if (readSize == bufferSize) {
127
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
128
} else {
129
bufferState_ = ATRAC_STATUS_HALFWAY_BUFFER;
130
}
131
return hleLogSuccessI(Log::ME, successCode);
132
}
133
134
u32 Atrac2::SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) {
135
return 0;
136
}
137
138
u32 Atrac2::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, int *remains) {
139
140
return 0;
141
}
142
143
u32 Atrac2::GetNextSamples() {
144
return 0;
145
}
146
147
void Atrac2::InitLowLevel(u32 paramsAddr, bool jointStereo) {
148
track_.AnalyzeReset();
149
track_.channels = Memory::Read_U32(paramsAddr);
150
outputChannels_ = Memory::Read_U32(paramsAddr + 4);
151
track_.bytesPerFrame = Memory::Read_U32(paramsAddr + 8);
152
if (track_.codecType == PSP_MODE_AT_3) {
153
track_.bitrate = (track_.bytesPerFrame * 352800) / 1000;
154
track_.bitrate = (track_.bitrate + 511) >> 10;
155
track_.jointStereo = false;
156
} else if (track_.codecType == PSP_MODE_AT_3_PLUS) {
157
track_.bitrate = (track_.bytesPerFrame * 352800) / 1000;
158
track_.bitrate = ((track_.bitrate >> 11) + 8) & 0xFFFFFFF0;
159
track_.jointStereo = false;
160
}
161
track_.dataByteOffset = 0;
162
bufferState_ = ATRAC_STATUS_LOW_LEVEL;
163
currentSample_ = 0;
164
CreateDecoder();
165
WriteContextToPSPMem();
166
}
167
168