net.sourceforge.javaflacencoder.FrameHeader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-flac-encoder Show documentation
Show all versions of java-flac-encoder Show documentation
javaFlacEncoder is a pure java implementation of a FLAC encoder library. It is designed to allow third-party java applications to enable flac encoding without resorting to use of JNI or scripted file conversions. Additionally, a basic console wav->flac encoding tool is included as part of this package.
Original project can be found here: http://javaflacencoder.sourceforge.net/
The newest version!
/*
* Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
* All Rights Reserved.
*
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.sourceforge.javaflacencoder;
/**
* This class is used to generate a Frame Header for a FLAC Frame.
*
* @author Preston Lacey
*/
public class FrameHeader {
/** For Debugging: Higher level equals more debug statements */
public static int DEBUG_LEV = 0;
private static final int definedBlockSizes[] = {
-1,
192,
576,
1152,
2304,
4608,
-1,
-1,
256,
512,
1024,
2048,
4096,
8192,
16384,
32768
};
private static final int definedSampleRates[] = {
0,
88200,
176400,
192000,
8000,
16000,
22050,
24000,
32000,
44100,
48000,
96000,
-1,
-1,
-1,
-1
};
/** Maximum size a header can be according to FLAC specification. */
public static final int MAX_HEADER_SIZE = 128;//in bytes
/** Synchronization code used at beginning of frame(low-order 14 bits
* used) */
public static final short syncCode = 0x3FFE;//14 bits used
static final byte reserved = 0;//1 bit used; 0 mandatory value
byte blockingStrategy = 0;//1 bit used; 0=fixed-blocksize. 1=variable
byte blockSize = 0xC;//4 bits used; see format docs
byte sampleRate = 4;//0;//4 bits used; see format docs
//byte channelAssignment = 0;//4 bits used; see format docs
byte sampleSize = 4;//3 bits used; see format docs
static final byte reserved2 = 0;//1 bit used; 0 mandatory value
long frameNumber = 0;//8-56 bits used; UTF-8 coded sample number
int blockSizeMod = 0;//if(blocksize bits == 011x) 8/16 bit (blocksize-1)
int SampleRateMod = 0;//if(sample rate bits == 11xx) 8/16 bit sample rate
byte crc8 = 0;
CRC8 crcCalculator;
/**
* Constructor creates a new FrameHeader object which is ready to
* generate headers. We can't use static functions to do this, since the
* process uses a CRC8 object which must be instantiated.
*
*/
public FrameHeader() {
crcCalculator = new CRC8();
}
/**
* Create the header for a frame with the given parameters. Header data is
* stored out to an EncodedElement, in the proper form for a FLAC stream.
*
* @param fixBlock True to use a fixed block size, false to use variable. At
* this time, this *must* be set to True, as variable block size is
* not yet implemented.
* @param blockSize Block Size of this frame.
* @param sampleRate Sample rate of this frame.
* @param channelAssign Channel assignment used in this frame's encoding.
* See EncodingConfiguration class documentation for
* more information.
* @param sampleSize Bits per sample.
* @param frameNumber For fixed block-size encodings, this is the frame-number
* starting at zero and incrementing by one. For variable
* block encodings, this is the sample number of the
* first sample in the frame.
* @param channelCount Number of channels in the stream.
* @return EncodedElement where the header is saved to.
*/
public EncodedElement createHeader(boolean fixBlock, int blockSize,
int sampleRate, EncodingConfiguration.ChannelConfig channelAssign,
int sampleSize, long frameNumber, int channelCount, EncodedElement result) {
if(DEBUG_LEV > 0 )
System.err.println("FrameHeader::createHeader : Begin");
//EncodedElement result = new EncodedElement();
boolean useEndBlockSize = false;
boolean useEndSampleRate = false;
result.clear(MAX_HEADER_SIZE,0);
int blockingStrat = (fixBlock)? 0:1;
byte[] encodedFrameNumber = UTF8Modified.convertToExtendedUTF8(frameNumber);
//set block size bits
byte encodedBlockSize = encodeBlockSize(blockSize);
if(encodedBlockSize == 0x6 || encodedBlockSize == 0x7)
useEndBlockSize = true;
//set sample rate bits
byte encodedSampleRate = encodeSampleRate(sampleRate);
if(encodedSampleRate >= 12 && encodedSampleRate <= 14)
useEndSampleRate = true;
//set channelAssignment bits
int channelAssignment = 0;
if(channelAssign == EncodingConfiguration.ChannelConfig.INDEPENDENT)
channelAssignment = channelCount-1;
else if(channelAssign == EncodingConfiguration.ChannelConfig.LEFT_SIDE)
channelAssignment = 8;
else if(channelAssign == EncodingConfiguration.ChannelConfig.RIGHT_SIDE)
channelAssignment = 9;
else if(channelAssign == EncodingConfiguration.ChannelConfig.MID_SIDE)
channelAssignment = 10;
//set sample size bits
byte encodedSampleSize = 0;
switch(sampleSize) {
case 8: encodedSampleSize = 0x1; break;
case 12: encodedSampleSize = 0x2; break;
case 16: encodedSampleSize = 0x4; break;
case 20: encodedSampleSize = 0x5; break;
case 24: encodedSampleSize = 0x6; break;
default: encodedSampleSize = 0x0;
}
result.addInt(syncCode,14);
result.addInt(reserved, 1);
result.addInt(blockingStrat, 1);
result.addInt(encodedBlockSize, 4);
result.addInt(encodedSampleRate, 4);
result.addInt(channelAssignment, 4);
result.addInt(encodedSampleSize, 3);
result.addInt(reserved2, 1);
for(int i = 0; i < encodedFrameNumber.length; i++) {
result.addInt(encodedFrameNumber[i], 8);
}
//write blockSize if needed(two formats possible)
if(useEndBlockSize) {
if(encodedBlockSize == 0x6) {
result.addInt(blockSize-1, 8);
}
else {
result.addInt(blockSize-1, 16);
}
}
//write sampleRate if needed(three formats possible)
if(useEndSampleRate) {
switch(encodedSampleRate) {
case 0xC:
result.addInt(sampleRate/1000, 8);
break;
case 0xD:
result.addInt(sampleRate, 16);
break;
case 0xE:
result.addInt(sampleRate/10, 16);
break;
}
}
if(DEBUG_LEV > 20 )
System.err.println("FrameHeader::createHeader : pre-CRC");
crcCalculator.reset();
crcCalculator.updateCRC8(result.getData(), 0, result.getTotalBits()/8);
crc8 = crcCalculator.checksum();
if(DEBUG_LEV > 20 )
System.err.println("FrameHeader::createHeader : post-CRC");
result.addInt(crc8, 8);
if(DEBUG_LEV > 0 )
System.err.println("FrameHeader::createHeader : End");
return result;
}
/**
* Given a block size, select the proper bit settings to use according to
* the FLAC stream.
* @param blockSize
* @return
*/
private static byte encodeBlockSize(int blockSize) {
if(DEBUG_LEV > 0 )
System.err.println("FrameHeader::encodeBlockSize : Begin");
byte value = 0;
int i;
for(i = 0; i < definedBlockSizes.length; i++) {
if(blockSize == definedBlockSizes[i]) {
value = (byte)i;
break;
}
}
if(i >= definedBlockSizes.length) {
if(blockSize <= 255)
value = 0x6;
else
value = 0x7;
}
if(DEBUG_LEV > 0 )
System.err.println("FrameHeader::encodeBlockSize : End");
return value;
}
private static byte encodeSampleRate(int sampleRate) {
if(DEBUG_LEV > 0 )
System.err.println("FrameHeader::encodeSampleRate : Begin");
byte value = 0;
int i;
for(i = 0; i < definedSampleRates.length; i++) {
if(sampleRate == definedSampleRates[i]) {
value = (byte)i;
break;
}
}
if(i >= definedSampleRates.length) {
if(sampleRate % 1000 == 0 && sampleRate < 256000)
value = 0xC;
else if(sampleRate < 65536)
value = 0xD;
else if(sampleRate % 10 == 0 && sampleRate <= 655350)
value = 0xE;
else
value = 0x0;
}
if(DEBUG_LEV > 0 )
System.err.println("FrameHeader::encodeSampleRate : End");
return value;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy