FileDocCategorySizeDatePackage
VorbisIdentificationHeader.javaAPI DocJaudiotagger 2.0.45877Wed Mar 30 16:11:54 BST 2011org.jaudiotagger.audio.ogg.util

VorbisIdentificationHeader.java

/*
 * Entagged Audio Tag library
 * Copyright (c) 2003-2005 Raphaël Slinckx <raphael@slinckx.net>
 * 
 * This library 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 2.1 of the License, or (at your option) any later version.
 *  
 * This library 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.jaudiotagger.audio.ogg.util;

import org.jaudiotagger.audio.generic.Utils;
import org.jaudiotagger.audio.ogg.VorbisVersion;

import java.util.logging.Logger;


/**
 * Vorbis Identification header
 * <p/>
 * From http://xiph.org/vorbis/doc/Vorbis_I_spec.html#id326710
 * <p/>
 * The identification header is a short header of only a few fields used to declare the stream definitively as Vorbis,
 * and provide a few externally relevant pieces of information about the audio stream. The identification header is
 * coded as follows:
 * <p/>
 * 1) [vorbis_version] = read 32 bits as unsigned integer
 * 2) [audio_channels] = read 8 bit integer as unsigned
 * 3) [audio_sample_rate] = read 32 bits as unsigned integer
 * 4) [bitrate_maximum] = read 32 bits as signed integer
 * 5) [bitrate_nominal] = read 32 bits as signed integer
 * 6) [bitrate_minimum] = read 32 bits as signed integer
 * 7) [blocksize_0] = 2 exponent (read 4 bits as unsigned integer)
 * 8) [blocksize_1] = 2 exponent (read 4 bits as unsigned integer)
 * 9) [framing_flag] = read one bit
 * <p/>
 * $Id: VorbisIdentificationHeader.java 813 2009-09-03 09:23:25Z paultaylor $
 *
 * @author Raphael Slinckx (KiKiDonK)
 * @version 16 d�cembre 2003
 */
public class VorbisIdentificationHeader implements VorbisHeader
{
    // Logger Object
    public static Logger logger = Logger.getLogger("org.jaudiotagger.audio.ogg.atom");

    private int audioChannels;
    private boolean isValid = false;

    private int vorbisVersion, audioSampleRate;
    private int bitrateMinimal, bitrateNominal, bitrateMaximal;

    public static final int FIELD_VORBIS_VERSION_POS = 7;
    public static final int FIELD_AUDIO_CHANNELS_POS = 11;
    public static final int FIELD_AUDIO_SAMPLE_RATE_POS = 12;
    public static final int FIELD_BITRATE_MAX_POS = 16;
    public static final int FIELD_BITRATE_NOMAIML_POS = 20;
    public static final int FIELD_BITRATE_MIN_POS = 24;
    public static final int FIELD_BLOCKSIZE_POS = 28;
    public static final int FIELD_FRAMING_FLAG_POS = 29;

    public static final int FIELD_VORBIS_VERSION_LENGTH = 4;
    public static final int FIELD_AUDIO_CHANNELS_LENGTH = 1;
    public static final int FIELD_AUDIO_SAMPLE_RATE_LENGTH = 4;
    public static final int FIELD_BITRATE_MAX_LENGTH = 4;
    public static final int FIELD_BITRATE_NOMAIML_LENGTH = 4;
    public static final int FIELD_BITRATE_MIN_LENGTH = 4;
    public static final int FIELD_BLOCKSIZE_LENGTH = 1;
    public static final int FIELD_FRAMING_FLAG_LENGTH = 1;


    public VorbisIdentificationHeader(byte[] vorbisData)
    {
        decodeHeader(vorbisData);
    }


    public int getChannelNumber()
    {
        return audioChannels;
    }


    public String getEncodingType()
    {
        return VorbisVersion.values()[vorbisVersion].toString();
    }


    public int getSamplingRate()
    {
        return audioSampleRate;
    }

    public int getNominalBitrate()
    {
        return bitrateNominal;
    }

    public int getMaxBitrate()
    {
        return bitrateMaximal;
    }

    public int getMinBitrate()
    {
        return bitrateMinimal;
    }

    public boolean isValid()
    {
        return isValid;
    }


    public void decodeHeader(byte[] b)
    {
        int packetType = b[FIELD_PACKET_TYPE_POS];
        logger.fine("packetType" + packetType);
        String vorbis = Utils.getString(b, VorbisHeader.FIELD_CAPTURE_PATTERN_POS, VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH, "ISO-8859-1");

        if (packetType == VorbisPacketType.IDENTIFICATION_HEADER.getType() && vorbis.equals(CAPTURE_PATTERN))
        {
            this.vorbisVersion = b[7] + (b[8] << 8) + (b[9] << 16) + (b[10] << 24);
            logger.fine("vorbisVersion" + vorbisVersion);
            this.audioChannels = u(b[FIELD_AUDIO_CHANNELS_POS]);
            logger.fine("audioChannels" + audioChannels);
            this.audioSampleRate = u(b[12]) + (u(b[13]) << 8) + (u(b[14]) << 16) + (u(b[15]) << 24);
            logger.fine("audioSampleRate" + audioSampleRate);
            logger.fine("audioSampleRate" + b[12] + " " + b[13] + " " + b[14]);

            //TODO is this right spec says signed
            this.bitrateMinimal = u(b[16]) + (u(b[17]) << 8) + (u(b[18]) << 16) + (u(b[19]) << 24);
            this.bitrateNominal = u(b[20]) + (u(b[21]) << 8) + (u(b[22]) << 16) + (u(b[23]) << 24);
            this.bitrateMaximal = u(b[24]) + (u(b[25]) << 8) + (u(b[26]) << 16) + (u(b[27]) << 24);
            //byte blockSize0 = (byte) ( b[28] & 240 );
            //byte blockSize1 = (byte) ( b[28] & 15 );

            int framingFlag = b[FIELD_FRAMING_FLAG_POS];
            logger.fine("framingFlag" + framingFlag);
            if (framingFlag != 0)
            {
                isValid = true;
            }

        }
    }

    private int u(int i)
    {
        return i & 0xFF;
    }
}