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 

libogg / libvorbis

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
hardfalcon



Joined: 19 Aug 2007
Posts: 5

PostPosted: Mon Aug 20, 2007 2:32 am    Post subject: libogg / libvorbis Reply with quote

Hi, I got two questions about libogg / libvorbis:
1.) Where can I find a documentation about the functions, constants, etc these 2 libs provide?
2.) Is there any simple sample code playing ogg-vorbis files on the PSP? I know about some programs which play ogg files, but I haven't found any source code so far... :/

Another thing is that I experienced problems while trying to compile libogg (checked out from via svn last night). It kept stating I hadn't installed automake though I actually hae installed automake 1.10 (according to the README.PSP, version 1.6 or above is required). I finally compiled it by changing autogen.sh so that it wouldn't check for autogen and aclocale anymore...

<edit>
I'm NOT using Cygwin but native Linux (Frugalware 0.7-pre2).
</edit>

thx in advance
Pascal
Back to top
View user's profile Send private message
Viper8896



Joined: 26 Jan 2006
Posts: 110

PostPosted: Fri Aug 24, 2007 1:30 pm    Post subject: Reply with quote

The official web site has docs I've made a simple player that plays a .ogg vorbis file including pausing, showing the current time in seconds of the track and skipping forward and back but the code is written using SDL not native vorbis but here it is anyway.

Code:
/*
 * OGG PLAYER
 *
 *
 */

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <psppower.h>
#include <pspctrl.h>
#include <pspiofilemgr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspumd.h>
#include <SDL.h>
#include <SDL_main.h>
#include <SDL_thread.h>
#include <SDL_mixer.h>
#include <psprtc.h>
#include <vorbis/vorbisfile.h>

/* to make typing easier */
#define printf pspDebugScreenPrintf

/* known file types */
#define file1 8557
#define file2 8630
#define file3 8703
#define dire1 4461
#define dire2 4607
#define specialfile 511

/* Screen resolution */
#define W 480
#define H 272

int menu = 0; //menu options
int i = 0; //used for loops
SceCtrlData pad; //stores which button has been pressed
int x = 22; //character that changes while music is playing: /-\|
char nowplaying[256] = ""; //actuall string of currently playing music file
int playthid; //used for playing thread

/* 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;
}

int goupdirectory(char location[256])
{
   for(i=0; i<=256; i++)
   {
      if(location[i] == '\0') //find the first null character
         {
         i --; //go back one character
         location[i] = '\0'; //take of the ending '/'
         /* keep removing charcters until a '/' is found */
         while(location[i] != '/')
         {
            /* if a ':' is found its gone too far eg: 'ms0:/' */
            if(location[i] == ':')
            {
               i++;
               location[i] = '/'; //add on a '/'
               i++;
               location[i] = '\0'; // add on the null character
               return 1;
            }
            location[i] = '\0';
            i--;
         }
         return 0;
      }
   }
   return 1;
}

int checkextension(char filename[256])
{
   for(i=0; i<=255; i++)
   {
      if(filename[i] == '\0') //find the first null character
      {
         i--;
         if((filename[i] == 71) || (filename[i] == 103)) //should end in g or G
            {
            i--;
            if((filename[i] == 71) || (filename[i] == 103)) /*and another g
            or G before that */
            {
               i--;
               if((filename[i] == 79) || (filename[i] == 111)) /*and o or O before that */
               {
                  i--;
                  if(filename[i] == 46) //and finally a dot
                  {
                     return 1; //return 1 for .ogg (will add further extensions such as mp3 in future)
                  }
                  else
                  {
                     break; //no dot before ogg so its of the wrong type
                  }
               }
               else
               {
                  break; //no o before gg so its of the wrong type
               }
            }
            else
            {
               break; //ends in a g but there isnt another g before it
            }
         }
         else
         {
            break; //doesnt end in g so wrong file type
         }
      }
   }
   return 0; //not a playable file
}

int playing() //thread to run when being played
{
   int k;
   while(1)
   {
      if(Mix_PlayingMusic() && !Mix_PausedMusic()) //if its playing and not paused
      {
         switch(x) //this is the spinning character to show music is being played
         {
            case 22:
               x=29;
               break;
            case 23:
               x=30;
               break;
            case 29:
               x=23;
               break;
            case 30:
               x=22;
               break;
         }
      }
      if(Mix_PlayingMusic() && Mix_PausedMusic()) //if it is playing but paused
      {
      }
      if(!Mix_PlayingMusic()) //if not playing
      {
         sceKernelExitDeleteThread(0);
      }
      /* this loop slows the thread down for controlling the speed of the spinning character */
      for(k=0;k<10;k++)
      {
         sceDisplayWaitVblankStart();
      }
   }
}

int starttheogg()
{
   /* the next 4 variables are used for opening the audio device */
   int audio_rate = 22050;
   Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */
   int audio_channels = 2;
   int audio_buffers = 4096;
   /* Mix_Music actually holds the music information.  */
   Mix_Music *music = NULL;
   /* manually open the ogg vorbis file to see how long it is as not available with SDL_mixer */
   OggVorbis_File ovf;
   /* file pointer must be used with ovfile pointer see above^ */
   FILE *fp;
   /* total length of music file(seconds) */
   int vorbis_time;
   /* ticks per second */
   u32 tickspersecond;
   /* start time(ticks) */
   u64 time1;
   /* end time(ticks) */
   u64 time2;
   /* position in current playing music file(in ticks so must divide by tickspersecond) */
   u64 musicposition;
   /* position to seek to */
   double seekto;

   /* get how many ticks per second for working out position in play stream */
   tickspersecond = sceRtcGetTickResolution();
   /* open the file for getting its total time as no function available in SDL_mixer */
   fp=fopen(nowplaying, "r");
   ov_open(fp,&ovf,NULL,0);
   vorbis_time = ov_time_total(&ovf,-1);
   ov_clear(&ovf);
    fclose(fp);
   /* create the thread that goes when playing (int playing()) see above for the code^.
    * first initializing playthid to 0. then calling the create thread function.
    * giving it the name playing_thread. 0x32 priority. 0xFA0 initial stack size.
    * 0 attributes. NULL options
    */
   playthid = 0;
   playthid = sceKernelCreateThread("playing_thread", playing, 0x32, 0xFA0, 0, NULL);
   /* start at 0 and work towards end */
   musicposition = 0;
   pspDebugScreenSetXY(0,8);
   printf("%-256s", nowplaying);
   pspDebugScreenSetXY(0,26);
   printf("<START>  %c  %-25s\n", 61, "Pause/Resume");
   printf("%c        %c  %-25s\n", -8, 61, "Stop");
   printf("L        %c  %-25s\n", 61, "Rewind to start");
   printf("%c        %c  %-25s\n", -48, 61, "Seek Back");
   printf("%c        %c  %-25s", -49, 61, "Seek Forward");
   /* Open the audio device not the music file */
   if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers))
   {
      return 1;
   }
      
   if(music != NULL) //make sure no music is already loaded
   {
      Mix_HaltMusic();
      Mix_FreeMusic(music);
      music = NULL;
   }
   music = Mix_LoadMUS(nowplaying);
   if(music == NULL) //music should not be null anymore but if it still null, it failed to load
   {
      return 2;
   }
   if(Mix_PlayMusic(music, 0) == -1) //play music returns 0 on success or -1 on error
   {
      return 3;
   }
   if(playthid>=0) //if thread created ok start it
   {
      sceKernelStartThread(playthid,0,0);
   }
   if(playthid<0)
   {
      pspDebugScreenClear();
      printf("thread error");
      while(1) //just sit here in infinite loop so i can see where the error is
      {
      }
   }
   sceRtcGetCurrentTick(&time1);
   while(Mix_PlayingMusic())
   {
      if(Mix_PausedMusic())
      {
         pspDebugScreenSetXY(25,15);
         printf("music paused \n");
      }
      else
      {
         pspDebugScreenSetXY(25,15);
         printf("music playing\n");
      }
      for(i=0;i<10;i++)
      {
         sceDisplayWaitVblankStart();
      }
      while(1)
      {
         if(!Mix_PlayingMusic())
         {
            break;
         }
         pspDebugScreenSetXY(40,15);
         if(Mix_PausedMusic())
         {
            sceRtcGetCurrentTick(&time1);
         }
         sceRtcGetCurrentTick(&time2);
         musicposition = musicposition + (time2-time1);
         printf("%c  %d/%d          ",x,(int)(musicposition/tickspersecond),vorbis_time);
         sceRtcGetCurrentTick(&time1);
         sceCtrlReadBufferPositive(&pad, 1);
         if(pad.Buttons & PSP_CTRL_LEFT)
         {
            musicposition = musicposition - (tickspersecond*4);//seek backward 4 seconds
            if(((int)musicposition)<0)
            {
               musicposition=0;
               sceRtcGetCurrentTick(&time1);
               seekto = 0;
            }
            else
            {
               seekto = (musicposition/tickspersecond);
            }
            Mix_SetMusicPosition(seekto);
            x = 30;
            break;
         }
         if(pad.Buttons & PSP_CTRL_RIGHT)
         {
            musicposition = musicposition + (tickspersecond*4);//seek forward 4 seconds
            if((musicposition/tickspersecond)>vorbis_time)
            {
               Mix_HaltMusic();
               Mix_FreeMusic(music);
               music = NULL;
               break;
            }
            seekto = (musicposition/tickspersecond);
            Mix_SetMusicPosition(seekto);
            break;
         }
         if(pad.Buttons & PSP_CTRL_START)
         {
            if(Mix_PausedMusic())
            {
               Mix_ResumeMusic();
               sceRtcGetCurrentTick(&time1);
            }
            else
            {
               Mix_PauseMusic();
            }
            break;
         }
         if(pad.Buttons & PSP_CTRL_CIRCLE)
         {
            Mix_HaltMusic();
            Mix_FreeMusic(music);
            music = NULL;
            break;
         }
         if(pad.Buttons & PSP_CTRL_LTRIGGER)
         {
            x = 30;
            musicposition = 0;
            Mix_RewindMusic();
            sceRtcGetCurrentTick(&time1);
            break;
         }
      }
   }
   pspDebugScreenSetXY(25,15);
   printf("%-50c", ' ');
   return 0;
}

int main(void)
{
   int drive = 0; //used to change drive
   int pos = 0; //file position in current directory
   int dfd; //directory file descriptor
   int morede = 1; //more directory entrys to read
   char location[256] = "fatms0:/"; //location to open
   int filecount = 0; //count how many files in current directory
   int driveneedstochange = 0; //used to check if drive needs to change
   SceIoDirent dir; //store name and info

   memset(&dir, 0, sizeof dir); //set memory (must do this to make it work)
   SetupCallbacks(); //setup callbacks
   pspDebugScreenInit(); //initialize screen
   SDL_Init(SDL_INIT_AUDIO); //must be called to use sdl audio
   printf("OGG VORBIS PLAYER\nCoded by Viper");
   
   /* Start main loop */
   while(1)
   {
      if(driveneedstochange == 1)
      {
         switch (drive)
         {
            case 0:
               strcpy(location, "fatms0:/");
               break;
            case 1:
               pspDebugScreenSetXY(0,8);
               printf("%-256s", "Checking UMD...");
               i = sceUmdCheckMedium(0);
               if(i != 0)
               {
                  sceUmdActivate(1, "disc0:");
                  strcpy(location, "disc0:/");
                  sceUmdWaitDriveStat(UMD_WAITFORINIT);
                  break;
               }
               else
               {
                  drive = 2;
               }
            case 2:
               strcpy(location, "flash0:/");
               break;
            case 3:
               strcpy(location, "flash1:/");
               break;
         }
         driveneedstochange = 0;
      }

      pspDebugScreenSetXY(0,8);

      if((dfd = sceIoDopen(location)) >= 0)
      {
         morede = 1;
         filecount = 0;
         while(morede > 0) //while there is more directory entries to read
         {
            morede = sceIoDread(dfd, &dir);
            filecount ++;
         }
         filecount --;
         sceIoDclose(dfd);
         dfd = sceIoDopen(location); //reopening it now that ive got the count
         printf("%-256s", location);
         pspDebugScreenSetXY(0,10);
         for(i = pos; i >= 0; i--)
         {
            morede = sceIoDread(dfd, &dir);
            if(morede < 0) //error
            {
               printf("Error reading %-242s", location); /* it managed to open the directory but couldnt
               read it contents (unlikely going to happen)*/
               while(1)
               {
                  sceDisplayWaitVblankStart();
               }
            }
         }
         printf("%d/%-5d", (pos+1), filecount);
         pspDebugScreenSetXY(15,10);
         switch(dir.d_stat.st_mode)
         {
            case dire1:
            case dire2:
               printf("directory");
               break;
            case file1:
            case file2:
            case file3:
               printf("file     ");
               break;
            case specialfile:
               printf("special  ");
               break;
            default:
               printf("?:%-7d", dir.d_stat.st_mode);
               break;
         }
         pspDebugScreenSetXY(25,10);
         printf("%-256s", dir.d_name);

         sceIoDclose(dfd);
      }

      
      else
      {
         printf("%-256s", "Error opening drive");
      }

      pspDebugScreenSetXY(0,26);
      printf("%c        %c  %-25s\n", -40, 61, "Change drive"); //triangle equals change drive
      printf("%c        %c  %-25s\n", -8 , 61, "Go up to parent directory"); //circle equals go up a dir
      printf("%c        %c  %-25s\n", 28, 61, "Play / enter directory"); //cross equalls play / enter directory
      printf("%c/%c      %c  %-25s\n", -50, -51, 61, "Choose file / directory"); //up/down equals choose file / director
      printf("%-40c", ' ');

      for(i = 0; i < 10; i++) //so user cant make accidently press the buttons to quickly
      {
            sceDisplayWaitVblankStart();
      }


      /* Start input check loop */
      while(1)
      {
         sceCtrlReadBufferPositive(&pad, 1);
         if(pad.Buttons & PSP_CTRL_UP)
         {
            if(pos > 0)
            {
               pos--;
               break;
            }
            else
            {
               break;
            }
         }

         if(pad.Buttons & PSP_CTRL_DOWN)
         {
            if(pos < (filecount-1))
            {
               pos++;
               break;
            }
            else
            {
               break;
            }
         }

         if(pad.Buttons & PSP_CTRL_TRIANGLE)
         {
            pos = 0;
            driveneedstochange = 1;            
            switch (drive)
            {
               case 0:
                  drive = 1;
                  break;
               case 1:
                  drive = 2;
                  break;
               case 2:
                  drive = 3;
                  break;
               case 3:
                  drive = 0;
                  break;
            }
            
            break;
         }

         if(pad.Buttons & PSP_CTRL_CIRCLE) //when on UMD ther is no .. to go up a dir so we need this
         {
            if(goupdirectory(location) == 0)
            {
               pos = 0;
            }
            break;
         }

         if(pad.Buttons & PSP_CTRL_CROSS) //if ogg play it or if dir change to that dir
         {
            switch(dir.d_stat.st_mode)
            {
               case dire1: //this is to check if its a directory
               case dire2:
                  /* do nothing bcos a single dot means the same working dir */
                  if((dir.d_name[0] == '.') && (dir.d_name[1] == '\0'))
                  {
                     break;
                  }
                   /* if we get 2 dots however that means go up a directory */
                  if((dir.d_name[0] == '.') && (dir.d_name[1] == '.') && (dir.d_name[2] == '\0'))
                  {
                     if(goupdirectory(location) == 0)
                     {
                        pos = 0;
                     }
                     break;
                  }
                  else //must be regular directory
                  {
                     pos = 0; //start at the first file
                     strcat(location, dir.d_name); //add the directory name to the current location
                     for(i=0; i<255; i++)
                     {
                        if(location[i] == '\0') //find the first null character
                        {
                           location[i] = '/'; //and make it a forward slash
                           i++;
                           location[i] = '\0'; //add the final null character
                           break;
                        }
                     }
                  }
                  break;
               case file1: //check if file
               case file2:
               case file3:
                  //now check if it ends in .ogg
                  if(checkextension(dir.d_name) == 1)
                  {
                     strcpy(nowplaying, location);
                     strcat(nowplaying, dir.d_name);
                     starttheogg();
                     break;
                  }
                  break;
               default:
                  break; //dont know how to handle this
            }
            break;
         }

      } //end input check loop
      
      morede = 1;

   } //end main loop


   return 0;
} //end main function




This should compile if you have installed the psp toolchain along with the psp ports of libogg libvorbis and libsdl.
Back to top
View user's profile Send private message
kundarmah



Joined: 18 May 2009
Posts: 12

PostPosted: Sun May 24, 2009 9:57 pm    Post subject: Reply with quote

what's the Makefile for this?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
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