/* * Copyright (C) 2011 in-somnia * * This file is part of JAAD. * * JAAD is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * JAAD 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 Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see <http://www.gnu.org/licenses/>. */ package net.sourceforge.jaad.mp4.api; import net.sourceforge.jaad.mp4.MP4InputStream; import net.sourceforge.jaad.mp4.boxes.Box; import net.sourceforge.jaad.mp4.boxes.BoxTypes; import net.sourceforge.jaad.mp4.boxes.impl.SampleDescriptionBox; import net.sourceforge.jaad.mp4.boxes.impl.SoundMediaHeaderBox; import net.sourceforge.jaad.mp4.boxes.impl.sampleentries.AudioSampleEntry; import net.sourceforge.jaad.mp4.boxes.impl.sampleentries.codec.CodecSpecificBox; import net.sourceforge.jaad.mp4.boxes.impl.ESDBox; public class AudioTrack extends Track { public enum AudioCodec implements Codec { AAC, AC3, AMR, AMR_WIDE_BAND, EVRC, EXTENDED_AC3, QCELP, SMV, UNKNOWN_AUDIO_CODEC; static Codec forType(long type) { final Codec ac; if(type==BoxTypes.MP4A_SAMPLE_ENTRY) ac = AAC; else if(type==BoxTypes.AC3_SAMPLE_ENTRY) ac = AC3; else if(type==BoxTypes.AMR_SAMPLE_ENTRY) ac = AMR; else if(type==BoxTypes.AMR_WB_SAMPLE_ENTRY) ac = AMR_WIDE_BAND; else if(type==BoxTypes.EVRC_SAMPLE_ENTRY) ac = EVRC; else if(type==BoxTypes.EAC3_SAMPLE_ENTRY) ac = EXTENDED_AC3; else if(type==BoxTypes.QCELP_SAMPLE_ENTRY) ac = QCELP; else if(type==BoxTypes.SMV_SAMPLE_ENTRY) ac = SMV; else ac = UNKNOWN_AUDIO_CODEC; return ac; } } private final SoundMediaHeaderBox smhd; private final AudioSampleEntry sampleEntry; private Codec codec; public AudioTrack(Box trak, MP4InputStream in) { super(trak, in); final Box mdia = trak.getChild(BoxTypes.MEDIA_BOX); final Box minf = mdia.getChild(BoxTypes.MEDIA_INFORMATION_BOX); smhd = (SoundMediaHeaderBox) minf.getChild(BoxTypes.SOUND_MEDIA_HEADER_BOX); final Box stbl = minf.getChild(BoxTypes.SAMPLE_TABLE_BOX); //sample descriptions: 'mp4a' and 'enca' have an ESDBox, all others have a CodecSpecificBox final SampleDescriptionBox stsd = (SampleDescriptionBox) stbl.getChild(BoxTypes.SAMPLE_DESCRIPTION_BOX); if(stsd.getChildren().get(0) instanceof AudioSampleEntry) { sampleEntry = (AudioSampleEntry) stsd.getChildren().get(0); final long type = sampleEntry.getType(); if(sampleEntry.hasChild(BoxTypes.ESD_BOX)) findDecoderSpecificInfo((ESDBox) sampleEntry.getChild(BoxTypes.ESD_BOX)); else decoderInfo = DecoderInfo.parse((CodecSpecificBox) sampleEntry.getChildren().get(0)); if(type==BoxTypes.ENCRYPTED_AUDIO_SAMPLE_ENTRY||type==BoxTypes.DRMS_SAMPLE_ENTRY) { findDecoderSpecificInfo((ESDBox) sampleEntry.getChild(BoxTypes.ESD_BOX)); protection = Protection.parse(sampleEntry.getChild(BoxTypes.PROTECTION_SCHEME_INFORMATION_BOX)); codec = protection.getOriginalFormat(); } else codec = AudioCodec.forType(sampleEntry.getType()); } else { sampleEntry = null; codec = AudioCodec.UNKNOWN_AUDIO_CODEC; } } @Override public Type getType() { return Type.AUDIO; } @Override public Codec getCodec() { return codec; } /** * The balance is a floating-point number that places mono audio tracks in a * stereo space: 0 is centre (the normal value), full left is -1.0 and full * right is 1.0. * * @return the stereo balance for a this track */ public double getBalance() { return smhd.getBalance(); } /** * Returns the number of channels in this audio track. * @return the number of channels */ public int getChannelCount() { return sampleEntry.getChannelCount(); } /** * Returns the sample rate of this audio track. * @return the sample rate */ public int getSampleRate() { return sampleEntry.getSampleRate(); } /** * Returns the sample size in bits for this track. * @return the sample size */ public int getSampleSize() { return sampleEntry.getSampleSize(); } public double getVolume() { return tkhd.getVolume(); } }