2 * Sonitus - Metainfo.java - Copyright © 2013 David Roden
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.
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.
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/>.
18 package net.pterodactylus.sonitus.data;
20 import com.google.common.base.Optional;
23 * Metadata contains information about a source, e.g. the number of channels,
24 * the frequency, the encoding, the name of the content, the artist performing
25 * it, dates, comments, URLs, etc.
27 * Metadata, once created, is immutable.
29 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
31 public class Metadata {
33 /** Constant for an unknown number of channels. */
34 public static final int UNKNOWN_CHANNELS = -1;
36 /** Constant for an unknown frequency. */
37 public static final int UNKNOWN_FREQUENCY = -1;
39 /** Constant for an unknown metadata. */
40 public static final String UNKNOWN_ENCODING = "UNKNOWN";
42 /** The number of channels of this metadata. */
43 private final int channels;
45 /** The sampling frequency of this metadata. */
46 private final int frequency;
48 /** The encoding of this metadata. */
49 private final String encoding;
51 /** The artist performing the content. */
52 private final Optional<String> artist;
54 /** The name of the content. */
55 private final Optional<String> name;
57 /** Creates empty metadata. */
58 public Metadata(int channels, int frequency, String encoding) {
59 this(channels, frequency, encoding, null, null);
63 * Creates metadata with the given attributes.
66 * The artist performing the content (may be {@code null})
68 * The name of the content (may be {@code null})
70 private Metadata(int channels, int frequency, String encoding, String artist, String name) {
71 this.channels = channels;
72 this.frequency = frequency;
73 this.encoding = encoding;
74 this.artist = Optional.fromNullable(artist);
75 this.name = Optional.fromNullable(name);
83 * Returns the number of channels of this metadata.
85 * @return The number of channels of this metadata
87 public int channels() {
92 * Returns a metadata with the same parameters as this metadata and the given
96 * The new number of channels
97 * @return A new metadata with the given number of channels
99 public Metadata channels(int channels) {
100 return new Metadata(channels, frequency, encoding, artist.orNull(), name.orNull());
104 * Returns the sampling frequency of this metadata.
106 * @return The sampling frequency of this metadata
108 public int frequency() {
113 * Returns a new metadata with the same parameters as this metadata and the
118 * @return A new metadata with the given frequency
120 public Metadata frequency(int frequency) {
121 return new Metadata(channels, frequency, encoding, artist.orNull(), name.orNull());
125 * Returns the encoding of this metadata
127 * @return The encoding of this metadata
129 public String encoding() {
134 * Returns a new metadata with the same parameters as this metadata and the
139 * @return A new metadata with the given encoding
141 public Metadata encoding(String encoding) {
142 return new Metadata(channels, frequency, encoding, artist.orNull(), name.orNull());
146 * Returns the artist, if any.
148 * @return The artist, or {@link Optional#absent()}
150 public Optional<String> artist() {
155 * Returns new metadata with the same attributes as this metadata, except for
160 * @return New metadata with a changed artist
162 public Metadata artist(String artist) {
163 return new Metadata(channels, frequency, encoding, artist, name.orNull());
167 * Returns the name of the content, if any.
169 * @return The name, or {@link Optional#absent()}
171 public Optional<String> name() {
176 * Returns new metadata with the same attributes as this metadata, except for
181 * @return New metadata with a changed name
183 public Metadata name(String name) {
184 return new Metadata(channels, frequency, encoding, artist.orNull(), name);
192 public int hashCode() {
193 int hashCode = (channels << 16) ^ frequency ^ encoding.toUpperCase().hashCode();
194 if (artist.isPresent()) {
195 hashCode ^= artist.get().hashCode();
197 if (name.isPresent()) {
198 hashCode ^= name.get().hashCode();
204 public boolean equals(Object object) {
205 if ((object == null) || (getClass() != object.getClass())) {
208 Metadata metadata = (Metadata) object;
209 if ((metadata.channels != channels) || (metadata.frequency != frequency) || !metadata.encoding.equalsIgnoreCase(encoding())) {
212 if (artist.equals(metadata.artist)) {
215 if (name.equals(metadata.name)) {
222 public String toString() {
223 StringBuilder string = new StringBuilder();
224 string.append(String.format("%d Channel%s, %d Hz, %s:", channels, channels != 1 ? "s" : "", frequency, encoding));
225 if (artist.isPresent()) {
226 string.append(" Artist(").append(artist.get()).append(")");
228 if (name.isPresent()) {
229 string.append(" Name(").append(name.get()).append(")");
231 return string.toString();