bool Mp3PspStream::initStreamME() { // The following will eventually go into the thread memset(_codecParams, 0, sizeof(_codecParams)); // Init the MP3 hardware int ret = 0; ret = sceAudiocodecCheckNeedMem(_codecParams, 0x1002); if (ret < 0) { PSP_ERROR("failed to init MP3 ME module. sceAudiocodecCheckNeedMem returned 0x%x.\n", ret); return false; } PSP_DEBUG_PRINT("sceAudiocodecCheckNeedMem returned %d\n", ret); ret = sceAudiocodecGetEDRAM(_codecParams, 0x1002); if (ret < 0) { PSP_ERROR("failed to init MP3 ME module. sceAudiocodecGetEDRAM returned 0x%x.\n", ret); return false; } PSP_DEBUG_PRINT("sceAudioCodecGetEDRAM returned %d\n", ret); PSP_DEBUG_PRINT("samplerate[%d]\n", _sampleRate); _codecParams[10] = _sampleRate; ret = sceAudiocodecInit(_codecParams, 0x1002); if (ret < 0) { PSP_ERROR("failed to init MP3 ME module. sceAudiocodecInit returned 0x%x.\n", ret); return false; } return true; }
void MP3PlayInit(play_ops* ops){ ops->load = MP3_Load; ops->play = MP3_Play; ops->pause = MP3_Pause; ops->stop = MP3_Stop; ops->resume= MP3_Resume; ops->time = MP3_Time; ops->seek = MP3_Seek; ops->eos = MP3_Eos; ops->volume = MP3_Volume; strncpy(ops->extension,"mp3",4); memset(mp3_codec_buffer, 0, sizeof(mp3_codec_buffer) ); if ( sceAudiocodecCheckNeedMem(mp3_codec_buffer, 0x1002) < 0 ) { CleanUp(); return; } if ( sceAudiocodecGetEDRAM(mp3_codec_buffer, 0x1002) < 0 ) { CleanUp(); return; } if ( sceAudiocodecInit(mp3_codec_buffer, 0x1002) < 0 ) { CleanUp(); return; } mp3_codec_flag = 1; }
char* Mp3Codec::initialize(AudioCodecInitData* init_data) { audio_samplerate = init_data->samplerate; audio_samples_per_frame = init_data->samples_per_frame; audio_type = 0x1002; memset(me_audio_codec_buffer, 0, 65*sizeof(uint32_t)); if ( sceAudiocodecCheckNeedMem((long unsigned int*) me_audio_codec_buffer, audio_type) < 0 ) return "Mp3Codec : sceAudiocodecCheckNeedMem fail"; if ( sceAudiocodecGetEDRAM((long unsigned int*)me_audio_codec_buffer, audio_type) < 0 ) return "Mp3Codec : sceAudiocodecGetEDRAM fail"; if ( sceAudiocodecInit((long unsigned int*)me_audio_codec_buffer, audio_type) < 0 ) { sceAudiocodecReleaseEDRAM((long unsigned int*)me_audio_codec_buffer); return "Mp3Codec : sceAudiocodecInit fail"; } init_flag = true; return 0; };
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //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 offset = 0; sceAudiocodecReleaseEDRAM(MP3ME_codec_buffer); //Fix: ReleaseEDRAM at the end is not enough to play another mp3. MP3ME_threadActive = 1; MP3ME_threadExited = 0; OutputBuffer_flip = 0; OutputPtrME = OutputBuffer[0]; MP3ME_handle = sceIoOpen(MP3ME_Name, 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 size = sceIoLseek32(MP3ME_handle, 0, PSP_SEEK_END); sceIoLseek32(MP3ME_handle, 0, PSP_SEEK_SET); data_start = ID3v2TagSize(MP3ME_Name); sceIoLseek32(MP3ME_handle, data_start, PSP_SEEK_SET); data_start = MP3ME_SeekNextFrameMP3(MP3ME_handle); if (data_start < 0) MP3ME_threadActive = 0; size -= data_start; memset(MP3ME_codec_buffer, 0, sizeof(MP3ME_codec_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; 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 = MP3ME_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; }else{ sample_per_frame = 576; frame_size = 72000*bitrates_v2[bitrate]/samplerate + padding; } sceIoLseek32(MP3ME_handle, data_start, PSP_SEEK_SET); //seek back 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_Name, 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 = MP3ME_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; //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]) { audioOutput(PSP_AUDIO_VOLUME_MAX, OutputBuffer[OutputBuffer_flip]); OutputBuffer_flip ^= 1; OutputPtrME = OutputBuffer[OutputBuffer_flip]; } } sceKernelDelayThread(10000); // Not sure if necessary or purpose } if (getEDRAM) sceAudiocodecReleaseEDRAM(MP3ME_codec_buffer); if ( MP3ME_handle >= 0){ sceIoClose(MP3ME_handle); MP3ME_handle = -1; } MP3ME_threadExited = 1; return 0; }
int main(void) { SetupCallbacks(); int result = pspSdkLoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL); pspSdkFixupImports(result); SceUID at3_handle = sceIoOpen("ms0:/Test.AT3", PSP_O_RDONLY, 0777); if ( ! at3_handle ) goto wait; u32 riff_header[2]; if ( sceIoRead( at3_handle, riff_header, 8 ) != 8 ) goto wait; if ( riff_header[0] != 0x46464952 ) goto wait; u32 wavefmt_header[3]; if ( sceIoRead( at3_handle, wavefmt_header, 12 ) != 12 ) goto wait; if ( wavefmt_header[0] != 0x45564157 || wavefmt_header[1] != 0x20746D66 ) goto wait; u8* wavefmt_data = (u8*)malloc(wavefmt_header[2]); if ( wavefmt_data == NULL ) goto wait; if ( sceIoRead( at3_handle, wavefmt_data, wavefmt_header[2] ) != wavefmt_header[2] ) { free(wavefmt_data); goto wait; } at3_type = *((u16*)wavefmt_data); at3_channels = *((u16*)(wavefmt_data+2)); at3_samplerate = *((u32*)(wavefmt_data+4)); at3_data_align = *((u16*)(wavefmt_data+12)); if ( at3_type == TYPE_ATRAC3PLUS) { at3_at3plus_flagdata[0] = wavefmt_data[42]; at3_at3plus_flagdata[1] = wavefmt_data[43]; } free(wavefmt_data); u32 data_header[2]; if ( sceIoRead( at3_handle, data_header, 8 ) != 8 ) goto wait; while(data_header[0] != 0x61746164 ) { sceIoLseek32(at3_handle, data_header[1], PSP_SEEK_CUR); if ( sceIoRead( at3_handle, data_header, 8 ) != 8 ) goto wait; } at3_data_start = sceIoLseek32(at3_handle, 0, PSP_SEEK_CUR); at3_data_size = data_header[1]; if ( at3_data_size % at3_data_align != 0 ) goto wait; memset(at3_codec_buffer, 0, sizeof(at3_codec_buffer)); if ( at3_type == TYPE_ATRAC3 ) { at3_channel_mode = 0x0; if ( at3_data_align == 0xC0 ) // atract3 have 3 bitrate, 132k,105k,66k, 132k align=0x180, 105k align = 0x130, 66k align = 0xc0 at3_channel_mode = 0x1; at3_sample_per_frame = 1024; at3_data_buffer = (u8*)memalign(64, 0x180); if ( at3_data_buffer == NULL) goto wait; at3_codec_buffer[26] = 0x20; if ( sceAudiocodecCheckNeedMem(at3_codec_buffer, 0x1001) < 0 ) goto wait; if ( sceAudiocodecGetEDRAM(at3_codec_buffer, 0x1001) < 0 ) goto wait; at3_getEDRAM = 1; at3_codec_buffer[10] = 4; at3_codec_buffer[44] = 2; if ( at3_data_align == 0x130 ) at3_codec_buffer[10] = 6; if ( sceAudiocodecInit(at3_codec_buffer, 0x1001) < 0 ) { goto wait; } } else if ( at3_type == TYPE_ATRAC3PLUS ) { at3_sample_per_frame = 2048; int temp_size = at3_data_align+8; int mod_64 = temp_size & 0x3f; if (mod_64 != 0) temp_size += 64 - mod_64; at3_data_buffer = (u8*)memalign(64, temp_size); if ( at3_data_buffer == NULL) goto wait; at3_codec_buffer[5] = 0x1; at3_codec_buffer[10] = at3_at3plus_flagdata[1]; at3_codec_buffer[10] = (at3_codec_buffer[10] << 8 ) | at3_at3plus_flagdata[0]; at3_codec_buffer[12] = 0x1; at3_codec_buffer[14] = 0x1; if ( sceAudiocodecCheckNeedMem(at3_codec_buffer, 0x1000) < 0 ) goto wait; if ( sceAudiocodecGetEDRAM(at3_codec_buffer, 0x1000) < 0 ) goto wait; at3_getEDRAM = 1; if ( sceAudiocodecInit(at3_codec_buffer, 0x1000) < 0 ) { goto wait; } } else goto wait; int eof = 0; while( !eof ) { int samplesdecoded; memset(at3_mix_buffer, 0, 2048*2*2); unsigned long decode_type = 0x1001; if ( at3_type == TYPE_ATRAC3 ) { memset( at3_data_buffer, 0, 0x180); if (sceIoRead( at3_handle, at3_data_buffer, at3_data_align ) != at3_data_align) { eof = 1; continue; } if ( at3_channel_mode ) { memcpy(at3_data_buffer+at3_data_align, at3_data_buffer, at3_data_align); } decode_type = 0x1001; } else { memset( at3_data_buffer, 0, at3_data_align+8); at3_data_buffer[0] = 0x0F; at3_data_buffer[1] = 0xD0; at3_data_buffer[2] = at3_at3plus_flagdata[0]; at3_data_buffer[3] = at3_at3plus_flagdata[1]; if (sceIoRead( at3_handle, at3_data_buffer+8, at3_data_align ) != at3_data_align) { eof = 1; continue; } decode_type = 0x1000; } at3_codec_buffer[6] = (unsigned long)at3_data_buffer; at3_codec_buffer[8] = (unsigned long)at3_mix_buffer; int res = sceAudiocodecDecode(at3_codec_buffer, decode_type); if ( res < 0 ) { eof = 1; continue; } samplesdecoded = at3_sample_per_frame; } wait: if ( at3_handle ) { sceIoClose(at3_handle); } if ( at3_data_buffer) { free(at3_data_buffer); } if ( at3_getEDRAM ) { sceAudiocodecReleaseEDRAM(at3_codec_buffer); } sceCtrlReadBufferPositive(&input, 1); while(!(input.Buttons & PSP_CTRL_TRIANGLE)) { sceKernelDelayThread(10000); // wait 10 milliseconds sceCtrlReadBufferPositive(&input, 1); } sceKernelExitGame(); return 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //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; }
int audiocodecCheckNeedMem (int*arg1, int arg2, int*arg3){//! int ret = sceAudiocodecCheckNeedMem (pAudioCodecStruct, 0x00001000); *arg1 = pAudioCodecStruct[4]; return ret; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //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; }
int main(void) { SetupCallbacks(); int result = pspSdkLoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL); pspSdkFixupImports(result); SceUID aa3_handle = sceIoOpen("ms0:/Test.AA3", PSP_O_RDONLY, 0777); // or ms0:/Test.OMA if ( ! aa3_handle ) goto wait; sceIoLseek32(aa3_handle, 0x0C00, PSP_SEEK_SET); u8 ea3_header[0x60]; if ( sceIoRead( aa3_handle, ea3_header, 0x60 ) != 0x60 ) goto wait; if ( ea3_header[0] != 0x45 || ea3_header[1] != 0x41 || ea3_header[2] != 0x33 || ea3_header[3] != 0x01 ) goto wait; aa3_at3plus_flagdata[0] = ea3_header[0x22]; aa3_at3plus_flagdata[1] = ea3_header[0x23]; aa3_type = (ea3_header[0x22] == 0x20) ? TYPE_ATRAC3 : ((ea3_header[0x22] == 0x28) ? TYPE_ATRAC3PLUS : 0x0); if ( aa3_type != TYPE_ATRAC3 && aa3_type != TYPE_ATRAC3PLUS ) goto wait; aa3_channels = 2; aa3_samplerate = 44100; if ( aa3_type == TYPE_ATRAC3 ) aa3_data_align = ea3_header[0x23]*8; else aa3_data_align = (ea3_header[0x23]+1)*8; aa3_data_start = 0x0C60; aa3_data_size = sceIoLseek32(aa3_handle, 0, PSP_SEEK_END) - aa3_data_start; if ( aa3_data_size % aa3_data_align != 0 ) goto wait; sceIoLseek32(aa3_handle, aa3_data_start, PSP_SEEK_SET); memset(aa3_codec_buffer, 0, sizeof(aa3_codec_buffer)); if ( aa3_type == TYPE_ATRAC3 ) { aa3_channel_mode = 0x0; if ( aa3_data_align == 0xC0 ) // atract3 have 3 bitrate, 132k,105k,66k, 132k align=0x180, 105k align = 0x130, 66k align = 0xc0 aa3_channel_mode = 0x1; aa3_sample_per_frame = 1024; aa3_data_buffer = (u8*)memalign(64, 0x180); if ( aa3_data_buffer == NULL) goto wait; aa3_codec_buffer[26] = 0x20; if ( sceAudiocodecCheckNeedMem(aa3_codec_buffer, 0x1001) < 0 ) goto wait; if ( sceAudiocodecGetEDRAM(aa3_codec_buffer, 0x1001) < 0 ) goto wait; aa3_getEDRAM = 1; aa3_codec_buffer[10] = 4; aa3_codec_buffer[44] = 2; if ( aa3_data_align == 0x130 ) aa3_codec_buffer[10] = 6; if ( sceAudiocodecInit(aa3_codec_buffer, 0x1001) < 0 ) { goto wait; } } else if ( aa3_type == TYPE_ATRAC3PLUS ) { aa3_sample_per_frame = 2048; int temp_size = aa3_data_align+8; int mod_64 = temp_size & 0x3f; if (mod_64 != 0) temp_size += 64 - mod_64; aa3_data_buffer = (u8*)memalign(64, temp_size); if ( aa3_data_buffer == NULL) goto wait; aa3_codec_buffer[5] = 0x1; aa3_codec_buffer[10] = aa3_at3plus_flagdata[1]; aa3_codec_buffer[10] = (aa3_codec_buffer[10] << 8 ) | aa3_at3plus_flagdata[0]; aa3_codec_buffer[12] = 0x1; aa3_codec_buffer[14] = 0x1; if ( sceAudiocodecCheckNeedMem(aa3_codec_buffer, 0x1000) < 0 ) goto wait; if ( sceAudiocodecGetEDRAM(aa3_codec_buffer, 0x1000) < 0 ) goto wait; aa3_getEDRAM = 1; if ( sceAudiocodecInit(aa3_codec_buffer, 0x1000) < 0 ) { goto wait; } } else goto wait; int eof = 0; while( !eof ) { int samplesdecoded; memset(aa3_mix_buffer, 0, 2048*2*2); unsigned long decode_type = 0x1001; if ( aa3_type == TYPE_ATRAC3 ) { memset( aa3_data_buffer, 0, 0x180); if (sceIoRead( aa3_handle, aa3_data_buffer, aa3_data_align ) != aa3_data_align) { eof = 1; continue; } if ( aa3_channel_mode ) { memcpy(aa3_data_buffer+aa3_data_align, aa3_data_buffer, aa3_data_align); } decode_type = 0x1001; } else { memset( aa3_data_buffer, 0, aa3_data_align+8); aa3_data_buffer[0] = 0x0F; aa3_data_buffer[1] = 0xD0; aa3_data_buffer[2] = aa3_at3plus_flagdata[0]; aa3_data_buffer[3] = aa3_at3plus_flagdata[1]; if (sceIoRead( aa3_handle, aa3_data_buffer+8, aa3_data_align ) != aa3_data_align) { eof = 1; continue; } decode_type = 0x1000; } aa3_codec_buffer[6] = (unsigned long)aa3_data_buffer; aa3_codec_buffer[8] = (unsigned long)aa3_mix_buffer; int res = sceAudiocodecDecode(aa3_codec_buffer, decode_type); if ( res < 0 ) { eof = 1; continue; } samplesdecoded = aa3_sample_per_frame; } wait: if ( aa3_handle ) { sceIoClose(aa3_handle); } if ( aa3_data_buffer) { free(aa3_data_buffer); } if ( aa3_getEDRAM ) { sceAudiocodecReleaseEDRAM(aa3_codec_buffer); } sceCtrlReadBufferPositive(&input, 1); while(!(input.Buttons & PSP_CTRL_TRIANGLE)) { sceKernelDelayThread(10000); // wait 10 milliseconds sceCtrlReadBufferPositive(&input, 1); } sceKernelExitGame(); return 0; }
// ------------------------------------------------------- // Initialize the AT3 replay static triSInt AT3_FileInit(triVoid *File_Mem, triSInt File_Length, triVoid (*Mixing_CallBack)(triS16 *AT3_Audio_Buffer, triSInt AT3_Buffer_Size)) { triUInt *dwFile_Mem; triUChar *tmpFile_Mem; typedef struct { unsigned short wFormatTag; // Format category unsigned short wChannels; // Number of channels unsigned long dwSamplesPerSec; // Sampling rate unsigned long dwAvgBytesPerSec; // For buffer estimation unsigned short wBlockAlign; // Data block size unsigned short wBitsPerSample; // Sample size } WAVFMTCHUNK; WAVFMTCHUNK fmt; memset( &fmt, 0, sizeof(WAVFMTCHUNK) ); AT3_Playing = 0; AT3_CallBack = Mixing_CallBack; dwFile_Mem = (triUInt *) File_Mem; if(*dwFile_Mem++ == 'FFIR') { dwFile_Mem++; if(*dwFile_Mem++ == 'EVAW') { tmpFile_Mem = (triUChar *) (dwFile_Mem + 2); AT3_align = 384; while(*dwFile_Mem != 'atad') { if (*dwFile_Mem++ == ' tmf') { memcpy( &fmt, (dwFile_Mem+1), sizeof(WAVFMTCHUNK) ); AT3_align = fmt.wBlockAlign; //printf("Fmt:\nFormat: %x\nChannels: %i\nRate: %i\nBPS: %i\nAlign: %i\nBits: %i\n", fmt.wFormatTag, fmt.wChannels, fmt.dwSamplesPerSec, fmt.dwAvgBytesPerSec, fmt.wBlockAlign, fmt.wBitsPerSample ); } dwFile_Mem = (triUInt *) (tmpFile_Mem + *dwFile_Mem); tmpFile_Mem = (triUChar *) (dwFile_Mem + 2); } dwFile_Mem++; AT3_Datas_Start = (triSInt) tmpFile_Mem - (triSInt) File_Mem; memset(AT3_Codec_Buffer, 0, sizeof(AT3_Codec_Buffer)); memset(AT3_Mix_Buffer, 0, AT3_SAMPLES * 2 * 2); AT3_Codec_Buffer[26] = 0x20; AT3_Codec_Buffer[43] = 0x1001; memcpy( (void*)AT3_Buffer, (void*)(File_Mem + AT3_Datas_Start), AT3_align ); if (AT3_align==192) { memcpy( (void*)(AT3_Buffer+192), (void*)AT3_Buffer, 192 ); } AT3_pos = (triUInt)(File_Mem + AT3_Datas_Start); AT3_Codec_Buffer[AT3_CURRENT_BUFFER] = (triSInt)AT3_Buffer; //(File_Mem + AT3_Datas_Start); AT3_Codec_Buffer[AT3_TEMPORARY_BUFFER] = (triSInt) AT3_Mix_Buffer; if (AT3_align==304) AT3_Codec_Buffer[10] = 6; else AT3_Codec_Buffer[10] = 4; AT3_Codec_Buffer[44] = 2; AT3_length = File_Length; AT3_Codec_Buffer[AT3_INITIAL_BUFFER] = (triSInt) File_Mem; AT3_Codec_Buffer[AT3_LENGTH_BUFFER] = 384; if(sceAudiocodecCheckNeedMem(AT3_Codec_Buffer, AT3_TYPE_ATRAC3) < 0) return(0); if(sceAudiocodecGetEDRAM(AT3_Codec_Buffer, AT3_TYPE_ATRAC3) < 0) return(0); if(sceAudiocodecInit(AT3_Codec_Buffer, AT3_TYPE_ATRAC3) < 0) return(0); AT3_Channel = sceAudioChReserve(0, AT3_SAMPLES, PSP_AUDIO_FORMAT_STEREO); if(AT3_Channel < 0) return(0); AT3_ThreadID = sceKernelCreateThread("TriAtrac3", (triVoid *) AT3_Thread, AT3_THREAD_PRIORITY, (1024 * 4), PSP_THREAD_ATTR_USER, NULL); if(AT3_ThreadID < 0) return(0); sceKernelStartThread(AT3_ThreadID, 0, NULL); return(1); } } return(0); }