forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

now,we can use libaudiocodec to decode mp3 and aac
Goto page Previous  1, 2
 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
egorive



Joined: 22 Jun 2006
Posts: 24

PostPosted: Thu Aug 02, 2007 4:02 pm    Post subject: upss Reply with quote

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 ;).
Back to top
View user's profile Send private message
DookFook



Joined: 01 Aug 2007
Posts: 6

PostPosted: Fri Aug 03, 2007 2:02 pm    Post subject: Reply with quote

heh, no worries man. So can we get a nudge in the right direction to get this thing to play songs? :P
Back to top
View user's profile Send private message
cooleyes



Joined: 18 May 2006
Posts: 125

PostPosted: Fri Aug 03, 2007 2:40 pm    Post subject: Reply with quote

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

Code:

#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();

PSP_MODULE_INFO("MP3 decodeTest", 0x1000, 1, 1);
PSP_MAIN_THREAD_ATTR(0);

__attribute__ ((constructor))
void loaderInit(){
   pspKernelSetKernelPC();
   pspSdkInstallNoDeviceCheckPatch();
   pspSdkInstallNoPlainModuleCheckPatch();
   pspSdkInstallKernelLoadModulePatch();
}

SceCtrlData input;

static int bitrates[] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };

unsigned long mp3_codec_buffer[65] __attribute__((aligned(64)));
short mp3_mix_buffer[1152 * 2] __attribute__((aligned(64)));

short mp3_output_buffer[4][1152 * 2] __attribute__((aligned(64)));
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(void)
{
   SetupCallbacks();
   
   int result = pspSdkLoadStartModule("flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL);
   
   result = pspSdkLoadStartModule("flash0:/kd/videocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
   
   result = pspSdkLoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
   
   result = pspSdkLoadStartModule("flash0:/kd/mpegbase.prx", PSP_MEMORY_PARTITION_KERNEL);
   
   result = pspSdkLoadStartModule("flash0:/kd/mpeg_vsh.prx", PSP_MEMORY_PARTITION_USER);
   
   pspSdkFixupImports(result);
   
   sceMpegInit();
   
   mp3_handle = sceIoOpen("ms0:/Test.MP3", PSP_O_RDONLY, 0777);
   if (  ! mp3_handle )
      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(mp3_handle, 0, PSP_SEEK_CUR);
   
   memset(mp3_codec_buffer, 0, sizeof(mp3_codec_buffer));
   
   if ( sceAudiocodecCheckNeedMem(mp3_codec_buffer, 0x1002) < 0 )
      goto wait;
   if ( sceAudiocodecGetEDRAM(mp3_codec_buffer, 0x1002) < 0 )
         goto wait;
   mp3_getEDRAM = 1;
   
   if ( sceAudiocodecInit(mp3_codec_buffer, 0x1002) < 0 ) {
      goto wait;
   }
   int audio_channel = sceAudioChReserve(0, mp3_sample_per_frame , PSP_AUDIO_FORMAT_STEREO);
   int eof = 0;   
   while( !eof ) {
      int samplesdecoded;
      memset(mp3_mix_buffer, 0, mp3_sample_per_frame*2*2); 
      unsigned char mp3_header_buf[4];
      if ( sceIoRead( mp3_handle, mp3_header_buf, 4 ) != 4 ) {
         eof = 1;
         continue;
      }
      int mp3_header = mp3_header_buf[0];
      mp3_header = (mp3_header<<8) | mp3_header_buf[1];
      mp3_header = (mp3_header<<8) | mp3_header_buf[2];
      mp3_header = (mp3_header<<8) | mp3_header_buf[3];
       
      int bitrate = (mp3_header & 0xf000) >> 12;
      int padding = (mp3_header & 0x200) >> 9;
       
      int frame_size = 144000*bitrates[bitrate]/mp3_samplerate + padding;
       
      if ( mp3_data_buffer )
         free(mp3_data_buffer);
      mp3_data_buffer = (u8*)memalign(64, frame_size);
       
      sceIoLseek32(mp3_handle, mp3_data_start, PSP_SEEK_SET); //seek back
       
      if ( sceIoRead( mp3_handle, mp3_data_buffer, frame_size ) != frame_size ) {
         eof = 1;
         continue;
      }
       
      mp3_data_start += frame_size;
       
      mp3_codec_buffer[6] = (unsigned long)mp3_data_buffer;
      mp3_codec_buffer[8] = (unsigned long)mp3_mix_buffer;
       
      mp3_codec_buffer[7] = mp3_codec_buffer[10] = frame_size;
      mp3_codec_buffer[9] = mp3_sample_per_frame * 4;
   
      int res = sceAudiocodecDecode(mp3_codec_buffer, 0x1002);
      if ( res < 0 ) {

         eof = 1;
         continue;
      } 
      memcpy(mp3_output_buffer[mp3_output_index], mp3_mix_buffer, 1152*4);
      sceAudioOutputBlocking(audio_channel, PSP_AUDIO_VOLUME_MAX, mp3_output_buffer[mp3_output_index]);
      mp3_output_index = (mp3_output_index+1)%4;
     
      samplesdecoded = mp3_sample_per_frame;
   }

wait:
   
   if ( mp3_handle ) {
      sceIoClose(mp3_handle);
   }
   if ( mp3_data_buffer) {
      free(mp3_data_buffer);
   }
   if ( mp3_getEDRAM ) {
      sceAudiocodecReleaseEDRAM(mp3_codec_buffer);
   }
   
   sceCtrlReadBufferPositive(&input, 1);
   while(!(input.Buttons & PSP_CTRL_TRIANGLE))
   {
      sceKernelDelayThread(10000);   // wait 10 milliseconds
      sceCtrlReadBufferPositive(&input, 1);
   }
   
   sceKernelExitGame();
   return 0;
}


/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   sceKernelExitGame();
   return 0;
}


/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
   int cbid;

   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);

   sceKernelSleepThreadCB();

   return 0;
}


/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}


Makefile
Code:

TARGET = mp3decoderdemo
OBJS = main.o

CFLAGS = -G0 -Wall -O2
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

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

EXTRA_TARGETS = EBOOT.PBP SCEkxploit
PSP_EBOOT_TITLE = mp3 decoder demo

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Back to top
View user's profile Send private message
DookFook



Joined: 01 Aug 2007
Posts: 6

PostPosted: Fri Aug 03, 2007 5:08 pm    Post subject: Reply with quote

Very cool, thank you cooleyes
Back to top
View user's profile Send private message
Brunni



Joined: 08 Oct 2005
Posts: 186

PostPosted: Sat Aug 04, 2007 7:22 am    Post subject: Reply with quote

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:
#include "oslib.h"
#include <pspaudiocodec.h>
#include <pspsdk.h>

typedef struct MP3_INFO      {
   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
} MP3_INFO;


#define NUMBLOCKS 4

static int osl_at3Inited = 0, osl_mp3Inited = 0;

static int osl_at3Init()      {
   int result = 0;
   if (!osl_at3Inited)      {
      int result = pspSdkLoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
      pspSdkFixupImports(result);
   }

   osl_at3Inited = 1;

   return result;
}

static int osl_mp3Init()      {
   int result = 0;

   if (!osl_mp3Inited)      {
      sceMpegInit();

      result = pspSdkLoadStartModule("flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL);
      pspSdkFixupImports(result);

      result = pspSdkLoadStartModule("flash0:/kd/videocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
      pspSdkFixupImports(result);

      result = osl_at3Init();

      result = pspSdkLoadStartModule("flash0:/kd/mpegbase.prx", PSP_MEMORY_PARTITION_KERNEL);
      pspSdkFixupImports(result);

      result = pspSdkLoadStartModule("flash0:/kd/mpeg_vsh.prx", PSP_MEMORY_PARTITION_USER);
      pspSdkFixupImports(result);
   }

   osl_mp3Inited = 1;
   return result;
}

static void osl_mp3DestroyInfo(MP3_INFO *info)      {
   if (info->codecBuffer)
      free(info->codecBuffer);

   if (info->dataBuffer)
      free(info->dataBuffer);

   if (info->handle)
      VirtualFileClose(info->handle);

   if (info->getEDRAM)
      sceAudiocodecReleaseEDRAM(info->codecBuffer);

   if (info->codecBuffer)
      free(info->codecBuffer);

   if (info)
      free(info);
}

static MP3_INFO *osl_mp3CreateInfo()      {
   int success = 0;
   MP3_INFO *info;

   info = (MP3_INFO*)malloc(sizeof(MP3_INFO));

   if (info)      {
      memset(info, 0, sizeof(MP3_INFO));

      //Allocate memory for the codec param buffer
      info->codecBuffer = memalign(64, 65 * sizeof(unsigned long));

      if (info->codecBuffer)      {
         memset(info->codecBuffer, 0, sizeof(info->codecBuffer));
         success = 1;
      }
   }

   //Clean up if failed
   if (!success)      {
      osl_mp3DestroyInfo(info);
      info = NULL;
   }

   return info;
}

static int osl_mp3Load(const char *fileName, MP3_INFO *info)      {
   int success = 0;

   //Try to load the file
   info->handle = VirtualFileOpen((char*)fileName, 0, PSP_O_RDONLY, 0777);
   if (info->handle)         {
      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(info->handle);

      //Initialize the codec
      if (sceAudiocodecCheckNeedMem(info->codecBuffer, 0x1002) >= 0)         {
         if (sceAudiocodecGetEDRAM(info->codecBuffer, 0x1002) >= 0)         {
            info->getEDRAM = 1;

            if (sceAudiocodecInit(info->codecBuffer, 0x1002) >= 0)
               success = 1;
         }
      }
   }
   return success;
}



/*
   Callbacks standard
*/
void oslAudioCallback_PlaySound_ME(OSL_SOUND *s)      {
   MP3_INFO *info = (MP3_INFO*)s->data;
   info->data_start = info->data_start_init;
}

void oslAudioCallback_StopSound_ME(OSL_SOUND *s)      {
   //Do nothing
}

int oslAudioCallback_AudioCallback_ME(unsigned int i, void* buf, unsigned int length)         {
   static int bitrates[] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
   int eof = 0;
   MP3_INFO *info = (MP3_INFO*)osl_audioVoices[i].data;
   unsigned long decode_type = 0x1002;
   unsigned char mp3_header_buf[4];

   if (VirtualFileRead(mp3_header_buf, 4, 1, info->handle) != 4)         {
         eof = 1;
         goto end;
   }

   int mp3_header = mp3_header_buf[0];
   mp3_header = (mp3_header<<8) | mp3_header_buf[1];
   mp3_header = (mp3_header<<8) | mp3_header_buf[2];
   mp3_header = (mp3_header<<8) | mp3_header_buf[3];

   int bitrate = (mp3_header & 0xf000) >> 12;
   int padding = (mp3_header & 0x200) >> 9;

   int frame_size = 144000*bitrates[bitrate]/info->samplerate + padding;

   if (info->dataBuffer)
      free(info->dataBuffer);
   info->dataBuffer = (u8*)memalign(64, frame_size);

   VirtualFileSeek(info->handle, info->data_start, PSP_SEEK_SET); //seek back

   if ( VirtualFileRead(info->dataBuffer, frame_size, 1, info->handle) != frame_size)         {
      eof = 1;
      goto end;
   }

   info->data_start += frame_size;
      
   info->codecBuffer[7] = info->codecBuffer[10] = frame_size;
   info->codecBuffer[9] = info->sample_per_frame * 4;

   info->codecBuffer[6] = (unsigned long)info->dataBuffer;
   info->codecBuffer[8] = (unsigned long)buf;

   int res = sceAudiocodecDecode(info->codecBuffer, decode_type);
   if ( res < 0 )
      eof = 1;
   
end:
   if (eof)      {
//      osl_mp3CleanUp();
      //Efface le channel
      return 0;
   }

   return 1;
}

VIRTUAL_FILE **oslAudioCallback_ReactiveSound_ME(OSL_SOUND *s, VIRTUAL_FILE *f)         {
   MP3_INFO *info = (MP3_INFO*)s->data;
   VIRTUAL_FILE **w = &info->handle;
   return w;
}

VIRTUAL_FILE *oslAudioCallback_StandBy_ME(OSL_SOUND *s)      {
   MP3_INFO *info = (MP3_INFO*)s->data;
   return info->handle;
}

void oslAudioCallback_DeleteSound_ME(OSL_SOUND *s)      {
   osl_mp3DestroyInfo((MP3_INFO*)s->data);
   s->data = NULL;
}


OSL_SOUND *oslLoadSoundFileMP3(const char *filename, int stream)      {
   OSL_SOUND *s = NULL;
   MP3_INFO *info;
   int success = 0;

   //Mp3 must be streamed for now
   if (!stream & OSL_FMT_STREAM)
      return NULL;

   osl_mp3Init();

   s = (OSL_SOUND*)malloc(sizeof(OSL_SOUND));
   if (s)         {
      //Never forget that! If any member is added to OSL_SOUND, it is assumed to be zero!
      memset(s, 0, sizeof(OSL_SOUND));

      //Allocate the size of a mp3 info structure
      info = osl_mp3CreateInfo();

      if (info)   {
         if (osl_mp3Load(filename, info))         {
            s->data = (void*)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;
         }
         else   {
            osl_mp3DestroyInfo(info);
            info = NULL;
         }
      }
   }

   if (!success)      {
      if (s)
         free(s);
      s = NULL;
   }

   if (!s)
      oslHandleLoadNoFailError(filename);
   return s;
}

_________________
Sorry for my bad english
Oldschool library for PSP - PC version released
Back to top
View user's profile Send private message
egorive



Joined: 22 Jun 2006
Posts: 24

PostPosted: Sat Aug 04, 2007 8:10 pm    Post subject: Thank you cooleyes Reply with quote

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?
Back to top
View user's profile Send private message
sakya



Joined: 28 Apr 2006
Posts: 190

PostPosted: Mon Sep 10, 2007 7:18 pm    Post subject: Reply with quote

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:
float duration = 32.0*36.0/(float)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
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group