platform ps2, handle audio similar to psp
[picodrive.git] / platform / common / mp3.c
index 9b347e8..2f3846f 100644 (file)
@@ -21,33 +21,6 @@ unsigned short mpeg1_l3_bitrates[16] = {
        0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
 };
 
-int mp3_find_sync_word(const unsigned char *buf, int size)
-{
-       const unsigned char *p, *pe;
-
-       /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
-       for (p = buf, pe = buf + size - 3; p <= pe; p++)
-       {
-               int pn;
-               if (p[0] != 0xff)
-                       continue;
-               pn = p[1];
-               if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
-                   (pn & 6) == 0) {       // invalid layer
-                       p++; continue;
-               }
-               pn = p[2];
-               if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
-                   (pn & 0x0c) != 0) { // not 44kHz
-                       continue;
-               }
-
-               return p - buf;
-       }
-
-       return -1;
-}
-
 static int try_get_bitrate(unsigned char *buf, int buf_size)
 {
        int offs1, offs = 0;
@@ -90,8 +63,9 @@ int mp3_get_bitrate(void *f_, int len)
        if (ret <= 0) {
                // try to read somewhere around the middle
                fseek(f, len / 2, SEEK_SET);
-               fread(buf, 1, sizeof(buf), f);
-               ret = try_get_bitrate(buf, sizeof(buf));
+               ret = fread(buf, 1, sizeof(buf), f);
+               if (ret == sizeof(buf))
+                       ret = try_get_bitrate(buf, sizeof(buf));
        }
        if (ret > 0)
                retval = ret;
@@ -103,7 +77,7 @@ out:
        return retval;
 }
 
-void mp3_start_play(void *f_, int pos)
+void mp3_start_play(void *f_, int pos1024)
 {
        unsigned char buf[2048];
        FILE *f = f_;
@@ -114,16 +88,9 @@ void mp3_start_play(void *f_, int pos)
        cdda_out_pos = 0;
        decoder_active = 0;
 
-       if (!(PicoOpt & POPT_EN_MCD_CDDA) || f == NULL) // cdda disabled or no file?
-               return;
-
-       ret = mp3dec_start();
-       if (ret != 0)
+       if (!(PicoIn.opt & POPT_EN_MCD_CDDA) || f == NULL) // cdda disabled or no file?
                return;
 
-       decoder_active = 1;
-
-       mp3_current_file = f;
        fseek(f, 0, SEEK_END);
        mp3_file_len = ftell(f);
 
@@ -144,19 +111,27 @@ void mp3_start_play(void *f_, int pos)
        }
 
        // seek..
-       if (pos) {
+       if (pos1024 != 0) {
                unsigned long long pos64 = mp3_file_len - mp3_file_pos;
-               pos64 *= pos;
+               pos64 *= pos1024;
                mp3_file_pos += pos64 >> 10;
        }
 
+       ret = mp3dec_start(f, mp3_file_pos);
+       if (ret != 0) {
+               return;
+       }
+
+       mp3_current_file = f;
+       decoder_active = 1;
+
        mp3dec_decode(mp3_current_file, &mp3_file_pos, mp3_file_len);
 }
 
-void mp3_update(int *buffer, int length, int stereo)
+void mp3_update(s32 *buffer, int length, int stereo)
 {
-       int length_mp3, shr = 0;
-       void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;
+       int length_mp3;
+       void (*mix_samples)(s32 *dest_buf, short *mp3_buf, int count, int fac16) = mix_16h_to_32_resample_stereo;
 
        if (mp3_current_file == NULL || mp3_file_pos >= mp3_file_len)
                return; /* no file / EOF */
@@ -164,34 +139,29 @@ void mp3_update(int *buffer, int length, int stereo)
        if (!decoder_active)
                return;
 
-       length_mp3 = length;
-       if (PsndRate <= 11025 + 100) {
-               mix_samples = mix_16h_to_32_s2;
-               length_mp3 <<= 2; shr = 2;
-       }
-       else if (PsndRate <= 22050 + 100) {
-               mix_samples = mix_16h_to_32_s1;
-               length_mp3 <<= 1; shr = 1;
-       }
+       length_mp3 = length * Pico.snd.cdda_mult >> 16;
+       if (!stereo)
+               mix_samples = mix_16h_to_32_resample_mono;
 
        if (1152 - cdda_out_pos >= length_mp3) {
                mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
-                       length * 2);
+                       length, Pico.snd.cdda_mult);
 
                cdda_out_pos += length_mp3;
        } else {
-               int ret, left = 1152 - cdda_out_pos;
+               int left = (1152 - cdda_out_pos) * Pico.snd.cdda_div >> 16;
+               int ret, sm = stereo ? 2 : 1;
 
-               mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
-                       (left >> shr) * 2);
+               if (left > 0)
+                       mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
+                               left, Pico.snd.cdda_mult);
 
                ret = mp3dec_decode(mp3_current_file, &mp3_file_pos,
                        mp3_file_len);
                if (ret == 0) {
-                       cdda_out_pos = length_mp3 - left;
-                       mix_samples(buffer + (left >> shr) * 2,
-                               cdda_out_buffer,
-                               (cdda_out_pos >> shr) * 2);
+                       mix_samples(buffer + left * sm, cdda_out_buffer,
+                               length-left, Pico.snd.cdda_mult);
+                       cdda_out_pos = (length-left) * Pico.snd.cdda_mult >> 16;
                } else
                        cdda_out_pos = 0;
        }