int32_t Mp3Codec::decode(void* data, uint32_t data_len, void* pcm_data) { if( init_flag ) { me_audio_codec_buffer[6] = (uint32_t)data; me_audio_codec_buffer[8] = (uint32_t)pcm_data; me_audio_codec_buffer[7] = data_len; me_audio_codec_buffer[10] = data_len; me_audio_codec_buffer[9] = audio_samples_per_frame << 2; if ( sceAudiocodecDecode((long unsigned int*)me_audio_codec_buffer, audio_type) < 0 ) ;//return 0; return audio_samples_per_frame; } else return -1; };
triSInt AT3_Thread(SceSize args, ScePVoid argp) { while(AT3_Loaded) { if(AT3_Playing) { if(AT3_CallBack) AT3_CallBack((triS16 *) ((triSInt) AT3_Mix_Buffer | 0x40000000), AT3_SAMPLES); AT3_Samples_Played += sceAudioOutputBlocking(AT3_Channel, AT3_Volume, (triVoid *) ((triSInt) AT3_Mix_Buffer | 0x40000000)); sceAudiocodecDecode(AT3_Codec_Buffer, AT3_TYPE_ATRAC3); AT3_pos += AT3_Codec_Buffer[AT3_POS_INPUT_BUFFER]; memcpy( (void*)AT3_Buffer, (void*)AT3_pos, AT3_align ); if (AT3_align==192) { memcpy( (void*)(AT3_Buffer+192), (void*)AT3_Buffer, 192 ); } //AT3_Codec_Buffer[AT3_POS_INPUT_BUFFER] = AT3_pos; if(AT3_pos >= ((AT3_length - AT3_Datas_Start) + AT3_Codec_Buffer[AT3_INITIAL_BUFFER])) { AT3_pos = AT3_Codec_Buffer[AT3_INITIAL_BUFFER] + AT3_Datas_Start; if(!AT3_Loop) AT3_Playing = 0; } } else memset(AT3_Mix_Buffer, 0, AT3_SAMPLES * 2 * 2); sceKernelDcacheWritebackInvalidateAll(); sceKernelDelayThread(10); } return(0); }
void Mp3PspStream::decodeMP3Data() { DEBUG_ENTER_FUNC(); do { if (_state == MP3_STATE_INIT) { initStream(); initStreamME(); } if (_state == MP3_STATE_EOS) return; findValidHeader(); // seach for next valid header while (_state == MP3_STATE_READY) { // not a real 'while'. Just for easy flow _stream.error = MAD_ERROR_NONE; uint32 frame_size = _stream.next_frame - _stream.this_frame; updatePcmLength(); // Retrieve the number of PCM samples. // We seem to change this, so it needs to be dynamic PSP_DEBUG_PRINT("MP3 frame size[%d]. pcmLength[%d]\n", frame_size, _pcmLength); memcpy(_codecInBuffer, _stream.this_frame, frame_size); // we need it aligned // set up parameters for ME _codecParams[6] = (unsigned long)_codecInBuffer; _codecParams[8] = (unsigned long)_pcmSamples; _codecParams[7] = frame_size; _codecParams[9] = _pcmLength * 2; // x2 for stereo, though this one's not so important // debug #ifdef PRINT_BUFFERS PSP_DEBUG_PRINT("mp3 frame:\n"); for (int i=0; i < (int)frame_size; i++) { PSP_DEBUG_PRINT_SAMELN("%x ", _codecInBuffer[i]); } PSP_DEBUG_PRINT("\n"); #endif // Decode the next frame // This function blocks. We'll want to put it in a thread int ret = sceAudiocodecDecode(_codecParams, 0x1002); if (ret < 0) { PSP_INFO_PRINT("failed to decode MP3 data in ME. sceAudiocodecDecode returned 0x%x\n", ret); } #ifdef PRINT_BUFFERS PSP_DEBUG_PRINT("PCM frame:\n"); for (int i=0; i < (int)_codecParams[9]; i+=2) { // changed from i+=2 PSP_DEBUG_PRINT_SAMELN("%d ", (int16)_pcmSamples[i]); } PSP_DEBUG_PRINT("\n"); #endif _posInFrame = 0; break; } } while (_state != MP3_STATE_EOS && _stream.error == MAD_ERROR_BUFLEN); if (_stream.error != MAD_ERROR_NONE) // catch EOS _state = MP3_STATE_EOS; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //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; }
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; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //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 audiocodecDecode (unsigned long*arg1){ waitSema (mpegAtracSema); int ret=sceAudiocodecDecode (arg1, 0x00001000); signalSema (mpegAtracSema); 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; }