Recognize files that begin with “mod.” as ProTracker modules.
[demoscenemusic.git] / src / main / java / net / pterodactylus / demoscenemusic / utils / AudioCodecs.java
1 /*
2  * DemosceneMusic - AudioCodecFilter.java - Copyright © 2012 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.demoscenemusic.utils;
19
20 import java.util.HashMap;
21 import java.util.Map;
22
23 /**
24  * Helper for audio codec descriptions.
25  *
26  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
27  */
28 public class AudioCodecs {
29
30         /** Descriptions for audio codecs. */
31         public static final Map<String, AudioCodecDescription> codecDescriptions = new HashMap<String, AudioCodecDescription>();
32
33         static {
34                 codecDescriptions.put("mp3", new AudioCodecDescription("mp3", "MPEG 1 Layer 3", "MP3", "audio/mpeg", true, false));
35                 codecDescriptions.put("vorbis", new AudioCodecDescription("vorbis", "Ogg Vorbis", "Vorbis", "audio/vorbis", true, false));
36                 codecDescriptions.put("aac", new AudioCodecDescription("aac", "Advanced Audio Coding", "AAC", "audio/x-aac", true, false));
37                 codecDescriptions.put("flac", new AudioCodecDescription("flac", "Free Lossless Audio Codec", "FLAC", "audio/ogg", true, true));
38                 codecDescriptions.put("wav", new AudioCodecDescription("wav", "Waveform Audio", "WAV", "audio/vnc.wave", true, true));
39                 codecDescriptions.put("mod", new AudioCodecDescription("mod", "ProTracker Module", "MOD", "audio/mod", false, true));
40                 codecDescriptions.put("ft2", new AudioCodecDescription("ft2", "FastTracker II Module", "XM", "audio/xm", false, true));
41                 codecDescriptions.put("it",  new AudioCodecDescription("it", "Impulse Tracker Module", "IT", "audio/it", false, true));
42                 codecDescriptions.put("s3m",  new AudioCodecDescription("s3m", "Scream Tracker 3 Module", "S3M", "audio/s3m", false, true));
43         }
44
45         /**
46          * Tries to automatically detect the audio codec from the filename. In most
47          * cases this will match the {@link AudioCodecDescription#code} of the codec
48          * but in some cases other extensions are possible, too. Also, on Amiga
49          * filenames usually start with the extension (mod files are often named
50          * “mod.somethingsomethingsomethingdarkside”).
51          *
52          * @param filename
53          *            The name of the file
54          * @return The audio codec of the file, or {@code null} if no codec could be
55          *         detected
56          */
57         public static AudioCodecDescription detect(String filename) {
58                 String extension = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
59                 if (codecDescriptions.containsKey(extension)) {
60                         return codecDescriptions.get(extension);
61                 }
62                 if (extension.equals("ogg")) {
63                         return codecDescriptions.get("vorbis");
64                 }
65                 if (extension.equals("mp4")) {
66                         return codecDescriptions.get("aac");
67                 }
68                 if (extension.equals("xm")) {
69                         return codecDescriptions.get("ft2");
70                 }
71                 if (filename.toLowerCase().startsWith("mod.")) {
72                         return codecDescriptions.get("mod");
73                 }
74                 return null;
75         }
76
77         /**
78          * Bundles descriptions for various audio codecs. For simplicity reasons,
79          * file formats such as MOD, IT, or SID are also treated as audio codecs
80          * even though they are not.
81          *
82          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
83          */
84         public final static class AudioCodecDescription {
85
86                 /** The code of this codec. */
87                 public final String code;
88
89                 /** The full name of the codec. */
90                 public final String name;
91
92                 /** The short name of the codec. */
93                 public final String shortName;
94
95                 /** The MIME type. */
96                 public final String mimeType;
97
98                 /** Whether this is a streaming codec. */
99                 public final boolean streaming;
100
101                 /** Whether this codec is lossless. */
102                 public final boolean lossless;
103
104                 /**
105                  * Creates a new audio codec description.
106                  *
107                  * @param code
108                  *            The code of the codec
109                  * @param name
110                  *            The full name of the codec
111                  * @param shortName
112                  *            The short name of the codec
113                  * @param mimeType
114                  *            The MIME type of the audio codec
115                  * @param streaming
116                  *            {@code true} if the codec is a streaming audio codec,
117                  *            {@code false} otherwise
118                  * @param lossless
119                  *            {@code true} if the codec is a lossless audio codec,
120                  *            {@code false} otherwise
121                  */
122                 AudioCodecDescription(String code, String name, String shortName, String mimeType, boolean streaming, boolean lossless) {
123                         this.code = code;
124                         this.name = name;
125                         this.shortName = shortName;
126                         this.mimeType = mimeType;
127                         this.streaming = streaming;
128                         this.lossless = lossless;
129                 }
130
131                 //
132                 // OBJECT METHODS
133                 //
134
135                 /**
136                  * {@inheritDoc}
137                  */
138                 @Override
139                 public String toString() {
140                         return String.format("AudioCodec[%s,%s,%s,%s,%s,%s]", code, name, shortName, mimeType, streaming, lossless);
141                 }
142
143         }
144
145 }