int PlayThread(SceSize argsize, void* args) { if (argsize!=sizeof(int)) { sceKernelExitThread(0); } int hardwareChannel=*((int*)args); int channel=hardwareChannels[hardwareChannel]; int stopReason; void *mainBuf,*backBuf,*tempBuf; mainBuf=malloc(4096); backBuf=malloc(4096); sceAudioChReserve(hardwareChannel,1024,PSP_AUDIO_FORMAT_STEREO); while(TRUE) { stopReason=AalibGetStopReason(channel); if (!stopReason) { goto Play; } else if (stopReason<0) { sceKernelDelayThread(10); continue; } else { goto Release; } } Play: GetProcessedBuffer(mainBuf,1024,channel); while (!AalibGetStopReason(channel)) { sceAudioOutputPanned(hardwareChannel,(unsigned int)(channels[channel].volume.left*channels[channel].audioStrength*PSP_AUDIO_VOLUME_MAX),(unsigned int)(channels[channel].volume.right*channels[channel].audioStrength*PSP_AUDIO_VOLUME_MAX),mainBuf); GetProcessedBuffer(backBuf,1024,channel); while (sceAudioGetChannelRestLen(hardwareChannel)) sceKernelDelayThread(100); tempBuf=mainBuf; mainBuf=backBuf; backBuf=tempBuf; } Release: FreeHardwareChannel(channel); AalibStop(channel); sceKernelExitThread(0); return 0; }
static int audioMainLoop(SceSize args, void* argp) { psp1_audio_t* psp = *((psp1_audio_t**)argp); sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2); while (psp->running) { /* Get a non-volatile copy. */ uint16_t readPos = psp->readPos; if (((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2)) sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, psp->zeroBuffer); else { sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, psp->buffer + readPos); readPos += AUDIO_OUT_COUNT; readPos &= AUDIO_BUFFER_SIZE_MASK; psp->readPos = readPos; } } sceAudioSRCChRelease(); sceKernelExitThread(0); return 0; }
static int threadEndedFunction3(int args, void* argp) { printf("Thread3.Started\n"); sceKernelDelayThread(10 * 1000); printf("Thread3.GoingToEnd\n"); sceKernelExitThread(0); return 0; }
int ball_thread(int size, Ball *b) { int inPlay = 1; // Loop until game ends or until ball is no longer in play. while (_gameState != GAME_OVER && inPlay) { if (_gameState == GAME_PAUSED) { sceKernelWaitSema(_pauseSem, 1, 0); // Block on semaphore sceKernelSignalSema(_pauseSem, 1); // Once awake, signal semaphore so next in line wakes up } inPlay = DrawBall(b); sceKernelDelayThread(10000); } _activeBalls[b->ballId] = 0; // Remove this ball from array of active balls sceKernelExitThread(0); return 0; }
static int channel_thread(int args, void *argp) { volatile int bufidx = 0; int channel = *(int*)argp; int i, j; unsigned short *ptr_m; unsigned int *ptr_s; void *bufptr; unsigned int samples; pl_snd_callback callback; pl_snd_channel_info *ch_info; ch_info = &sound_stream[channel]; for (j = 0; j < 2; j++) memset(ch_info->sample_buffer[j], 0, ch_info->samples[j] * get_bytes_per_sample(channel)); while (!sound_stop) { callback = ch_info->callback; bufptr = ch_info->sample_buffer[bufidx]; samples = ch_info->samples[bufidx]; if (callback && !ch_info->paused) /* Use callback to fill buffer */ callback(bufptr, samples, ch_info->user_data); else { /* Fill buffer with silence */ if (ch_info->stereo) for (i = 0, ptr_s = bufptr; i < samples; i++) *(ptr_s++) = 0; else for (i = 0, ptr_m = bufptr; i < samples; i++) *(ptr_m++) = 0; } /* Play sound */ play_blocking(channel, ch_info->left_vol, ch_info->right_vol, bufptr); /* Switch active buffer */ bufidx = (bufidx ? 0 : 1); } sceKernelExitThread(0); return 0; }
/* psp_audio_channel_thread: * This PSP thread manages the audio playing. */ static int psp_audio_channel_thread() { while (psp_audio_on) { void *bufptr = &sound_buffer[curr_buffer]; /* Asks to the Allegro mixer to fill the buffer */ _mix_some_samples((uintptr_t)bufptr, 0, IS_SIGNED); /* Send mixed buffer to sound card */ sceAudioOutputPannedBlocking(hw_channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, bufptr); curr_buffer = !curr_buffer; } sceKernelExitThread(0); return 0; }
/*** * Callback thread that handles audio output, when it's available. */ static int audio_channel_thread(int args, void *argp) { volatile int bufidx = 0; int channel = *(int*)argp; int i; int readedLength; unsigned short *ptr_m; unsigned int *ptr_s; void *bufptr; unsigned int samples; pspAudioCallback callback; for (i = 0; i < 2; i++) { memset(audio_buffer[channel][bufidx], 0, AUDIO_SAMPLE_COUNT * sizeof(PspStereoSample)); } while (!stop_audio) { callback = audio_status[channel].Callback; bufptr = audio_buffer[channel][bufidx]; samples = audio_buffer_samples[channel][bufidx]; if (callback) { readedLength = callback(bufptr, &samples, audio_status[channel].Userdata); } else { for (i = 0, ptr_s = bufptr; i < samples; i++) { *(ptr_s++) = 0; } } if (readedLength > 0) { output_audio_blocking(channel, audio_status[channel].LeftVolume, audio_status[channel].RightVolume, bufptr, samples); bufidx = (bufidx ? 0 : 1); } } sceKernelExitThread(0); return 0; }
void psp_audio_thread(int args, void *argp) { int buff_id = 0; char* snd_buff = 0; while (psp_audio_term == 0) { if (psp_audio_sleep || (! HUGO.hugo_snd_enable)) { snd_buff = psp_audio_empty; } else { snd_buff = psp_audio_buffer[buff_id]; MixSound( snd_buff, 1024 ); buff_id = ! buff_id; } sceAudioOutputPannedBlocking(psp_audio_chid, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, snd_buff); } sceKernelExitThread(0); }
static int main_thread(SceSize args, void *argp) { SceCtrlData paddata; thread_active = 1; while (thread_active) { sceCtrlPeekBufferPositive(&paddata, 1); buttons = paddata.Buttons; sceKernelDelayThread(1000000/60); } sceKernelExitThread(0); return 0; }
static int audioMainLoop(SceSize args, void* argp) { psp_audio_t* psp = *((psp_audio_t**)argp); #ifdef VITA int port = sceAudioOutOpenPort(PSP2_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT, psp->rate, PSP2_AUDIO_OUT_MODE_STEREO); #else sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2); #endif while (psp->running) { /* Get a non-volatile copy. */ uint16_t readPos = psp->readPos; bool cond = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2); #ifdef VITA sceAudioOutOutput(port, cond ? psp->zeroBuffer : (psp->buffer + readPos)); #else sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer) : (psp->buffer + readPos)); #endif if (!cond) { readPos += AUDIO_OUT_COUNT; readPos &= AUDIO_BUFFER_SIZE_MASK; psp->readPos = readPos; } } #ifdef VITA sceAudioOutReleasePort(port); #else sceAudioSRCChRelease(); #endif sceKernelExitThread(0); return 0; }
static int AudioChannelThread(int args, void *argp) { volatile int bufidx=0; int channel=*(int *)argp; while (audio_terminate==0) { void *bufptr=&audio_sndbuf[channel][bufidx]; pspAudioCallback_t callback; callback=AudioStatus[channel].callback; if (callback) { char*c = bufptr; c[0]='s'; c[1]='I'; c[2]='b'; c[3]='E'; callback(bufptr, PSP_NUM_AUDIO_SAMPLES, AudioStatus[channel].pdata); if (c[0] != 's'+10 || c[1] != 'I'+10 || c[2] != 'b'+10 || c[3] != 'E'+10 ) pspAudioOutBlocking(channel,AudioStatus[channel].volumeleft,AudioStatus[channel].volumeright,bufptr); } else { sceKernelWakeupThread(deletingthread); sceKernelSleepThread(); // pspAudioOutBlocking(channel,AudioStatus[channel].volumeleft,AudioStatus[channel].volumeright,audio_zerobuf); } bufidx=(bufidx?0:1); } sceKernelExitThread(0); return 0; }
void psp_cdaudio_thread(int args, void *argp) { char* snd_buff = 0; int buff_id = 0; while (psp_audio_term == 0) { if (psp_audio_sleep || (! HUGO.hugo_snd_enable) || (! HUGO.hugo_cdaudio_enable)) { myPowerSetClockFrequency(HUGO.psp_cpu_clock); snd_buff = psp_audio_empty; } else { snd_buff = psp_cdaudio_buffer[buff_id]; if (! MP3Callback(snd_buff, 1024, NULL)) { snd_buff = psp_audio_empty; } else { myPowerSetClockFrequency(HUGO.psp_cpu_cdclock); buff_id = ! buff_id; } } sceAudioOutputPannedBlocking(psp_cdaudio_chid, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, snd_buff); } sceKernelExitThread(0); }
static int AudioChannelThread(int args, void *argp) { volatile int bufidx=0; int channel=*(int *)argp; while (audio_terminate==0) { void *bufptr=&audio_sndbuf[channel][bufidx]; pspAudioCallback_t callback; callback=AudioStatus[channel].callback; if (callback) { callback(bufptr, PSP_NUM_AUDIO_SAMPLES, AudioStatus[channel].pdata); } else { unsigned int *ptr=bufptr; int i; for (i=0; i<PSP_NUM_AUDIO_SAMPLES; ++i) *(ptr++)=0; } pspAudioOutBlocking(channel,AudioStatus[channel].volumeleft,AudioStatus[channel].volumeright,bufptr); bufidx=(bufidx?0:1); } sceKernelExitThread(0); return 0; }
/* psp_timer_thread: * This PSP thread measures the elapsed time. */ static int psp_timer_thread() { uint64_t old_tick, new_tick; int interval; long delay; sceRtcGetCurrentTick(&old_tick); while (psp_timer_on) { /* Calculate actual time elapsed. */ sceRtcGetCurrentTick(&new_tick); interval = PSPTIMER_TO_TIMER(new_tick - old_tick); old_tick = new_tick; /* Handle a tick and rest. */ delay = _handle_timer_tick(interval); sceKernelDelayThreadCB(TIMER_TO_USEC(delay)); } sceKernelExitThread(0); return 0; }
void exit_reset(void) { psplinkSetK1(0); if(g_context.resetonexit) { /* Create a new thread to do the reset */ SceUID thid; thid = sceKernelCreateThread("PspLinkReset", reset_thread, 8, 4*1024, 0, NULL); if(thid >= 0) { sceKernelStartThread(thid, 0, NULL); } } else { SHELL_PRINT("\nsceKernelExitGame caught!\n"); /* Kill the thread, bad idea to drop back to the program */ } sceKernelExitThread(0); }
static int SystemButtonsThread(SceSize args, void *argp) { SceCtrlData paddata; thread_active = 1; while (thread_active) { if (__sceCtrlPeekBufferPositive) { (*__sceCtrlPeekBufferPositive)(&paddata, 1); system_buttons = paddata.Buttons & 0xf70000; if (__sceImposeGetParam) main_volume = (*__sceImposeGetParam)(PSP_IMPOSE_MAIN_VOLUME); } sceKernelDelayThread(1000000/60); } sceKernelExitThread(0); return 0; }
static int audio_ChannelThread(SceSize argc, void* argv) { int i = 0; void *bufptr = NULL; unsigned int *ptr = NULL; volatile int bufid = 0; int channel = *(int *)argv; void (*audio_UpdateCallback)(void *buf, unsigned len); while(audio_terminate == 0) { bufptr = &audio_buffers[channel][bufid]; audio_UpdateCallback = audio_ChannelCallback[channel]; if(audio_UpdateCallback) audio_UpdateCallback(bufptr, SAMPLES); else { ptr = bufptr; for(i=0; i<SAMPLES; i++) *(ptr++)=0; } audio_OutputPannedBlocking(channel, audio_volumes[channel][0], audio_volumes[channel][1], bufptr); bufid = (bufid ? 0:1); } sceKernelExitThread(0); return 0; }
static int MP3OutputThread(SceSize args, void *argp){ while(mp3_play) { if (mp3_pause) { sceKernelDelayThread(1000); continue; } if ( sceIoRead( mp3_file_handle, mp3_header_buffer, 4 ) != 4 ) { mp3_play = 0; continue; } if ( mp3_header_buffer[0] == 'T' && mp3_header_buffer[1] == 'A' && mp3_header_buffer[2] == 'G' ) { mp3_play = 0; continue; } unsigned int mp3_header = mp3_header_buffer[0]; mp3_header = (mp3_header<<8) | mp3_header_buffer[1]; mp3_header = (mp3_header<<8) | mp3_header_buffer[2]; mp3_header = (mp3_header<<8) | mp3_header_buffer[3]; if ( (mp3_header & 0xFFFE0000) != 0xFFFA0000) { sceIoLseek32(mp3_file_handle, -3, PSP_SEEK_CUR); continue; } int bitrate = (mp3_header & 0xf000) >> 12; int padding = (mp3_header & 0x200) >> 9; int frame_size = 144000*mp3_bitrates[bitrate]/mp3_samplerate + padding; if ( mp3_data_buffer ) free(mp3_data_buffer); mp3_data_buffer = (unsigned char*)memalign(64, frame_size); if ( !mp3_data_buffer ) { sceIoLseek32(mp3_file_handle, -4, PSP_SEEK_CUR); continue; } sceIoLseek32(mp3_file_handle, -4, PSP_SEEK_CUR); if ( sceIoRead( mp3_file_handle, mp3_data_buffer, frame_size ) != frame_size ) { mp3_play = 0; continue; } memset(mp3_output_buffer[mp3_output_buffers], 0, MP3_SAMPLE_COUNT * 4); mp3_codec_buffer[6] = (unsigned long)mp3_data_buffer; mp3_codec_buffer[8] = (unsigned long)mp3_output_buffer[mp3_output_buffers]; mp3_codec_buffer[7] = mp3_codec_buffer[10] = frame_size; mp3_codec_buffer[9] = MP3_SAMPLE_COUNT * 4; sceAudiocodecDecode(mp3_codec_buffer, 0x1002); sceAudioOutputPannedBlocking(mp3_audio_channel, mp3_volume, mp3_volume,mp3_output_buffer[mp3_output_buffers]); mp3_output_buffers = (mp3_output_buffers+1)%2; } if ( mp3_data_buffer ){ free(mp3_data_buffer); mp3_data_buffer = 0; } sceKernelExitThread(0); return 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); } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Private functions: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Decode thread: int decodeThread(SceSize args, void *argp){ int res; unsigned char MP3ME_header_buf[4]; int MP3ME_header; int version; int bitrate; int padding; int frame_size; int size; int total_size; int offset = 0; sceAudiocodecReleaseEDRAM(MP3ME_codec_buffer); //Fix: ReleaseEDRAM at the end is not enough to play another mp3. MP3ME_threadActive = 1; OutputBuffer_flip = 0; OutputPtrME = OutputBuffer[0]; sceIoChdir(audioCurrentDir); MP3ME_handle = sceIoOpen(MP3ME_fileName, PSP_O_RDONLY, 0777); if (MP3ME_handle < 0) MP3ME_threadActive = 0; //now search for the first sync byte, tells us where the mp3 stream starts total_size = sceIoLseek32(MP3ME_handle, 0, PSP_SEEK_END); size = total_size; sceIoLseek32(MP3ME_handle, 0, PSP_SEEK_SET); data_start = ID3v2TagSize(MP3ME_fileName); sceIoLseek32(MP3ME_handle, data_start, PSP_SEEK_SET); data_start = SeekNextFrameMP3(MP3ME_handle); if (data_start < 0) MP3ME_threadActive = 0; size -= data_start; memset(MP3ME_codec_buffer, 0, sizeof(MP3ME_codec_buffer)); memset(MP3ME_input_buffer, 0, sizeof(MP3ME_input_buffer)); memset(MP3ME_output_buffer, 0, sizeof(MP3ME_output_buffer)); if ( sceAudiocodecCheckNeedMem(MP3ME_codec_buffer, 0x1002) < 0 ) MP3ME_threadActive = 0; if ( sceAudiocodecGetEDRAM(MP3ME_codec_buffer, 0x1002) < 0 ) MP3ME_threadActive = 0; getEDRAM = 1; if ( sceAudiocodecInit(MP3ME_codec_buffer, 0x1002) < 0 ) MP3ME_threadActive = 0; MP3ME_eof = 0; MP3ME_info.framesDecoded = 0; while (MP3ME_threadActive){ while( !MP3ME_eof && MP3ME_isPlaying ) { MP3ME_filePos = sceIoLseek32(MP3ME_handle, 0, PSP_SEEK_CUR); if ( sceIoRead( MP3ME_handle, MP3ME_header_buf, 4 ) != 4 ){ MP3ME_isPlaying = 0; MP3ME_threadActive = 0; continue; } MP3ME_header = MP3ME_header_buf[0]; MP3ME_header = (MP3ME_header<<8) | MP3ME_header_buf[1]; MP3ME_header = (MP3ME_header<<8) | MP3ME_header_buf[2]; MP3ME_header = (MP3ME_header<<8) | MP3ME_header_buf[3]; bitrate = (MP3ME_header & 0xf000) >> 12; padding = (MP3ME_header & 0x200) >> 9; version = (MP3ME_header & 0x180000) >> 19; samplerate = samplerates[version][ (MP3ME_header & 0xC00) >> 10 ]; if ((bitrate > 14) || (version == 1) || (samplerate == 0) || (bitrate == 0))//invalid frame, look for the next one { data_start = SeekNextFrameMP3(MP3ME_handle); if(data_start < 0) { MP3ME_eof = 1; continue; } size -= (data_start - offset); offset = data_start; continue; } if (version == 3) //mpeg-1 { sample_per_frame = 1152; frame_size = 144000*bitrates[bitrate]/samplerate + padding; MP3ME_info.instantBitrate = bitrates[bitrate] * 1000; }else{ sample_per_frame = 576; frame_size = 72000*bitrates_v2[bitrate]/samplerate + padding; MP3ME_info.instantBitrate = bitrates_v2[bitrate] * 1000; } sceIoLseek32(MP3ME_handle, data_start, PSP_SEEK_SET); //seek back if (MP3ME_newFilePos >= 0) { if (!MP3ME_newFilePos) MP3ME_newFilePos = ID3v2TagSize(MP3ME_fileName); long old_start = data_start; if (sceIoLseek32(MP3ME_handle, MP3ME_newFilePos, PSP_SEEK_SET) != old_start){ data_start = SeekNextFrameMP3(MP3ME_handle); if(data_start < 0){ MP3ME_eof = 1; } MP3ME_playingTime = (float)data_start / (float)frame_size / (float)samplerate / 1000.0f; offset = data_start; size = total_size - data_start; } MP3ME_newFilePos = -1; continue; } size -= frame_size; if ( size <= 0) { MP3ME_eof = 1; continue; } //since we check for eof above, this can only happen when the file // handle has been invalidated by syspend/resume/usb if ( sceIoRead( MP3ME_handle, MP3ME_input_buffer, frame_size ) != frame_size ){ //Resume from suspend: if ( MP3ME_handle >= 0 ){ sceIoClose(MP3ME_handle); MP3ME_handle = -1; } MP3ME_handle = sceIoOpen(MP3ME_fileName, PSP_O_RDONLY, 0777); if (MP3ME_handle < 0){ MP3ME_isPlaying = 0; MP3ME_threadActive = 0; continue; } size = sceIoLseek32(MP3ME_handle, 0, PSP_SEEK_END); sceIoLseek32(MP3ME_handle, offset, PSP_SEEK_SET); data_start = offset; continue; } data_start += frame_size; offset = data_start; MP3ME_codec_buffer[6] = (unsigned long)MP3ME_input_buffer; MP3ME_codec_buffer[8] = (unsigned long)MP3ME_output_buffer; MP3ME_codec_buffer[7] = MP3ME_codec_buffer[10] = frame_size; MP3ME_codec_buffer[9] = sample_per_frame * 4; res = sceAudiocodecDecode(MP3ME_codec_buffer, 0x1002); if ( res < 0 ) { //instead of quitting see if the next frame can be decoded //helps play files with an invalid frame //we must look for a valid frame, the offset above may be wrong data_start = SeekNextFrameMP3(MP3ME_handle); if(data_start < 0) { MP3ME_eof = 1; continue; } size -= (data_start - offset); offset = data_start; continue; } MP3ME_playingTime += (float)sample_per_frame/(float)samplerate; MP3ME_info.framesDecoded++; //Output: memcpy( OutputPtrME, MP3ME_output_buffer, sample_per_frame*4); OutputPtrME += (sample_per_frame * 4); if( OutputPtrME + (sample_per_frame * 4) > &OutputBuffer[OutputBuffer_flip][OUTPUT_BUFFER_SIZE]) { //Volume Boost: if (MP3ME_volume_boost){ int i; for (i=0; i<OUTPUT_BUFFER_SIZE; i++){ OutputBuffer[OutputBuffer_flip][i] = volume_boost(&OutputBuffer[OutputBuffer_flip][i], &MP3ME_volume_boost); } } audioOutput(MP3ME_volume, OutputBuffer[OutputBuffer_flip]); OutputBuffer_flip ^= 1; OutputPtrME = OutputBuffer[OutputBuffer_flip]; //Check for playing speed: if (MP3ME_playingSpeed){ long old_start = data_start; if (sceIoLseek32(MP3ME_handle, frame_size * MP3ME_playingSpeed, PSP_SEEK_CUR) != old_start){ data_start = SeekNextFrameMP3(MP3ME_handle); if(data_start < 0){ MP3ME_eof = 1; continue; } float framesSkipped = (float)abs(old_start - data_start) / (float)frame_size; if (MP3ME_playingSpeed > 0) MP3ME_playingTime += framesSkipped * (float)sample_per_frame/(float)samplerate; else MP3ME_playingTime -= framesSkipped * (float)sample_per_frame/(float)samplerate; offset = data_start; size = total_size - data_start; }else MP3ME_setPlayingSpeed(0); } } } sceKernelDelayThread(10000); } if (getEDRAM) sceAudiocodecReleaseEDRAM(MP3ME_codec_buffer); if ( MP3ME_handle >= 0){ sceIoClose(MP3ME_handle); MP3ME_handle = -1; } sceKernelExitThread(0); return 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Private functions: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Decode thread: int AACdecodeThread(SceSize args, void *argp){ u8* aac_data_buffer = NULL; u32 aac_data_start; u8 aac_getEDRAM; u32 aac_channels; u32 aac_samplerate; sceAudiocodecReleaseEDRAM(aac_codec_buffer); sceIoChdir(audioCurrentDir); AAC_threadActive = 1; AAC_handle = sceIoOpen(AAC_fileName, PSP_O_RDONLY, 0777); if ( ! AAC_handle ){ AAC_threadActive = 0; goto end; } aac_output_index = 0; aac_channels = 2; aac_samplerate = AAC_info.hz; aac_data_start = 0; if (AAC_tagsize > 0) aac_data_start = AAC_tagsize + 10; sceIoLseek32(AAC_handle, aac_data_start, PSP_SEEK_SET); aac_data_start = SeekNextFrameMP3(AAC_handle); memset(aac_codec_buffer, 0, sizeof(aac_codec_buffer)); if ( sceAudiocodecCheckNeedMem(aac_codec_buffer, 0x1003) < 0 ){ AAC_threadActive = 0; goto end; } if ( sceAudiocodecGetEDRAM(aac_codec_buffer, 0x1003) < 0 ){ AAC_threadActive = 0; goto end; } aac_getEDRAM = 1; aac_codec_buffer[10] = aac_samplerate; if ( sceAudiocodecInit(aac_codec_buffer, 0x1003) < 0 ){ AAC_threadActive = 0; goto end; } int samplesdecoded; AAC_eof = 0; unsigned char aac_header_buf[7]; int skip = 0; while (AAC_threadActive){ while( !AAC_eof && AAC_isPlaying ){ memset(aac_mix_buffer, 0, aac_sample_per_frame*2*2); if ( sceIoRead( AAC_handle, aac_header_buf, 7 ) != 7 ) { AAC_eof = 1; continue; } int aac_header = aac_header_buf[3]; aac_header = (aac_header<<8) | aac_header_buf[4]; aac_header = (aac_header<<8) | aac_header_buf[5]; aac_header = (aac_header<<8) | aac_header_buf[6]; int frame_size = aac_header & 67100672; frame_size = frame_size >> 13; frame_size = frame_size - 7; if ( aac_data_buffer ){ free(aac_data_buffer); aac_data_buffer = NULL; } aac_data_buffer = (u8*)memalign(64, frame_size); if (AAC_newFilePos >= 0) { if (!AAC_newFilePos) AAC_newFilePos = AAC_tagsize + 10; u32 old_start = aac_data_start; if (sceIoLseek32(AAC_handle, AAC_newFilePos, PSP_SEEK_SET) != old_start){ aac_data_start = SeekNextFrameMP3(AAC_handle); if(aac_data_start < 0){ AAC_eof = 1; } AAC_playingTime = (float)aac_data_start / (float)frame_size / (float)aac_samplerate / 1000.0f; } AAC_newFilePos = -1; continue; } //Check for playing speed: if (AAC_playingSpeed){ if (skip){ u32 old_start = aac_data_start; if (sceIoLseek32(AAC_handle, frame_size / 4 * AAC_playingSpeed, PSP_SEEK_CUR) != old_start){ aac_data_start = SeekNextFrameMP3(AAC_handle); if(aac_data_start < 0){ AAC_eof = 1; continue; } AAC_filePos = aac_data_start; float framesSkipped = (float)aac_data_start / (float)frame_size; AAC_playingTime = framesSkipped * (float)aac_sample_per_frame/(float)aac_samplerate; }else AAC_setPlayingSpeed(0); skip = !skip; continue; } skip = !skip; } if ( sceIoRead( AAC_handle, aac_data_buffer, frame_size ) != frame_size ) { AAC_eof = 1; continue; } aac_data_start += (frame_size+7); AAC_filePos = aac_data_start; aac_codec_buffer[6] = (unsigned long)aac_data_buffer; aac_codec_buffer[8] = (unsigned long)aac_mix_buffer; aac_codec_buffer[7] = frame_size; aac_codec_buffer[9] = aac_sample_per_frame * 4; int res = sceAudiocodecDecode(aac_codec_buffer, 0x1003); if ( res < 0 ) { AAC_eof = 1; continue; } memcpy(aac_output_buffer[aac_output_index], aac_mix_buffer, aac_sample_per_frame*4); //Volume Boost: if (AAC_volume_boost){ int i; for (i=0; i<aac_sample_per_frame * 2; i++){ aac_output_buffer[aac_output_index][i] = volume_boost(&aac_output_buffer[aac_output_index][i], &AAC_volume_boost); } } audioOutput(AAC_volume, aac_output_buffer[aac_output_index]); aac_output_index = (aac_output_index+1)%4; samplesdecoded = aac_sample_per_frame; AAC_playingTime += (float)aac_sample_per_frame/(float)aac_samplerate; AAC_info.framesDecoded++; } sceKernelDelayThread(10000); } end: if ( AAC_handle ) sceIoClose(AAC_handle); if ( aac_data_buffer) { free(aac_data_buffer); aac_data_buffer = NULL; } if ( aac_getEDRAM ) sceAudiocodecReleaseEDRAM(aac_codec_buffer); sceKernelExitThread(0); return 0; }
static int audioMainLoop(SceSize args, void* argp) { psp_audio_t* psp = *((psp_audio_t**)argp); #ifdef VITA int port = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT, psp->rate, SCE_AUDIO_OUT_MODE_STEREO); #else sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2); #endif while (psp->running) { #ifdef VITA //sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT); sceKernelLockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1, 0); uint16_t readPos = psp->readPos; uint16_t readPos2 = psp->readPos; bool cond = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2); if (!cond) { readPos += AUDIO_OUT_COUNT; readPos &= AUDIO_BUFFER_SIZE_MASK; psp->readPos = readPos; } sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1); sceKernelSignalLwCond(&psp->cond); sceAudioOutOutput(port, cond ? (psp->zeroBuffer) : (psp->buffer + readPos2)); #else /* Get a non-volatile copy. */ uint16_t readPos = psp->readPos; bool cond = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2); sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer) : (psp->buffer + readPos)); if (!cond) { readPos += AUDIO_OUT_COUNT; readPos &= AUDIO_BUFFER_SIZE_MASK; psp->readPos = readPos; } #endif } #ifdef VITA sceAudioOutReleasePort(port); #else sceAudioSRCChRelease(); sceKernelExitThread(0); #endif return 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; }
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; }
static int threadEndedFunction2(int args, void* argp) { printf("Thread2.Started\n"); sceKernelExitThread(0); return 0; }