mirror of https://github.com/RPCS3/rpcs3.git
cellAdec improved
This commit is contained in:
parent
ffda60996d
commit
09a4d14f8f
|
@ -2266,7 +2266,7 @@ void RSXThread::Task()
|
||||||
if(cmd == 0)
|
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));
|
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
|
//HACK! We shouldn't be here
|
||||||
m_ctrl->get = get + (count + 1) * 4;
|
m_ctrl->get = get + (count + 1) * 4;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -52,7 +52,7 @@ AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<Cell
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
io_buf = (u8*)av_malloc(4096);
|
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)
|
if (!fmt->pb)
|
||||||
{
|
{
|
||||||
cellAdec->Error("AudioDecoder(): avio_alloc_context failed");
|
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;
|
AudioDecoder& adec = *(AudioDecoder*)opaque;
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
next:
|
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*/)
|
if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/)
|
||||||
{
|
{
|
||||||
AdecTask task;
|
AdecTask task;
|
||||||
|
@ -125,6 +156,7 @@ next:
|
||||||
|
|
||||||
adec.reader.addr = adec.task.au.addr;
|
adec.reader.addr = adec.task.au.addr;
|
||||||
adec.reader.size = adec.task.au.size;
|
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);
|
//LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", adec.task.au.size, adec.task.au.pts);
|
||||||
}
|
}
|
||||||
break;
|
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)
|
u32 adecOpen(AudioDecoder* data)
|
||||||
{
|
{
|
||||||
AudioDecoder& adec = *data;
|
AudioDecoder& adec = *data;
|
||||||
|
@ -292,10 +241,13 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
adec.reader.addr = 0;
|
adec.reader.addr = 0;
|
||||||
adec.reader.size = 0;
|
adec.reader.size = 0;
|
||||||
adec.reader.init = false;
|
adec.reader.init = false;
|
||||||
if (adec.reader.rem) free(adec.reader.rem);
|
adec.reader.has_ats = false;
|
||||||
adec.reader.rem = nullptr;
|
|
||||||
adec.reader.rem_size = 0;
|
|
||||||
adec.just_started = true;
|
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;
|
break;
|
||||||
|
|
||||||
|
@ -315,12 +267,13 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
|
|
||||||
adec.reader.addr = task.au.addr;
|
adec.reader.addr = task.au.addr;
|
||||||
adec.reader.size = task.au.size;
|
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);
|
//LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts);
|
||||||
|
|
||||||
if (adec.just_started)
|
if (adec.just_started)
|
||||||
{
|
{
|
||||||
adec.first_pts = task.au.pts;
|
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
|
struct AVPacketHolder : AVPacket
|
||||||
|
@ -344,36 +297,30 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
~AVPacketHolder()
|
~AVPacketHolder()
|
||||||
{
|
{
|
||||||
av_free(data);
|
av_free(data);
|
||||||
//av_free_packet(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} au(0);
|
} 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)
|
if (adec.just_started && adec.just_finished)
|
||||||
{
|
{
|
||||||
avcodec_flush_buffers(adec.ctx);
|
avcodec_flush_buffers(adec.ctx);
|
||||||
adec.reader.init = true;
|
|
||||||
|
adec.reader.init = true; // wrong
|
||||||
adec.just_finished = false;
|
adec.just_finished = false;
|
||||||
adec.just_started = false;
|
adec.just_started = false;
|
||||||
}
|
}
|
||||||
else if (adec.just_started) // deferred initialization
|
else if (adec.just_started) // deferred initialization
|
||||||
{
|
{
|
||||||
err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL);
|
AVDictionary* opts = nullptr;
|
||||||
if (err)
|
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();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ???
|
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ???
|
||||||
if (!codec)
|
if (!codec)
|
||||||
{
|
{
|
||||||
|
@ -402,14 +349,14 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
}
|
}
|
||||||
adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data
|
adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data
|
||||||
|
|
||||||
AVDictionary* opts = nullptr;
|
opts = nullptr;
|
||||||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(g_mutex_avcodec_open2);
|
std::lock_guard<std::mutex> lock(g_mutex_avcodec_open2);
|
||||||
// not multithread-safe (???)
|
// not multithread-safe (???)
|
||||||
err = avcodec_open2(adec.ctx, codec, &opts);
|
err = avcodec_open2(adec.ctx, codec, &opts);
|
||||||
}
|
}
|
||||||
if (err)
|
if (err || opts)
|
||||||
{
|
{
|
||||||
cellAdec->Error("adecDecodeAu: avcodec_open2() failed");
|
cellAdec->Error("adecDecodeAu: avcodec_open2() failed");
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
|
@ -428,22 +375,6 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
break;
|
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;
|
last_frame = av_read_frame(adec.fmt, &au) < 0;
|
||||||
if (last_frame)
|
if (last_frame)
|
||||||
{
|
{
|
||||||
|
@ -501,7 +432,7 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
}
|
}
|
||||||
else
|
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;
|
||||||
}
|
}
|
||||||
//frame.pts = adec.last_pts;
|
//frame.pts = adec.last_pts;
|
||||||
|
@ -517,12 +448,6 @@ u32 adecOpen(AudioDecoder* data)
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
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)",
|
//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,
|
//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
|
// TODO: check values
|
||||||
attr->adecVerLower = 0x280000; // from dmux
|
attr->adecVerLower = 0x280000; // from dmux
|
||||||
attr->adecVerUpper = 0x260000;
|
attr->adecVerUpper = 0x260000;
|
||||||
attr->workMemSize = 4 * 1024 * 1024; // 4 MB
|
attr->workMemSize = 256 * 1024; // 256 KB
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -655,7 +580,7 @@ int cellAdecClose(u32 handle)
|
||||||
|
|
||||||
int cellAdecStartSeq(u32 handle, u32 param_addr)
|
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;
|
AudioDecoder* adec;
|
||||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||||
|
@ -665,7 +590,31 @@ int cellAdecStartSeq(u32 handle, u32 param_addr)
|
||||||
|
|
||||||
AdecTask task(adecStartSeq);
|
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);
|
adec->job.Push(task, &adec->is_closed);
|
||||||
return CELL_OK;
|
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.pts = ((u64)auInfo->pts.upper << 32) | (u64)auInfo->pts.lower;
|
||||||
task.au.userdata = auInfo->userData;
|
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);
|
adec->job.Push(task, &adec->is_closed);
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -733,14 +683,30 @@ int cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer)
|
||||||
|
|
||||||
if (outBuffer)
|
if (outBuffer)
|
||||||
{
|
{
|
||||||
// reverse byte order, extract data:
|
// reverse byte order:
|
||||||
float* in_f[2];
|
if (frame->channels == 1)
|
||||||
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];
|
float* in_f = (float*)frame->extended_data[0];
|
||||||
outBuffer[i * 2 + 1] = in_f[1][i];
|
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;
|
pcm->auInfo.userData = af.userdata;
|
||||||
|
|
||||||
auto atx = vm::ptr<CellAdecAtracXInfo>::make(pcm.addr() + sizeof(CellAdecPcmItem));
|
auto atx = vm::ptr<CellAdecAtracXInfo>::make(pcm.addr() + sizeof(CellAdecPcmItem));
|
||||||
atx->samplingFreq = frame->sample_rate; // ???
|
atx->samplingFreq = frame->sample_rate;
|
||||||
atx->nbytes = frame->nb_samples * frame->channels * sizeof(float); // ???
|
atx->nbytes = frame->nb_samples * sizeof(float);
|
||||||
atx->channelConfigIndex = CELL_ADEC_CH_STEREO; // ???
|
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();
|
*pcmItem_ptr = pcm.addr();
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -790,7 +790,7 @@ struct CellAdecParamAtracX
|
||||||
be_t<s32> ch_config_idx;
|
be_t<s32> ch_config_idx;
|
||||||
be_t<s32> nch_out;
|
be_t<s32> nch_out;
|
||||||
be_t<s32> nbytes;
|
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;
|
be_t<ATRACX_WordSize> bw_pcm;
|
||||||
ATRACX_DownmixFlag downmix_flag;
|
ATRACX_DownmixFlag downmix_flag;
|
||||||
ATRACX_ATSHeaderInclude au_includes_ats_hdr_flg;
|
ATRACX_ATSHeaderInclude au_includes_ats_hdr_flg;
|
||||||
|
@ -1010,6 +1010,18 @@ struct AdecTask
|
||||||
u64 pts;
|
u64 pts;
|
||||||
u64 userdata;
|
u64 userdata;
|
||||||
} au;
|
} 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)
|
AdecTask(AdecJobType type)
|
||||||
|
@ -1034,6 +1046,8 @@ struct AdecFrame
|
||||||
|
|
||||||
int adecRead(void* opaque, u8* buf, int buf_size);
|
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
|
struct OMAHeader // OMA Header
|
||||||
{
|
{
|
||||||
u32 magic; // 0x01334145
|
u32 magic; // 0x01334145
|
||||||
|
@ -1043,26 +1057,34 @@ struct OMAHeader // OMA Header
|
||||||
u64 unk2; // 0xcef5000000000400ULL
|
u64 unk2; // 0xcef5000000000400ULL
|
||||||
u64 unk3; // 0x1c458024329192d2ULL
|
u64 unk3; // 0x1c458024329192d2ULL
|
||||||
u8 codecId; // 1 for ATRAC3P
|
u8 codecId; // 1 for ATRAC3P
|
||||||
u8 reserved0; // 0
|
u8 code0; // 0
|
||||||
u8 code1;
|
u8 code1;
|
||||||
u8 code2;
|
u8 code2;
|
||||||
u32 reserved1; // 0
|
u32 reserved[15]; // 0
|
||||||
u64 reserved[7]; // 0
|
|
||||||
|
|
||||||
OMAHeader(u8 id, u8 code1, u8 code2)
|
OMAHeader(u8 codec_id, u32 freq, u8 channel_count, u32 frame_size)
|
||||||
: magic(0x01334145)
|
: magic(0x01334145)
|
||||||
, size(96 << 8)
|
, size(96 << 8)
|
||||||
, unk0(0xffff)
|
, unk0(0xffff)
|
||||||
, unk1(0x00500f0100000000ULL)
|
, unk1(0x00500f0100000000ULL)
|
||||||
, unk2(0xcef5000000000400ULL)
|
, unk2(0xcef5000000000400ULL)
|
||||||
, unk3(0x1c458024329192d2ULL)
|
, unk3(0x1c458024329192d2ULL)
|
||||||
, codecId(id)
|
, codecId(codec_id)
|
||||||
, reserved0(0)
|
, code0(0)
|
||||||
, code1(code1)
|
|
||||||
, code2(code2)
|
|
||||||
, reserved1(0)
|
|
||||||
{
|
{
|
||||||
memset(reserved, 0, sizeof(reserved));
|
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 addr;
|
||||||
u32 size;
|
u32 size;
|
||||||
bool init;
|
bool init;
|
||||||
u8* rem;
|
bool has_ats;
|
||||||
u32 rem_size;
|
|
||||||
|
|
||||||
AudioReader()
|
AudioReader()
|
||||||
: rem(nullptr)
|
: init(false)
|
||||||
, rem_size(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~AudioReader()
|
|
||||||
{
|
|
||||||
if (rem) free(rem);
|
|
||||||
rem = nullptr;
|
|
||||||
}
|
|
||||||
} reader;
|
} reader;
|
||||||
|
|
||||||
SQueue<AdecFrame> frames;
|
SQueue<AdecFrame> frames;
|
||||||
|
@ -1115,6 +1130,11 @@ public:
|
||||||
AdecTask task;
|
AdecTask task;
|
||||||
u64 last_pts, first_pts;
|
u64 last_pts, first_pts;
|
||||||
|
|
||||||
|
u32 channels;
|
||||||
|
u32 frame_size;
|
||||||
|
u32 sample_rate;
|
||||||
|
bool use_ats_headers;
|
||||||
|
|
||||||
PPUThread* adecCb;
|
PPUThread* adecCb;
|
||||||
|
|
||||||
AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg);
|
AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg);
|
||||||
|
|
|
@ -1,48 +1,71 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
|
#include "Emu/System.h"
|
||||||
#include "Emu/SysCalls/Modules.h"
|
#include "Emu/SysCalls/Modules.h"
|
||||||
|
|
||||||
Module *cellAtrac = nullptr;
|
Module *cellAtrac = nullptr;
|
||||||
|
|
||||||
#include "cellAtrac.h"
|
#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)",
|
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());
|
pHandle.addr(), pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x11F4, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*puiWorkMemByte = 0x1000; // unproved
|
*puiWorkMemByte = 0x1000; // unproved
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)",
|
||||||
pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority);
|
pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority);
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0FF0, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
pHandle->data.pucWorkMem_addr = pucWorkMem_addr;
|
pHandle->data.pucWorkMem_addr = pucWorkMem_addr;
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)",
|
||||||
pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.addr());
|
pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0DB0, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
pHandle->data.pucWorkMem_addr = pucWorkMem_addr;
|
pHandle->data.pucWorkMem_addr = pucWorkMem_addr;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAtracDeleteDecoder(vm::ptr<CellAtracHandle> pHandle)
|
s32 cellAtracDeleteDecoder(vm::ptr<CellAtracHandle> pHandle)
|
||||||
{
|
{
|
||||||
cellAtrac->Todo("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr());
|
cellAtrac->Todo("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0D08, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return CELL_OK;
|
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)",
|
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());
|
pHandle.addr(), pfOutAddr, puiSamples.addr(), puiFinishflag.addr(), piRemainFrame.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x09A8, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*puiSamples = 0;
|
*puiSamples = 0;
|
||||||
*puiFinishflag = 1;
|
*puiFinishflag = 1;
|
||||||
|
@ -50,10 +73,13 @@ int cellAtracDecode(vm::ptr<CellAtracHandle> pHandle, u32 pfOutAddr, vm::ptr<u32
|
||||||
return CELL_OK;
|
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)",
|
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());
|
pHandle.addr(), ppucWritePointer.addr(), puiWritableByte.addr(), puiReadPosition.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0BE8, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*ppucWritePointer = pHandle->data.pucWorkMem_addr;
|
*ppucWritePointer = pHandle->data.pucWorkMem_addr;
|
||||||
*puiWritableByte = 0x1000;
|
*puiWritableByte = 0x1000;
|
||||||
|
@ -61,79 +87,112 @@ int cellAtracGetStreamDataInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> pp
|
||||||
return CELL_OK;
|
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);
|
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;
|
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());
|
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;
|
*piRemainFrame = CELL_ATRAC_ALLDATA_IS_ON_MEMORY;
|
||||||
return CELL_OK;
|
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());
|
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;
|
*puiVacantSize = 0x1000;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAtracIsSecondBufferNeeded(vm::ptr<CellAtracHandle> pHandle)
|
s32 cellAtracIsSecondBufferNeeded(vm::ptr<CellAtracHandle> pHandle)
|
||||||
{
|
{
|
||||||
cellAtrac->Todo("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr());
|
cellAtrac->Todo("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0010, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)",
|
||||||
pHandle.addr(), puiReadPosition.addr(), puiDataByte.addr());
|
pHandle.addr(), puiReadPosition.addr(), puiDataByte.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x07E8, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*puiReadPosition = 0;
|
*puiReadPosition = 0;
|
||||||
*puiDataByte = 0; // write to null block will occur
|
*puiDataByte = 0; // write to null block will occur
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)",
|
||||||
pHandle.addr(), pucSecondBufferAddr, uiSecondBufferByte);
|
pHandle.addr(), pucSecondBufferAddr, uiSecondBufferByte);
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0704, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return CELL_OK;
|
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());
|
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;
|
*puiChannel = 2;
|
||||||
return CELL_OK;
|
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());
|
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;
|
*puiMaxSample = 512;
|
||||||
return CELL_OK;
|
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());
|
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;
|
*puiNextSample = 0;
|
||||||
return CELL_OK;
|
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)",
|
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());
|
pHandle.addr(), piEndSample.addr(), piLoopStartSample.addr(), piLoopEndSample.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0104, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*piEndSample = 0;
|
*piEndSample = 0;
|
||||||
*piLoopStartSample = 0;
|
*piLoopStartSample = 0;
|
||||||
|
@ -141,44 +200,60 @@ int cellAtracGetSoundInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u32> piEndSa
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)",
|
||||||
pHandle.addr(), puiSamplePosition.addr());
|
pHandle.addr(), puiSamplePosition.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0190, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*puiSamplePosition = 0;
|
*puiSamplePosition = 0;
|
||||||
return CELL_ATRAC_ERROR_ALLDATA_WAS_DECODED;
|
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)",
|
cellAtrac->Todo("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)",
|
||||||
pHandle.addr(), puiBitrate.addr());
|
pHandle.addr(), puiBitrate.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0374, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*puiBitrate = 128;
|
*puiBitrate = 128;
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)",
|
||||||
pHandle.addr(), piLoopNum.addr(), puiLoopStatus.addr());
|
pHandle.addr(), piLoopNum.addr(), puiLoopStatus.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x025C, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*piLoopNum = 0;
|
*piLoopNum = 0;
|
||||||
*puiLoopStatus = 0;
|
*puiLoopStatus = 0;
|
||||||
return CELL_OK;
|
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);
|
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;
|
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)",
|
cellAtrac->Todo("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)",
|
||||||
pHandle.addr(), uiSample, pBufferInfo.addr());
|
pHandle.addr(), uiSample, pBufferInfo.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x05BC, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
pBufferInfo->pucWriteAddr = pHandle->data.pucWorkMem_addr;
|
pBufferInfo->pucWriteAddr = pHandle->data.pucWorkMem_addr;
|
||||||
pBufferInfo->uiWritableByte = 0x1000;
|
pBufferInfo->uiWritableByte = 0x1000;
|
||||||
|
@ -187,17 +262,24 @@ int cellAtracGetBufferInfoForResetting(vm::ptr<CellAtracHandle> pHandle, u32 uiS
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)",
|
||||||
pHandle.addr(), uiSample, uiWriteByte);
|
pHandle.addr(), uiSample, uiWriteByte);
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x04E4, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return CELL_OK;
|
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)",
|
cellAtrac->Todo("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)",
|
||||||
pHandle.addr(), piResult.addr());
|
pHandle.addr(), piResult.addr());
|
||||||
|
#ifdef PRX_DEBUG
|
||||||
|
return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x02E4, libatrac3plus_rtoc);
|
||||||
|
#endif
|
||||||
|
|
||||||
*piResult = 0;
|
*piResult = 0;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -237,4 +319,25 @@ void cellAtrac_init(Module *pxThis)
|
||||||
cellAtrac->AddFunc(0x7772eb2b, cellAtracResetPlayPosition);
|
cellAtrac->AddFunc(0x7772eb2b, cellAtracResetPlayPosition);
|
||||||
|
|
||||||
cellAtrac->AddFunc(0xb5c11938, cellAtracGetInternalErrorInfo);
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// Return Codes
|
// Return Codes
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CELL_ATRAC_OK = 0x00000000,
|
|
||||||
CELL_ATRAC_ERROR_API_FAIL = 0x80610301,
|
CELL_ATRAC_ERROR_API_FAIL = 0x80610301,
|
||||||
CELL_ATRAC_ERROR_READSIZE_OVER_BUFFER = 0x80610311,
|
CELL_ATRAC_ERROR_READSIZE_OVER_BUFFER = 0x80610311,
|
||||||
CELL_ATRAC_ERROR_UNKNOWN_FORMAT = 0x80610312,
|
CELL_ATRAC_ERROR_UNKNOWN_FORMAT = 0x80610312,
|
||||||
|
@ -27,6 +26,32 @@ enum
|
||||||
CELL_ATRAC_ERROR_ILLEGAL_SPU_THREAD_PRIORITY = 0x80610382,
|
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
|
// Remain Frame
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -38,6 +63,7 @@ enum
|
||||||
union CellAtracHandle
|
union CellAtracHandle
|
||||||
{
|
{
|
||||||
u8 uiWorkMem[512];
|
u8 uiWorkMem[512];
|
||||||
|
|
||||||
struct AtracHandle
|
struct AtracHandle
|
||||||
{
|
{
|
||||||
u32 pucWorkMem_addr;
|
u32 pucWorkMem_addr;
|
||||||
|
|
|
@ -337,7 +337,7 @@ int cellAudioInit()
|
||||||
// 2x MAXPS (optional)
|
// 2x MAXPS (optional)
|
||||||
// 2x MINPS (optional)
|
// 2x MINPS (optional)
|
||||||
// 2x CVTPS2DQ (converts float to s32)
|
// 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)
|
if (g_is_u16)
|
||||||
{
|
{
|
||||||
|
|
|
@ -401,11 +401,6 @@ u32 dmuxOpen(Demuxer* data)
|
||||||
|
|
||||||
PesHeader pes(stream);
|
PesHeader pes(stream);
|
||||||
|
|
||||||
if (!pes.new_au) // temporarily
|
|
||||||
{
|
|
||||||
cellDmux->Error("No pts info found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// read additional header:
|
// read additional header:
|
||||||
stream.peek(ch); // ???
|
stream.peek(ch); // ???
|
||||||
//stream.skip(4);
|
//stream.skip(4);
|
||||||
|
|
Loading…
Reference in New Issue