--- /home/kikidonk/Devel/entagged/audioformats/mp3/util/Mp3InfoReader.java 2005-09-01 14:20:09.000000000 +0200 +++ Mp3InfoReader.java 2005-12-02 00:36:09.000000000 +0100 @@ -55,15 +55,23 @@ byte[] b = new byte[4]; raf.read(b); - + // BEGIN CHANGE - BHL + if (!( (b[0]&0xFF)==0xFF && (b[1]&0xE0)==0xE0 && (b[1]&0x06)!=0 && (b[2]&0xF0)!=0xF0 && (b[2]&0x0C)!=0x0C )) + { // search for sync mark, but also for a right bitrate, samplerate and layer(that way you can // read corrupted but playable files) + b = findSync(raf, b); + } + // REMOVE OLD CODE + /* while ( !( (b[0]&0xFF)==0xFF && (b[1]&0xE0)==0xE0 && (b[1]&0x06)!=0 && (b[2]&0xF0)!=0xF0 && (b[2]&0x0C)!=0x0C ) && raf.getFilePointer() < raf.length()-4) { //System.err.println(sync[0]+"|"+(sync[1]&0xE0)+"|"+((sync[1]&0xE0)==0xE0)); raf.seek( raf.getFilePointer() - 3); //raf.read(sync); raf.read(b); } + */ + // END CHANGE //raf.seek( raf.getFilePointer() - 2 ); //System.err.println(raf.getFilePointer()); @@ -188,5 +196,64 @@ return value; } + + // BEGIN CHANGE - BHL + // Optimized findSync routine. + // Reads data from disk in chunks + // Can reduce the time to process from 120 seconds to 2/10th of a second. + private byte[] findSync(RandomAccessFile raf, byte b[]) throws IOException + { + final int kBuffSize = 1024; + byte[] buf = new byte[kBuffSize]; + long pos = raf.getFilePointer(); + + long fileLen = raf.length(); + long remain = fileLen; + + // Copy first 4 bytes from initial read. + for (int x=0;x<4;x++) + buf[x] = b[x]; + + while (remain > 4) + { + int read = (remain > kBuffSize-4) ? kBuffSize-4 : (int) remain; + raf.read(buf, 4, read); + + for (int x = 0; x < read - 4; x++) + { + if ((buf[x] & 0xFF) == 0xFF && (buf[x + 1] & 0xE0) == 0xE0 + && (buf[x + 1] & 0x06) != 0 + && (buf[x + 2] & 0xF0) != 0xF0 + && (buf[x + 2] & 0x0C) != 0x0C) + { + + // for debugging purposes, you can uncomment these lines... + // to verify that the file position is correct. + // raf.seek(pos + x - 4); // we subtract 4, since the first 4 bytes were already read. + // raf.read(b); + + // copy sync bytes into the result + for (int i = 0; i < 4; i++) + b[i] = buf[x + i]; + // set file position to just after the sync bytes + raf.seek(pos + x); + + return b; + } + + } + + // Copy last 4 bytes that we didn't check into beginning of buffer. + for (int x=0;x<4;x++) + buf[x] = buf[kBuffSize-5+x]; + + pos += read; + remain -= read; + } + return null; + } + // END CHANGE - BHL + + }