Skip to content

Commit

Permalink
Merge branch 'master' of github.com:hrydgard/ppsspp
Browse files Browse the repository at this point in the history
Conflicts:
	UI/GameInfoCache.h
  • Loading branch information
hrydgard committed Jun 8, 2013
2 parents 51daa1f + 928ef37 commit 5335416
Show file tree
Hide file tree
Showing 17 changed files with 393 additions and 58 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,9 @@ elseif(SDL_FOUND)
elseif(PANDORA OR MAEMO)
set(nativeExtraLibs ${nativeExtraLibs} pthread EGL X11)
endif()
# FFMPEG
add_definitions(-DUSE_FFMPEG)
set(nativeExtraLibs ${nativeExtraLibs} avformat avcodec swresample swscale)
set(TargetBin PPSSPPSDL)
else()
message(FATAL_ERROR "Could not find SDL. Failing.")
Expand Down Expand Up @@ -758,6 +761,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/sceAtrac.cpp
Core/HLE/sceAtrac.h
Core/HLE/sceAudio.cpp
Core/HLE/sceAudioCodec.cpp
Core/HLE/sceAudioCodec.h
Core/HLE/sceAudio.h
Core/HLE/sceChnnlsv.cpp
Core/HLE/sceChnnlsv.h
Expand Down
1 change: 1 addition & 0 deletions Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ set(SRCS
HLE/sceParseUri.cpp
HLE/sceParseHttp.cpp
HLE/sceVaudio.cpp
HLE/sceAudiocodec.cpp
HW/MemoryStick.cpp
HW/MediaEngine.cpp
HW/SasAudio.cpp
Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
<ClCompile Include="HLE\HLETables.cpp" />
<ClCompile Include="HLE\sceAtrac.cpp" />
<ClCompile Include="HLE\sceAudio.cpp" />
<ClCompile Include="HLE\sceAudiocodec.cpp" />
<ClCompile Include="HLE\sceChnnlsv.cpp" />
<ClCompile Include="HLE\sceCtrl.cpp" />
<ClCompile Include="HLE\sceDeflt.cpp" />
Expand Down Expand Up @@ -368,6 +369,7 @@
<ClInclude Include="HLE\HLETables.h" />
<ClInclude Include="HLE\sceAtrac.h" />
<ClInclude Include="HLE\sceAudio.h" />
<ClInclude Include="HLE\sceAudiocodec.h" />
<ClInclude Include="HLE\sceCtrl.h" />
<ClInclude Include="HLE\sceChnnlsv.h" />
<ClInclude Include="HLE\sceDeflt.h" />
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,9 @@
<ClCompile Include="HW\MpegDemux.cpp">
<Filter>HW</Filter>
</ClCompile>
<ClCompile Include="HLE\sceAudiocodec.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
Expand Down Expand Up @@ -801,6 +804,9 @@
<ClInclude Include="HW\MpegDemux.h">
<Filter>HW</Filter>
</ClInclude>
<ClInclude Include="HLE\sceAudiocodec.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
Expand Down
2 changes: 2 additions & 0 deletions Core/HLE/HLETables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "sceNp.h"
#include "sceMd5.h"
#include "sceJpeg.h"
#include "sceAudiocodec.h"

#define N(s) s

Expand Down Expand Up @@ -269,6 +270,7 @@ void RegisterAllModules() {
Register_sceNpAuth();
Register_sceMd5();
Register_sceJpeg();
Register_sceAudiocodec();

for (int i = 0; i < numModules; i++)
{
Expand Down
183 changes: 133 additions & 50 deletions Core/HLE/sceAtrac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#include "sceKernel.h"
#include "sceUtility.h"
#include "sceKernelMemory.h"
#include "sceAtrac.h"


#define ATRAC_ERROR_API_FAIL 0x80630002
Expand Down Expand Up @@ -113,6 +115,7 @@ struct Atrac {
pFrame = 0;
#endif // USE_FFMPEG
decoder_context = 0;
atracContext = 0;
sampleQueue.clear();
}

Expand All @@ -131,6 +134,9 @@ struct Atrac {

Atrac3plus_Decoder::CloseContext(&decoder_context);
sampleQueue.clear();

if (atracContext.Valid())
kernelMemory.Free(atracContext.ptr);
}

void DoState(PointerWrap &p) {
Expand Down Expand Up @@ -172,6 +178,11 @@ struct Atrac {
p.Do(loopEndSample);
p.Do(loopNum);

// Is NULL okay for this?
if (p.mode == p.MODE_READ)
decoder_context = 0;
p.Do(atracContext);

p.DoMarker("Atrac");
}

Expand Down Expand Up @@ -230,6 +241,8 @@ struct Atrac {
Atrac3plus_Decoder::BufferQueue sampleQueue;
void* decoder_context;

PSPPointer<SceAtracId> atracContext;

#ifdef USE_FFMPEG
AVFormatContext *pFormatCtx;
AVIOContext *pAVIOCtx;
Expand Down Expand Up @@ -483,18 +496,17 @@ u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd)
return 0;
}

u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishFlagAddr, u32 remainAddr)
u32 _AtracDecodeData(int atracID, u8* outbuf, u32 *SamplesNum, u32* finish, int *remains)
{
DEBUG_LOG(HLE, "sceAtracDecodeData(%i, %08x, %08x, %08x, %08x)", atracID, outAddr, numSamplesAddr, finishFlagAddr, remainAddr);
Atrac *atrac = getAtrac(atracID);

u32 ret = 0;
if (atrac != NULL) {
// We already passed the end - return an error (many games check for this.)
if (atrac->currentSample >= atrac->endSample && atrac->loopNum == 0) {
Memory::Write_U32(0, numSamplesAddr);
Memory::Write_U32(1, finishFlagAddr);
Memory::Write_U32(0, remainAddr);
*SamplesNum = 0;
*finish = 1;
*remains = 0;
ret = ATRAC_ERROR_ALL_DATA_DECODED;
} else {
// TODO: This isn't at all right, but at least it makes the music "last" some time.
Expand All @@ -520,7 +532,7 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
// got a frame
int decoded = av_samples_get_buffer_size(NULL, atrac->pFrame->channels,
atrac->pFrame->nb_samples, (AVSampleFormat)atrac->pFrame->format, 1);
u8* out = Memory::GetPointer(outAddr);
u8* out = outbuf;
numSamples = atrac->pFrame->nb_samples;
avret = swr_convert(atrac->pSwrCtx, &out, atrac->pFrame->nb_samples,
(const u8**)atrac->pFrame->extended_data, atrac->pFrame->nb_samples);
Expand All @@ -547,11 +559,10 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
inbytes = std::min(inbytes, (int)atrac->atracBytesPerFrame);
if (inbytes > 0 && inbytes == atrac->atracBytesPerFrame) {
Atrac3plus_Decoder::Decode(atrac->decoder_context, atrac->data_buf + atrac->decodePos, inbytes, &decodebytes, buf);
DEBUG_LOG(HLE, "atracID: %i decodebytes: %i outAddr: %08x", atracID, decodebytes, outAddr);
atrac->sampleQueue.push(buf, decodebytes);
}
}
s16* out = (s16*)Memory::GetPointer(outAddr);
s16* out = (s16*)outbuf;
memset(out, 0, ATRAC3PLUS_MAX_SAMPLES * sizeof(s16) * atrac->atracOutputChannels);
int gotsize = atrac->sampleQueue.pop_front(buf, ATRAC3PLUS_MAX_SAMPLES * sizeof(s16) * atrac->atracChannels);
numSamples = gotsize / sizeof(s16) / atrac->atracChannels;
Expand All @@ -569,7 +580,7 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
} else
{
numSamples = atrac->endSample - atrac->currentSample;
int atracSamplesPerFrame = (atrac->codeType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
u32 atracSamplesPerFrame = (atrac->codeType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
if (atrac->currentSample >= atrac->endSample) {
numSamples = 0;
} else if (numSamples > atracSamplesPerFrame) {
Expand All @@ -579,10 +590,10 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
if (numSamples == 0 && (atrac->loopNum != 0)) {
numSamples = atracSamplesPerFrame;
}
Memory::Memset(outAddr, 0, numSamples * sizeof(s16) * atrac->atracOutputChannels);
memset(outbuf, 0, numSamples * sizeof(s16) * atrac->atracOutputChannels);
}

Memory::Write_U32(numSamples, numSamplesAddr);
*SamplesNum = numSamples;
// update current sample and decodePos
atrac->currentSample += numSamples;
atrac->decodePos = atrac->getDecodePosBySample(atrac->currentSample);
Expand All @@ -597,23 +608,33 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
(numSamples == 0 && atrac->first.size >= atrac->first.filesize))
finishFlag = 1;

Memory::Write_U32(finishFlag, finishFlagAddr);
int remains = atrac->getRemainFrames();
Memory::Write_U32(remains, remainAddr);
*finish = finishFlag;
*remains = atrac->getRemainFrames();
}
// TODO: Can probably remove this after we validate no wrong ids?
} else {
Memory::Write_U16(0, outAddr); // Write a single 16-bit stereo
Memory::Write_U16(0, outAddr + 2);

Memory::Write_U32(1, numSamplesAddr);
Memory::Write_U32(1, finishFlagAddr); // Lie that decoding is finished
Memory::Write_U32(-1, remainAddr); // Lie that decoding is finished
memset(outbuf, 0, ATRAC3_MAX_SAMPLES * sizeof(s16) * atrac->atracOutputChannels);
*SamplesNum = ATRAC3_MAX_SAMPLES;
*finish = 1;
*remains = -1;
}

return ret;
}

u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishFlagAddr, u32 remainAddr)
{
DEBUG_LOG(HLE, "sceAtracDecodeData(%i, %08x, %08x, %08x, %08x)", atracID, outAddr, numSamplesAddr, finishFlagAddr, remainAddr);
u32 numSamples = 0;
u32 finish = 0;
int remains = 0;
int ret = _AtracDecodeData(atracID, Memory::GetPointer(outAddr), &numSamples, &finish, &remains);
Memory::Write_U32(numSamples, numSamplesAddr);
Memory::Write_U32(finish, finishFlagAddr);
Memory::Write_U32(remains, remainAddr);
return ret;
}

u32 sceAtracEndEntry()
{
ERROR_LOG(HLE, "UNIMPL sceAtracEndEntry()");
Expand Down Expand Up @@ -756,7 +777,7 @@ u32 sceAtracGetNextSample(int atracID, u32 outNAddr)
Memory::Write_U32(0, outNAddr);
} else {
u32 numSamples = atrac->endSample - atrac->currentSample;
int atracSamplesPerFrame = (atrac->codeType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
u32 atracSamplesPerFrame = (atrac->codeType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
if (numSamples > atracSamplesPerFrame)
numSamples = atracSamplesPerFrame;
if (Memory::IsValidAddress(outNAddr))
Expand Down Expand Up @@ -896,6 +917,39 @@ int64_t _AtracSeekbuffer(void *opaque, int64_t offset, int whence)

#endif // USE_FFMPEG

#ifdef USE_FFMPEG
int __AtracUpdateOutputMode(Atrac *atrac, int wanted_channels) {
if (atrac->pSwrCtx && atrac->atracOutputChannels == wanted_channels)
return 0;
atrac->atracOutputChannels = wanted_channels;
int64_t wanted_channel_layout = av_get_default_channel_layout(wanted_channels);
int64_t dec_channel_layout = av_get_default_channel_layout(atrac->atracChannels);

atrac->pSwrCtx =
swr_alloc_set_opts
(
atrac->pSwrCtx,
wanted_channel_layout,
AV_SAMPLE_FMT_S16,
atrac->pCodecCtx->sample_rate,
dec_channel_layout,
atrac->pCodecCtx->sample_fmt,
atrac->pCodecCtx->sample_rate,
0,
NULL
);
if (!atrac->pSwrCtx) {
ERROR_LOG(HLE, "swr_alloc_set_opts: Could not allocate resampler context");
return -1;
}
if (swr_init(atrac->pSwrCtx) < 0) {
ERROR_LOG(HLE, "swr_init: Failed to initialize the resampling context");
return -1;
}
return 0;
}
#endif // USE_FFMPEG

int __AtracSetContext(Atrac *atrac)
{
if (atrac->codeType == PSP_MODE_AT_3_PLUS) {
Expand Down Expand Up @@ -938,31 +992,8 @@ int __AtracSetContext(Atrac *atrac)
return -1;
}

int wanted_channels = atrac->atracOutputChannels;
int64_t wanted_channel_layout = av_get_default_channel_layout(wanted_channels);
int64_t dec_channel_layout = av_get_default_channel_layout(atrac->atracChannels);

atrac->pSwrCtx =
swr_alloc_set_opts
(
NULL,
wanted_channel_layout,
AV_SAMPLE_FMT_S16,
atrac->pCodecCtx->sample_rate,
dec_channel_layout,
atrac->pCodecCtx->sample_fmt,
atrac->pCodecCtx->sample_rate,
0,
NULL
);
if (!atrac->pSwrCtx) {
ERROR_LOG(HLE, "swr_alloc_set_opts: Could not allocate resampler context %d", ret);
return -1;
}
if ((ret = swr_init(atrac->pSwrCtx)) < 0) {
ERROR_LOG(HLE, "swr_init: Failed to initialize the resampling context %d", ret);
return -1;
}
if ((ret = __AtracUpdateOutputMode(atrac, atrac->atracOutputChannels)) < 0)
return ret;

// alloc audio frame
atrac->pFrame = avcodec_alloc_frame();
Expand Down Expand Up @@ -1232,15 +1263,67 @@ int sceAtracSetAA3DataAndGetID(u32 buffer, int bufferSize, int fileSize, u32 met
return createAtrac(atrac);
}

int _AtracGetIDByContext(u32 contextAddr) {
int atracID = (int)Memory::Read_U32(contextAddr + 0xfc);
#ifdef USE_FFMPEG
Atrac *atrac = getAtrac(atracID);
if (atrac)
__AtracUpdateOutputMode(atrac, 1);
#endif // USE_FFMPEG
return atracID;
}

void _AtracGenarateContext(Atrac *atrac, SceAtracId *context) {
context->info.buffer = atrac->first.addr;
context->info.bufferByte = atrac->atracBufSize;
context->info.codec = atrac->codeType;
context->info.loopNum = atrac->loopNum;
context->info.loopStart = atrac->loopStartSample > 0 ? atrac->loopStartSample : 0;
context->info.loopEnd = atrac->loopEndSample > 0 ? atrac->loopEndSample : 0;
if (atrac->first.size >= atrac->first.fileoffset) {
// state 2, all data loaded
context->info.state = 2;
} else if (atrac->loopinfoNum == 0) {
// state 3, lack some data, no loop info
context->info.state = 3;
} else {
// state 6, lack some data, has loop info
context->info.state = 6;
}
context->info.samplesPerChan = (atrac->codeType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
context->info.sampleSize = atrac->atracBytesPerFrame;
context->info.numChan = atrac->atracChannels;
context->info.dataOff = atrac->firstSampleoffset;
context->info.endSample = atrac->endSample;
context->info.dataEnd = atrac->first.filesize;
context->info.curOff = atrac->first.size;
context->info.streamDataByte = atrac->first.size - atrac->firstSampleoffset;

u8* buf = (u8*)context;
*(u32*)(buf + 0xfc) = atrac->atracID;
}

int _sceAtracGetContextAddress(int atracID)
{
ERROR_LOG(HLE, "UNIMPL _sceAtracGetContextAddress(%i)", atracID);
Atrac *atrac = getAtrac(atracID);
if (!atrac) {
// Sol Trigger requires return -1 otherwise hangup .
return -1;
ERROR_LOG(HLE, "_sceAtracGetContextAddress(%i): bad atrac id", atracID);
return 0;
}
return 0;
if (!atrac->atracContext.Valid()) {
// allocate a new atracContext
u32 contextsize = 256;
atrac->atracContext = kernelMemory.Alloc(contextsize, false, "Atrac Context");
if (atrac->atracContext.Valid())
Memory::Memset(atrac->atracContext.ptr, 0, 256);

WARN_LOG(HLE, "%08x=_sceAtracGetContextAddress(%i): allocated new context", atrac->atracContext.ptr, atracID);
}
else
WARN_LOG(HLE, "%08x=_sceAtracGetContextAddress(%i)", atrac->atracContext.ptr, atracID);
if (atrac->atracContext.Valid())
_AtracGenarateContext(atrac, atrac->atracContext);
return atrac->atracContext.ptr;
}

static u8 at3Header[] ={0x52,0x49,0x46,0x46,0x3b,0xbe,0x00,0x00,0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,0x20,0x00,0x00,0x00,0x70,0x02,0x02,0x00,0x44,0xac,0x00,0x00,0x4d,0x20,0x00,0x00,0xc0,0x00,0x00,0x00,0x0e,0x00,0x01,0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x64,0x61,0x74,0x61,0xc0,0xbd,0x00,0x00};
Expand Down
Loading

0 comments on commit 5335416

Please sign in to comment.