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 

has anyone got FLAC code?

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



Joined: 26 Jan 2006
Posts: 110

PostPosted: Sat Oct 20, 2007 7:06 am    Post subject: has anyone got FLAC code? Reply with quote

has anyone here ported over the FLAC library to the psp (and like to share) bcos i noticed that on qj net someone released an app called flacplay but he didn't release any source code with it.
Back to top
View user's profile Send private message
weltall



Joined: 20 Feb 2004
Posts: 310

PostPosted: Sat Oct 20, 2007 7:11 am    Post subject: Re: has anyone got FLAC code? Reply with quote

Viper8896 wrote:
has anyone here ported over the FLAC library to the psp (and like to share) bcos i noticed that on qj net someone released an app called flacplay but he didn't release any source code with it.

flac is bsd so they aren't obliged to release it.
you may have a look at http://sourceforge.net/project/showfiles.php?group_id=13478&package_id=12677
Back to top
View user's profile Send private message Visit poster's website
Viper8896



Joined: 26 Jan 2006
Posts: 110

PostPosted: Sat Oct 20, 2007 7:40 am    Post subject: Reply with quote

no i don't think you read me correctly. i'm aware of flacs license and availability I was looking for already ported code.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat Oct 20, 2007 6:02 pm    Post subject: Reply with quote

You're in luck, FLAC is easy to get on the PSP. First start by making libFLAC.

Code:
1 - Download latest flac source archive from SourceForge.

http://sourceforge.net/project/showfiles.php?group_id=13478&package_id=12677

2 - Unpack archive.

3 - Edit config.sub: look for

   ps2)
      basic_machine=i386-ibm
      ;;


and paste this right after it

   psp)
      basic_machine=mipsallegrexel-psp
      os=-elf
      ;;

4 - Run:

CFLAGS="-ffast-math -fsigned-char -G0" LDFLAGS="-L$(psp-config --pspsdk-path)/lib -lc -lpspuser" ./configure --enable-maintainer-mode --host=psp --prefix=$(psp-config --psp-prefix) --with-ogg=$(psp-config --psp-prefix)
cd src/libFLAC
make
make install
cd ../../include/FLAC
make
make install


You now have libFLAC and the necessary includes in your PSPSDK lib/include directories. Now you just need to use it. I modified my simple ogg player so that it now plays oggs and flacs. Note that flac is not compatible with tremor. You wind up with multiply defined functions. You have to use ogg with flac. Oh well. Here's the code and makefile for my simple ogg player, which now also plays flacs.

makefile
Code:
TARGET = OggPlayer
OBJS = main.o reqfile.o

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

BUILD_PRX = 1
PSP_FW_VERSION = 371

LIBDIR =
#LIBS = -lvorbisidec -lvorbis -logg -lpspaudiolib -lpspaudio -lpsppower
LIBS = -lFLAC -lvorbisfile -lvorbis -logg -lpspaudiolib -lpspaudio -lpsppower -lm
LDFLAGS =

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Simple Ogg Player
PSP_EBOOT_ICON="icon0.png"
#PSP_EBOOT_PIC1="pic1.png"
#PSP_EBOOT_SND0="snd0.at3"

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


main.c
Code:
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdebug.h>
#include <pspaudio.h>
#include <pspaudiolib.h>
#include <psppower.h>
#include <pspdisplay.h>
#include <string.h>
#include <stdio.h>

//#include <tremor/ivorbiscodec.h>
//#include <tremor/ivorbisfile.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>

#include <FLAC/stream_decoder.h>

#define printf pspDebugScreenPrintf

#define VERS    1
#define REVS    0

extern char *RequestFile(char *);

PSP_MODULE_INFO("OggPlayer", 0, VERS, REVS);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
PSP_HEAP_SIZE_MAX();

#define OUTPUT_BUFFER 32768  // must be less than PSP_AUDIO_SAMPLE_MAX*4

/////////////////////////////////////////////////////////////////////////////////////////
//Globals
/////////////////////////////////////////////////////////////////////////////////////////

int runningFlag;
int bufferEmpty;
int bufferFull;

int audioVol = PSP_AUDIO_VOLUME_MAX;

char pcmout1[OUTPUT_BUFFER];
char pcmout2[OUTPUT_BUFFER];
long pcmlen1, pcmlen2;
int bufferFlip = 0;

// Ogg variables

OggVorbis_File OGG_VorbisFile;
int OGG_eos = 0;
int OGG_audio_channel = 0;
int bitStream;
FILE *the_file = 0;

// FLAC variables

FLAC__uint64 total_samples = 0;
unsigned int sample_rate = 0;
unsigned int channels = 0;
unsigned int bps = 0;

/////////////////////////////////////////////////////////////////////////////////////////
//Callbacks
/////////////////////////////////////////////////////////////////////////////////////////

/* 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, PSP_THREAD_ATTR_USER, 0);
   if(thid >= 0) {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}


/////////////////////////////////////////////////////////////////////////////////////////
//FLAC callbacks
/////////////////////////////////////////////////////////////////////////////////////////

FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
//   FILE *f = (FILE*)client_data;
//   const FLAC__uint32 total_size = (FLAC__uint32)(total_samples * channels * (bps/8));
   int i;
   FLAC__int16 *fillbuf;
   SceCtrlData pad;

   (void)decoder, (void)client_data;

   if(channels != 2 || bps != 16)
   {
      printf(" ERROR: this player only supports 16bit stereo streams\n");
      return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   }

   /* copy decoded PCM samples to buffer */
   sceKernelWaitSema(bufferEmpty, 1, 0);

   fillbuf = bufferFlip ? (FLAC__int16 *)pcmout2 : (FLAC__int16 *)pcmout1;
   for (i=0; i<frame->header.blocksize; i++)
   {
      fillbuf[i<<1] = (FLAC__int16)buffer[0][i];
      fillbuf[(i<<1)+1] = (FLAC__int16)buffer[1][i];
   }
   if (bufferFlip)
      pcmlen2 = frame->header.blocksize<<2;
   else
      pcmlen1 = frame->header.blocksize<<2;
   sceKernelSignalSema(bufferFull, 1);

   sceCtrlReadBufferPositive(&pad, 1);
   if(pad.Buttons & PSP_CTRL_CROSS)
      return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;

   if (pad.Buttons & PSP_CTRL_LTRIGGER)
      if (audioVol > 0)
         audioVol -= 0x0800; // 16 steps on the audio

   if (pad.Buttons & PSP_CTRL_RTRIGGER)
      if (audioVol < 0x8000)
         audioVol += 0x0800; // 16 steps on the audio

   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}

void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
   int secs = 0;
   int h = 0;
   int m = 0;
   int s = 0;
   char dest[9];

   (void)decoder, (void)client_data;

   /* print some stats */
   if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
      /* save for later */
      total_samples = metadata->data.stream_info.total_samples;
      sample_rate = metadata->data.stream_info.sample_rate;
      channels = metadata->data.stream_info.channels;
      bps = metadata->data.stream_info.bits_per_sample;

      printf(" sample rate    : %u Hz\n", sample_rate);
      printf(" channels       : %u\n", channels);
      printf(" bits per sample: %u\n", bps);

      secs = total_samples/sample_rate;
      h = secs / 3600;
      m = (secs - h * 3600) / 60;
      s = secs - h * 3600 - m * 60;
      snprintf(dest, sizeof(dest), "%2.2i:%2.2i:%2.2i", h, m, s);
      printf(" length         : %s\n", dest);
   }
}

void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
   (void)decoder, (void)client_data;

   printf(" Error: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
}

/////////////////////////////////////////////////////////////////////////////////////////
//Buffer filling
/////////////////////////////////////////////////////////////////////////////////////////

int fillBuffer(SceSize args, void *argp)
{
   int bytes, bytesRed;
   int fillbuf;

   while(runningFlag){
      sceKernelWaitSema(bufferEmpty, 1, 0);
      if (OGG_eos || !runningFlag)
         break;
      bytesRed = 0;
      fillbuf = bufferFlip ? (int)pcmout2 : (int)pcmout1;
      while (bytesRed < OUTPUT_BUFFER && runningFlag && !OGG_eos)
      {
         //bytes = ov_read(&OGG_VorbisFile,(char *)(fillbuf+bytesRed),OUTPUT_BUFFER-bytesRed,&bitStream);
         bytes = ov_read(&OGG_VorbisFile,(char *)(fillbuf+bytesRed),OUTPUT_BUFFER-bytesRed,0,2,1,&bitStream);
         if (bytes == 0)
         {
            //EOF:
            OGG_eos = 1;
            ov_clear(&OGG_VorbisFile);
         }
         else if (bytes > 0)
         {
            bytesRed += bytes;
         }
      }
      if (bufferFlip)
         pcmlen2 = bytesRed;
      else
         pcmlen1 = bytesRed;
      sceKernelSignalSema(bufferFull, 1);
   }
   sceKernelExitDeleteThread(0);
   return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////
//Audio output
/////////////////////////////////////////////////////////////////////////////////////////

int audioOutput(SceSize args, void *argp)
{
   int playlen;
   char *playbuf;

   while(runningFlag)
   {
      sceKernelWaitSema(bufferFull, 1, 0);
      if (OGG_eos || !runningFlag)
         break;
      playlen = bufferFlip ? pcmlen1 : pcmlen2;
      playbuf = bufferFlip ? pcmout1 : pcmout2;
      bufferFlip ^= 1;
      sceKernelSignalSema(bufferEmpty, 1);
      sceAudioSetChannelDataLen(OGG_audio_channel, playlen/4);
      sceAudioOutputBlocking(OGG_audio_channel, audioVol, playbuf);
   }
   sceKernelExitDeleteThread(0);
   return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////
//Main
/////////////////////////////////////////////////////////////////////////////////////////

int main() {
   char *filename;
   SceCtrlData pad;
   char dest[9];
   long secs;
   int h;
   int m;
   int s;
   int audioThid;
   vorbis_info *vi;
   FLAC__bool ok = true;
   FLAC__StreamDecoder *decoder = 0;
   FLAC__StreamDecoderInitStatus init_status;

   pspDebugScreenInit();
   SetupCallbacks();

   //Creates semaphores:
   bufferEmpty = sceKernelCreateSema("bufferEmpty", 0, 1, 1, 0);
   bufferFull = sceKernelCreateSema("bufferFull", 0, 0, 1, 0);

   pspDebugScreenInit();
   pspDebugScreenSetBackColor(0xA0602000);
   pspDebugScreenSetTextColor(0xffffff00);

   audioVol = 0x4000; // half max volume

mloop:
   filename = RequestFile("ms0:/MUSIC/");

   pspDebugScreenClear();
   pspDebugScreenSetXY(25, 1);
   printf("Simple Ogg Player");
   pspDebugScreenSetXY(25, 3);
   printf("CPU: %i BUS: %i", scePowerGetCpuClockFrequency(), scePowerGetBusClockFrequency());
   pspDebugScreenSetXY(21, 4);
   printf("Press X to stop playback");

   printf("\n\n Playing %s\n\n", filename);
   sceKernelDelayThread(2*1000*1000);

   if ( !strcmp(&filename[strlen(filename)-3], "ogg") )
      goto play_ogg;

// play_flac:
   if((decoder = FLAC__stream_decoder_new()) == NULL)
   {
      printf(" Could not make FLAC decoder. FLAC files cannot be played.\n");
      sceKernelDelayThread(2*1000*1000);
      goto mloop;
   }

   (void)FLAC__stream_decoder_set_md5_checking(decoder, true);

   init_status = FLAC__stream_decoder_init_file(decoder, filename, write_callback, metadata_callback, error_callback, the_file);
   if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
   {
      printf(" ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
      fclose(the_file);
      sceKernelDelayThread(2*1000*1000);
      goto mloop;
   }

   memset(pcmout1, 0, OUTPUT_BUFFER);
   memset(pcmout2, 0, OUTPUT_BUFFER);
   pcmlen1 = 0;
   pcmlen2 = 0;

   OGG_eos = 0;
   runningFlag = 1;
   sceKernelSignalSema(bufferEmpty, 1);
   sceKernelSignalSema(bufferFull, 0);

   //Reserve audio channel:
   OGG_audio_channel = sceAudioChReserve(OGG_audio_channel, OUTPUT_BUFFER/4, PSP_AUDIO_FORMAT_STEREO);

   //Start audio output thread:
   audioThid = sceKernelCreateThread("audioOutput", audioOutput, 0x16, 0x1800, PSP_THREAD_ATTR_USER, NULL);
   if(audioThid < 0)
      sceKernelExitGame();
   sceKernelStartThread(audioThid, 0, NULL);

   ok = FLAC__stream_decoder_process_until_end_of_stream(decoder);
   printf(" decoding: %s\n", ok ? "succeeded" : "FAILED");
   printf("    state: %s\n", FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(decoder)]);

   FLAC__stream_decoder_delete(decoder);
   fclose(the_file);

   runningFlag = 0; // kill the threads
   sceKernelSignalSema(bufferEmpty, 1);
   sceKernelSignalSema(bufferFull, 1);
   sceKernelDelayThread(1*1000*1000);

   //Release channel:
   sceAudioChRelease(OGG_audio_channel);

   sceKernelDelayThread(1*1000*1000);
   goto mloop;

play_ogg:
   //Apro il file OGG:
   the_file = fopen(filename, "r");
   if ((the_file) != NULL)
      ov_open(the_file, &OGG_VorbisFile, NULL, 0);
   else
   {
      printf(" Error opening file\n");
      sceKernelDelayThread(2*1000*1000);
      goto mloop;
   }

   //Stampo le informazioni sul file:
   vi = ov_info(&OGG_VorbisFile, -1);
   printf(" Channels   : %d\n", vi->channels);
   printf(" Sample rate: %ld Hz\n", vi->rate);
   printf(" Bitrate    : %ld kBit\n", vi->bitrate_nominal/1000);

   h = 0;
   m = 0;
   s = 0;
   secs = (long)ov_time_total(&OGG_VorbisFile, -1)/1000;
   h = secs / 3600;
   m = (secs - h * 3600) / 60;
   s = secs - h * 3600 - m * 60;
   snprintf(dest, sizeof(dest), "%2.2i:%2.2i:%2.2i", h, m, s);
   printf(" Length   : %s\n", dest);

   sceKernelDelayThread(2*1000*1000);

   memset(pcmout1, 0, OUTPUT_BUFFER);
   memset(pcmout2, 0, OUTPUT_BUFFER);
   pcmlen1 = 0;
   pcmlen2 = 0;

   OGG_eos = 0;
   runningFlag = 1;
   sceKernelSignalSema(bufferEmpty, 1);
   sceKernelSignalSema(bufferFull, 0);

   //Reserve audio channel:
   OGG_audio_channel = sceAudioChReserve(OGG_audio_channel, OUTPUT_BUFFER/4, PSP_AUDIO_FORMAT_STEREO);

   //Start buffer filling thread:
   int bufferThid = sceKernelCreateThread("bufferFilling", fillBuffer, 0x12, 0x1800, PSP_THREAD_ATTR_USER, NULL);
   if(bufferThid < 0)
      sceKernelExitGame();
   sceKernelStartThread(bufferThid, 0, NULL);

   //Start audio output thread:
   audioThid = sceKernelCreateThread("audioOutput", audioOutput, 0x16, 0x1800, PSP_THREAD_ATTR_USER, NULL);
   if(audioThid < 0)
      sceKernelExitGame();
   sceKernelStartThread(audioThid, 0, NULL);

   while(runningFlag && !OGG_eos)
   {
      //Print timestring:
      secs = (long) ov_time_tell(&OGG_VorbisFile)/1000;
      h = secs / 3600;
      m = (secs - h * 3600) / 60;
      s = secs - h * 3600 - m * 60;
      snprintf(dest, sizeof(dest), "%2.2i:%2.2i:%2.2i", h, m, s);
      pspDebugScreenSetXY(1, 16);
      printf("Current    : %s\n", dest);

      sceCtrlReadBufferPositive(&pad, 1);
      if(pad.Buttons & PSP_CTRL_CROSS)
         break; // stop playback

      if (pad.Buttons & PSP_CTRL_LTRIGGER)
         if (audioVol > 0)
            audioVol -= 0x0800; // 16 steps on the audio

      if (pad.Buttons & PSP_CTRL_RTRIGGER)
         if (audioVol < 0x8000)
            audioVol += 0x0800; // 16 steps on the audio

      sceKernelDelayThread(100*1000);
   }

   if (OGG_eos == 1)
      printf("\n\n End of file\n");
   else
      printf("\n\n Playback stopped\n");

   runningFlag = 0; // kill the threads
   sceKernelSignalSema(bufferEmpty, 1);
   sceKernelSignalSema(bufferFull, 1);
   sceKernelDelayThread(1*1000*1000);

   //Release channel:
   sceAudioChRelease(OGG_audio_channel);

   goto mloop;

   return 0; // never reaches here - just supresses compiler warning
}


reqfile.c
Code:
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdebug.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>


#define printf pspDebugScreenPrintf


#define MAXFILES 1000
#define PAGESIZE 32


static struct fileentries {
   char filename[FILENAME_MAX];
   char path[FILENAME_MAX];
   int flags;
} cdfiles[MAXFILES];

static int maxfiles;


/****************************************************************************
 * get_buttons
 *
 ****************************************************************************/

static unsigned int get_buttons()
{
   SceCtrlData pad;

   sceCtrlReadBufferPositive(&pad, 1);
   return pad.Buttons;
}

/****************************************************************************
 * ParseDirectory
 *
 * Parse the directory, returning the number of files found
 ****************************************************************************/

int parse_dir (char *path)
{
   DIR *dir;
   DIR *test_dir;
   struct dirent *dirent = 0;
   struct stat fstat;
   char file_name[FILENAME_MAX];
   FILE *file;

   maxfiles = 0;
   /* open directory */
   if ( ( dir = opendir( path ) ) == 0 )
      return 0;

   while ( ( dirent = readdir( dir ) ) != 0 )
   {
      if ( dirent->d_name[0] == '.' ) continue;
      /* get stats */
      sprintf( file_name, "%s/%s", path, dirent->d_name );
      if ( stat( file_name, &fstat ) == -1 ) continue;
      /* check directory */
      if ( S_ISDIR( fstat.st_mode ) )
      {
         if ( ( test_dir = opendir( file_name ) ) == 0  ) continue;
         closedir( test_dir );
         memset (&cdfiles[maxfiles], 0, sizeof (struct fileentries));
         strncpy(cdfiles[maxfiles].path, path, FILENAME_MAX);
         cdfiles[maxfiles].path[FILENAME_MAX-1] = 0;
         strncpy(cdfiles[maxfiles].filename, dirent->d_name, FILENAME_MAX);
         cdfiles[maxfiles].filename[FILENAME_MAX-1] = 0;
         cdfiles[maxfiles].flags = 1;
         maxfiles++;
      }
      else
      /* check regular file */
      if ( S_ISREG( fstat.st_mode ) )
      {
         /* test it */
         if ( ( file = fopen( file_name, "r" ) ) == 0 ) continue;
         fclose( file );
         memset (&cdfiles[maxfiles], 0, sizeof (struct fileentries));
         strncpy(cdfiles[maxfiles].path, path, FILENAME_MAX);
         cdfiles[maxfiles].path[FILENAME_MAX-1] = 0;
         strncpy(cdfiles[maxfiles].filename, dirent->d_name, FILENAME_MAX);
         cdfiles[maxfiles].filename[FILENAME_MAX-1] = 0;
         maxfiles++;
      }

      if (maxfiles == MAXFILES)
         break;
   }
   /* close dir */
   closedir( dir );

   return maxfiles;
}

/****************************************************************************
 * ShowFiles
 *
 * Support function for FileSelector
 ****************************************************************************/

void ShowFiles( int offset, int selection )
{
   int i,j;
   char text[69];

   pspDebugScreenClear();

   j = 0;
   for ( i = offset; i < ( offset + PAGESIZE ) && i < maxfiles ; i++ )
   {
      if ( cdfiles[i].flags )
      {
         strcpy(text,"[");
         strncat(text, cdfiles[i].filename,66);
         strcat(text,"]");
      }
      else
         strncpy(text, cdfiles[i].filename, 68);

      text[68]=0;

      pspDebugScreenSetTextColor(j == ( selection - offset ) ? 0xbbbbbb00 : 0xffffff00);
      pspDebugScreenSetXY((68 - strlen(text)) / 2, i - offset + 1);
      printf("%s", text);

      j++;
   }
   pspDebugScreenSetTextColor(0xffffff00);
}

/****************************************************************************
 * FileSelector
 *
 * Press X to select, O to cancel, and Triangle to go back a level
 ****************************************************************************/

int FileSelector()
{
   int offset = 0;
   int selection = 0;
   int havefile = 0;
   int redraw = 1;
   unsigned int p = get_buttons();

   while ( havefile == 0 && !(p & PSP_CTRL_CIRCLE) )
   {
      if ( redraw )
         ShowFiles( offset, selection );
      redraw = 0;

      while (!(p = get_buttons()))
         sceKernelDelayThread(10000);
      while (p == get_buttons())
         sceKernelDelayThread(10000);

      if ( p & PSP_CTRL_DOWN )
      {
         selection++;
         if ( selection == maxfiles )
            selection = offset = 0;   // wrap around to top

         if ( ( selection - offset ) == PAGESIZE )
            offset += PAGESIZE; // next "page" of entries

         redraw = 1;
      }

      if ( p & PSP_CTRL_UP )
      {
         selection--;
         if ( selection < 0 )
         {
            selection = maxfiles - 1;
            offset = maxfiles > PAGESIZE ? selection - PAGESIZE + 1 : 0; // wrap around to bottom
         }

         if ( selection < offset )
         {
            offset -= PAGESIZE; // previous "page" of entries
            if ( offset < 0 )
               offset = 0;
         }

         redraw = 1;
      }

      if ( p & PSP_CTRL_RIGHT )
      {
         selection += PAGESIZE;
         if ( selection >= maxfiles )
            selection = offset = 0;   // wrap around to top

         if ( ( selection - offset ) >= PAGESIZE )
            offset += PAGESIZE; // next "page" of entries

         redraw = 1;
      }

      if ( p & PSP_CTRL_LEFT )
      {
         selection -= PAGESIZE;
         if ( selection < 0 )
         {
            selection = maxfiles - 1;
            offset = maxfiles > PAGESIZE ? selection - PAGESIZE + 1 : 0; // wrap around to bottom
         }

         if ( selection < offset )
         {
            offset -= PAGESIZE; // previous "page" of entries
            if ( offset < 0 )
               offset = 0;
         }

         redraw = 1;
      }

      if ( p & PSP_CTRL_CROSS )
      {
         if ( cdfiles[selection].flags )   /*** This is directory ***/
         {
            char fname[FILENAME_MAX+FILENAME_MAX];

            strncpy(fname, cdfiles[selection].path, FILENAME_MAX);
            fname[FILENAME_MAX-1] = 0;
            strncat(fname, cdfiles[selection].filename, FILENAME_MAX);
            fname[FILENAME_MAX+FILENAME_MAX-2] = 0;
            strcat(fname, "/");
            offset = selection = 0;
            parse_dir(fname);
         }
         else
            return selection;

         redraw = 1;
      }

      if ( p & PSP_CTRL_TRIANGLE )
      {
         char fname[FILENAME_MAX];
         int pathpos = strlen(cdfiles[1].path) - 2;

         while (pathpos > 5)
         {
            if (cdfiles[1].path[pathpos] == '/') break;
            pathpos--;
         }
         if (pathpos < 5) pathpos = 5; /** handle root case */
         strncpy(fname, cdfiles[1].path, pathpos+1);
         fname[pathpos+1] = 0;
         offset = selection = 0;
         parse_dir(fname);

         redraw = 1;
      }
   }

   return -1; // no file selected
}

/****************************************************************************
 * RequestFile
 *
 * return pointer to filename selected
 ****************************************************************************/

char *RequestFile (char *initialPath)
{
   int selection;
   static char fname[FILENAME_MAX+FILENAME_MAX];

   if (!parse_dir(initialPath))
      return 0;

   selection = FileSelector ();
   if (selection < 0)
      return 0;

   strncpy (fname, cdfiles[selection].path, FILENAME_MAX);
   fname[FILENAME_MAX-1] = 0;
   strncat (fname, cdfiles[selection].filename, FILENAME_MAX);
   fname[FILENAME_MAX+FILENAME_MAX-1] = 0;

   return fname;
}


And there you have it. FLAC on the PSP.
Back to top
View user's profile Send private message AIM Address
Viper8896



Joined: 26 Jan 2006
Posts: 110

PostPosted: Sun Oct 21, 2007 7:03 am    Post subject: Reply with quote

thanks jf i didn't realize it would be so simple. i think flac and theora libraries should be added to the ps2dev.org svn.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sun Oct 21, 2007 7:58 am    Post subject: Reply with quote

Viper8896 wrote:
thanks jf i didn't realize it would be so simple.


Me neither. I just took a quick look at it, tried a few things, then realized all we need was just libFLAC. Turned out to be disgustingly simple.

Quote:
i think flac and theora libraries should be added to the ps2dev.org svn.


Well, FLAC for certain. I don't know how well the PSP will do with Theora. You'd really need to put a lot of work into PSP optimizations. Couple that with the fact that virtually no one uses Theora and you see it's probably not worth the effort.
Back to top
View user's profile Send private message AIM Address
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Mon Nov 26, 2007 12:58 pm    Post subject: Reply with quote

Note: you can use libFLAC with tremor if you disable the ogg support. You won't be able to play Ogg-FLAC streams, but native FLAC works fine. That's really all you need for a FLAC player. Just follow the instructions above, but use this for configuring:

Code:
CFLAGS="-ffast-math -fsigned-char -G0" LDFLAGS="-L$(psp-config --pspsdk-path)/lib -lc -lpspuser" ./configure --enable-maintainer-mode --host=psp --prefix=$(psp-config --psp-prefix) --disable-ogg
Back to top
View user's profile Send private message AIM Address
kundarmah



Joined: 18 May 2009
Posts: 12

PostPosted: Sat May 23, 2009 5:02 pm    Post subject: Reply with quote

Why is that when I'm installing flac and made the config.sub edit correctly there's an error coming out?

Code:
$ CFLAGS="-ffast-math -fsigned-char -G0" LDFLAGS="-L$(psp-config --pspsdk-path)
/lib -lc -lpspuser" ./configure --enable-maintainer-mode --host=psp --prefix=$(
psp-config --psp-prefix) --with-ogg=$(psp-config --psp-prefix)
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for psp-strip... psp-strip
checking whether to enable maintainer-specific portions of Makefiles... yes
configure: error: cannot run /bin/sh ./config.sub
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat May 23, 2009 5:18 pm    Post subject: Reply with quote

Looks like when you edited config.sub, you screwed something up. Better double check it.
Back to top
View user's profile Send private message AIM Address
kundarmah



Joined: 18 May 2009
Posts: 12

PostPosted: Sat May 23, 2009 5:26 pm    Post subject: Reply with quote

J.F. wrote:
Looks like when you edited config.sub, you screwed something up. Better double check it.


[code]3 - Edit config.sub: look for

edit:

already installed it TNX.
Back to top
View user's profile Send private message
kundarmah



Joined: 18 May 2009
Posts: 12

PostPosted: Sun May 24, 2009 3:00 am    Post subject: Reply with quote

TNX it can play flac files but why cant it play OGG files? Does this support OGG files?
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sun May 24, 2009 6:49 am    Post subject: Reply with quote

kundarmah wrote:
TNX it can play flac files but why cant it play OGG files? Does this support OGG files?


If you compile libFLAC with ogg support, you can use libvorbisdec to play ogg files. If you want to use libvorbisidec (tremor) to play ogg, you cannot compile libFLAC with ogg support as the way tremor and flac use the ogg code conflicts.

If you compile flac without ogg support, it just means that flac streams cannot be in ogg containers, but I've never seen flac in ogg containers anyway.
Back to top
View user's profile Send private message AIM Address
kundarmah



Joined: 18 May 2009
Posts: 12

PostPosted: Sun May 24, 2009 6:52 am    Post subject: Reply with quote

J.F. wrote:
kundarmah wrote:
TNX it can play flac files but why cant it play OGG files? Does this support OGG files?


If you compile libFLAC with ogg support, you can use libvorbisdec to play ogg files. If you want to use libvorbisidec (tremor) to play ogg, you cannot compile libFLAC with ogg support as the way tremor and flac use the ogg code conflicts.

If you compile flac without ogg support, it just means that flac streams cannot be in ogg containers, but I've never seen flac in ogg containers anyway.


Thanks man! I got it working.
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