/*
* PS3 Media Server, for streaming any medias to your PS3.
* Copyright (C) 2008 A.Brochard
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.pms.dlna;
import java.util.Locale;
import net.pms.configuration.FormatConfiguration;
import net.pms.formats.v2.AudioProperties;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class keeps track of the audio properties of media.
*
* TODO: Change all instance variables to private. For backwards compatibility
* with external plugin code the variables have all been marked as deprecated
* instead of changed to private, but this will surely change in the future.
* When everything has been changed to private, the deprecated note can be
* removed.
*/
public class DLNAMediaAudio extends DLNAMediaLang implements Cloneable {
private static final Logger LOGGER = LoggerFactory.getLogger(DLNAMediaAudio.class);
private AudioProperties audioProperties = new AudioProperties();
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public int bitsperSample = 16;
private int bitRate;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String sampleFrequency;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public int nrAudioChannels;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String codecA;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String album;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String artist;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String songname;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String genre;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public int year;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public int track;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public int delay;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String audioTrackTitleFromMetadata;
/**
* @deprecated Use standard getter and setter to access this variable.
*/
@Deprecated
public String muxingModeAudio;
/**
* Returns the sample rate for this audio media.
*
* @return The sample rate.
*/
public int getSampleRate() {
int sr = 0;
if (getSampleFrequency() != null && getSampleFrequency().length() > 0) {
try {
sr = Integer.parseInt(getSampleFrequency());
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse sample rate from \"" + getSampleFrequency() + "\"");
}
}
return sr;
}
/**
* @return True if the audio codec is 3GA.
*/
public boolean is3GA() {
return FormatConfiguration.THREEGA.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is AAC.
*/
public boolean isAAC() {
return isAACLC() || isAACHE();
}
/**
* @return True if the audio codec is AAC LC.
*/
public boolean isAACLC() {
return FormatConfiguration.AAC.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is AAC HE.
*/
public boolean isAACHE() {
return FormatConfiguration.AAC_HE.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is AC-3.
*/
public boolean isAC3() {
return FormatConfiguration.AC3.equalsIgnoreCase(getCodecA()) || getCodecA() != null && getCodecA().contains("a52");
}
/**
* @return True if the audio codec is ADPCM.
*/
public boolean isADPCM() {
return FormatConfiguration.ADPCM.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is AIFF.
*/
public boolean isAIFF() {
return FormatConfiguration.AIFF.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is ALAC.
*/
public boolean isALAC() {
return FormatConfiguration.ALAC.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is Atmos.
*/
public boolean isAtmos() {
return FormatConfiguration.ATMOS.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is ATRAC.
*/
public boolean isATRAC() {
return FormatConfiguration.ATRAC.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is Cook.
*/
public boolean isCook() {
return FormatConfiguration.COOK.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is DSD Audio.
*/
public boolean isDSDAudio() {
return FormatConfiguration.DSDAudio.equalsIgnoreCase(getCodecA()); //TODO: CHANGE
}
/**
* @return True if the audio codec is DTS.
*/
public boolean isDTS() {
return FormatConfiguration.DTS.equalsIgnoreCase(getCodecA()) || getCodecA() != null && getCodecA().contains("dca");
}
/**
* @return True if the audio codec is DTS HD.
*/
public boolean isDTSHD() {
return FormatConfiguration.DTSHD.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is EAC-3.
*/
public boolean isEAC3() {
return FormatConfiguration.EAC3.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is FLAC.
*/
public boolean isFLAC() {
return getCodecA() != null && getCodecA().startsWith("fla");
}
/**
* @return True if the audio codec is HE-AAC.
*/
public boolean isHEAAC() {
return FormatConfiguration.AAC_HE.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is Matroska Audio.
*/
public boolean isMKA() {
return FormatConfiguration.MKA.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is MLP.
*/
public boolean isMLP() {
return FormatConfiguration.MLP.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is MonkeysAudio.
*/
public boolean isMonkeysAudio() {
return FormatConfiguration.MONKEYS_AUDIO.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is MP3.
*/
public boolean isMP3() {
return FormatConfiguration.MP3.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is MPEG-1/MPEG-2.
*/
public boolean isMpegAudio() {
return FormatConfiguration.MP2.equalsIgnoreCase(getCodecA()) || FormatConfiguration.MPA.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is MPC.
*/
public boolean isMPC() {
return FormatConfiguration.MPC.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is OPUS.
*/
public boolean isOpus() {
return FormatConfiguration.OPUS.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is PCM.
*/
public boolean isPCM() {
return FormatConfiguration.LPCM.equals(getCodecA()) || getCodecA() != null && getCodecA().startsWith("pcm");
}
/**
* @return True if the audio codec is QDesign.
*/
public boolean isQDesign() {
return FormatConfiguration.QDESIGN.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is RealAudio Lossless.
*/
public boolean isRALF() {
return FormatConfiguration.REALAUDIO_LOSSLESS.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is Shorten.
*/
public boolean isShorten() {
return FormatConfiguration.SHORTEN.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is Vorbis.
*/
public boolean isVorbis() {
return FormatConfiguration.VORBIS.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is TrueHD.
*/
public boolean isTrueHD() {
return FormatConfiguration.TRUEHD.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is TTA.
*/
public boolean isTTA() {
return FormatConfiguration.TTA.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is Wav.
*/
public boolean isWAV() {
return FormatConfiguration.WAV.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is WavPack.
*/
public boolean isWavPack() {
return FormatConfiguration.WAVPACK.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is WMA.
*/
public boolean isWMA() {
return FormatConfiguration.WMA.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is WMA Lossless.
*/
public boolean isWMALossless() {
return FormatConfiguration.WMALOSSLESS.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is WMA Pro.
*/
public boolean isWMAPro() {
return FormatConfiguration.WMAPRO.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is WMA Voice.
*/
public boolean isWMAVoice() {
return FormatConfiguration.WMAVOICE.equalsIgnoreCase(getCodecA());
}
/**
* @return True if the audio codec is AC-3, DTS, DTS-HD or TrueHD.
*/
public boolean isNonPCMEncodedAudio() {
return isAC3() || isAtmos() || isDTS() || isTrueHD() || isDTSHD();
}
/**
* @return True if the audio codec is lossless.
*/
public boolean isLossless() {
return getCodecA() != null &&
(
isAIFF() || isALAC() || isFLAC() || isMLP() ||
isMonkeysAudio() || isPCM() || isRALF() || isShorten() ||
isTrueHD() || isTTA() || isWAV() || isWavPack() ||
isWMALossless()
);
}
/**
* Returns a standardized name for the audio codec that is used.
*
* @return The standardized name.
*/
public String getAudioCodec() {
if (is3GA()) {
return "3GA";
} else if (isAACLC()) {
return "AAC";
} else if (isAC3()) {
return "AC3";
} else if (isADPCM()) {
return "ADPCM";
} else if (isAIFF()) {
return "AIFF";
} else if (isALAC()) {
return "ALAC";
} else if (isAtmos()) {
return "Atmos";
} else if (isATRAC()) {
return "ATRAC";
} else if (isCook()) {
return "Cook";
} else if (isDSDAudio()) {
return "DSD Audio";
} else if (isDTS()) {
return "DTS";
} else if (isDTSHD()) {
return "DTS HD";
} else if (isEAC3()) {
return "Enhanced AC-3";
} else if (isFLAC()) {
return "FLAC";
} else if (isHEAAC()) {
return "HE-AAC";
} else if (isMKA()) {
return "Matroska Audio";
} else if (isMLP()) {
return "MLP";
} else if (isMonkeysAudio()) {
return "Monkey's Audio";
} else if (isMP3()) {
return "MP3";
} else if (isMpegAudio()) {
return "Mpeg Audio";
} else if (isMPC()) {
return "Musepack";
} else if (isOpus()) {
return "Opus";
} else if (isPCM()) {
return "LPCM";
} else if (isQDesign()) {
return "QDesign";
} else if (isRALF()) {
return "RealAudio Lossless";
} else if (isShorten()) {
return "Shorten";
} else if (isVorbis()) {
return "Vorbis";
} else if (isTrueHD()) {
return "TrueHD";
} else if (isTTA()) {
return "TTA";
} else if (isWAV()) {
return "WAV";
} else if (isWavPack()) {
return "WavPack";
} else if (isWMA()) {
return "WMA";
} else if (isWMALossless()) {
return "WMA Lossless";
} else if (isWMAPro()) {
return "WMA Pro";
} else if (isWMAVoice()) {
return "WMA Voice";
}
return getCodecA() != null ? getCodecA() : "-";
}
/**
* Returns a string containing all identifying audio properties.
*
* @return The properties string.
*/
@Override
public String toString() {
StringBuilder result = new StringBuilder();
if (getLang() != null && !getLang().equals("und")) {
result.append("Id: ").append(getId());
result.append(", Language Code: ").append(getLang());
}
if (isNotBlank(getAudioTrackTitleFromMetadata())) {
if (result.length() > 0) {
result.append(", ");
}
result.append("Audio Track Title From Metadata: ").append(getAudioTrackTitleFromMetadata());
}
if (result.length() > 0) {
result.append(", ");
}
result.append("Audio Codec: ").append(getAudioCodec());
result.append(", Bitrate: ").append(getBitRate());
if (getBitsperSample() != 16) {
result.append(", Bits per Sample: ").append(getBitsperSample());
}
if (getAudioProperties() != null) {
result.append(", ").append(getAudioProperties());
}
if (isNotBlank(getArtist())) {
result.append(", Artist: ").append(getArtist());
}
if (isNotBlank(getAlbum())) {
result.append(", Album: ").append(getAlbum());
}
if (isNotBlank(getSongname())) {
result.append(", Track Name: ").append(getSongname());
}
if (getYear() != 0) {
result.append(", Year: ").append(getYear());
}
if (getTrack() != 0) {
result.append(", Track: ").append(getTrack());
}
if (isNotBlank(getGenre())) {
result.append(", Genre: ").append(getGenre());
}
if (isNotBlank(getMuxingModeAudio())) {
result.append(", Muxing Mode: ").append(getMuxingModeAudio());
}
return result.toString();
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* Returns the number of bits per sample for the audio.
*
* @return The number of bits per sample.
* @since 1.50
*/
public int getBitsperSample() {
return bitsperSample;
}
/**
* Sets the number of bits per sample for the audio.
*
* @param bitsperSample The number of bits per sample to set.
* @since 1.50
*/
public void setBitsperSample(int bitsperSample) {
this.bitsperSample = bitsperSample;
}
/**
* Returns audio bitrate.
*
* @return Audio bitrate.
*/
public int getBitRate() {
return bitRate;
}
/**
* Sets audio bitrate.
*
* @param bitRate Audio bitrate to set.
*/
public void setBitRate(int bitRate) {
this.bitRate = bitRate;
}
/**
* Returns the sample frequency for the audio.
*
* @return The sample frequency.
* @since 1.50
*/
public String getSampleFrequency() {
return sampleFrequency;
}
/**
* Sets the sample frequency for the audio.
*
* @param sampleFrequency The sample frequency to set.
* @since 1.50
*/
public void setSampleFrequency(String sampleFrequency) {
if (isNotBlank(sampleFrequency)) {
this.sampleFrequency = sampleFrequency;
try {
audioProperties.setSampleFrequency(Integer.parseInt(sampleFrequency));
} catch (NumberFormatException e) {
LOGGER.warn("Audio sample frequency \"{}\" cannot be parsed, using (probably wrong) default", sampleFrequency);
}
}
}
/**
* Returns the number of channels for the audio.
*
* @return The number of channels
* @since 1.50
* @deprecated Use getAudioProperties().getNumberOfChannels() instead
*/
@Deprecated
public int getNrAudioChannels() {
return audioProperties.getNumberOfChannels();
}
/**
* Sets the number of channels for the audio.
*
* @param numberOfChannels The number of channels to set.
* @since 1.50
* @deprecated Use getAudioProperties().setNumberOfChannels(int numberOfChannels) instead
*/
@Deprecated
public void setNrAudioChannels(int numberOfChannels) {
this.nrAudioChannels = numberOfChannels;
audioProperties.setNumberOfChannels(numberOfChannels);
}
/**
* Returns the name of the audio codec that is being used.
*
* @return The name of the audio codec.
* @since 1.50
*/
public String getCodecA() {
return codecA;
}
/**
* Sets the name of the audio codec that is being used.
*
* @param codecA The name of the audio codec to set.
* @since 1.50
*/
public void setCodecA(String codecA) {
this.codecA = codecA != null ? codecA.toLowerCase(Locale.ROOT) : null;
}
/**
* Returns the name of the album to which an audio track belongs.
*
* @return The album name.
* @since 1.50
*/
public String getAlbum() {
return album;
}
/**
* Sets the name of the album to which an audio track belongs.
*
* @param album The name of the album to set.
* @since 1.50
*/
public void setAlbum(String album) {
this.album = album;
}
/**
* Returns the name of the artist performing the audio track.
*
* @return The artist name.
* @since 1.50
*/
public String getArtist() {
return artist;
}
/**
* Sets the name of the artist performing the audio track.
*
* @param artist The artist name to set.
* @since 1.50
*/
public void setArtist(String artist) {
this.artist = artist;
}
/**
* Returns the name of the song for the audio track.
*
* @return The song name.
* @since 1.50
*/
public String getSongname() {
return songname;
}
/**
* Sets the name of the song for the audio track.
*
* @param songname The song name to set.
* @since 1.50
*/
public void setSongname(String songname) {
this.songname = songname;
}
/**
* Returns the name of the genre for the audio track.
*
* @return The genre name.
* @since 1.50
*/
public String getGenre() {
return genre;
}
/**
* Sets the name of the genre for the audio track.
*
* @param genre The name of the genre to set.
* @since 1.50
*/
public void setGenre(String genre) {
this.genre = genre;
}
/**
* Returns the year of inception for the audio track.
*
* @return The year.
* @since 1.50
*/
public int getYear() {
return year;
}
/**
* Sets the year of inception for the audio track.
*
* @param year The year to set.
* @since 1.50
*/
public void setYear(int year) {
this.year = year;
}
/**
* Returns the track number within an album for the audio.
*
* @return The track number.
* @since 1.50
*/
public int getTrack() {
return track;
}
/**
* Sets the track number within an album for the audio.
*
* @param track The track number to set.
* @since 1.50
*/
public void setTrack(int track) {
this.track = track;
}
/**
* Returns the delay for the audio.
*
* @return The delay.
* @since 1.50
* @deprecated Use getAudioProperties().getAudioDelay() instead
*/
@Deprecated
public int getDelay() {
return audioProperties.getAudioDelay();
}
/**
* Sets the delay for the audio.
*
* @param audioDelay The delay to set.
* @since 1.50
* @deprecated Use getAudioProperties().setAudioDelay(int audioDelay) instead
*/
@Deprecated
public void setDelay(int audioDelay) {
this.delay = audioDelay;
audioProperties.setAudioDelay(audioDelay);
}
/**
* @deprecated use getAudioTrackTitleFromMetadata()
*/
@Deprecated
public String getFlavor() {
return getAudioTrackTitleFromMetadata();
}
/**
* @deprecated use setAudioTrackTitleFromMetadata()
*/
@Deprecated
public void setFlavor(String value) {
setAudioTrackTitleFromMetadata(value);
}
public String getAudioTrackTitleFromMetadata() {
return audioTrackTitleFromMetadata;
}
public void setAudioTrackTitleFromMetadata(String value) {
this.audioTrackTitleFromMetadata = value;
}
/**
* Returns the audio codec to use for muxing.
*
* @return The audio codec to use.
* @since 1.50
*/
public String getMuxingModeAudio() {
return muxingModeAudio;
}
/**
* Sets the audio codec to use for muxing.
*
* @param muxingModeAudio The audio codec to use.
* @since 1.50
*/
public void setMuxingModeAudio(String muxingModeAudio) {
this.muxingModeAudio = muxingModeAudio;
}
public AudioProperties getAudioProperties() {
return audioProperties;
}
public void setAudioProperties(AudioProperties audioProperties) {
if (audioProperties == null) {
throw new IllegalArgumentException("Can't set null AudioProperties.");
}
this.audioProperties = audioProperties;
}
}