now,we can use libaudiocodec to decode atrac3 and atrac3plus

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
cooleyes
Posts: 123
Joined: Thu May 18, 2006 3:30 pm

now,we can use libaudiocodec to decode atrac3 and atrac3plus

Post by cooleyes »

hi, all

I just found out how to decode atrac3 and atrac3plus using libaudiocodec now!

here is some sample code for decode atrac3 and atrac3plus in AT3 or AA3 file:

AT3 file decode

Code: Select all

#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <psppower.h>
#include <stdio.h>
#include <stdlib.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <psppower.h>
#include <pspdebug.h>
#include <psprtc.h>
#include <pspsdk.h>
#include <pspaudiocodec.h>
#include <pspaudio.h>
#include <string.h>
#include <malloc.h>

int SetupCallbacks&#40;&#41;;

PSP_MODULE_INFO&#40;"AT3 decodeTest", 0x1000, 1, 1&#41;;
PSP_MAIN_THREAD_ATTR&#40;0&#41;;

__attribute__ &#40;&#40;constructor&#41;&#41;
void loaderInit&#40;&#41;&#123;
	pspKernelSetKernelPC&#40;&#41;;
	pspSdkInstallNoDeviceCheckPatch&#40;&#41;;
	pspSdkInstallNoPlainModuleCheckPatch&#40;&#41;;
	pspSdkInstallKernelLoadModulePatch&#40;&#41;;
&#125;

SceCtrlData input;

#define TYPE_ATRAC3 0x270
#define TYPE_ATRAC3PLUS 0xFFFE

unsigned long at3_codec_buffer&#91;65&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;
short at3_mix_buffer&#91;2048 * 2&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;


SceUID at3_handle;
u16 at3_type;
u8* at3_data_buffer;
u16 at3_data_align;
u32 at3_sample_per_frame;
u16 at3_channel_mode;
u8 at3_at3plus_flagdata&#91;2&#93;;
u32 at3_data_start;
u32 at3_data_size;
u8 at3_getEDRAM;
u32 at3_channels;
u32 at3_samplerate;


int main&#40;void&#41;
&#123;
	SetupCallbacks&#40;&#41;;
	
	int result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
	pspSdkFixupImports&#40;result&#41;;
	
	SceUID at3_handle = sceIoOpen&#40;"ms0&#58;/Test.AT3", PSP_O_RDONLY, 0777&#41;;
	if &#40;  ! at3_handle &#41;
		goto wait;
	
	u32 riff_header&#91;2&#93;;
	if &#40; sceIoRead&#40; at3_handle, riff_header, 8 &#41; != 8 &#41; 
		goto wait;
	if &#40; riff_header&#91;0&#93; != 0x46464952 &#41;
		goto wait;
	u32 wavefmt_header&#91;3&#93;;
	if &#40; sceIoRead&#40; at3_handle, wavefmt_header, 12 &#41; != 12 &#41; 
		goto wait;
	if &#40; wavefmt_header&#91;0&#93; != 0x45564157 || wavefmt_header&#91;1&#93; != 0x20746D66 &#41;
		goto wait;
	u8* wavefmt_data = &#40;u8*&#41;malloc&#40;wavefmt_header&#91;2&#93;&#41;;
	if &#40; wavefmt_data == NULL &#41;
		goto wait;
	if &#40; sceIoRead&#40; at3_handle, wavefmt_data, wavefmt_header&#91;2&#93; &#41; != wavefmt_header&#91;2&#93; &#41; &#123;
		free&#40;wavefmt_data&#41;;
		goto wait;
	&#125;
	at3_type = *&#40;&#40;u16*&#41;wavefmt_data&#41;;
	at3_channels = *&#40;&#40;u16*&#41;&#40;wavefmt_data+2&#41;&#41;;
	at3_samplerate = *&#40;&#40;u32*&#41;&#40;wavefmt_data+4&#41;&#41;;
	at3_data_align = *&#40;&#40;u16*&#41;&#40;wavefmt_data+12&#41;&#41;;
	
	if &#40; at3_type == TYPE_ATRAC3PLUS&#41; &#123;
		at3_at3plus_flagdata&#91;0&#93; = wavefmt_data&#91;42&#93;;
		at3_at3plus_flagdata&#91;1&#93; = wavefmt_data&#91;43&#93;;
	&#125;
	
	free&#40;wavefmt_data&#41;;
	
	u32 data_header&#91;2&#93;;
	if &#40; sceIoRead&#40; at3_handle, data_header, 8 &#41; != 8 &#41; 
		goto wait;
	while&#40;data_header&#91;0&#93; != 0x61746164 &#41; &#123;
		sceIoLseek32&#40;at3_handle, data_header&#91;1&#93;, PSP_SEEK_CUR&#41;;
		if &#40; sceIoRead&#40; at3_handle, data_header, 8 &#41; != 8 &#41; 
			goto wait;
	&#125;
	
	at3_data_start = sceIoLseek32&#40;at3_handle, 0, PSP_SEEK_CUR&#41;;
	at3_data_size = data_header&#91;1&#93;;
	
	if &#40; at3_data_size % at3_data_align != 0 &#41;
		goto wait;
	
	memset&#40;at3_codec_buffer, 0, sizeof&#40;at3_codec_buffer&#41;&#41;;
	
	if &#40; at3_type == TYPE_ATRAC3 &#41; &#123;
		at3_channel_mode = 0x0;
		if &#40; at3_data_align == 0xC0 &#41; // 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 = &#40;u8*&#41;memalign&#40;64, 0x180&#41;;
		if &#40; at3_data_buffer == NULL&#41;
			goto wait;
		at3_codec_buffer&#91;26&#93; = 0x20;
		if &#40; sceAudiocodecCheckNeedMem&#40;at3_codec_buffer, 0x1001&#41; < 0 &#41; 
			goto wait;
		if &#40; sceAudiocodecGetEDRAM&#40;at3_codec_buffer, 0x1001&#41; < 0 &#41;
			goto wait;
		at3_getEDRAM = 1;
		at3_codec_buffer&#91;10&#93; = 4;
		at3_codec_buffer&#91;44&#93; = 2;
		if &#40; at3_data_align == 0x130 &#41;
			at3_codec_buffer&#91;10&#93; = 6;
		if &#40; sceAudiocodecInit&#40;at3_codec_buffer, 0x1001&#41; < 0 &#41; &#123;
			goto wait;
		&#125;
	&#125;
	else if &#40; at3_type == TYPE_ATRAC3PLUS &#41; &#123;
		at3_sample_per_frame = 2048;
		int temp_size = at3_data_align+8;
		int mod_64 = temp_size & 0x3f;
		if &#40;mod_64 != 0&#41; temp_size += 64 - mod_64;
		at3_data_buffer = &#40;u8*&#41;memalign&#40;64, temp_size&#41;;
		if &#40; at3_data_buffer == NULL&#41;
			goto wait;
		at3_codec_buffer&#91;5&#93; = 0x1;
		at3_codec_buffer&#91;10&#93; = at3_at3plus_flagdata&#91;1&#93;;
		at3_codec_buffer&#91;10&#93; = &#40;at3_codec_buffer&#91;10&#93; << 8 &#41; | at3_at3plus_flagdata&#91;0&#93;;
		at3_codec_buffer&#91;12&#93; = 0x1;
		at3_codec_buffer&#91;14&#93; = 0x1;
		if &#40; sceAudiocodecCheckNeedMem&#40;at3_codec_buffer, 0x1000&#41; < 0 &#41; 
			goto wait;
		if &#40; sceAudiocodecGetEDRAM&#40;at3_codec_buffer, 0x1000&#41; < 0 &#41;
			goto wait;
		at3_getEDRAM = 1;
		if &#40; sceAudiocodecInit&#40;at3_codec_buffer, 0x1000&#41; < 0 &#41; &#123;
			goto wait;
		&#125;
	&#125;
	else
		goto wait;
	
	int eof = 0;	
	while&#40; !eof &#41; &#123;
		int samplesdecoded;
		memset&#40;at3_mix_buffer, 0, 2048*2*2&#41;;
		unsigned long decode_type = 0x1001;
		if &#40; at3_type == TYPE_ATRAC3 &#41; &#123;
			memset&#40; at3_data_buffer, 0, 0x180&#41;;
			if &#40;sceIoRead&#40; at3_handle, at3_data_buffer, at3_data_align &#41; != at3_data_align&#41; &#123;
				eof = 1;
				continue;
			&#125;
			if &#40; at3_channel_mode &#41; &#123;
				memcpy&#40;at3_data_buffer+at3_data_align, at3_data_buffer, at3_data_align&#41;;
			&#125;
			decode_type = 0x1001;
		&#125;
		else &#123;
			memset&#40; at3_data_buffer, 0, at3_data_align+8&#41;;
			at3_data_buffer&#91;0&#93; = 0x0F;
			at3_data_buffer&#91;1&#93; = 0xD0;
			at3_data_buffer&#91;2&#93; = at3_at3plus_flagdata&#91;0&#93;;
			at3_data_buffer&#91;3&#93; = at3_at3plus_flagdata&#91;1&#93;;
			if &#40;sceIoRead&#40; at3_handle, at3_data_buffer+8, at3_data_align &#41; != at3_data_align&#41; &#123;
				eof = 1;
				continue;
			&#125;
			decode_type = 0x1000;
		&#125;
	
		at3_codec_buffer&#91;6&#93; = &#40;unsigned long&#41;at3_data_buffer;
		at3_codec_buffer&#91;8&#93; = &#40;unsigned long&#41;at3_mix_buffer;
	
		int res = sceAudiocodecDecode&#40;at3_codec_buffer, decode_type&#41;;
		if &#40; res < 0 &#41; &#123;
			eof = 1;
			continue;
		&#125;
		samplesdecoded = at3_sample_per_frame;
	&#125;

wait&#58;
	
	if &#40; at3_handle &#41; &#123;
		sceIoClose&#40;at3_handle&#41;;
	&#125;
	if &#40; at3_data_buffer&#41; &#123;
		free&#40;at3_data_buffer&#41;;
	&#125;
	if &#40; at3_getEDRAM &#41; &#123;
		sceAudiocodecReleaseEDRAM&#40;at3_codec_buffer&#41;;
	&#125;
	
	sceCtrlReadBufferPositive&#40;&input, 1&#41;;
	while&#40;!&#40;input.Buttons & PSP_CTRL_TRIANGLE&#41;&#41;
	&#123;
		sceKernelDelayThread&#40;10000&#41;;	// wait 10 milliseconds
		sceCtrlReadBufferPositive&#40;&input, 1&#41;;
	&#125;
	
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;


/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;


/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
	int cbid;

	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;

	sceKernelSleepThreadCB&#40;&#41;;

	return 0;
&#125;


/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41;
&#123;
	int thid = 0;

	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;

AA3 file decode:

Code: Select all

#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <psppower.h>
#include <stdio.h>
#include <stdlib.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <psppower.h>
#include <pspdebug.h>
#include <psprtc.h>
#include <pspsdk.h>
#include <pspaudiocodec.h>
#include <pspaudio.h>
#include <string.h>
#include <malloc.h>

int SetupCallbacks&#40;&#41;;

PSP_MODULE_INFO&#40;"AA3 decodeTest", 0x1000, 1, 1&#41;;
PSP_MAIN_THREAD_ATTR&#40;0&#41;;

__attribute__ &#40;&#40;constructor&#41;&#41;
void loaderInit&#40;&#41;&#123;
	pspKernelSetKernelPC&#40;&#41;;
	pspSdkInstallNoDeviceCheckPatch&#40;&#41;;
	pspSdkInstallNoPlainModuleCheckPatch&#40;&#41;;
	pspSdkInstallKernelLoadModulePatch&#40;&#41;;
&#125;

SceCtrlData input;

#define TYPE_ATRAC3 0x270
#define TYPE_ATRAC3PLUS 0xFFFE

unsigned long aa3_codec_buffer&#91;65&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;
short aa3_mix_buffer&#91;2048 * 2&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;


SceUID aa3_handle;
u16 aa3_type;
u8* aa3_data_buffer;
u16 aa3_data_align;
u32 aa3_sample_per_frame;
u16 aa3_channel_mode;
u8 aa3_at3plus_flagdata&#91;2&#93;;
u32 aa3_data_start;
u32 aa3_data_size;
u8 aa3_getEDRAM;
u32 aa3_channels;
u32 aa3_samplerate;


int main&#40;void&#41;
&#123;
	SetupCallbacks&#40;&#41;;
	
	int result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
	pspSdkFixupImports&#40;result&#41;;
	
	SceUID aa3_handle = sceIoOpen&#40;"ms0&#58;/Test.AA3", PSP_O_RDONLY, 0777&#41;; // or ms0&#58;/Test.OMA
	if &#40;  ! aa3_handle &#41;
		goto wait;
	
	sceIoLseek32&#40;aa3_handle, 0x0C00, PSP_SEEK_SET&#41;;
	
	u8 ea3_header&#91;0x60&#93;;
	if &#40; sceIoRead&#40; aa3_handle, ea3_header, 0x60 &#41; != 0x60 &#41; 
		goto wait;
	if &#40; ea3_header&#91;0&#93; != 0x45 || ea3_header&#91;1&#93; != 0x41 || ea3_header&#91;2&#93; != 0x33 || ea3_header&#91;3&#93; != 0x01 &#41;
		goto wait;
	
	aa3_at3plus_flagdata&#91;0&#93; = ea3_header&#91;0x22&#93;;
	aa3_at3plus_flagdata&#91;1&#93; = ea3_header&#91;0x23&#93;;
	
	aa3_type = &#40;ea3_header&#91;0x22&#93; == 0x20&#41; ? TYPE_ATRAC3 &#58; &#40;&#40;ea3_header&#91;0x22&#93; == 0x28&#41; ? TYPE_ATRAC3PLUS &#58; 0x0&#41;;
	
	if &#40; aa3_type != TYPE_ATRAC3 && aa3_type != TYPE_ATRAC3PLUS &#41;
		goto wait;
	
	aa3_channels = 2;
	aa3_samplerate = 44100;
	if &#40; aa3_type == TYPE_ATRAC3 &#41; 
		aa3_data_align = ea3_header&#91;0x23&#93;*8;
	else
		aa3_data_align = &#40;ea3_header&#91;0x23&#93;+1&#41;*8;
	
	aa3_data_start = 0x0C60;
	aa3_data_size = sceIoLseek32&#40;aa3_handle, 0, PSP_SEEK_END&#41; - aa3_data_start;
	
	if &#40; aa3_data_size % aa3_data_align != 0 &#41;
		goto wait;
	
	sceIoLseek32&#40;aa3_handle, aa3_data_start, PSP_SEEK_SET&#41;;
	
	memset&#40;aa3_codec_buffer, 0, sizeof&#40;aa3_codec_buffer&#41;&#41;;
	
	if &#40; aa3_type == TYPE_ATRAC3 &#41; &#123;
		aa3_channel_mode = 0x0;
		if &#40; aa3_data_align == 0xC0 &#41; // 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 = &#40;u8*&#41;memalign&#40;64, 0x180&#41;;
		if &#40; aa3_data_buffer == NULL&#41;
			goto wait;
		aa3_codec_buffer&#91;26&#93; = 0x20;
		if &#40; sceAudiocodecCheckNeedMem&#40;aa3_codec_buffer, 0x1001&#41; < 0 &#41; 
			goto wait;
		if &#40; sceAudiocodecGetEDRAM&#40;aa3_codec_buffer, 0x1001&#41; < 0 &#41;
			goto wait;
		aa3_getEDRAM = 1;
		aa3_codec_buffer&#91;10&#93; = 4;
		aa3_codec_buffer&#91;44&#93; = 2;
		if &#40; aa3_data_align == 0x130 &#41;
			aa3_codec_buffer&#91;10&#93; = 6;
		if &#40; sceAudiocodecInit&#40;aa3_codec_buffer, 0x1001&#41; < 0 &#41; &#123;
			goto wait;
		&#125;
	&#125;
	else if &#40; aa3_type == TYPE_ATRAC3PLUS &#41; &#123;
		aa3_sample_per_frame = 2048;
		int temp_size = aa3_data_align+8;
		int mod_64 = temp_size & 0x3f;
		if &#40;mod_64 != 0&#41; temp_size += 64 - mod_64;
		aa3_data_buffer = &#40;u8*&#41;memalign&#40;64, temp_size&#41;;
		if &#40; aa3_data_buffer == NULL&#41;
			goto wait;
		aa3_codec_buffer&#91;5&#93; = 0x1;
		aa3_codec_buffer&#91;10&#93; = aa3_at3plus_flagdata&#91;1&#93;;
		aa3_codec_buffer&#91;10&#93; = &#40;aa3_codec_buffer&#91;10&#93; << 8 &#41; | aa3_at3plus_flagdata&#91;0&#93;;
		aa3_codec_buffer&#91;12&#93; = 0x1;
		aa3_codec_buffer&#91;14&#93; = 0x1;
		if &#40; sceAudiocodecCheckNeedMem&#40;aa3_codec_buffer, 0x1000&#41; < 0 &#41; 
			goto wait;
		if &#40; sceAudiocodecGetEDRAM&#40;aa3_codec_buffer, 0x1000&#41; < 0 &#41;
			goto wait;
		aa3_getEDRAM = 1;
		if &#40; sceAudiocodecInit&#40;aa3_codec_buffer, 0x1000&#41; < 0 &#41; &#123;
			goto wait;
		&#125;
	&#125;
	else
		goto wait;
	
	int eof = 0;	
	while&#40; !eof &#41; &#123;
		int samplesdecoded;
		memset&#40;aa3_mix_buffer, 0, 2048*2*2&#41;;
		unsigned long decode_type = 0x1001;
		if &#40; aa3_type == TYPE_ATRAC3 &#41; &#123;
			memset&#40; aa3_data_buffer, 0, 0x180&#41;;
			if &#40;sceIoRead&#40; aa3_handle, aa3_data_buffer, aa3_data_align &#41; != aa3_data_align&#41; &#123;
				eof = 1;
				continue;
			&#125;
			if &#40; aa3_channel_mode &#41; &#123;
				memcpy&#40;aa3_data_buffer+aa3_data_align, aa3_data_buffer, aa3_data_align&#41;;
			&#125;
			decode_type = 0x1001;
		&#125;
		else &#123;
			memset&#40; aa3_data_buffer, 0, aa3_data_align+8&#41;;
			aa3_data_buffer&#91;0&#93; = 0x0F;
			aa3_data_buffer&#91;1&#93; = 0xD0;
			aa3_data_buffer&#91;2&#93; = aa3_at3plus_flagdata&#91;0&#93;;
			aa3_data_buffer&#91;3&#93; = aa3_at3plus_flagdata&#91;1&#93;;
			if &#40;sceIoRead&#40; aa3_handle, aa3_data_buffer+8, aa3_data_align &#41; != aa3_data_align&#41; &#123;
				eof = 1;
				continue;
			&#125;
			decode_type = 0x1000;
		&#125;
	
		aa3_codec_buffer&#91;6&#93; = &#40;unsigned long&#41;aa3_data_buffer;
		aa3_codec_buffer&#91;8&#93; = &#40;unsigned long&#41;aa3_mix_buffer;
	
		int res = sceAudiocodecDecode&#40;aa3_codec_buffer, decode_type&#41;;
		if &#40; res < 0 &#41; &#123;
			eof = 1;
			continue;
		&#125;
		samplesdecoded = aa3_sample_per_frame;
	&#125;

wait&#58;
	
	if &#40; aa3_handle &#41; &#123;
		sceIoClose&#40;aa3_handle&#41;;
	&#125;
	if &#40; aa3_data_buffer&#41; &#123;
		free&#40;aa3_data_buffer&#41;;
	&#125;
	if &#40; aa3_getEDRAM &#41; &#123;
		sceAudiocodecReleaseEDRAM&#40;aa3_codec_buffer&#41;;
	&#125;
	
	sceCtrlReadBufferPositive&#40;&input, 1&#41;;
	while&#40;!&#40;input.Buttons & PSP_CTRL_TRIANGLE&#41;&#41;
	&#123;
		sceKernelDelayThread&#40;10000&#41;;	// wait 10 milliseconds
		sceCtrlReadBufferPositive&#40;&input, 1&#41;;
	&#125;
	
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;


/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;


/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
	int cbid;

	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;

	sceKernelSleepThreadCB&#40;&#41;;

	return 0;
&#125;


/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41;
&#123;
	int thid = 0;

	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;


ps :
thanks for hitchhikr's help,
he is the first one who found out how to use libaudiocodec to decode 132k atrac3.
jockyw2001
Posts: 339
Joined: Thu Sep 29, 2005 4:19 pm

Post by jockyw2001 »

Very cool :)
I wonder if MP3 decoding can be done similar?
cooleyes
Posts: 123
Joined: Thu May 18, 2006 3:30 pm

Post by cooleyes »

jockyw2001 wrote:Very cool :)
I wonder if MP3 decoding can be done similar?
I am trying to find out how to decode MP3 and AAC,
but I need some time to do this.
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

Excellent, another format down.

MP3 should be possible, I've tried it myself but to no avail.

Maybe that's cooleyes next step?
danzel
Posts: 182
Joined: Fri Nov 04, 2005 11:03 pm

Post by danzel »

Awesome stuff :D
dr_watson
Posts: 42
Joined: Mon Nov 28, 2005 11:30 am

Post by dr_watson »

Wow! This is really nice! Excellent work!
Cpasjuste
Posts: 214
Joined: Sun May 29, 2005 8:28 am

Post by Cpasjuste »

Yup, thanks for the work guys, i will probably test this in my app :)
SamuraiX
Posts: 76
Joined: Tue Jan 31, 2006 6:28 am
Location: USA
Contact:

Post by SamuraiX »

Nice one! I could definately use this in my applications. Perhaps this should be added to the SDK audio samples unless my view is out of date then I should update ;p
Brunni
Posts: 186
Joined: Sat Oct 08, 2005 10:27 pm

Post by Brunni »

Cool :)
But does this always need KERNEL mode? I'm wondering how official games do :/
Sorry for my bad english
Image Oldschool library for PSP - PC version released
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

It needs kernel mode.

Official games load the PRX from the game disc, not flash if I recall correctly.
Vincent_M
Posts: 73
Joined: Tue Apr 03, 2007 4:16 am

Post by Vincent_M »

Now, how do we play/stream the file? I'm a bit new to audio/video streaming atm. Now that the file is decoded, where do we go from here? Just curious, really...
ACh
Posts: 3
Joined: Sun Jun 03, 2007 5:12 pm

Post by ACh »

If you're targeting 3.xx firmware, you should be able to use sceUtilityLoadAvModule() to get at the audio/video decoders from user mode. I personally avoid ATRAC3, but here's how I set up for AVC decoding to work on both 1.50 (psplink) and 3.40 OE-A:

Code: Select all

int loadav_ok = 0;
int32_t firmware_version = sceKernelDevkitVersion&#40;&#41;;
if &#40;firmware_version >= 0x02070000&#41; &#123;
    loadav_ok = 1;
    res = sceUtilityLoadAvModule&#40;0&#41;;
    if &#40;res < 0&#41; &#123;
        loadav_ok = 0;
    &#125;
    if &#40;loadav_ok&#41; &#123;
        res = sceUtilityLoadAvModule&#40;3&#41;;
        if &#40;res < 0&#41; &#123;
            sceUtilityUnloadAvModule&#40;0&#41;;
            loadav_ok = 0;
        &#125;
    &#125;
&#125;
if &#40;!loadav_ok&#41; &#123;
    res = load_start_module&#40;"flash0&#58;/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
    if &#40;res < 0 && res != SCE_KERNEL_ERROR_EXCLUSIVE_LOAD&#41; &#123;
        return NULL;
    &#125;
    res = load_start_module&#40;"flash0&#58;/kd/videocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
    if &#40;res < 0 && res != SCE_KERNEL_ERROR_EXCLUSIVE_LOAD&#41; &#123;
        return NULL;
    &#125;
    res = load_start_module&#40;"flash0&#58;/kd/mpegbase.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
    if &#40;res < 0 && res != SCE_KERNEL_ERROR_EXCLUSIVE_LOAD&#41; &#123;
        return NULL;
    &#125;
    res = load_start_module&#40;"flash0&#58;/kd/mpeg_vsh.prx", PSP_MEMORY_PARTITION_USER&#41;;
    if &#40;res < 0 && res != SCE_KERNEL_ERROR_EXCLUSIVE_LOAD&#41; &#123;
        return NULL;
    &#125;
&#125;
(Note--load_start_module() is an internal routine of mine that loads and starts the given module; it's essentially a streamlined version of pspSdkLoadStartModule(), but the latter should work just as well.)
Post Reply