Example #1
0
// Audio thread code
static int bgmThread(unsigned int args, void* arg){
	
	// Initializing audio port
	int ch = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, NSAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO);
	sceAudioOutSetConfig(ch, -1, -1, -1);
	old_vol = bgmvolume.value;
	int vol = 32767 * bgmvolume.value;
	int vol_stereo[] = {vol, vol};
	sceAudioOutSetVolume(ch, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);
	
	DecodedMusic* mus;
	for (;;){
		
		// Waiting for an audio output request
		sceKernelWaitSema(Audio_Mutex, 1, NULL);
		
		// Fetching track
		mus = BGM;
		
		// Checking if a new track is available
		if (mus == NULL){
			
			//If we enter here, we probably are in the exiting procedure
			if (mustExit){
				sceAudioOutReleasePort(ch);
				mustExit = false;
				sceKernelExitDeleteThread(0);
			}
		
		}
		
		// Initializing audio decoder
		audio_decoder = AudioDecoder::Create(mus->handle, "Track");
		audio_decoder->Open(mus->handle);
		audio_decoder->SetLooping(mus->loop);
		audio_decoder->SetFormat(48000, AudioDecoder::Format::S16, 2);
		
		// Initializing audio buffers
		mus->audiobuf = (uint8_t*)malloc(BUFSIZE);
		mus->audiobuf2 = (uint8_t*)malloc(BUFSIZE);
		mus->cur_audiobuf = mus->audiobuf;
		
		// Audio playback loop
		for (;;){
		
			// Check if the music must be paused
			if (mus->pauseTrigger || mustExit){
			
				// Check if the music must be closed
				if (mus->closeTrigger){
					free(mus->audiobuf);
					free(mus->audiobuf2);
					audio_decoder.reset();
					free(mus);
					BGM = NULL;
					if (!mustExit){
						sceKernelSignalSema(Talk_Mutex, 1);
						break;
					}
				}
				
				// Check if the thread must be closed
				if (mustExit){
				
					// Check if the audio stream has already been closed
					if (mus != NULL){
						mus->closeTrigger = true;
						continue;
					}
					
					// Recursively closing all the threads
					sceAudioOutReleasePort(ch);
					mustExit = false;
					sceKernelExitThread(0);
					
				}
			
				mus->isPlaying = !mus->isPlaying;
				mus->pauseTrigger = false;
			}
			
			// Check if a volume change is required
			if (mus->changeVol){
				old_vol = bgmvolume.value;
				int vol = 32767 * bgmvolume.value;
				int vol_stereo[] = {vol, vol};
				sceAudioOutSetVolume(ch, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);
				mus->changeVol = false;
			}
			
			if (mus->isPlaying){
				
				// Check if audio playback finished
				if ((!mus->loop) && audio_decoder->IsFinished()) mus->isPlaying = false;
				
				// Update audio output
				if (mus->cur_audiobuf == mus->audiobuf) mus->cur_audiobuf = mus->audiobuf2;
				else mus->cur_audiobuf = mus->audiobuf;
				audio_decoder->Decode(mus->cur_audiobuf, BUFSIZE);	
				sceAudioOutOutput(ch, mus->cur_audiobuf);
				
			}
			
		}
		
	}
	
}
static inline void unlock(void)
{
	sceKernelSignalSema(g_sema, 1);
}
Example #3
0
static int pmp_output_thread(SceSize input_length, void *input)
	{
	volatile struct pmp_play_struct *p = *((void **) input);


	sceCtrlSetSamplingCycle(0);
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
	SceCtrlData previous_controller;
	sceCtrlPeekBufferPositive(&previous_controller, 1);


    	unsigned int first_video_frame     = 1;
	unsigned int current_buffer_number = 0;


	while (p->return_request == 0)
		{
		volatile struct pmp_decode_buffer_struct *current_buffer = &p->decoder.output_frame_buffers[current_buffer_number];


		if (pmp_wait(p, p->semaphore_can_get, "pmp_output_thread: sceKernelWaitSema failed on semaphore_can_get") == 0)
			{
			break;
			}




		if (sceKernelSignalSema(p->semaphore_can_show, 1) < 0)
			{
			p->return_result  = "pmp_output_thread: sceKernelSignalSema failed on semaphore_can_show";
			p->return_request = 1;
			break;
			}


		if (p->seek == 0)
			{
			current_buffer->first_delay -= 500;
			sceKernelDelayThread(current_buffer->first_delay < 1 ? 1 : current_buffer->first_delay);
			sceAudioOutputBlocking(0, PSP_AUDIO_VOLUME_MAX, current_buffer->audio_frame);
			}


		pmp_input(p, &previous_controller);


		if (p->seek == 0)
			{
			int i = 1;
			for (; i < current_buffer->number_of_audio_frames; i++)
				{
				sceAudioOutputBlocking(0, PSP_AUDIO_VOLUME_MAX, current_buffer->audio_frame + p->decoder.audio_frame_size * i);
				}

			current_buffer->last_delay -= 500;
			sceKernelDelayThread(current_buffer->last_delay < 1 ? 1 : current_buffer->last_delay);
			}


		current_buffer_number = (current_buffer_number + 1) % p->decoder.number_of_frame_buffers;




		if (pmp_wait(p, p->semaphore_show_done, "pmp_output_thread: sceKernelWaitSema failed on semaphore_show_done") == 0)
			{
			break;
			}


		if (first_video_frame == 1)
			{
			first_video_frame = 0;
			}
		else
			{
			if (sceKernelSignalSema(p->semaphore_can_put, 1) < 0)
				{
				p->return_result  = "pmp_output_thread: sceKernelSignalSema failed on semaphore_can_put";
				p->return_request = 1;
				break;
				}
			}




		while (p->return_request == 0 && p->paused == 1)
			{
			sceKernelDelayThread(100000);

			pmp_input(p, &previous_controller);
			}
		}


	return(0);
	}
Example #4
0
char *pmp_play_start(volatile struct pmp_play_struct *p)
	{
	sceKernelStartThread(p->output_thread, 4, &p);
	sceKernelStartThread(p->show_thread,   4, &p);




	int current_video_frame = 0;


	while (p->return_request == 0 && current_video_frame != p->decoder.reader.file.header.video.number_of_frames)
		{
		if (pmp_wait(p, p->semaphore_can_put, "pmp_play_start: sceKernelWaitSema failed on semaphore_can_put") == 0)
			{
			break;
			}

		//modify by cooleyes 2007/02/01
		char *result = pmp_decode_get((struct pmp_decode_struct *) &p->decoder, current_video_frame, p->audio_stream, p->audio_channel, 1, p->volume_boost, p->aspect_ratio, p->zoom, p->luminosity_boost, p->show_interface, p->subtitle, p->subtitle_format, p->loop);
		//char *result = pmp_decode_get((struct pmp_decode_struct *) &p->decoder, current_video_frame, p->audio_stream, 1, p->volume_boost, p->aspect_ratio, p->zoom, p->luminosity_boost, p->show_interface, p->subtitle, p->subtitle_format, p->loop);
		//modify end
		if (result != 0)
			{
			p->return_result  = result;
			p->return_request = 1;
			break;
			}


		if (sceKernelSignalSema(p->semaphore_can_get, 1) < 0)
			{
			p->return_result  = "pmp_play_start: sceKernelSignalSema failed on semaphore_can_get";
			p->return_request = 1;
			break;
			}


		current_video_frame = pmp_next_video_frame(p, current_video_frame);


		if ((p->loop == 1) && (current_video_frame == p->decoder.reader.file.header.video.number_of_frames))
			{
			current_video_frame = 0;
			}
		}

	//*/ 2006.08.28 cooleyes
	if (current_video_frame == p->decoder.reader.file.header.video.number_of_frames)
		{
			p->last_keyframe_pos = 0;
		}
	//*/
	
	sceKernelDelayThread(1000000);
	p->return_request = 1;




	sceKernelWaitThreadEnd(p->output_thread, 0);
	sceKernelWaitThreadEnd(p->show_thread,   0);


	return(p->return_result);
	}
void Psp2Audio::BGM_Play(std::string const& file, int volume, int pitch, int fadein) {

	// If a BGM is currently playing, we kill it
	BGM_Stop();
	sceKernelWaitSema(BGM_Mutex, 1, NULL);
	if (BGM != NULL){
		free(BGM->audiobuf);
		free(BGM->audiobuf2);
		audio_decoder.reset();
		free(BGM);
		BGM = NULL;
	}

	// Opening file
	FILE* stream = FileFinder::fopenUTF8(file, "rb");
	if (!stream) {
		Output::Warning("Couldn't open music file %s", file.c_str());
		sceKernelSignalSema(BGM_Mutex, 1);
		return;
	}

	// Trying to use internal decoder
	audio_decoder = AudioDecoder::Create(stream, file);
	if (audio_decoder == NULL){
		fclose(stream);
		Output::Warning("Unsupported music format (%s)", file.c_str());
		sceKernelSignalSema(BGM_Mutex, 1);
		return;
	}

	// Initializing internal audio decoder
	int audiotype;
	fseek(stream, 0, SEEK_SET);
	if (!audio_decoder->Open(stream)) Output::Error("An error occured in audio decoder (%s)", audio_decoder->GetError().c_str());
	audio_decoder->SetLooping(true);
	AudioDecoder::Format int_format;
	int samplerate;
	audio_decoder->SetFormat(48000, AudioDecoder::Format::S16, 2);
	audio_decoder->GetFormat(samplerate, int_format, audiotype);
	if (samplerate != 48000) Output::Warning("Cannot resample music file. Music will be distorted.");

	// Initializing music block
	DecodedMusic* myFile = (DecodedMusic*)malloc(sizeof(DecodedMusic));

	// Check for file audiocodec
	if (audiotype == 2) myFile->isStereo = true;
	else myFile->isStereo = false;

	// Setting audiobuffer size
	myFile->audiobuf = (uint8_t*)malloc(AUDIO_BUFSIZE);
	myFile->audiobuf2 = (uint8_t*)malloc(AUDIO_BUFSIZE);
	myFile->cur_audiobuf = myFile->audiobuf;

	//Setting default streaming values
	myFile->handle = stream;
	myFile->endedOnce = false;

	// Passing new music block to the audio thread
	BGM = myFile;

	// Music settings
	audio_decoder->SetFade(0, volume, fadein);
	audio_decoder->SetPitch(pitch);
	BGM->tick = DisplayUi->GetTicks();
	BGM->vol = volume;

	// Starting BGM
	BGM->isNewTrack = true;
	BGM->isPlaying = true;
	sceKernelSignalSema(BGM_Mutex, 1);

}
Example #6
0
	void Unlock()
	{
		sceKernelSignalSema(handle, 1);
	}
Example #7
0
/* Subroutine sceDdrdb_driver_05D50F41 - Address 0x00002B3C */
s32 sceDdrdbEncrypt(u8 *pSrcData, SceSize size) 
{
    s32 status;
    SceSize workSize;
    s32 tmpStatus;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002B78
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    if (size <= SCE_DNAS_USER_DATA_MAX_LEN && IS_AES_BLOCK_LEN_MULTIPLE(size)) { // 0x00002B84 & 0x00002B90
        // 0x00002C10 - 0x00002C24

        /* Set up the work area for KIRK. */
        KirkAESHeader *pAesHdr = (KirkAESHeader *)g_pWorkData;
        pAesHdr->mode = 4;
        pAesHdr->unk4 = 0;
        pAesHdr->unk8 = 0;
        pAesHdr->keyIndex = 0xB;
        pAesHdr->dataSize = size;

        /* Copy data to be encrypted into work area. */
        u8 *pData = g_pWorkData + sizeof(KirkAESHeader);
        for (i = 0; i < size; i++) // 0x00002C34 - 0x00002C50
            pData[i] = pSrcData[i]; //0x00002C50

        workSize = size + sizeof(KirkAESHeader); //0x00002C58
        status = SCE_DNAS_ERROR_OPERATION_FAILED;

        /* Encrypt the specified data. */
        tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, workSize, g_pWorkData, workSize, KIRK_CMD_ENCRYPT_AES_CBC_IV_NONE); //0x00002C6C
        if (tmpStatus == SCE_ERROR_OK) { //0x00002C74    

            /* Copy encrypted data into provided buffer. */
            for (i = 0; i < size; i++)
                pSrcData[i] = pData[i];

            status = SCE_ERROR_OK; //0x00002CAC
        }
    }
    else {
        status = SCE_DNAS_ERROR_INVALID_ARGUMENTS; // 0x00002BA0

        /*
        * UOFW: size here is > SCE_DDRDB_MAX_BUFFER_SIZE, so more data gets cleared
        * below then neccessary. Depending on size, we even clear data which does not
        * belong to the work area.
        * Another note: Why do we have to clear any data in this case? The work area
        * wasn't set up. workSize should be 0.
        */
        workSize = size + sizeof(KirkAESHeader); //0x00002B9C
    }
    
    /* Clear the work area. */
    for (i = 0; i < workSize; i++) //0x00002BB0 - 0x00002BC4
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1);
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002BD4 - 0x00002BDC
}
Example #8
0
void Psp2Ui::UpdateDisplay() {
	sceKernelWaitSema(GPU_Mutex, 1, NULL);
	memcpy(vita2d_texture_get_datap(next_texture), vita2d_texture_get_datap(main_texture), vita2d_texture_get_stride(main_texture)*240);
	sceKernelSignalSema(GPU_Mutex, 1);
}
Example #9
0
/*----------------------------------------------------------------------
|       NPT_PSPMutex::Unlock
+---------------------------------------------------------------------*/
NPT_Result
NPT_PSPMutex::Unlock()
{
    sceKernelSignalSema(m_semaphore, 1);
    return NPT_SUCCESS;
}
Example #10
0
int T_Audio(SceSize _args, void *_argp)
{
	DecoderThreadData* D = *((DecoderThreadData**)_argp);

	sceKernelWaitSema(D->Audio->m_SemaphoreStart, 1, 0);

	for(;;)
	{
		if(D->Audio->m_iAbort != 0)
			break;

		if(D->Audio->m_iFullBuffers > 0)
		{
			sceAudioOutputBlocking(D->Audio->m_AudioChannel, PSP_AUDIO_VOLUME_MAX,
				D->Audio->m_pAudioBuffer[D->Audio->m_iPlayBuffer]);

			D->Audio->m_iPlayBuffer = (D->Audio->m_iPlayBuffer + 1) % D->Audio->m_iNumBuffers;

			sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0);

			D->Audio->m_iFullBuffers--;

			sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1);
		}
		else
		{
			sceKernelDelayThread(1000);
		}
        sceKernelDelayThread(100);

		stop_pmf();
		/*Human-Behind ** use to stop*/
		if(stop == 1)
		{
		break;
		}/*Human-Behind ** use to stop*/
	}

	while(D->Audio->m_iFullBuffers > 0)
	{
		sceAudioOutputBlocking(D->Audio->m_AudioChannel, PSP_AUDIO_VOLUME_MAX,
			D->Audio->m_pAudioBuffer[D->Audio->m_iPlayBuffer]);

		D->Audio->m_iPlayBuffer = (D->Audio->m_iPlayBuffer + 1) % D->Audio->m_iNumBuffers;

		sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0);

		D->Audio->m_iFullBuffers--;

		sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1);
        sceKernelDelayThread(100);

		stop_pmf();
		/*Human-Behind ** use to stop*/
		if(stop == 1)
		{
		break;
		}/*Human-Behind ** use to stop*/
	}

	sceKernelExitThread(0);

	return 0;
}
void Psp2Audio::SE_Play(std::string const& file, int volume, int pitch) {
	// Opening file
	FILE* stream = FileFinder::fopenUTF8(file, "rb");
	if (!stream) {
		Output::Warning("Couldn't open sound file %s", file.c_str());
		return;
	}

	// Pick the next free SE slot.
	// Does not need synchronisation
	int idx = -1;
	for (int i = 0; i < AUDIO_CHANNELS; ++i) {
		if (sfx_sounds[i].isPlaying && sfx_sounds[i].isFinished) {
			idx = i;
			break;
		}
	}

	if (idx == -1) {
		fclose(stream);
		Output::Warning("SE: No free channels available (%s)", file.c_str());
		return;
	}

	DecodedSound& sfx = sfx_sounds[idx];

	sfx.decoder = AudioDecoder::Create(stream, file);
	if (sfx.decoder == nullptr){
		fclose(stream);
		Output::Warning("Unsupported sound format (%s)", file.c_str());
		return;
	}

	// Initializing internal audio decoder
	int audiotype;

	AudioDecoder* decoder = sfx.decoder.get();

	if (!decoder->Open(stream)) {
		Output::Warning("Error occured in audio decoder (%s)", audio_decoder->GetError().c_str());
		return;
	}

	decoder->SetLooping(false);
	AudioDecoder::Format int_format;
	int samplerate;
	decoder->SetFormat(48000, AudioDecoder::Format::S16, 2);
	decoder->GetFormat(samplerate, int_format, audiotype);
	if (samplerate != 48000) Output::Warning("Cannot resample sound file. Sound will be distorted.");

	// Check for file audiocodec
	sfx.isStereo = audiotype == 2;

	// Setting default streaming values
	sfx.cur_audiobuf = sfx.audiobuf;

	decoder->SetPitch(pitch);
	decoder->SetVolume(volume);

	// Wait and signal is required to prevent reordering
	sceKernelWaitSema(SFX_Mutex_ID, 1, NULL);
	sfx.isPlaying = false;
	sfx.isFinished = false;
	sceKernelSignalSema(SFX_Mutex_ID, 1);

	// Start one SE thread
	sceKernelSignalSema(SFX_Mutex, 1);
}
void Psp2Audio::BGM_Stop() {
	sceKernelWaitSema(BGM_Mutex, 1, NULL);
	if (BGM != NULL) BGM->isPlaying = false;
	sceKernelSignalSema(BGM_Mutex, 1);
}
void Psp2Audio::BGM_Resume() {
	sceKernelWaitSema(BGM_Mutex, 1, NULL);
	if (BGM != NULL && (!BGM->isPlaying)) BGM->isPlaying = true;
	sceKernelSignalSema(BGM_Mutex, 1);
}
Example #14
0
	sceKernelDeleteSema(sema);

	sema = sceKernelCreateSema("signal", 0, -3, 3, NULL);
	PRINT_SEMAPHORE(sema);
	SIGNAL_TEST("Start negative", sema, 1);
	sceKernelDeleteSema(sema);

	SIGNAL_TEST("NULL", 0, 1);
	SIGNAL_TEST("Invalid", 0xDEADBEEF, 1);
	SIGNAL_TEST("Deleted", sema, 1);

	TWO_STEP_SCHED_TEST("Signal other then same", 0, 0,
		result = sceKernelSignalSema(sema2, 1);
	,
		result = sceKernelSignalSema(sema1, 1);
	);

	BASIC_SCHED_TEST("NULL",
		result = sceKernelSignalSema(0, 0);
	);
	BASIC_SCHED_TEST("Other + 2",
		result = sceKernelSignalSema(sema2, 2);
	);
	BASIC_SCHED_TEST("Other + 1",
		result = sceKernelSignalSema(sema2, 1);
	);
	BASIC_SCHED_TEST("Other - 1",
		result = sceKernelSignalSema(sema2, -1);
	);
	BASIC_SCHED_TEST("Same + 2",
Example #15
0
/* Subroutine sceDdrdb_driver_B33ACB44 - Address 0x00002CB0 */
s32 sceDdrdbDecrypt(u8 *pSrcData, SceSize size) 
{
    s32 status;
    s32 workSize;
    s32 tmpStatus;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002CF0
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    if (size <= SCE_DNAS_USER_DATA_MAX_LEN && IS_AES_BLOCK_LEN_MULTIPLE(size)) { //0x00002CFC & 0x00002CD0
         // 0x00002D8C - 0x00002DA4

        /* Set up the work area for KIRK. */
        KirkAESHeader *pAesHdr = (KirkAESHeader *)g_pWorkData;
        pAesHdr->mode = 5;
        pAesHdr->unk4 = 0;
        pAesHdr->unk8 = 0;
        pAesHdr->keyIndex = 0xB;
        pAesHdr->dataSize = size;

        /* Copy data to be decrypted into work area. */
        u8 *pData = g_pWorkData + sizeof(KirkAESHeader);
        for (i = 0; i < size; i++) //0x00002DB4 - 0x00002DD0
            pData[i] = pSrcData[i];

        workSize = size + sizeof(KirkAESHeader); //0x00002DD8
        status = SCE_DNAS_ERROR_OPERATION_FAILED; //0x00002DF0 & 0x00002DF8

        /* Decrypt the specified data. */
        tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, workSize, g_pWorkData, workSize, KIRK_CMD_DECRYPT_AES_CBC_IV_NONE); //0x00002DEC
        if (tmpStatus == SCE_ERROR_OK) { //0x00002DF4
            
            /* Copy the computed data back into the provided buffer. */
            for (i = 0; i < size; i++) //0x00002E04 - 0x00002E20
                /*
                 * UOFW: Is this correct? We are copying <size> bytes from the beginning of the
                 * the work data, which includes the KIRK AES header. If the header is still 
                 * inside the workData after decryption, we copy wrong data over and miss out
                 * the last <sizeof(KirkAESHeader)> bits of the data to be decrypted.
                 *
                 * Note: sceDdrdbEncrypt() assumes the header is still there and skips it accordingly.
                 */
                pSrcData[i] = g_pWorkData[i]; //0x00002E20

            status = SCE_ERROR_OK; //0x00002E20
        }
    }
    else {
        status = SCE_DNAS_ERROR_INVALID_ARGUMENTS; //0x00002D10 & 0x00002D18

        /* 
         * UOFW: size here is > SCE_DDRDB_MAX_BUFFER_SIZE, so more data gets cleared 
         * below then neccessary. Depending on size, we even clear data which does not 
         * belong to the work area.
         * Another note: Why do we have to clear any data in this case? The work area 
         * wasn't set up. workSize should be 0.
         */
        workSize = size + sizeof(KirkAESHeader); //0x00002D14
    }

    /* Clear the work area. */
    for (i = 0; i < workSize; i++) // 0x00002D20 - 0x00002D3C
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x00002D44
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002D4C & 0x00002D50 & 0x00002D54
}
Example #16
0
int T_Decoder(SceSize _args, void *_argp)
{
	int retVal;
	int oldButtons = 0;
	SceCtrlData pad;
#if DEBUG_TIMING
	int start, end;
	char s[200];
#endif

	int iInitAudio = 1;
	SceInt32 iVideoStatus = 0;
	int videoFrameCount = 0;
	int audioFrameCount = 0;

	SceInt32 unknown = 0;

	int iThreadsRunning = 0;

	SceInt32 m_iAudioCurrentTimeStamp = 0;
	SceInt32 m_iVideoCurrentTimeStamp = 0;
	SceInt32 m_iVideoLastTimeStamp = 0;

	DecoderThreadData* D = *((DecoderThreadData**)_argp);

	SceUInt32 m_iLastPacketsWritten = D->Reader->m_Ringbuffer->iUnk1;
	SceInt32  m_iLastPacketsAvailable = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer);

	D->Connector->initConnector();

	for(;;)
	{
		sceKernelDelayThread(1);

		scePowerTick(0);

		sceCtrlReadBufferPositive(&pad, 1);
		int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons;

		if (buttonDown & PSP_CTRL_CIRCLE)
		{
			break;
		}

		if( iThreadsRunning == 0 &&
			IsRingbufferFull(D->Reader) &&
			D->Video->m_iNumBuffers == D->Video->m_iFullBuffers)
		{
			iThreadsRunning = 1;
			sceKernelSignalSema(D->Video->m_SemaphoreStart, 1);
			sceKernelSignalSema(D->Audio->m_SemaphoreStart, 1);
		}

		if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
		{
			break;
		}
		else if(D->Reader->m_Status == ReaderThreadData::READER_EOF)
		{
			retVal = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer);

			if(retVal == D->Reader->m_RingbufferPackets)
				break;
		}

		if(!IsRingbufferFull(D->Reader))
		{
			sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

			if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
				break;
		}

		if (DEBUG_USERDATA)
		{
			SceInt32 unknown2[2];
			SceUInt32 i;
			unknown2[0] = 0x12345678;
			unknown2[1] = 0xABCDEF98;
			retVal = sceMpegGetUserdataAu(&D->m_Mpeg, D->m_MpegStreamUserdata, D->m_MpegAuUserdata, unknown2);

			u8 *esBuffer = (u8 *) D->m_MpegAuUserdata->iEsBuffer;
			SceUInt32 esSize = D->m_MpegAuUserdata->iAuSize;

			sprintf(s, "sceMpegGetUserdataAu result 0x%08X", retVal);
			debug(s);

			if (retVal == 0)
			{
				sprintf(s, "sceMpegGetUserdataAu unknown[0]=0x%08X, unknown[1]=0x%08X, esBuffer=0x%08X, esSize=0x%X", unknown2[0], unknown2[1], D->m_MpegAuUserdata->iEsBuffer, esSize);
				debug(s);
				debug(D->m_MpegAuUserdata);
				for (i = 0; i < esSize; i += 8)
				{
					sprintf(s, "0x%08X: %02X %02X %02X %02X %02X %02X %02X %02X", D->m_MpegAuUserdata->iEsBuffer + i, esBuffer[i], esBuffer[i+1], esBuffer[i+2], esBuffer[i+3], esBuffer[i+4], esBuffer[i+5], esBuffer[i+6], esBuffer[i+7]);
					debug(s);
				}
			}
		}

		if(D->Audio->m_iFullBuffers < D->Audio->m_iNumBuffers)
		{
#if DEBUG_TIMING
			start = sceKernelGetSystemTimeLow();
#endif
			retVal = sceMpegGetAtracAu(&D->m_Mpeg, D->m_MpegStreamAtrac, D->m_MpegAuAtrac, &unknown);
#if DEBUG_TIMING
			end = sceKernelGetSystemTimeLow();
			sprintf(s, "Duration sceMpegGetAtracAu %d, return %X, presentation timeStamp %d (%d), decode timeStamp %d", end - start, retVal, D->m_MpegAuAtrac->iPts, m_iAudioCurrentTimeStamp + D->m_iAudioFrameDuration, D->m_MpegAuAtrac->iDts);
			debug(s);
			debug(D->m_MpegAuAtrac);
			debug(D->Reader->m_Ringbuffer);
#endif
			if(retVal != 0)
			{
				if(!IsRingbufferFull(D->Reader))
				{
					sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

					if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
						break;
				}
			}
			else
			{
				if(m_iAudioCurrentTimeStamp >= D->m_iLastTimeStamp - D->m_iVideoFrameDuration)
					break;

#if DEBUG_TIMING
				start = sceKernelGetSystemTimeLow();
#endif
				retVal = sceMpegAtracDecode(&D->m_Mpeg, D->m_MpegAuAtrac, D->Audio->m_pAudioBuffer[D->Audio->m_iDecodeBuffer], iInitAudio);
#if DEBUG_TIMING
				end = sceKernelGetSystemTimeLow();
				sprintf(s, "Duration sceMpegAtracDecode %d, return %X", end - start, retVal);
				debug(s);
				debug(D->Reader->m_Ringbuffer);
#endif
				if(retVal != 0)
				{
					sprintf(D->m_LastError, "sceMpegAtracDecode() failed: 0x%08X", retVal);
					break;
				}

				if(D->m_MpegAuAtrac->iPts == 0xFFFFFFFF)
					m_iAudioCurrentTimeStamp += D->m_iAudioFrameDuration;
				else
					m_iAudioCurrentTimeStamp = D->m_MpegAuAtrac->iPts;

				if(m_iAudioCurrentTimeStamp <= 0x15F90 /* video start ts */ - D->m_iAudioFrameDuration)
					iInitAudio = 1;

				D->Audio->m_iBufferTimeStamp[D->Audio->m_iDecodeBuffer] = m_iAudioCurrentTimeStamp;

				if(iInitAudio == 0)
				{
					D->Connector->sendAudioFrame(audioFrameCount, D->Audio->m_pAudioBuffer[D->Audio->m_iDecodeBuffer], D->m_MpegAtracOutSize, m_iAudioCurrentTimeStamp);
					audioFrameCount++;

					sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0);

					D->Audio->m_iFullBuffers++;

					sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1);

					D->Audio->m_iDecodeBuffer = (D->Audio->m_iDecodeBuffer + 1) % D->Audio->m_iNumBuffers;
				}

				iInitAudio = 0;
			}
		}

		if(!IsRingbufferFull(D->Reader))
		{
			sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

			if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
				break;
		}

		if(D->Video->m_iFullBuffers < D->Video->m_iNumBuffers)
		{
#if DEBUG_TIMING
			start = sceKernelGetSystemTimeLow();
#endif
			retVal = sceMpegGetAvcAu(&D->m_Mpeg, D->m_MpegStreamAVC, D->m_MpegAuAVC, &unknown);
#if DEBUG_TIMING
			end = sceKernelGetSystemTimeLow();
			sprintf(s, "Duration sceMpegGetAvcAu %d, return %X, presentation timeStamp %d (%d), decode timeStamp %d", end - start, retVal, D->m_MpegAuAVC->iPts, m_iVideoCurrentTimeStamp + 3004, D->m_MpegAuAVC->iDts);
			debug(s);
			debug(D->m_MpegAuAVC);
			debug(D->Reader->m_Ringbuffer);
#endif
			if((SceUInt32)retVal == 0x80618001)
			{
				if(!IsRingbufferFull(D->Reader))
				{
					sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

					if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
						break;
				}
			}
			else if(retVal != 0)
			{
				sprintf(D->m_LastError, "sceMpegGetAvcAu() failed: 0x%08X", retVal);
				break;
			}
			else
			{
				if(m_iVideoCurrentTimeStamp >= D->m_iLastTimeStamp - D->m_iVideoFrameDuration)
					break;

#if DEBUG_TIMING
				start = sceKernelGetSystemTimeLow();
#endif
				retVal = sceMpegAvcDecode(&D->m_Mpeg, D->m_MpegAuAVC, BUFFER_WIDTH, &D->Video->m_pVideoBuffer[D->Video->m_iPlayBuffer], &iVideoStatus);
#if DEBUG_TIMING
				end = sceKernelGetSystemTimeLow();
				sprintf(s, "Duration sceMpegAvcDecode %d, return %X", end - start, retVal);
				debug(s);
				debug(D->Reader->m_Ringbuffer);
#endif
				if(retVal != 0)
				{
					sprintf(D->m_LastError, "sceMpegAvcDecode() failed: 0x%08X", retVal);
					break;
				}

				if(D->m_MpegAuAVC->iPts == 0xFFFFFFFF)
					m_iVideoCurrentTimeStamp += 0x0BBC;
				else
					m_iVideoCurrentTimeStamp = D->m_MpegAuAVC->iPts;

				if(iVideoStatus == 1)
				{
					SceUInt32 m_iPacketsWritten = D->Reader->m_Ringbuffer->iUnk1;
					SceInt32  m_iPacketsAvailable = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer);

					SceInt32  m_iDeltaPacketsWritten = m_iPacketsWritten - m_iLastPacketsWritten;
					if (m_iDeltaPacketsWritten < 0)
					{
						m_iDeltaPacketsWritten += D->Reader->m_Ringbuffer->iPackets;
					}
					SceInt32 m_iDeltaPacketsAvailable = m_iPacketsAvailable - m_iLastPacketsAvailable;
					SceInt32 m_iConsumedPackets = m_iDeltaPacketsAvailable + m_iDeltaPacketsWritten;

					m_iLastPacketsWritten = m_iPacketsWritten;
					m_iLastPacketsAvailable = m_iPacketsAvailable;

					D->Connector->sendVideoFrame(videoFrameCount, D->Video->m_pVideoBuffer[D->Video->m_iPlayBuffer], m_iVideoCurrentTimeStamp, D->Reader, m_iConsumedPackets);
					videoFrameCount++;

					D->Video->m_iBufferTimeStamp[D->Video->m_iPlayBuffer] = m_iVideoLastTimeStamp;

					sceKernelWaitSema(D->Video->m_SemaphoreLock, 1, 0);

					D->Video->m_iFullBuffers++;

					sceKernelSignalSema(D->Video->m_SemaphoreLock, 1);
				}

				m_iVideoLastTimeStamp = m_iVideoCurrentTimeStamp;
			}
		}

		if(!IsRingbufferFull(D->Reader))
		{
			sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

			if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
				break;
		}

	}

	D->Connector->exitConnector();

	sceKernelSignalSema(D->Audio->m_SemaphoreStart, 1);
	sceKernelSignalSema(D->Video->m_SemaphoreStart, 1);

	D->Reader->m_Status = ReaderThreadData::READER_ABORT;

	D->Audio->m_iAbort = 1;

	while(D->Video->m_iFullBuffers > 0)
	{
		sceKernelWaitSema(D->Video->m_SemaphoreWait, 1, 0);
		sceKernelSignalSema(D->Video->m_SemaphoreLock, 1);
	}

	sceMpegAvcDecodeStop(&D->m_Mpeg, BUFFER_WIDTH, D->Video->m_pVideoBuffer, &iVideoStatus);

	if(iVideoStatus > 0)
	{
		sceKernelWaitSema(D->Video->m_SemaphoreLock, 1, 0);

		D->Video->m_iFullBuffers++;

		sceKernelSignalSema(D->Video->m_SemaphoreLock, 1);
	}

	D->Video->m_iAbort = 1;

	sceMpegFlushAllStream(&D->m_Mpeg);

	sceKernelExitThread(0);

	return 0;
}
Example #17
0
File: libmpeg.c Project: yne/js-psp
int signalSema(int sema){
	return sceKernelSignalSema(sema, 1);
}
Example #18
0
int fillFileBuffer() { 
	// wait for semaphore to be open
	sceKernelWaitSema(mutex, 1, 0); 

	// Open the file if it's not open. 
	if (SongIsChanged == 1) {
		SongIsChanged = 0;
		if (file>0) sceIoClose(file); // If the file wasn't closed before (got to next song before reaching EOF), close it now 
		file = 0;
	}
	if (file <= 0) { 
		char   cd[1024]; 
		memset(cd, 0, sizeof(cd)); 
		getcwd(cd, sizeof(cd) - 1); 

		char   fileName[1024]; 
		memset(fileName, 0, sizeof(fileName)); 
		snprintf(fileName, sizeof(fileName) - 1, "%s/%s", cd, Song);

		file = sceIoOpen(fileName, PSP_O_RDONLY, 777); 
		if (file <= 0) 
		{ 
			pspDebugScreenPrintf("Failed (%s).\n", Song); 
			sceKernelSignalSema(mutex, 1);
			/*
			* do something when file is not loaded
			*/
			return 1; 
		} 

		// Get the size. 
		fileSize = sceIoLseek(file, 0, SEEK_END); 
		sceIoLseek(file, 0, SEEK_SET); 
	} 

	// Find out how much to keep and how much to fill. 
	const unsigned int   bytesToKeep   = stream.bufend - stream.next_frame; 
	unsigned int      bytesToFill   = sizeof(fileBuffer) - bytesToKeep; 
	//pspDebugScreenPrintf("bytesToFill = %u, bytesToKeep = %u.\n", bytesToFill, bytesToKeep); 

	// Want to keep any bytes? 
	if (bytesToKeep) 
	{ 
		// Copy the tail to the head. 
		memmove(fileBuffer, fileBuffer + sizeof(fileBuffer) - bytesToKeep, bytesToKeep); 
	} 

	// Read into the rest of the file buffer. 
	unsigned char* bufferPos = fileBuffer + bytesToKeep; 
	while (bytesToFill > 0) 
	{ 
		// Read some. 
		//pspDebugScreenPrintf("Reading %u bytes...\n", bytesToFill); 
		const unsigned int bytesRead = sceIoRead(file, bufferPos, bytesToFill); 

		// EOF? 
		if (bytesRead == 0) { 
			sceKernelSignalSema(mutex, 1);
			return 2; //handle stuff when end of file with return value !!!NOT HERE
		} 

		// Adjust where we're writing to. 
		bytesToFill -= bytesRead; 
		bufferPos += bytesRead; 
		filePos += bytesRead; 

		//pspDebugScreenPrintf("Read %u bytes from the file, %u left to fill.\n", bytesRead, bytesToFill); 
		//pspDebugScreenPrintf("%u%%.\n", filePos * 100 / fileSize); 
	} 
	// release the semaphore
	sceKernelSignalSema(mutex, 1);
	return 0;
} 
static int sfxThread(unsigned int args, void* arg){
	int ch = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, 64, 48000, SCE_AUDIO_OUT_MODE_STEREO);
	if (ch < 0){
		Output::Warning("SFX Thread: Cannot open audio port");
		sceKernelExitDeleteThread(0);
	}

	for (;;){
		sceKernelWaitSema(SFX_Mutex, 1, NULL);

		// Check if the thread must be closed
		if (mustExit){
			sfx_exited++;
			if (sfx_exited < AUDIO_CHANNELS) sceKernelSignalSema(SFX_Mutex, 1);
			else mustExit = false;
			sceAudioOutReleasePort(ch);
			sceKernelExitDeleteThread(0);
		}

		// Pick the next SE that wants to be played
		sceKernelWaitSema(SFX_Mutex_ID, 1, NULL);
		int idx = -1;
		for (int i = 0; i < AUDIO_CHANNELS; ++i) {
			if (!sfx_sounds[i].isPlaying && !sfx_sounds[i].isFinished) {
				idx = i;
				break;
			}
		}

		if (idx == -1) {
			sceKernelSignalSema(SFX_Mutex_ID, 1);
			// Shouldn't happen...
			Output::Warning("No pending SE found");
			continue;
		} else {
			sfx_sounds[idx].isPlaying = true;
			sceKernelSignalSema(SFX_Mutex_ID, 1);
		}

		DecodedSound& sfx = sfx_sounds[idx];

		// Preparing audio port
		uint8_t audio_mode = sfx.isStereo ? SCE_AUDIO_OUT_MODE_STEREO : SCE_AUDIO_OUT_MODE_MONO;
		int nsamples = AUDIO_BUFSIZE / ((audio_mode+1)<<1);
		sceAudioOutSetConfig(ch, nsamples, 48000, audio_mode);
		int vol = sfx.decoder->GetVolume() * 327;
		int vol_stereo[] = {vol, vol};
		sceAudioOutSetVolume(ch, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);

		// Playing sound
		while (!sfx.isFinished){
			if (sfx.cur_audiobuf == sfx.audiobuf) sfx.cur_audiobuf = sfx.audiobuf2;
			else sfx.cur_audiobuf = sfx.audiobuf;
			sfx.decoder->Decode(sfx.cur_audiobuf, AUDIO_BUFSIZE);
			sceAudioOutOutput(ch, sfx.cur_audiobuf);
			if (sfx.decoder->IsFinished()) { // EoF
				// SE slot is free again
				sfx.isFinished = true;
				break;
			}
		}
	}

}