Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/tuneology/avm/InfoReader.java


1   /*
2     InfoReader.java
3     
4     Copyright (C) 2002 Fran Taylor
5   
6     This file is part of java-avm.
7   
8     java-avm is free software; you can redistribute it and/or modify it
9     under the terms of the GNU Lesser General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12  
13    java-avm is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17  
18    You should have received a copy of the GNU Lesser General Public
19    License along with java-avm; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21    USA
22  
23    $Id: InfoReader.java,v 1.6 2002/11/05 08:15:32 xnarf Exp $
24  
25  */
26  
27  package com.tuneology.avm;
28  
29  import java.io.*;
30  import java.util.*;
31  import helliker.id3.*;
32  
33  /** 
34   * This class is used to read and write meta-information 
35   * to media files.
36   *
37   * @version $Id: InfoReader.java,v 1.6 2002/11/05 08:15:32 xnarf Exp $
38   * 
39   * @author Fran Taylor
40   */
41  
42  public class InfoReader {
43      /**
44       * Returns the size that the file will have after it has been
45       * converted according to the specified preferences.
46       * 
47       * @param ent
48       * @param prefs
49       * @return the estimated size in bytes.
50       */
51      public static long calculateSize(TocEntry ent, FormatPrefs prefs) {
52    return (((long) ent.len) * ((long) prefs.bitRate) * 8) / 75;
53      }
54      /**
55       * Returns the size that the album will have after it has been
56       * converted according to the specified preferences.
57       * 
58       * @param info
59       * @param prefs
60       * @return the estimages size in bytes;
61       */
62      public static long calculateSize(DiscInfo info, FormatPrefs prefs) {
63    long retval = 0;
64    for(int i = 0; i < info.tocs.length; i++)
65        retval += calculateSize(info.tocs[i], prefs);
66    return retval;
67      }
68      /** 
69       * Reads header information from the specified file and fills in the supplied TocEntry 
70       * object.
71       */
72      public static void readFileInfo(File f, final TocEntry info) throws Exception {
73    info.fileSize = f.length();
74    switch(AudioConverter.getFileFormat(f)) {
75    case FormatPrefs.MP3_FORMAT:
76              MP3File mp3 = new MP3File(f.getCanonicalPath());
77              info.title = mp3.getTitle().trim();
78              info.album = mp3.getAlbum().trim();
79              info.artist = mp3.getArtist().trim();
80              info.rate = mp3.getBitRate() * 1024;
81              info.len = (int) (mp3.getPlayingTime() * 75);
82              info.genre = mp3.getGenre();
83              info.arranger = mp3.getComposer().trim();
84              info.comment = mp3.getComment().trim();
85              try { 
86                  info.year = Integer.parseInt(mp3.getYear());
87              } 
88              catch (NumberFormatException ex) { }
89        return;
90    case FormatPrefs.OGG_FORMAT:
91              // someday we will use libogg but in the meantime
92              // we can run ogginfo and parse what it prints out
93              Vector cmd = getOggInfoCmd();
94              cmd.add(f.getCanonicalPath());
95              Native.runCommand(cmd, null, new Native.LineReader() {
96                      public boolean processLine(String str, boolean e) throws IOException {
97                          if (str.indexOf("Unable to open") != -1) { throw new IOException(str); }
98                          else if (str.indexOf("Nominal bitrate:") != -1) {
99                              StringTokenizer tok = new StringTokenizer(str, " :.");
100                             tok.nextToken();
101                             tok.nextToken();
102                             String rt = tok.nextToken();
103                             info.rate = Integer.parseInt(rt) * 1024;
104                             return true;
105                         } 
106                         if (!started) {
107                             if (str.indexOf("comments section") != -1) {
108                                 started = true;
109                             }
110                             return true;
111                         }
112       int eq = str.indexOf("=");
113       if (eq != -1) {
114                             String key = str.substring(0, eq).trim();
115                             String val = str.substring(eq + 1);
116                             if (key.equals("title")) { info.title = val; }
117                             else if (key.equals("artist")) { info.artist = val; }
118                             else if (key.equals("album")) { info.album = val; }
119                             else if (key.equals("genre")) { info.genre = val; }
120                             return true;
121                         } else if (str.indexOf("Playback length") != -1) {
122                             eq = str.indexOf(":");
123                             if (eq != -1) {
124                                 String tm = str.substring(eq + 1);
125                                 StringTokenizer tok = new StringTokenizer(tm, ":ms ");
126                                 String m = tok.nextToken();
127                                 String s = tok.nextToken();
128                                 info.len = ((Integer.parseInt(m) * 60) + Integer.parseInt(s)) * 75;
129                             }
130                         }
131                         return true;
132                     }
133                     boolean started = false;
134                 }, false);
135       break;
136   }
137     }
138     /**
139      * Writes changed meta-info to the music file.
140      * Currently only supports MP3.
141      */
142     public static void writeInfo(File f, TocEntry ent) throws Exception {
143   switch(AudioConverter.getFileFormat(f)) {
144   case FormatPrefs.MP3_FORMAT:
145             MP3File mp3 = new MP3File(f.getCanonicalPath());
146             mp3.setTitle(ent.title);
147             mp3.setArtist(ent.artist);
148             mp3.setAlbum(ent.album);
149             mp3.setYear(Integer.toString(ent.year));
150             mp3.setComment(ent.comment);
151             mp3.setGenre(ent.genre);
152             mp3.setComposer(ent.arranger);
153             mp3.writeTags();
154             break;
155         case FormatPrefs.OGG_FORMAT:
156         case FormatPrefs.WMA_FORMAT:
157             break;
158         }
159     }
160     /**
161      *
162      * @return the command for running ogginfo.
163      */
164     static public Vector getOggInfoCmd() { 
165         return Native.parseUserInput(oggInfoCmd);
166     }
167     /**
168      * Sets the path for the ogginfo command.
169      * 
170      * @param cmd the command for running ogginfo.
171      */
172     public static void setOggInfoCmd(String cmd) { oggInfoCmd = cmd; }
173     /**
174      * Returns the list of ID3 genres.
175      * 
176      * @return a string array of ID3 genres.
177      */
178     public static String[] getId3GenreArray() { return genreArray; }
179     private static int parseInt(String str, int defval) {
180         try {
181             return Integer.parseInt(str);
182         } catch (Exception ex) {
183             return defval;
184         }
185     }
186     private static String getGenre(int genre) {
187         if ((genre < 0) || (genre >= genreArray.length)) {
188             return "Unknown";
189         } else {
190             return genreArray[genre];
191         }
192     }
193     private static String getString(byte tag[], int p1, int p2) {
194         int endChar;
195         for(endChar = 0; endChar < p2; endChar++) if (tag[p1 + endChar] == 0) break;
196         return new String(tag,p1,endChar); 
197     }
198     private static void encodeString(byte[] buf, int pos, String str, int len) {
199         byte[] bytes;
200         try {
201             bytes = str.getBytes(encoding);
202         } catch (UnsupportedEncodingException e) {
203             return;
204         }
205         byte[] data = new byte[len];
206         System.arraycopy(bytes, 0, data, 0, Math.min(bytes.length, len));
207         System.arraycopy(data, 0, buf, pos, len);
208     }
209     private static int getInt(byte[] wavbuf, int ind) {
210         int val = ((((int) wavbuf[ind]) & 0xff) | 
211                    ((((int) wavbuf[ind + 1]) & 0xff) << 8) | 
212                    ((((int) wavbuf[ind + 2]) & 0xff) << 16) | 
213                    ((((int) wavbuf[ind + 3]) & 0xff) << 24));
214         return val;
215     }
216     private static int getLen(byte[] wavbuf) { return getInt(wavbuf, 4); }
217     private static int getBytesPerSec(byte[] wavbuf) { return getInt(wavbuf, 28); }
218     /**
219      * This function processes the name/value pairs produced by ogginfo.
220      */
221     private static void processOggInfoKey(TocEntry ent, String key, String val) {
222     }
223     private static String oggInfoCmd;
224     private static final String encoding = "UTF-8";
225     private static final String[] genreArray = {"Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge","Hip-Hop","Jazz","Metal","New Age",
226                                                 "Oldies","Other","Pop","R&B","Rap","Reggae","Rock","Techno","Industrial","Alternative","Ska",
227                                                "Death Metal","Pranks","Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal","Jazz+Funk","Fusion",
228                                                "Trance","Classical","Instrumental","Acid","House","Game","Sound Clip","Gospel","Noise","AlternRock",
229                                                "Bass","Soul","Punk","Space","Meditative","Instrumental Pop","Instrumental Rock","Ethnic","Gothic",
230                                                "Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance","Dream","Southern Rock","Comedy",
231                                                "Cult","Gangsta","Top 40","Christian Rap","Pop/Funk","Jungle","Native American","Cabaret","New Wave",
232                                                "Psychedelic","Rave","Showtunes","Trailer","Lo-Fi","Tribal","Acid Punk","Acid Jazz","Polka","Retro",
233                                                "Musical","Rock & Roll","Hard Rock","Folk","Folk-Rock","National Folk","Swing","Fast Fusion","Bebob",
234                                                "Latin","Revival","Celtic","Bluegrass","Avantgarde","Gothic Rock","Progressive Rock","Psychedelic Rock",
235                                                "Symphonic Rock","Slow Rock","Big Band","Chorus","Easy Listening","Acoustic","Humour","Speech","Chanson",
236                                                "Opera","Chamber Music","Sonata","Symphony","Booty Brass","Primus","Porn Groove","Satire","Slow Jam",
237                                                "Club","Tango","Samba","Folklore","Ballad","Power Ballad","Rhytmic Soul","Freestyle","Duet","Punk Rock",
238                                                "Drum Solo","Acapella","Euro-House","Dance Hall"}; // > 125 Unknown
239     private static int[] brateList = {-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320,-1};
240 }
241 
242 
243 /*
244   Local Variables:
245   mode:java
246   indent-tabs-mode:nil 
247   c-basic-offset:4
248   c-indent-level:4
249   c-continued-statement-offset:4
250   c-brace-offset:-4
251   c-brace-imaginary-offset:-4
252   c-argdecl-indent:0
253   c-label-offset:0
254   End:
255 */