예제 #1
0
파일: sceAtrac.cpp 프로젝트: Almamu/ppsspp
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;
} 
예제 #2
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);
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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;
}
예제 #7
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;
}