Forum

PSP Engines: Proper MP3 end of file fix

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

PSP Engines: Proper MP3 end of file fix

Postby Baker » Thu Dec 30, 2010 9:34 pm

The Kurok engine has hardware mp3 support.

And it crashes at the end of the music. MDave cheated and made a part in the QuakeC of Kurok that restarted the music 1 second before the end. He had to hardcode this by map name.

I cheated around this problem way back in April, but that was a very ugly cheat. 2 months ago ... I decided to fix it properly and unravel the whole issue and repair it.

The Short Version

Open mp3.cpp and find this function and replace it with mine. I threw some comments in there that gives a basic explanation of what was wrong with EOF situation and what I did to make it work correctly.

Code: Select all
// Baker: called only by decode_thread
static int read_next_frame(int which_buffer)
{
   int i, bytes_read, frame_offset;
   int bitrate, padding, frame_size = 0;

   for (i = 0; i < 32; i++)
   {
      bytes_read = sceIoRead(mp3_handle, mp3_src_buffer[which_buffer], sizeof(mp3_src_buffer[which_buffer]));
      mp3_src_pos += bytes_read;
      if (bytes_read < MIN_INFRAME_SIZE)
      {
         // Baker: end of file hit, restart + re-read
         mp3_src_pos = 0;
         sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
         bytes_read = sceIoRead(mp3_handle, mp3_src_buffer[which_buffer], sizeof(mp3_src_buffer[which_buffer]));
         mp3_src_pos += bytes_read;

      }
      frame_offset = find_sync_word(mp3_src_buffer[which_buffer], bytes_read);
      if (frame_offset < 0) {
         printf("missing syncword, foffs=%i\n", mp3_src_pos - bytes_read);
         mp3_src_pos--;
         sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
         continue;
      }
      if (bytes_read - frame_offset < 4) {
         printf("syncword @ EOB, foffs=%i\n", mp3_src_pos - bytes_read);
         mp3_src_pos--;
         sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
         continue;
      }

      bitrate =  mp3_src_buffer[which_buffer][frame_offset+2] >> 4;
      padding = (mp3_src_buffer[which_buffer][frame_offset+2] & 2) >> 1;

      frame_size = 144000*bitrates[bitrate]/44100 + padding;
      if (frame_size <= 0) {
         printf("bad frame, foffs=%i\n", mp3_src_pos - bytes_read);
         continue; // bad frame
      }

      if (bytes_read - frame_offset < frame_size)
      {
         printf("unfit, foffs=%i\n", mp3_src_pos - bytes_read);
         mp3_src_pos -= bytes_read - frame_offset;
         if (mp3_src_size - mp3_src_pos < frame_size) {
            mp3_src_pos = mp3_src_size;
            return 0; // EOF
         }
         sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
         continue; // didn't fit, re-read..
      }

      if (frame_offset) {
         //printf("unaligned, foffs=%i, offs=%i\n", mp3_src_pos - bytes_read, frame_offset);
         memmove(mp3_src_buffer[which_buffer], mp3_src_buffer[which_buffer] + frame_offset, frame_size);
      }

      // align for next frame read
      mp3_src_pos -= bytes_read - (frame_offset + frame_size);
      sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);

      break;
   }

   return frame_size > 0 ? frame_size : -1;
}


For reference, the old code read like this and maybe that might work if you want to play the music without repeating it over and over, but if you are repeating that is setting an invalid read position so you get a nice crash.

Code: Select all
      if (bytes_read < MIN_INFRAME_SIZE) {
         mp3_src_pos = mp3_src_size;
         return 0; // EOF/IO failure
      }
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Mexicouger » Fri Dec 31, 2010 12:39 am

:D

Finally, Now our precious mods can Play music! Thanks baker!
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm

Postby Jukki » Fri Dec 31, 2010 8:06 am

Nice. Well just added this. Havent tryed. You are the man ;)
Jukki
 
Posts: 214
Joined: Wed Apr 07, 2010 4:59 am


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest