now,we can use libaudiocodec to decode mp3 and aac

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

Moderators: cheriff, TyRaNiD

egorive
Posts: 24
Joined: Thu Jun 22, 2006 11:50 pm

upss

Post by egorive »

Upss then I'm so sorry DookFook :( I thought it was like saying the code was very bad or something similar. My apologize. Thank you ufoz for telling me, you don't go to bed without knowing something else.

It's up to us to make this thing sound. Thank you I don't know if I'll be able to play it but thank you ;).
DookFook
Posts: 6
Joined: Wed Aug 01, 2007 11:08 pm

Post by DookFook »

heh, no worries man. So can we get a nudge in the right direction to get this thing to play songs? :P
cooleyes
Posts: 123
Joined: Thu May 18, 2006 3:30 pm

Post by cooleyes »

new demo code, it can play ms0:/Test.mp3

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> 
#include <pspmpeg.h>

int SetupCallbacks&#40;&#41;; 

PSP_MODULE_INFO&#40;"MP3 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; 

static int bitrates&#91;&#93; = &#123;0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 &#125;; 

unsigned long mp3_codec_buffer&#91;65&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;; 
short mp3_mix_buffer&#91;1152 * 2&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;

short mp3_output_buffer&#91;4&#93;&#91;1152 * 2&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;
int mp3_output_index = 0;


SceUID mp3_handle; 
u8* mp3_data_buffer; 
u16 mp3_data_align; 
u32 mp3_sample_per_frame; 
u16 mp3_channel_mode; 
u32 mp3_data_start; 
u32 mp3_data_size; 
u8 mp3_getEDRAM; 
u32 mp3_channels; 
u32 mp3_samplerate; 


int main&#40;void&#41; 
&#123; 
   SetupCallbacks&#40;&#41;; 
    
   int result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL&#41;; 
    
   result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/videocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;; 
    
   result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;; 
    
   result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/mpegbase.prx", PSP_MEMORY_PARTITION_KERNEL&#41;; 
    
   result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/mpeg_vsh.prx", PSP_MEMORY_PARTITION_USER&#41;; 
    
   pspSdkFixupImports&#40;result&#41;; 
    
   sceMpegInit&#40;&#41;; 
    
   mp3_handle = sceIoOpen&#40;"ms0&#58;/Test.MP3", PSP_O_RDONLY, 0777&#41;; 
   if &#40;  ! mp3_handle &#41; 
      goto wait; 
    
   mp3_channels = 2; 
   mp3_samplerate = 44100; //this is mp3 file's samplerate, also can be 48000,.... 
   mp3_sample_per_frame = 1152; 
    
   mp3_data_start = sceIoLseek32&#40;mp3_handle, 0, PSP_SEEK_CUR&#41;; 
    
   memset&#40;mp3_codec_buffer, 0, sizeof&#40;mp3_codec_buffer&#41;&#41;; 
    
   if &#40; sceAudiocodecCheckNeedMem&#40;mp3_codec_buffer, 0x1002&#41; < 0 &#41; 
      goto wait; 
   if &#40; sceAudiocodecGetEDRAM&#40;mp3_codec_buffer, 0x1002&#41; < 0 &#41; 
         goto wait; 
   mp3_getEDRAM = 1; 
    
   if &#40; sceAudiocodecInit&#40;mp3_codec_buffer, 0x1002&#41; < 0 &#41; &#123; 
      goto wait; 
   &#125; 
   int audio_channel = sceAudioChReserve&#40;0, mp3_sample_per_frame , PSP_AUDIO_FORMAT_STEREO&#41;; 
   int eof = 0;    
   while&#40; !eof &#41; &#123; 
      int samplesdecoded; 
      memset&#40;mp3_mix_buffer, 0, mp3_sample_per_frame*2*2&#41;;  
      unsigned char mp3_header_buf&#91;4&#93;; 
      if &#40; sceIoRead&#40; mp3_handle, mp3_header_buf, 4 &#41; != 4 &#41; &#123; 
         eof = 1; 
         continue; 
      &#125; 
      int mp3_header = mp3_header_buf&#91;0&#93;; 
      mp3_header = &#40;mp3_header<<8&#41; | mp3_header_buf&#91;1&#93;; 
      mp3_header = &#40;mp3_header<<8&#41; | mp3_header_buf&#91;2&#93;; 
      mp3_header = &#40;mp3_header<<8&#41; | mp3_header_buf&#91;3&#93;; 
       
      int bitrate = &#40;mp3_header & 0xf000&#41; >> 12; 
      int padding = &#40;mp3_header & 0x200&#41; >> 9; 
       
      int frame_size = 144000*bitrates&#91;bitrate&#93;/mp3_samplerate + padding; 
       
      if &#40; mp3_data_buffer &#41; 
         free&#40;mp3_data_buffer&#41;; 
      mp3_data_buffer = &#40;u8*&#41;memalign&#40;64, frame_size&#41;; 
       
      sceIoLseek32&#40;mp3_handle, mp3_data_start, PSP_SEEK_SET&#41;; //seek back 
       
      if &#40; sceIoRead&#40; mp3_handle, mp3_data_buffer, frame_size &#41; != frame_size &#41; &#123; 
         eof = 1; 
         continue; 
      &#125; 
       
      mp3_data_start += frame_size; 
       
      mp3_codec_buffer&#91;6&#93; = &#40;unsigned long&#41;mp3_data_buffer; 
      mp3_codec_buffer&#91;8&#93; = &#40;unsigned long&#41;mp3_mix_buffer; 
       
      mp3_codec_buffer&#91;7&#93; = mp3_codec_buffer&#91;10&#93; = frame_size; 
      mp3_codec_buffer&#91;9&#93; = mp3_sample_per_frame * 4; 
    
      int res = sceAudiocodecDecode&#40;mp3_codec_buffer, 0x1002&#41;; 
      if &#40; res < 0 &#41; &#123; 

         eof = 1; 
         continue; 
      &#125;  
      memcpy&#40;mp3_output_buffer&#91;mp3_output_index&#93;, mp3_mix_buffer, 1152*4&#41;;
      sceAudioOutputBlocking&#40;audio_channel, PSP_AUDIO_VOLUME_MAX, mp3_output_buffer&#91;mp3_output_index&#93;&#41;;
      mp3_output_index = &#40;mp3_output_index+1&#41;%4;
      
      samplesdecoded = mp3_sample_per_frame; 
   &#125; 

wait&#58; 
    
   if &#40; mp3_handle &#41; &#123; 
      sceIoClose&#40;mp3_handle&#41;; 
   &#125; 
   if &#40; mp3_data_buffer&#41; &#123; 
      free&#40;mp3_data_buffer&#41;; 
   &#125; 
   if &#40; mp3_getEDRAM &#41; &#123; 
      sceAudiocodecReleaseEDRAM&#40;mp3_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; 
Makefile

Code: Select all

TARGET = mp3decoderdemo
OBJS = main.o

CFLAGS = -G0 -Wall -O2
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =
LDFLAGS =
LIBS= -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudio -lm 

EXTRA_TARGETS = EBOOT.PBP SCEkxploit
PSP_EBOOT_TITLE = mp3 decoder demo

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
DookFook
Posts: 6
Joined: Wed Aug 01, 2007 11:08 pm

Post by DookFook »

Very cool, thank you cooleyes
Brunni
Posts: 186
Joined: Sat Oct 08, 2005 10:27 pm

Post by Brunni »

Thank you very much! I've done a driver for the OldSchool Library (currently mp3 only). It's composed from simple functions such as init, load file, play, decode, etc. The rest is identical to a normal wave output.

Code: Select all

#include "oslib.h"
#include <pspaudiocodec.h>
#include <pspsdk.h>

typedef struct MP3_INFO		&#123;
	VIRTUAL_FILE *handle;
	unsigned long *codecBuffer;
	u8* dataBuffer;

	u32 channels;
	u32 samplerate;
	u32 sample_per_frame;
	u32 data_start;
	u32 data_start_init;
	u8 getEDRAM;

	//Codec specific
&#125; MP3_INFO;


#define NUMBLOCKS 4

static int osl_at3Inited = 0, osl_mp3Inited = 0;

static int osl_at3Init&#40;&#41;		&#123;
	int result = 0;
	if &#40;!osl_at3Inited&#41;		&#123;
		int result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
		pspSdkFixupImports&#40;result&#41;;
	&#125;

	osl_at3Inited = 1;

	return result;
&#125;

static int osl_mp3Init&#40;&#41;		&#123;
	int result = 0;

	if &#40;!osl_mp3Inited&#41;		&#123;
		sceMpegInit&#40;&#41;;

		result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
		pspSdkFixupImports&#40;result&#41;;

		result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/videocodec.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
		pspSdkFixupImports&#40;result&#41;;

		result = osl_at3Init&#40;&#41;;

		result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/mpegbase.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
		pspSdkFixupImports&#40;result&#41;;

		result = pspSdkLoadStartModule&#40;"flash0&#58;/kd/mpeg_vsh.prx", PSP_MEMORY_PARTITION_USER&#41;;
		pspSdkFixupImports&#40;result&#41;;
	&#125;

	osl_mp3Inited = 1;
	return result;
&#125;

static void osl_mp3DestroyInfo&#40;MP3_INFO *info&#41;		&#123;
	if &#40;info->codecBuffer&#41;
		free&#40;info->codecBuffer&#41;;

	if &#40;info->dataBuffer&#41;
		free&#40;info->dataBuffer&#41;;

	if &#40;info->handle&#41;
		VirtualFileClose&#40;info->handle&#41;;

	if &#40;info->getEDRAM&#41;
		sceAudiocodecReleaseEDRAM&#40;info->codecBuffer&#41;;

	if &#40;info->codecBuffer&#41;
		free&#40;info->codecBuffer&#41;;

	if &#40;info&#41;
		free&#40;info&#41;;
&#125;

static MP3_INFO *osl_mp3CreateInfo&#40;&#41;		&#123;
	int success = 0;
	MP3_INFO *info;

	info = &#40;MP3_INFO*&#41;malloc&#40;sizeof&#40;MP3_INFO&#41;&#41;;

	if &#40;info&#41;		&#123;
		memset&#40;info, 0, sizeof&#40;MP3_INFO&#41;&#41;;

		//Allocate memory for the codec param buffer
		info->codecBuffer = memalign&#40;64, 65 * sizeof&#40;unsigned long&#41;&#41;;

		if &#40;info->codecBuffer&#41;		&#123;
			memset&#40;info->codecBuffer, 0, sizeof&#40;info->codecBuffer&#41;&#41;;
			success = 1;
		&#125;
	&#125;

	//Clean up if failed
	if &#40;!success&#41;		&#123;
		osl_mp3DestroyInfo&#40;info&#41;;
		info = NULL;
	&#125;

	return info;
&#125;

static int osl_mp3Load&#40;const char *fileName, MP3_INFO *info&#41;		&#123;
	int success = 0;

	//Try to load the file
	info->handle = VirtualFileOpen&#40;&#40;char*&#41;fileName, 0, PSP_O_RDONLY, 0777&#41;;
	if &#40;info->handle&#41;			&#123;
		info->channels = 2;
		info->samplerate = 44100; //this is mp3 file's samplerate, also can be 48000,....
		info->sample_per_frame = 1152;

		info->data_start_init = VirtualFileTell&#40;info->handle&#41;;

		//Initialize the codec
		if &#40;sceAudiocodecCheckNeedMem&#40;info->codecBuffer, 0x1002&#41; >= 0&#41;			&#123;
			if &#40;sceAudiocodecGetEDRAM&#40;info->codecBuffer, 0x1002&#41; >= 0&#41;			&#123;
				info->getEDRAM = 1;

				if &#40;sceAudiocodecInit&#40;info->codecBuffer, 0x1002&#41; >= 0&#41;
					success = 1;
			&#125;
		&#125;
	&#125;
	return success;
&#125;



/*
	Callbacks standard
*/
void oslAudioCallback_PlaySound_ME&#40;OSL_SOUND *s&#41;		&#123;
	MP3_INFO *info = &#40;MP3_INFO*&#41;s->data;
	info->data_start = info->data_start_init;
&#125;

void oslAudioCallback_StopSound_ME&#40;OSL_SOUND *s&#41;		&#123;
	//Do nothing
&#125;

int oslAudioCallback_AudioCallback_ME&#40;unsigned int i, void* buf, unsigned int length&#41;			&#123;
	static int bitrates&#91;&#93; = &#123;0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 &#125;;
	int eof = 0;
	MP3_INFO *info = &#40;MP3_INFO*&#41;osl_audioVoices&#91;i&#93;.data;
	unsigned long decode_type = 0x1002;
	unsigned char mp3_header_buf&#91;4&#93;;

	if &#40;VirtualFileRead&#40;mp3_header_buf, 4, 1, info->handle&#41; != 4&#41;			&#123;
         eof = 1;
         goto end;
	&#125;

	int mp3_header = mp3_header_buf&#91;0&#93;;
	mp3_header = &#40;mp3_header<<8&#41; | mp3_header_buf&#91;1&#93;;
	mp3_header = &#40;mp3_header<<8&#41; | mp3_header_buf&#91;2&#93;;
	mp3_header = &#40;mp3_header<<8&#41; | mp3_header_buf&#91;3&#93;;

	int bitrate = &#40;mp3_header & 0xf000&#41; >> 12;
	int padding = &#40;mp3_header & 0x200&#41; >> 9;

	int frame_size = 144000*bitrates&#91;bitrate&#93;/info->samplerate + padding;

	if &#40;info->dataBuffer&#41;
		free&#40;info->dataBuffer&#41;;
	info->dataBuffer = &#40;u8*&#41;memalign&#40;64, frame_size&#41;;

	VirtualFileSeek&#40;info->handle, info->data_start, PSP_SEEK_SET&#41;; //seek back

	if &#40; VirtualFileRead&#40;info->dataBuffer, frame_size, 1, info->handle&#41; != frame_size&#41;			&#123;
		eof = 1;
		goto end;
	&#125;

	info->data_start += frame_size;
	    
	info->codecBuffer&#91;7&#93; = info->codecBuffer&#91;10&#93; = frame_size;
	info->codecBuffer&#91;9&#93; = info->sample_per_frame * 4;

	info->codecBuffer&#91;6&#93; = &#40;unsigned long&#41;info->dataBuffer;
	info->codecBuffer&#91;8&#93; = &#40;unsigned long&#41;buf;

	int res = sceAudiocodecDecode&#40;info->codecBuffer, decode_type&#41;;
	if &#40; res < 0 &#41;
		eof = 1;
   
end&#58;
	if &#40;eof&#41;		&#123;
//		osl_mp3CleanUp&#40;&#41;;
		//Efface le channel
		return 0;
	&#125;

	return 1;
&#125;

VIRTUAL_FILE **oslAudioCallback_ReactiveSound_ME&#40;OSL_SOUND *s, VIRTUAL_FILE *f&#41;			&#123;
	MP3_INFO *info = &#40;MP3_INFO*&#41;s->data;
	VIRTUAL_FILE **w = &info->handle;
	return w;
&#125;

VIRTUAL_FILE *oslAudioCallback_StandBy_ME&#40;OSL_SOUND *s&#41;		&#123;
	MP3_INFO *info = &#40;MP3_INFO*&#41;s->data;
	return info->handle;
&#125;

void oslAudioCallback_DeleteSound_ME&#40;OSL_SOUND *s&#41;		&#123;
	osl_mp3DestroyInfo&#40;&#40;MP3_INFO*&#41;s->data&#41;;
	s->data = NULL;
&#125;


OSL_SOUND *oslLoadSoundFileMP3&#40;const char *filename, int stream&#41;		&#123;
	OSL_SOUND *s = NULL;
	MP3_INFO *info;
	int success = 0;

	//Mp3 must be streamed for now
	if &#40;!stream & OSL_FMT_STREAM&#41;
		return NULL;

	osl_mp3Init&#40;&#41;;

	s = &#40;OSL_SOUND*&#41;malloc&#40;sizeof&#40;OSL_SOUND&#41;&#41;;
	if &#40;s&#41;			&#123;
		//Never forget that! If any member is added to OSL_SOUND, it is assumed to be zero!
		memset&#40;s, 0, sizeof&#40;OSL_SOUND&#41;&#41;;

		//Allocate the size of a mp3 info structure
		info = osl_mp3CreateInfo&#40;&#41;;

		if &#40;info&#41;	&#123;
			if &#40;osl_mp3Load&#40;filename, info&#41;&#41;			&#123;
				s->data = &#40;void*&#41;info;

				s->endCallback = NULL;
				s->volumeLeft = s->volumeRight = OSL_VOLUME_MAX;
				//No special format
				s->format = 0;
				//Always stereo output
				s->mono = 0;
				s->divider = OSL_FMT_44K;
				//MP3 files are always streamed for now
				s->isStreamed = 1;
				s->numSamples = info->sample_per_frame;

				s->audioCallback = oslAudioCallback_AudioCallback_ME;
				s->playSound = oslAudioCallback_PlaySound_ME;
				s->stopSound = oslAudioCallback_StopSound_ME;
				s->standBySound = oslAudioCallback_StandBy_ME;
				s->reactiveSound = oslAudioCallback_ReactiveSound_ME;
				s->deleteSound = oslAudioCallback_DeleteSound_ME;
				
				success = 1;
			&#125;
			else	&#123;
				osl_mp3DestroyInfo&#40;info&#41;;
				info = NULL;
			&#125;
		&#125;
	&#125;

	if &#40;!success&#41;		&#123;
		if &#40;s&#41;
			free&#40;s&#41;;
		s = NULL;
	&#125;

	if &#40;!s&#41;
		oslHandleLoadNoFailError&#40;filename&#41;;
	return s;
&#125;
Sorry for my bad english
Image Oldschool library for PSP - PC version released
egorive
Posts: 24
Joined: Thu Jun 22, 2006 11:50 pm

Thank you cooleyes

Post by egorive »

First of all thank you for your effort cooleyes, you are not only a great programmer, but also a great guide!

I was looking the code inside PPA (¡¡¡it's incredible!!!), specifically inside mod folder where I have seen the code of cooleyes and trying to follow it to know which were the next steps to make it play, but I admit I'm still too newbee for moving inside all this hole thing without sinking in it.

I know that a sound file is composed of headers+"data of music" , this code of cooleyes transform (decode) that mp3 "data of music" to samples that can be given to another sce functions that can play them, but this is quite simple and a little far from the reality.

Do you now a website or pdf book where I can understand it or study in depth all this process and especially how relating it with c programming language?
sakya
Posts: 190
Joined: Fri Apr 28, 2006 5:48 pm
Contact:

Post by sakya »

Hi! :)

Is there a way I can find the frame duration to know how many seconds have been played (like libMad Header.duration)?

Many thanks. :)

EDIT:
I think I found it:

Code: Select all

float duration = 32.0*36.0/&#40;float&#41;samplerate;
but the 36 value should not work with all mp3s (can be also 12 or 18).
Do someone knows ho to find the correct value?

Ciaooo
Sakya
Post Reply