View Javadoc

1   /*
2    * Entagged Audio Tag library
3    * Copyright (c) 2003-2005 Raphaël Slinckx <raphael@slinckx.net>
4    * 
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *  
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   * 
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18   */
19  package entagged.audioformats.mpc.util;
20  
21  import entagged.audioformats.EncodingInfo;
22  import entagged.audioformats.exceptions.*;
23  
24  import java.io.*;
25  
26  public class MpcInfoReader {
27  
28  	public EncodingInfo read( RandomAccessFile raf ) throws CannotReadException, IOException {
29  		EncodingInfo info = new EncodingInfo();
30  		
31  		//Begin info fetch-------------------------------------------
32  		if ( raf.length()==0 ) {
33  			//Empty File
34  			System.err.println("Error: File empty");
35  		
36  			throw new CannotReadException("File is empty");
37  		}
38  		raf.seek( 0 );
39  	
40  		
41  		//MP+ Header string
42  		byte[] b = new byte[3];
43  		raf.read(b);
44  		String mpc = new String(b);
45  		if (!mpc.equals("MP+") && mpc.equals("ID3")) {
46  			//TODO Do we have to do this ??
47  			//we have an ID3v2 tag at the beginning
48  			//We quickly jump to MPC data
49  			raf.seek(6);
50  			int tagSize = read_syncsafe_integer(raf);
51  			raf.seek(tagSize+10);
52  			
53  			//retry to read MPC stream
54  			b = new byte[3];
55  			raf.read(b);
56  			mpc = new String(b);
57  			if (!mpc.equals("MP+")) {
58  				//We could definitely not go there
59  				throw new CannotReadException("MP+ Header not found");
60  			}
61  		} else if (!mpc.equals("MP+")){
62  			throw new CannotReadException("MP+ Header not found");
63  		}
64  		
65  		b = new byte[25];
66  		raf.read(b);
67  		MpcHeader mpcH = new MpcHeader(b);
68  		//We only support v7 Stream format, so if it isn't v7, then returned values
69  		//will be bogus, and the file will be ignored
70  		
71  		double pcm = mpcH.getSamplesNumber();
72  //		info.setLength( (int) ( pcm * 1152 / mpcH.getSamplingRate() ) );
73  		info.setPreciseLength( (float) ( pcm * 1152 / mpcH.getSamplingRate() ) );
74  		info.setChannelNumber( mpcH.getChannelNumber() );
75  		info.setSamplingRate( mpcH.getSamplingRate() );
76  		info.setEncodingType( mpcH.getEncodingType() );
77  		info.setExtraEncodingInfos( mpcH.getEncoderInfo() );
78  		info.setBitrate( computeBitrate( info.getLength(), raf.length() ) );
79  
80  		return info;
81  	}
82  	
83  	private int read_syncsafe_integer(RandomAccessFile raf)	throws IOException {
84  		int value = 0;
85  
86  		value += (raf.read()& 0xFF) << 21;
87  		value += (raf.read()& 0xFF) << 14;
88  		value += (raf.read()& 0xFF) << 7;
89  		value += raf.read() & 0xFF;
90  
91  		return value;
92  	}
93  
94  	private int computeBitrate( int length, long size ) {
95  		return (int) ( ( size / 1000 ) * 8 / length );
96  	}
97  }
98