cellAdec improved

This commit is contained in:
Nekotekina 2014-10-28 00:24:11 +03:00
parent ffda60996d
commit 09a4d14f8f
7 changed files with 314 additions and 193 deletions

View File

@ -2266,7 +2266,7 @@ void RSXThread::Task()
if(cmd == 0)
{
LOG_ERROR(Log::RSX, "null cmd: cmd=0x%x, put=0x%x, get=0x%x (addr=0x%x)", cmd, put, get, (u32)Memory.RSXIOMem.RealAddr(get));
//Emu.Pause();
Emu.Pause();
//HACK! We shouldn't be here
m_ctrl->get = get + (count + 1) * 4;
continue;

View File

@ -52,7 +52,7 @@ AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<Cell
return;
}
io_buf = (u8*)av_malloc(4096);
fmt->pb = avio_alloc_context(io_buf, 4096, 0, this, adecRead, NULL, NULL);
fmt->pb = avio_alloc_context(io_buf, 256, 0, this, adecRead, NULL, NULL);
if (!fmt->pb)
{
cellAdec->Error("AudioDecoder(): avio_alloc_context failed");
@ -86,13 +86,44 @@ AudioDecoder::~AudioDecoder()
}
}
int adecRawRead(void* opaque, u8* buf, int buf_size)
int adecRead(void* opaque, u8* buf, int buf_size)
{
AudioDecoder& adec = *(AudioDecoder*)opaque;
int res = 0;
next:
if (adec.reader.has_ats)
{
u8 code1 = vm::read8(adec.reader.addr + 2);
u8 code2 = vm::read8(adec.reader.addr + 3);
adec.channels = code1 >> 2;
adec.frame_size = ((((u32)code1 & 0x3) << 8) | (u32)code2) * 8 + 8;
adec.sample_rate = at3freq[code1 >> 5];
adec.reader.size -= 8;
adec.reader.addr += 8;
adec.reader.has_ats = false;
}
if (!adec.reader.init)
{
OMAHeader oma(1 /* atrac3p id */, adec.sample_rate, adec.channels, adec.frame_size);
if (buf_size < sizeof(oma))
{
cellAdec->Error("adecRead(): OMAHeader writing failed");
Emu.Pause();
return 0;
}
memcpy(buf, &oma, sizeof(oma));
buf += sizeof(oma);
buf_size -= sizeof(oma);
res += sizeof(oma);
adec.reader.init = true;
}
if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/)
{
AdecTask task;
@ -125,6 +156,7 @@ next:
adec.reader.addr = adec.task.au.addr;
adec.reader.size = adec.task.au.size;
adec.reader.has_ats = adec.use_ats_headers;
//LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", adec.task.au.size, adec.task.au.pts);
}
break;
@ -158,89 +190,6 @@ next:
}
}
int adecRead(void* opaque, u8* buf, int buf_size)
{
AudioDecoder& adec = *(AudioDecoder*)opaque;
int res = 0;
if (adec.reader.rem_size && adec.reader.rem)
{
if (buf_size < (int)adec.reader.rem_size)
{
cellAdec->Error("adecRead(): too small buf_size (rem_size = %d, buf_size = %d)", adec.reader.rem_size, buf_size);
Emu.Pause();
return 0;
}
memcpy(buf, adec.reader.rem, adec.reader.rem_size);
free(adec.reader.rem);
adec.reader.rem = nullptr;
buf += adec.reader.rem_size;
buf_size -= adec.reader.rem_size;
res += adec.reader.rem_size;
adec.reader.rem_size = 0;
}
while (buf_size)
{
u8 header[8];
if (adecRawRead(opaque, header, 8) < 8) break;
if (header[0] != 0x0f || header[1] != 0xd0)
{
cellAdec->Error("adecRead(): 0x0FD0 header not found");
Emu.Pause();
return -1;
}
if (!adec.reader.init)
{
OMAHeader oma(1 /* atrac3p id */, header[2], header[3]);
if (buf_size < sizeof(oma) + 8)
{
cellAdec->Error("adecRead(): OMAHeader writing failed");
Emu.Pause();
return 0;
}
memcpy(buf, &oma, sizeof(oma));
buf += sizeof(oma);
buf_size -= sizeof(oma);
res += sizeof(oma);
adec.reader.init = true;
}
else
{
}
u32 size = (((header[2] & 0x3) << 8) | header[3]) * 8 + 8; // data to be read before next header
//LOG_NOTICE(HLE, "*** audio block read: size = 0x%x", size);
if (buf_size < (int)size)
{
if (adecRawRead(opaque, buf, buf_size) < buf_size) break; // ???
res += buf_size;
size -= buf_size;
buf_size = 0;
adec.reader.rem = (u8*)malloc(size);
adec.reader.rem_size = size;
if (adecRawRead(opaque, adec.reader.rem, size) < (int)size) break; // ???
}
else
{
if (adecRawRead(opaque, buf, size) < (int)size) break; // ???
buf += size;
buf_size -= size;
res += size;
}
}
return res;
}
u32 adecOpen(AudioDecoder* data)
{
AudioDecoder& adec = *data;
@ -292,10 +241,13 @@ u32 adecOpen(AudioDecoder* data)
adec.reader.addr = 0;
adec.reader.size = 0;
adec.reader.init = false;
if (adec.reader.rem) free(adec.reader.rem);
adec.reader.rem = nullptr;
adec.reader.rem_size = 0;
adec.reader.has_ats = false;
adec.just_started = true;
adec.channels = task.at3p.channels;
adec.frame_size = task.at3p.frame_size;
adec.sample_rate = task.at3p.sample_rate;
adec.use_ats_headers = task.at3p.ats_header == 1;
}
break;
@ -315,12 +267,13 @@ u32 adecOpen(AudioDecoder* data)
adec.reader.addr = task.au.addr;
adec.reader.size = task.au.size;
adec.reader.has_ats = adec.use_ats_headers;
//LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts);
if (adec.just_started)
{
adec.first_pts = task.au.pts;
adec.last_pts = task.au.pts - 0x10000; // hack
adec.last_pts = task.au.pts - 0x10000; // hack?
}
struct AVPacketHolder : AVPacket
@ -344,36 +297,30 @@ u32 adecOpen(AudioDecoder* data)
~AVPacketHolder()
{
av_free(data);
//av_free_packet(this);
}
} au(0);
/*{
wxFile dump;
dump.Open(wxString::Format("audio pts-0x%llx.dump", task.au.pts), wxFile::write);
u8* buf = (u8*)malloc(task.au.size);
if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size);
free(buf);
dump.Close();
}*/
if (adec.just_started && adec.just_finished)
{
avcodec_flush_buffers(adec.ctx);
adec.reader.init = true;
adec.reader.init = true; // wrong
adec.just_finished = false;
adec.just_started = false;
}
else if (adec.just_started) // deferred initialization
{
err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL);
if (err)
AVDictionary* opts = nullptr;
av_dict_set(&opts, "probesize", "96", 0);
err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), &opts);
if (err || opts)
{
cellAdec->Error("adecDecodeAu: avformat_open_input() failed");
cellAdec->Error("adecDecodeAu: avformat_open_input() failed (err=0x%x, opts=%d)", err, opts ? 1 : 0);
Emu.Pause();
break;
}
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ???
if (!codec)
{
@ -402,14 +349,14 @@ u32 adecOpen(AudioDecoder* data)
}
adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data
AVDictionary* opts = nullptr;
opts = nullptr;
av_dict_set(&opts, "refcounted_frames", "1", 0);
{
std::lock_guard<std::mutex> lock(g_mutex_avcodec_open2);
// not multithread-safe (???)
err = avcodec_open2(adec.ctx, codec, &opts);
}
if (err)
if (err || opts)
{
cellAdec->Error("adecDecodeAu: avcodec_open2() failed");
Emu.Pause();
@ -428,22 +375,6 @@ u32 adecOpen(AudioDecoder* data)
break;
}
/*if (!adec.ctx) // fake
{
AdecFrame frame;
frame.pts = task.au.pts;
frame.auAddr = task.au.addr;
frame.auSize = task.au.size;
frame.userdata = task.au.userdata;
frame.size = 4096;
frame.data = nullptr;
adec.frames.Push(frame);
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
break;
}*/
last_frame = av_read_frame(adec.fmt, &au) < 0;
if (last_frame)
{
@ -501,7 +432,7 @@ u32 adecOpen(AudioDecoder* data)
}
else
{
adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000;
adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / frame.data->sample_rate;
frame.pts = adec.last_pts;
}
//frame.pts = adec.last_pts;
@ -517,12 +448,6 @@ u32 adecOpen(AudioDecoder* data)
Emu.Pause();
break;
}
if (frame.data->channels != 2)
{
cellAdec->Error("adecDecodeAu: unsupported channel count (%d)", frame.data->channels);
Emu.Pause();
break;
}
//LOG_NOTICE(HLE, "got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)",
//frame.pts, frame.data->nb_samples, frame.data->channels, frame.data->sample_rate,
@ -596,7 +521,7 @@ int cellAdecQueryAttr(vm::ptr<CellAdecType> type, vm::ptr<CellAdecAttr> attr)
// TODO: check values
attr->adecVerLower = 0x280000; // from dmux
attr->adecVerUpper = 0x260000;
attr->workMemSize = 4 * 1024 * 1024; // 4 MB
attr->workMemSize = 256 * 1024; // 256 KB
return CELL_OK;
}
@ -655,7 +580,7 @@ int cellAdecClose(u32 handle)
int cellAdecStartSeq(u32 handle, u32 param_addr)
{
cellAdec->Todo("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr);
cellAdec->Warning("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr);
AudioDecoder* adec;
if (!Emu.GetIdManager().GetIDData(handle, adec))
@ -665,7 +590,31 @@ int cellAdecStartSeq(u32 handle, u32 param_addr)
AdecTask task(adecStartSeq);
// TODO: using parameters
switch (adec->type)
{
case CELL_ADEC_TYPE_ATRACX_2CH:
{
auto param = vm::ptr<const CellAdecParamAtracX>::make(param_addr);
task.at3p.sample_rate = param->sampling_freq;
task.at3p.channel_config = param->ch_config_idx;
task.at3p.channels = param->nch_out;
task.at3p.frame_size = param->nbytes;
task.at3p.extra_config = param->extra_config_data;
task.at3p.output = param->bw_pcm;
task.at3p.downmix = param->downmix_flag;
task.at3p.ats_header = param->au_includes_ats_hdr_flg;
cellAdec->Todo("*** CellAdecParamAtracX: sr=%d, ch_cfg=%d(%d), frame_size=0x%x, extra=0x%x, output=%d, downmix=%d, ats_header=%d",
task.at3p.sample_rate, task.at3p.channel_config, task.at3p.channels, task.at3p.frame_size, (u32&)task.at3p.extra_config, task.at3p.output, task.at3p.downmix, task.at3p.ats_header);
break;
}
default:
{
cellAdec->Todo("cellAdecStartSeq(): Unimplemented audio codec type(%d)", adec->type);
Emu.Pause();
return CELL_OK;
}
}
adec->job.Push(task, &adec->is_closed);
return CELL_OK;
@ -702,6 +651,7 @@ int cellAdecDecodeAu(u32 handle, vm::ptr<CellAdecAuInfo> auInfo)
task.au.pts = ((u64)auInfo->pts.upper << 32) | (u64)auInfo->pts.lower;
task.au.userdata = auInfo->userData;
cellAdec->Notice("cellAdecDecodeAu(): addr=0x%x, size=0x%x, pts=0x%llx", task.au.addr, task.au.size, task.au.pts);
adec->job.Push(task, &adec->is_closed);
return CELL_OK;
}
@ -733,14 +683,30 @@ int cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer)
if (outBuffer)
{
// reverse byte order, extract data:
float* in_f[2];
in_f[0] = (float*)frame->extended_data[0];
in_f[1] = (float*)frame->extended_data[1];
for (u32 i = 0; i < af.size / 8; i++)
// reverse byte order:
if (frame->channels == 1)
{
outBuffer[i * 2 + 0] = in_f[0][i];
outBuffer[i * 2 + 1] = in_f[1][i];
float* in_f = (float*)frame->extended_data[0];
for (u32 i = 0; i < af.size / 4; i++)
{
outBuffer[i] = in_f[i];
}
}
else if (frame->channels == 2)
{
float* in_f[2];
in_f[0] = (float*)frame->extended_data[0];
in_f[1] = (float*)frame->extended_data[1];
for (u32 i = 0; i < af.size / 8; i++)
{
outBuffer[i * 2 + 0] = in_f[0][i];
outBuffer[i * 2 + 1] = in_f[1][i];
}
}
else
{
cellAdec->Error("cellAdecGetPcm(): unsupported channel count (%d)", frame->channels);
Emu.Pause();
}
}
@ -788,12 +754,23 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr<u32> pcmItem_ptr)
pcm->auInfo.userData = af.userdata;
auto atx = vm::ptr<CellAdecAtracXInfo>::make(pcm.addr() + sizeof(CellAdecPcmItem));
atx->samplingFreq = frame->sample_rate; // ???
atx->nbytes = frame->nb_samples * frame->channels * sizeof(float); // ???
atx->channelConfigIndex = CELL_ADEC_CH_STEREO; // ???
atx->samplingFreq = frame->sample_rate;
atx->nbytes = frame->nb_samples * sizeof(float);
if (frame->channels == 1)
{
atx->channelConfigIndex = 1;
}
else if (frame->channels == 2)
{
atx->channelConfigIndex = 2;
}
else
{
cellAdec->Error("cellAdecGetPcmItem(): unsupported channel count (%d)", frame->channels);
Emu.Pause();
}
*pcmItem_ptr = pcm.addr();
return CELL_OK;
}

View File

@ -790,7 +790,7 @@ struct CellAdecParamAtracX
be_t<s32> ch_config_idx;
be_t<s32> nch_out;
be_t<s32> nbytes;
u8 extra_config_data[4]; // downmix coefficients
std::array<u8, 4> extra_config_data; // downmix coefficients
be_t<ATRACX_WordSize> bw_pcm;
ATRACX_DownmixFlag downmix_flag;
ATRACX_ATSHeaderInclude au_includes_ats_hdr_flg;
@ -1010,6 +1010,18 @@ struct AdecTask
u64 pts;
u64 userdata;
} au;
struct
{
s32 sample_rate;
s32 channel_config;
s32 channels;
s32 frame_size;
std::array<u8, 4> extra_config;
s32 output;
u8 downmix;
u8 ats_header;
} at3p;
};
AdecTask(AdecJobType type)
@ -1034,6 +1046,8 @@ struct AdecFrame
int adecRead(void* opaque, u8* buf, int buf_size);
static const u32 at3freq[8] = { 32000, 44100, 48000, 88200, 96000, 0, 0, 0 };
struct OMAHeader // OMA Header
{
u32 magic; // 0x01334145
@ -1043,26 +1057,34 @@ struct OMAHeader // OMA Header
u64 unk2; // 0xcef5000000000400ULL
u64 unk3; // 0x1c458024329192d2ULL
u8 codecId; // 1 for ATRAC3P
u8 reserved0; // 0
u8 code0; // 0
u8 code1;
u8 code2;
u32 reserved1; // 0
u64 reserved[7]; // 0
u32 reserved[15]; // 0
OMAHeader(u8 id, u8 code1, u8 code2)
OMAHeader(u8 codec_id, u32 freq, u8 channel_count, u32 frame_size)
: magic(0x01334145)
, size(96 << 8)
, unk0(0xffff)
, unk1(0x00500f0100000000ULL)
, unk2(0xcef5000000000400ULL)
, unk3(0x1c458024329192d2ULL)
, codecId(id)
, reserved0(0)
, code1(code1)
, code2(code2)
, reserved1(0)
, codecId(codec_id)
, code0(0)
{
memset(reserved, 0, sizeof(reserved));
u8 freq_code;
for (freq_code = 0; freq_code < 5; freq_code++)
{
if (at3freq[freq_code] == freq)
{
break;
}
}
u32 prepared_frame_size = (frame_size - 8) / 8;
code1 = ((prepared_frame_size >> 8) & 0x3) | ((channel_count & 0x7) << 2) | (freq_code << 5);
code2 = prepared_frame_size & 0xff;
}
};
@ -1087,20 +1109,13 @@ public:
u32 addr;
u32 size;
bool init;
u8* rem;
u32 rem_size;
bool has_ats;
AudioReader()
: rem(nullptr)
, rem_size(0)
: init(false)
{
}
~AudioReader()
{
if (rem) free(rem);
rem = nullptr;
}
} reader;
SQueue<AdecFrame> frames;
@ -1115,6 +1130,11 @@ public:
AdecTask task;
u64 last_pts, first_pts;
u32 channels;
u32 frame_size;
u32 sample_rate;
bool use_ats_headers;
PPUThread* adecCb;
AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg);

View File

@ -1,48 +1,71 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
Module *cellAtrac = nullptr;
#include "cellAtrac.h"
int cellAtracSetDataAndGetMemSize(vm::ptr<CellAtracHandle> pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr<u32> puiWorkMemByte)
#ifdef PRX_DEBUG
#include "prx_libatrac3plus.h"
u32 libatrac3plus;
u32 libatrac3plus_rtoc;
#endif
s32 cellAtracSetDataAndGetMemSize(vm::ptr<CellAtracHandle> pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr<u32> puiWorkMemByte)
{
cellAtrac->Todo("cellAtracSetDataAndGetMemSize(pHandle=0x%x, pucBufferAddr=0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte_addr=0x%x)",
pHandle.addr(), pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x11F4, libatrac3plus_rtoc);
#endif
*puiWorkMemByte = 0x1000; // unproved
return CELL_OK;
}
int cellAtracCreateDecoder(vm::ptr<CellAtracHandle> pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority)
s32 cellAtracCreateDecoder(vm::ptr<CellAtracHandle> pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority)
{
cellAtrac->Todo("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)",
pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority);
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0FF0, libatrac3plus_rtoc);
#endif
pHandle->data.pucWorkMem_addr = pucWorkMem_addr;
return CELL_OK;
}
int cellAtracCreateDecoderExt(vm::ptr<CellAtracHandle> pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, vm::ptr<CellAtracExtRes> pExtRes)
s32 cellAtracCreateDecoderExt(vm::ptr<CellAtracHandle> pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, vm::ptr<CellAtracExtRes> pExtRes)
{
cellAtrac->Todo("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)",
pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0DB0, libatrac3plus_rtoc);
#endif
pHandle->data.pucWorkMem_addr = pucWorkMem_addr;
return CELL_OK;
}
int cellAtracDeleteDecoder(vm::ptr<CellAtracHandle> pHandle)
s32 cellAtracDeleteDecoder(vm::ptr<CellAtracHandle> pHandle)
{
cellAtrac->Todo("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0D08, libatrac3plus_rtoc);
#endif
return CELL_OK;
}
int cellAtracDecode(vm::ptr<CellAtracHandle> pHandle, u32 pfOutAddr, vm::ptr<u32> puiSamples, vm::ptr<u32> puiFinishflag, vm::ptr<u32> piRemainFrame)
s32 cellAtracDecode(vm::ptr<CellAtracHandle> pHandle, u32 pfOutAddr, vm::ptr<u32> puiSamples, vm::ptr<u32> puiFinishflag, vm::ptr<u32> piRemainFrame)
{
cellAtrac->Todo("cellAtracDecode(pHandle=0x%x, pfOutAddr=0x%x, puiSamples_addr=0x%x, puiFinishFlag_addr=0x%x, piRemainFrame_addr=0x%x)",
pHandle.addr(), pfOutAddr, puiSamples.addr(), puiFinishflag.addr(), piRemainFrame.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x09A8, libatrac3plus_rtoc);
#endif
*puiSamples = 0;
*puiFinishflag = 1;
@ -50,10 +73,13 @@ int cellAtracDecode(vm::ptr<CellAtracHandle> pHandle, u32 pfOutAddr, vm::ptr<u32
return CELL_OK;
}
int cellAtracGetStreamDataInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> ppucWritePointer, vm::ptr<u32> puiWritableByte, vm::ptr<u32> puiReadPosition)
s32 cellAtracGetStreamDataInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> ppucWritePointer, vm::ptr<u32> puiWritableByte, vm::ptr<u32> puiReadPosition)
{
cellAtrac->Todo("cellAtracGetStreamDataInfo(pHandle=0x%x, ppucWritePointer_addr=0x%x, puiWritableByte_addr=0x%x, puiReadPosition_addr=0x%x)",
pHandle.addr(), ppucWritePointer.addr(), puiWritableByte.addr(), puiReadPosition.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0BE8, libatrac3plus_rtoc);
#endif
*ppucWritePointer = pHandle->data.pucWorkMem_addr;
*puiWritableByte = 0x1000;
@ -61,79 +87,112 @@ int cellAtracGetStreamDataInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> pp
return CELL_OK;
}
int cellAtracAddStreamData(vm::ptr<CellAtracHandle> pHandle, u32 uiAddByte)
s32 cellAtracAddStreamData(vm::ptr<CellAtracHandle> pHandle, u32 uiAddByte)
{
cellAtrac->Todo("cellAtracAddStreamData(pHandle=0x%x, uiAddByte=0x%x)", pHandle.addr(), uiAddByte);
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0AFC, libatrac3plus_rtoc);
#endif
return CELL_OK;
}
int cellAtracGetRemainFrame(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piRemainFrame)
s32 cellAtracGetRemainFrame(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piRemainFrame)
{
cellAtrac->Todo("cellAtracGetRemainFrame(pHandle=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), piRemainFrame.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x092C, libatrac3plus_rtoc);
#endif
*piRemainFrame = CELL_ATRAC_ALLDATA_IS_ON_MEMORY;
return CELL_OK;
}
int cellAtracGetVacantSize(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiVacantSize)
s32 cellAtracGetVacantSize(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiVacantSize)
{
cellAtrac->Todo("cellAtracGetVacantSize(pHandle=0x%x, puiVacantSize_addr=0x%x)", pHandle.addr(), puiVacantSize.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x08B0, libatrac3plus_rtoc);
#endif
*puiVacantSize = 0x1000;
return CELL_OK;
}
int cellAtracIsSecondBufferNeeded(vm::ptr<CellAtracHandle> pHandle)
s32 cellAtracIsSecondBufferNeeded(vm::ptr<CellAtracHandle> pHandle)
{
cellAtrac->Todo("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0010, libatrac3plus_rtoc);
#endif
return CELL_OK;
}
int cellAtracGetSecondBufferInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiReadPosition, vm::ptr<u32> puiDataByte)
s32 cellAtracGetSecondBufferInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiReadPosition, vm::ptr<u32> puiDataByte)
{
cellAtrac->Todo("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)",
pHandle.addr(), puiReadPosition.addr(), puiDataByte.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x07E8, libatrac3plus_rtoc);
#endif
*puiReadPosition = 0;
*puiDataByte = 0; // write to null block will occur
return CELL_OK;
}
int cellAtracSetSecondBuffer(vm::ptr<CellAtracHandle> pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte)
s32 cellAtracSetSecondBuffer(vm::ptr<CellAtracHandle> pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte)
{
cellAtrac->Todo("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)",
pHandle.addr(), pucSecondBufferAddr, uiSecondBufferByte);
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0704, libatrac3plus_rtoc);
#endif
return CELL_OK;
}
int cellAtracGetChannel(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiChannel)
s32 cellAtracGetChannel(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiChannel)
{
cellAtrac->Todo("cellAtracGetChannel(pHandle=0x%x, puiChannel_addr=0x%x)", pHandle.addr(), puiChannel.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0060, libatrac3plus_rtoc);
#endif
*puiChannel = 2;
return CELL_OK;
}
int cellAtracGetMaxSample(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiMaxSample)
s32 cellAtracGetMaxSample(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiMaxSample)
{
cellAtrac->Todo("cellAtracGetMaxSample(pHandle=0x%x, puiMaxSample_addr=0x%x)", pHandle.addr(), puiMaxSample.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x00AC, libatrac3plus_rtoc);
#endif
*puiMaxSample = 512;
return CELL_OK;
}
int cellAtracGetNextSample(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiNextSample)
s32 cellAtracGetNextSample(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiNextSample)
{
cellAtrac->Todo("cellAtracGetNextSample(pHandle=0x%x, puiNextSample_addr=0x%x)", pHandle.addr(), puiNextSample.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0688, libatrac3plus_rtoc);
#endif
*puiNextSample = 0;
return CELL_OK;
}
int cellAtracGetSoundInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piEndSample, vm::ptr<u32> piLoopStartSample, vm::ptr<u32> piLoopEndSample)
s32 cellAtracGetSoundInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piEndSample, vm::ptr<u32> piLoopStartSample, vm::ptr<u32> piLoopEndSample)
{
cellAtrac->Todo("cellAtracGetSoundInfo(pHandle=0x%x, piEndSample_addr=0x%x, piLoopStartSample_addr=0x%x, piLoopEndSample_addr=0x%x)",
pHandle.addr(), piEndSample.addr(), piLoopStartSample.addr(), piLoopEndSample.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0104, libatrac3plus_rtoc);
#endif
*piEndSample = 0;
*piLoopStartSample = 0;
@ -141,44 +200,60 @@ int cellAtracGetSoundInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piEndSa
return CELL_OK;
}
int cellAtracGetNextDecodePosition(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiSamplePosition)
s32 cellAtracGetNextDecodePosition(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiSamplePosition)
{
cellAtrac->Todo("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)",
pHandle.addr(), puiSamplePosition.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0190, libatrac3plus_rtoc);
#endif
*puiSamplePosition = 0;
return CELL_ATRAC_ERROR_ALLDATA_WAS_DECODED;
}
int cellAtracGetBitrate(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiBitrate)
s32 cellAtracGetBitrate(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> puiBitrate)
{
cellAtrac->Todo("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)",
pHandle.addr(), puiBitrate.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0374, libatrac3plus_rtoc);
#endif
*puiBitrate = 128;
return CELL_OK;
}
int cellAtracGetLoopInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piLoopNum, vm::ptr<u32> puiLoopStatus)
s32 cellAtracGetLoopInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piLoopNum, vm::ptr<u32> puiLoopStatus)
{
cellAtrac->Todo("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)",
pHandle.addr(), piLoopNum.addr(), puiLoopStatus.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x025C, libatrac3plus_rtoc);
#endif
*piLoopNum = 0;
*puiLoopStatus = 0;
return CELL_OK;
}
int cellAtracSetLoopNum(vm::ptr<CellAtracHandle> pHandle, int iLoopNum)
s32 cellAtracSetLoopNum(vm::ptr<CellAtracHandle> pHandle, int iLoopNum)
{
cellAtrac->Todo("cellAtracSetLoopNum(pHandle=0x%x, iLoopNum=0x%x)", pHandle.addr(), iLoopNum);
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x1538, libatrac3plus_rtoc);
#endif
return CELL_OK;
}
int cellAtracGetBufferInfoForResetting(vm::ptr<CellAtracHandle> pHandle, u32 uiSample, vm::ptr<CellAtracBufferInfo> pBufferInfo)
s32 cellAtracGetBufferInfoForResetting(vm::ptr<CellAtracHandle> pHandle, u32 uiSample, vm::ptr<CellAtracBufferInfo> pBufferInfo)
{
cellAtrac->Todo("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)",
pHandle.addr(), uiSample, pBufferInfo.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x05BC, libatrac3plus_rtoc);
#endif
pBufferInfo->pucWriteAddr = pHandle->data.pucWorkMem_addr;
pBufferInfo->uiWritableByte = 0x1000;
@ -187,17 +262,24 @@ int cellAtracGetBufferInfoForResetting(vm::ptr<CellAtracHandle> pHandle, u32 uiS
return CELL_OK;
}
int cellAtracResetPlayPosition(vm::ptr<CellAtracHandle> pHandle, u32 uiSample, u32 uiWriteByte)
s32 cellAtracResetPlayPosition(vm::ptr<CellAtracHandle> pHandle, u32 uiSample, u32 uiWriteByte)
{
cellAtrac->Todo("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)",
pHandle.addr(), uiSample, uiWriteByte);
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x04E4, libatrac3plus_rtoc);
#endif
return CELL_OK;
}
int cellAtracGetInternalErrorInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piResult)
s32 cellAtracGetInternalErrorInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piResult)
{
cellAtrac->Todo("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)",
pHandle.addr(), piResult.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x02E4, libatrac3plus_rtoc);
#endif
*piResult = 0;
return CELL_OK;
@ -237,4 +319,25 @@ void cellAtrac_init(Module *pxThis)
cellAtrac->AddFunc(0x7772eb2b, cellAtracResetPlayPosition);
cellAtrac->AddFunc(0xb5c11938, cellAtracGetInternalErrorInfo);
#ifdef PRX_DEBUG
CallAfter([]()
{
libatrac3plus = (u32)Memory.MainMem.AllocAlign(sizeof(libatrac3plus_data), 0x100000);
memcpy(vm::get_ptr<void>(libatrac3plus), libatrac3plus_data, sizeof(libatrac3plus_data));
libatrac3plus_rtoc = libatrac3plus + 0xBED0;
extern Module* cellAdec;
FIX_IMPORT(cellAdec, cellAdecDecodeAu, libatrac3plus + 0x399C);
FIX_IMPORT(cellAdec, cellAdecStartSeq, libatrac3plus + 0x39BC);
FIX_IMPORT(cellAdec, cellAdecQueryAttr, libatrac3plus + 0x39DC);
FIX_IMPORT(cellAdec, cellAdecClose, libatrac3plus + 0x39FC);
FIX_IMPORT(cellAdec, cellAdecGetPcm, libatrac3plus + 0x3A1C);
FIX_IMPORT(cellAdec, cellAdecOpen, libatrac3plus + 0x3A3C);
fix_import(cellAdec, 0xDF982D2C, libatrac3plus + 0x3A5C);
fix_relocs(cellAtrac, libatrac3plus, 0x3EF0, 0x5048, 0x3CE0);
});
#endif
}

View File

@ -3,7 +3,6 @@
// Return Codes
enum
{
CELL_ATRAC_OK = 0x00000000,
CELL_ATRAC_ERROR_API_FAIL = 0x80610301,
CELL_ATRAC_ERROR_READSIZE_OVER_BUFFER = 0x80610311,
CELL_ATRAC_ERROR_UNKNOWN_FORMAT = 0x80610312,
@ -27,6 +26,32 @@ enum
CELL_ATRAC_ERROR_ILLEGAL_SPU_THREAD_PRIORITY = 0x80610382,
};
enum
{
CELL_ATRACMULTI_ERROR_API_FAIL = 0x80610b01,
CELL_ATRACMULTI_ERROR_READSIZE_OVER_BUFFER = 0x80610b11,
CELL_ATRACMULTI_ERROR_UNKNOWN_FORMAT = 0x80610b12,
CELL_ATRACMULTI_ERROR_READSIZE_IS_TOO_SMALL = 0x80610b13,
CELL_ATRACMULTI_ERROR_ILLEGAL_SAMPLING_RATE = 0x80610b14,
CELL_ATRACMULTI_ERROR_ILLEGAL_DATA = 0x80610b15,
CELL_ATRACMULTI_ERROR_NO_DECODER = 0x80610b21,
CELL_ATRACMULTI_ERROR_UNSET_DATA = 0x80610b22,
CELL_ATRACMULTI_ERROR_DECODER_WAS_CREATED = 0x80610b23,
CELL_ATRACMULTI_ERROR_ALLDATA_WAS_DECODED = 0x80610b31,
CELL_ATRACMULTI_ERROR_NODATA_IN_BUFFER = 0x80610b32,
CELL_ATRACMULTI_ERROR_NOT_ALIGNED_OUT_BUFFER = 0x80610b33,
CELL_ATRACMULTI_ERROR_NEED_SECOND_BUFFER = 0x80610b34,
CELL_ATRACMULTI_ERROR_ALLDATA_IS_ONMEMORY = 0x80610b41,
CELL_ATRACMULTI_ERROR_ADD_DATA_IS_TOO_BIG = 0x80610b42,
CELL_ATRACMULTI_ERROR_NONEED_SECOND_BUFFER = 0x80610b51,
CELL_ATRACMULTI_ERROR_UNSET_LOOP_NUM = 0x80610b61,
CELL_ATRACMULTI_ERROR_ILLEGAL_SAMPLE = 0x80610b71,
CELL_ATRACMULTI_ERROR_ILLEGAL_RESET_BYTE = 0x80610b72,
CELL_ATRACMULTI_ERROR_ILLEGAL_PPU_THREAD_PRIORITY = 0x80610b81,
CELL_ATRACMULTI_ERROR_ILLEGAL_SPU_THREAD_PRIORITY = 0x80610b82,
CELL_ATRACMULTI_ERROR_API_PARAMETER = 0x80610b91,
};
// Remain Frame
enum
{
@ -38,6 +63,7 @@ enum
union CellAtracHandle
{
u8 uiWorkMem[512];
struct AtracHandle
{
u32 pucWorkMem_addr;
@ -56,4 +82,4 @@ struct CellAtracExtRes
{
be_t<u32> pSpurs_addr;
u8 priority[8];
};
};

View File

@ -337,7 +337,7 @@ int cellAudioInit()
// 2x MAXPS (optional)
// 2x MINPS (optional)
// 2x CVTPS2DQ (converts float to s32)
// PACKSSDW (converts s32 to s16 with clipping)
// PACKSSDW (converts s32 to s16 with signed saturation)
if (g_is_u16)
{

View File

@ -401,11 +401,6 @@ u32 dmuxOpen(Demuxer* data)
PesHeader pes(stream);
if (!pes.new_au) // temporarily
{
cellDmux->Error("No pts info found");
}
// read additional header:
stream.peek(ch); // ???
//stream.skip(4);