u32 sceAtracSetData(int atracID, u32 buffer, u32 bufferSize) { ERROR_LOG(HLE, "UNIMPL sceAtracSetData(%i, %08x, %08x)", atracID, buffer, bufferSize); Atrac *atrac = getAtrac(atracID); if (atrac != NULL) { atrac->first.addr = buffer; atrac->first.size = bufferSize; atrac->Analyze(); } return 0; }
int sceAtracSetAA3DataAndGetID(u32 buffer, int bufferSize, int fileSize, u32 metadataSizeAddr) { ERROR_LOG(HLE, "UNIMPL sceAtracSetAA3DataAndGetID(%08x, %i, %i, %08x)", buffer, bufferSize, fileSize, metadataSizeAddr); int codecType = getCodecType(buffer); Atrac *atrac = new Atrac(); atrac->first.addr = buffer; atrac->first.size = bufferSize; atrac->Analyze(); return createAtrac(atrac); }
int sceAtracSetHalfwayBufferAndGetID(int atracID, u32 halfBuffer, u32 readSize, u32 halfBufferSize) { ERROR_LOG(HLE, "UNIMPL sceAtracSetHalfwayBufferAndGetID(%i, %08x, %08x, %08x)", atracID, halfBuffer, readSize, halfBufferSize); int codecType = getCodecType(halfBuffer); Atrac *atrac = new Atrac(); atrac->first.addr = halfBuffer; atrac->first.size = halfBufferSize; atrac->Analyze(); return createAtrac(atrac); }
int sceAtracSetDataAndGetID(u32 buffer, u32 bufferSize) { ERROR_LOG(HLE, "UNIMPL sceAtracSetDataAndGetID(%08x, %08x)", buffer, bufferSize); int codecType = getCodecType(buffer); Atrac *atrac = new Atrac(); atrac->first.addr = buffer; atrac->first.size = bufferSize; atrac->Analyze(); return createAtrac(atrac); }
int sceAtracSetHalfwayBufferAndGetID(u32 halfBuffer, u32 readSize, u32 halfBufferSize) { ERROR_LOG(HLE, "UNIMPL sceAtracSetHalfwayBufferAndGetID(%08x, %08x, %08x)", halfBuffer, readSize, halfBufferSize); if (readSize > halfBufferSize) return ATRAC_ERROR_INCORRECT_READ_SIZE; int codecType = getCodecType(halfBuffer); Atrac *atrac = new Atrac(); atrac->first.addr = halfBuffer; atrac->first.size = halfBufferSize; atrac->Analyze(); return createAtrac(atrac); }
u32 sceAtracGetBufferInfoForReseting(int atracID, int sample, u32 bufferInfoAddr) { ERROR_LOG(HLE, "UNIMPL sceAtracGetBufferInfoForReseting(%i, %i, %08x)",atracID, sample, bufferInfoAddr); Atrac *atrac = getAtrac(atracID); if (!atrac) { // TODO: Write the right stuff instead. Memory::Memset(bufferInfoAddr, 0, 32); //return -1; } else { int Sampleoffset = atrac->getDecodePosBySample(sample); Memory::Write_U32(atrac->first.addr, bufferInfoAddr); Memory::Write_U32(atrac->first.writableBytes, bufferInfoAddr + 4); Memory::Write_U32(atrac->first.neededBytes, bufferInfoAddr + 8); Memory::Write_U32(Sampleoffset, bufferInfoAddr + 12); Memory::Write_U32(atrac->second.addr, bufferInfoAddr + 16); Memory::Write_U32(atrac->second.writableBytes, bufferInfoAddr + 20); Memory::Write_U32(atrac->second.neededBytes, bufferInfoAddr + 24); Memory::Write_U32(atrac->second.fileoffset, bufferInfoAddr + 28); } return 0; }
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); 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); ret = ATRAC_ERROR_ALL_DATA_DECODED; } else { // TODO: This isn't at all right, but at least it makes the music "last" some time. u32 numSamples = 0; #ifdef USE_FFMPEG if (atrac->codeType == PSP_MODE_AT_3 && atrac->pCodecCtx) { int forceseekSample = atrac->currentSample * 2 > atrac->endSample ? 0 : atrac->endSample; atrac->SeekToSample(forceseekSample); atrac->SeekToSample(atrac->currentSample); AVPacket packet; int got_frame, ret; while (av_read_frame(atrac->pFormatCtx, &packet) >= 0) { if (packet.stream_index == atrac->audio_stream_index) { got_frame = 0; ret = avcodec_decode_audio4(atrac->pCodecCtx, atrac->pFrame, &got_frame, &packet); if (ret < 0) { ERROR_LOG(HLE, "avcodec_decode_audio4: Error decoding audio %d", ret); av_free_packet(&packet); break; } if (got_frame) { // 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); numSamples = atrac->pFrame->nb_samples; ret = swr_convert(atrac->pSwrCtx, &out, atrac->pFrame->nb_samples, (const u8**)atrac->pFrame->extended_data, atrac->pFrame->nb_samples); if (ret < 0) { ERROR_LOG(HLE, "swr_convert: Error while converting %d", ret); } } av_free_packet(&packet); if (got_frame) break; } } } else #endif // USE_FFMPEG { numSamples = atrac->endSample - atrac->currentSample; if (atrac->currentSample >= atrac->endSample) { numSamples = 0; } else if (numSamples > ATRAC_MAX_SAMPLES) { numSamples = ATRAC_MAX_SAMPLES; } if (numSamples == 0 && (atrac->loopNum != 0)) { numSamples = ATRAC_MAX_SAMPLES; } Memory::Memset(outAddr, 0, numSamples * sizeof(s16) * atrac->atracOutputChannels); } Memory::Write_U32(numSamples, numSamplesAddr); // update current sample and decodePos atrac->currentSample += numSamples; atrac->decodePos = atrac->getDecodePosBySample(atrac->currentSample); int finishFlag = 0; if (atrac->loopNum != 0 && (atrac->currentSample >= atrac->loopEndSample || numSamples == 0)) { atrac->currentSample = atrac->loopStartSample; if (atrac->loopNum > 0) atrac->loopNum --; } else if (atrac->currentSample >= atrac->endSample || numSamples == 0) finishFlag = 1; Memory::Write_U32(finishFlag, finishFlagAddr); int remains = atrac->getRemainFrames(); Memory::Write_U32(remains, remainAddr); } // 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 } return ret; }