/* You may freely copy, distribute, modify and use this class as long as the original author attribution remains intact. See message below. Copyright (C) 2003 Christian Pesch. All Rights Reserved. */ package slash.metamusic.trm; import slash.metamusic.mp3.MP3File; import slash.metamusic.util.LibraryLoader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.ConnectException; import java.util.logging.Logger; /** * A client that calculates TRM ids. * * @author Christian Pesch * @version $Id: TRM.java 914 2006-12-26 20:44:49Z cpesch $ */ public class TRM { /** * Logging output */ protected static final Logger log = Logger.getLogger(TRM.class.getName()); private static boolean libraryLoaded = false; static { try { LibraryLoader.loadLibrary(TRM.class.getClassLoader(), "trm"); libraryLoaded = true; } catch (IOException e) { log.severe("Cannot load native library 'trm': " + e.getMessage()); } } static class TRMStruct { long duration = 0; // milliseconds of the sample String signature = null; // trm signature } private static final int TRM_OK = 0; private static final int TRM_FILENOTFOUND = -1; private static final int TRM_DECODEERR = -2; private static final int TRM_CANNOTCONNECT = -3; private static final int TRM_OTHERERROR = -4; private static native int generateTRMforMP3(String fileName, long duration, String proxyServer, int proxyPort, TRMStruct result); private static native int generateTRMforWAV(String fileName, long duration, String proxyServer, int proxyPort, TRMStruct result); private static native int generateTRMforOggVorbis(String fileName, long duration, String proxyServer, int proxyPort, TRMStruct result); private TRMStruct trmStruct = new TRMStruct(); private boolean valid = false; /** * Return whether the TRM calculation is supported on this plattform. * * @return true, if the TRM calculation is supported on this plattform */ public static boolean isSupported() { return libraryLoaded; } /** * Returns if the TRM has been calculated successfully. * * @return true if the TRM has been calculated successfully */ public boolean isValid() { return valid; } public long getDuration() { return trmStruct.duration; } public String getSignature() { String signature = trmStruct.signature; if (signature != null && signature.equals("00000000-0000-0000-0000-000000000000")) signature = null; return signature; } public void read(MP3File file) throws FileNotFoundException, ConnectException { if (!file.getFile().exists()) throw new FileNotFoundException(); if (!libraryLoaded) throw new UnsupportedOperationException("Native 'trm' library not loaded"); //noinspection UnusedAssignment int ret = TRM_OK; if (file.isMP3()) ret = generateTRMforMP3(file.getFile().getAbsolutePath(), file.getSeconds() * 1000, "", 0, trmStruct); else if (file.isWAV()) ret = generateTRMforWAV(file.getFile().getAbsolutePath(), file.getSeconds() * 1000, "", 0, trmStruct); else if (file.isOgg()) ret = generateTRMforOggVorbis(file.getFile().getAbsolutePath(), file.getSeconds() * 1000, "", 0, trmStruct); else throw new UnsupportedOperationException("File " + file + " is not supported"); switch (ret) { case TRM_FILENOTFOUND: throw new FileNotFoundException(); case TRM_DECODEERR: throw new Error("Decoder error"); case TRM_CANNOTCONNECT: throw new ConnectException(); case TRM_OTHERERROR: throw new Error("Other error"); } valid = true; } /** * Calculate TRM from given MP3File and return it. If an error * occurs or the file is invalid, null is returned. * * @param file the file to read * @return a signature for the given MP3File or null, if * the file is invalid or an error occured */ public static String readValidSignature(MP3File file) { try { if (TRM.isSupported()) { TRM trm = new TRM(); trm.read(file); if (trm.isValid()) return trm.getSignature(); } } catch (IOException e) { log.severe("Cannot calculate TRM for " + file.getFile().getAbsolutePath() + ": " + e.getMessage()); } return null; } public String toString() { return super.toString() + "[duration=" + getDuration() + ", signature=" + getSignature() + "]"; } public static void main(String[] args) throws IOException { if (args.length == 0) { System.out.println("slash.metamusic.trm.TRM <file1> <file2> ... <fileN>"); System.exit(1); } for (String arg : args) { TRM trm = new TRM(); MP3File mp3 = new MP3File(); File file = new File(arg); if (mp3.read(file)) { trm.read(mp3); System.out.println(trm); } else System.err.println("Cannot read invalid MP3 file: " + file.getAbsolutePath()); } System.exit(0); } }