/*
* @(#)MpaConverter.java - converter M1L2,48khz lossless
*
* Copyright (c) 2002-2006 by dvb.matt, All rights reserved.
*
* This file is part of ProjectX, a free Java based demux utility.
* By the authors, ProjectX is intended for educational purposes only,
* as a non-commercial test project.
*
* The part of audio parsing was derived from the MPEG/Audio
* Software Simulation Group's audio codec in a special modified manner.
*
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* rewritten Oct 2003 by dvb.matt
*/
package net.sourceforge.dvb.projectx.audio;
import java.util.Arrays;
import net.sourceforge.dvb.projectx.audio.AudioFormat;
import net.sourceforge.dvb.projectx.common.Common;
import net.sourceforge.dvb.projectx.common.Resource;
import net.sourceforge.dvb.projectx.parser.CommonParsing;
public class MpaConverter extends Object {
//mpeg-1 27 subbands
private final short alloc27[][] = {
{ 0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17 },
{ 0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17 },
{ 0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,3,4,5,6,17 },
{ 0,1,2,17 },
{ 0,1,2,17 },
{ 0,1,2,17 },
{ 0,1,2,17 }
};
private final short bal27mp1[] = { 4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2 };
private final short getbits[] = { 0,5,7,3,10,4,5,6,7,8,9,10,11,12,13,14,15,16 };
private final short grouping[] = { 0,3,5,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0 };
private final int MPA_48M1L2[] = { 0,768,1152,1344,1536,1920,2304,2688,3072,3840,4608,5376,6144,7680,9216,16384 };
private final int STEREO = 0;
private final int JSTEREO = 1;
private final int DUAL = 2;
private final int SINGLE = 3;
public static final int SINGLE_TO_3DSTEREO= 1;
public static final int SINGLE_TO_STEREO = 2;
public static final int SINGLE_TO_JSTEREO = 3;
public static final int SPLIT_INTO_SINGLE = 4;
public static final int SPLIT_INTO_SINGLE_DOUBLED = 5;
public static final int SPLIT_DUAL_INTO_SINGLE_DOUBLED = 6;
private boolean[] framebuffer;
private int maxBitSize = 0;
private short[] Bal = new short[0];
private short[][] Allocation;
private int[] Sizes;
private int[] BRindex = new int[3];
private int Restart = 0;
private int error_flag = 0;
private AudioFormat Audio;
//init
public MpaConverter()
{
Audio = new AudioFormat(CommonParsing.MPEG_AUDIO);
Sizes = MPA_48M1L2;
Arrays.sort(Sizes);
maxBitSize = Sizes[14];
Bal = bal27mp1;
Allocation = alloc27;
framebuffer = new boolean[maxBitSize]; //max=1152bytes=9216bits
}
/**
*
*/
public void resetBuffer()
{
Arrays.fill(framebuffer, false);
}
/**
* modify mpegaudio frame 48khz 56..384kbps M1L2
*/
public byte[][] modifyframe(byte[] AudioFrame, int MpaConversionMode)
{
byte newAudioFrames[][] = new byte[2][AudioFrame.length];
for (int i = 0; i < 3; i++) //0-s, 1-l, 2-r
BRindex[i] = (int)(0xF & CommonParsing.getAudioProcessingFlags()>>>(4 + (i<<2)));
Restart = 0;
error_flag = 0;
//secure, but most was already done by X.java
if (Audio.parseHeader(AudioFrame, 0) != 1 || Audio.getID() != 1 || Audio.getLayer() != 2 || Audio.getSamplingFrequency() != 48000 ||
Audio.getBitrate() < 56000 || (Audio.getMode() == SINGLE && Audio.getBitrate() > 192000) || (Audio.getMode() != SINGLE && Audio.getBitrate() < 112000))
{
System.arraycopy(AudioFrame, 0, newAudioFrames[0], 0, AudioFrame.length);
System.arraycopy(AudioFrame, 0, newAudioFrames[1], 0, AudioFrame.length); // copy frame
Common.setMessage(Resource.getString("audio.msg.convert.disabled", "" + (CommonParsing.getAudioProcessingFlags()>>>18)));
CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | 0x1000CL);
return newAudioFrames;
}
//explicit call necessary, if crc removing is disabled in presettings
Audio.removeCRC(AudioFrame, true);
switch(MpaConversionMode)
{
case SINGLE_TO_3DSTEREO: //single channel to 3D
case SINGLE_TO_STEREO: //single channel to stereo
case SINGLE_TO_JSTEREO: //single channel to jstereo
if (Audio.getChannel() == 1)
newAudioFrames = createByteArrays(makeTwoChannel(createBitArray(AudioFrame), MpaConversionMode, 0));
else
newAudioFrames = adaptSourceFrame(AudioFrame, newAudioFrames, MpaConversionMode); //check to pass BR
break;
case SPLIT_INTO_SINGLE: //dual-stereo-jointstereo to 2 x mono
case SPLIT_INTO_SINGLE_DOUBLED: //dual-stereo-jointstereo to 2 x jstereo - doubled mono
if (Audio.getChannel() == 2)
newAudioFrames = createByteArrays(splitTwoChannel(createBitArray(AudioFrame), MpaConversionMode));
else
newAudioFrames = adaptSourceFrame(AudioFrame, newAudioFrames, MpaConversionMode); //check to pass BR
break;
case SPLIT_DUAL_INTO_SINGLE_DOUBLED: //dual-only to 2 x jstereo - doubled mono
if (Audio.getMode() == DUAL)
newAudioFrames = createByteArrays(splitTwoChannel(createBitArray(AudioFrame), MpaConversionMode));
else
newAudioFrames = adaptSourceFrame(AudioFrame, newAudioFrames, MpaConversionMode); //check to pass BR
}
CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() & ~0xFFFCL);
for (int i = 0; i < 3; i++) //0-s, 1-l, 2-r
CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | BRindex[i]<<(4 + (i<<2)));
CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | Restart<<2);
if (error_flag > 0)
Common.setMessage(Resource.getString("audio.msg.convert.error", String.valueOf(error_flag), String.valueOf(CommonParsing.getAudioProcessingFlags()>>>18)));
return newAudioFrames;
}
private void setError(int error)
{
error_flag |= error;
}
//check to pass BR
private byte[][] adaptSourceFrame(byte[] AudioFrame, byte[][] input, int MpaConversionMode)
{
System.arraycopy(AudioFrame, 0, input[0], 0, AudioFrame.length);
System.arraycopy(AudioFrame, 0, input[1], 0, AudioFrame.length); // copy frame
int[] size = new int[2];
size[1] = size[0] = (0xF0 & AudioFrame[2])>>>4;
switch(MpaConversionMode)
{
case SINGLE_TO_3DSTEREO: //single channel to 3D
case SINGLE_TO_STEREO: //single channel to stereo
case SINGLE_TO_JSTEREO: //single channel to jstereo
if (size[0] == BRindex[0]) //same size
return input;
else if (size[0] > BRindex[0])
{ //restart with new size
if (BRindex[0] != 0)
Restart |= 3;
BRindex[0] = size[0];
return input;
}
break;
case SPLIT_INTO_SINGLE: //dual-stereo-jointstereo to 2 x mono
case SPLIT_INTO_SINGLE_DOUBLED: //dual-stereo-jointstereo to 2 x jstereo - doubled mono
case SPLIT_DUAL_INTO_SINGLE_DOUBLED: //dual-only to 2 x jstereo - doubled mono
if (size[0] == BRindex[1] && size[1] == BRindex[2] && Audio.getChannel() == 2) //same size
return input;
else
{ //restart with new size
if (size[0] > BRindex[1])
{ //fill to size L
if (BRindex[1] != 0)
Restart |= 1;
BRindex[1] = size[0];
}
if (size[1] > BRindex[2])
{ //fill to size R
if (BRindex[2] != 0)
Restart |= 2;
BRindex[2] = size[1];
}
if (Restart > 0)
return input;
}
}
byte[][] output = new byte[2][0];
for (int ch = 0; ch < 2; ch++)
{
output[ch] = new byte[Sizes[BRindex[ch + (MpaConversionMode>>>2)]]>>>3];
System.arraycopy(input[ch], 0, output[ch], 0, input[ch].length);
output[ch][2] &= (byte) ~0xF0;
output[ch][2] |= (byte) BRindex[ch + (MpaConversionMode>>>2)]<<4;
if (MpaConversionMode < SPLIT_INTO_SINGLE)
break;
else if (MpaConversionMode > SPLIT_INTO_SINGLE)
{
if (Audio.getChannel() == 1)
output[ch] = createByteArray(makeTwoChannel(createBitArray(output[ch]), SINGLE_TO_JSTEREO, ch + 1));
}
else if (BRindex[ch + 1] > 10)
output[ch] = createByteArray(makeTwoChannel(createBitArray(output[ch]), SINGLE_TO_JSTEREO, ch + 1));
}
return output;
}
//bytearray to bitarray
private boolean[] createBitArray(byte[] input)
{
boolean[] output = new boolean[maxBitSize]; //max=1152bytes=9216bits
for (int a=0; a < input.length; a++)
for (int b=0; b < 8; b++)
if ( ((0x80>>>b) & input[a]) != 0 )
output[b + (a<<3)] = true;
return output;
}
//1ch_bitarray to 1ch_bytearray, frame in bitform must already be compliant, but will be shortened in this method to the indexed BR
private byte[] createByteArray(boolean[] input)
{
int size = getSizeFromIndex(input)>>>3;
byte[] output = new byte[size];
for (int a=0; a < size; a++)
for (int b=0; b < 8; b++)
output[a] |= input[b + (a<<3)] ? 0x80>>>b : 0;
return output;
}
//1ch_bitarray to 2ch_bytearray, frame in bitform must already be compliant, but will be shortened in this method to the indexed BR
private byte[][] createByteArrays(boolean[] input)
{
int size = getSizeFromIndex(input)>>>3;
byte[][] output = { new byte[size], new byte[0] };
for (int a=0; a < size; a++)
for (int b=0; b < 8; b++)
output[0][a] |= input[b + (a<<3)] ? 0x80>>>b : 0;
return output;
}
//2ch_bitarray to 2ch_bytearray, frame in bitform must already be compliant, but will be shortened in this method to the indexed BR
private byte[][] createByteArrays(boolean[][] input)
{
int[] size = new int[2];
for (int ch=0; ch < 2; ch++)
size[ch] = getSizeFromIndex(input[ch])>>>3;
byte[][] output = { new byte[size[0]], new byte[size[1]] };
for (int ch=0; ch < 2; ch++)
for (int a=0; a < size[ch]; a++)
for (int b=0; b < 8; b++)
output[ch][a] |= input[ch][b + (a<<3)] ? 0x80>>>b : 0;
return output;
}
//read out BR_index in bitlength
private int getSizeFromIndex(boolean[] input)
{
int size = 0;
for (int i = 0; i < 4; i++)
size |= input[i + 16] ? 8>>>i : 0;
size = Sizes[size];
return size;
}
//set Bitrate index
private void setBitRateIndex(boolean[] input, int size, int channel)
{
if ( (size = Arrays.binarySearch(Sizes, size)) < 0);
size = Math.abs(size) - 1;
if (channel == 0 && size < 7)
size = 7;
if (channel > 0 && size < 3)
size = 3;
size = updateCBRIndex(size, channel);
for (int i = 0; i < 4; i++)
input[i + 16] = (size & 8>>i) != 0 ? true : false;
}
//update Bitrate index for CBR
private int updateCBRIndex(int size, int channel)
{
if (BRindex[channel] == 0) // if 0 set first BR
BRindex[channel] = size;
else if (BRindex[channel] >= size)
size = BRindex[channel];
else
{
Restart |= (3 - channel);
BRindex[channel] = size;
}
return size;
}
//set channelmode
private void setChannelMode(boolean[] input, int mode)
{
mode <<= 2;
for (int a=0; a < 4; a++)
input[a + 24] = (mode & 8>>a) != 0;
}
//single bitarray to one 2channel bitarray, bitrate_index must hold place for whole frame data
private boolean[] makeTwoChannel(boolean[] input, int MpaConversionMode, int channel)
{
boolean[] output = new boolean[maxBitSize];
int i = 32;
int i_b = 32;
int o = 32;
int size = getSizeFromIndex(input);
System.arraycopy(input, 0, output, 0, 32); //copy source frameheader 1:1
switch(MpaConversionMode)
{
case SINGLE_TO_3DSTEREO: //make a 3d stereo (delayed channel B)
int _Bal_length = Bal.length;
int[][] _allocation = new int[2][_Bal_length];
int[][] _scfsi = new int[2][_Bal_length];
try {
// copy BAL
for (int a = 0; a < _Bal_length; a++)
{
// ch A
for (int b = 0; b < Bal[a]; b++)
{
if (input[i + b])
{
output[o + b] = true;
_allocation[0][a] |= 1<<(Bal[a] - 1 - b);
}
}
i += Bal[a];
o += Bal[a];
// ch B
for (int b = 0; b < Bal[a]; b++)
{
if (framebuffer[i_b + b])
{
output[o + b] = true;
_allocation[1][a] |= 1<<(Bal[a] - 1 - b);
}
}
i_b += Bal[a];
o += Bal[a];
}
// copy SCFSI
for (int a = 0; a < _Bal_length; a++)
{
// ch A
if (_allocation[0][a] != 0)
{
for (int b = 0; b < 2; b++)
{
if (input[i + b])
{
output[o + b] = true;
_scfsi[0][a] |= 1<<(1 - b);
}
}
i += 2;
o += 2;
}
// ch B
if (_allocation[1][a] != 0)
{
for (int b = 0; b < 2; b++)
{
if (framebuffer[i_b + b])
{
output[o + b] = true;
_scfsi[1][a] |= 1<<(1 - b);
}
}
i_b += 2;
o += 2;
}
}
// copy Scalefactors
for (int a = 0, b = 0; a < _Bal_length; a++)
{
// ch A
if (_allocation[0][a] != 0)
{
switch (_scfsi[0][a])
{
case 0:
b = 18;
break;
case 1:
case 3:
b = 12;
break;
case 2:
b = 6;
}
System.arraycopy(input, i, output, o, b);
i += b;
o += b;
}
// ch B
if (_allocation[1][a] != 0)
{
switch (_scfsi[1][a])
{
case 0:
b = 18;
break;
case 1:
case 3:
b = 12;
break;
case 2:
b = 6;
}
System.arraycopy(framebuffer, i_b, output, o, b);
i_b += b;
o += b;
}
}
// copy Samples
for (int x = 0; x < 12; x++)
{
for (int a = 0, j, k; a < _Bal_length; a++)
{
// ch A
if (_allocation[0][a] != 0)
{
j = Allocation[a][_allocation[0][a]];
k = getbits[j];
if (grouping[j] > 0)
{
System.arraycopy(input, i, output, o, k);
o += k;
i += k;
}
else
{
System.arraycopy(input, i, output, o, (3 * k));
o += (3 * k);
i += (3 * k);
}
}
// ch B
if (_allocation[1][a] != 0)
{
j = Allocation[a][_allocation[1][a]];
k = getbits[j];
if (grouping[j] > 0)
{
System.arraycopy(framebuffer, i_b, output, o, k);
o += k;
i_b += k;
}
else
{
System.arraycopy(framebuffer, i_b, output, o, (3 * k));
o += (3 * k);
i_b += (3 * k);
}
}
}
}
} catch (Exception e) {
setError(1);
}
setChannelMode(output, STEREO); //set to stereo/jstereo
setBitRateIndex(output, o, channel); //set BR_index
System.arraycopy(input, 0, framebuffer, 0, input.length); //copy source frame 1:1
break;
case SINGLE_TO_STEREO: // make a stereo
case SINGLE_TO_JSTEREO: // make a jointstereo mode 00, sb 4..31 shared
case SPLIT_DUAL_INTO_SINGLE_DOUBLED:
int Bal_length = Bal.length;
int[] allocation = new int[Bal_length];
int[] scfsi = new int[Bal_length];
try {
// copy BAL
for (int a=0; a < Bal_length; a++)
{
for (int b=0; b < Bal[a]; b++)
{
if (input[i + b])
{
output[o + b] = true;
if (MpaConversionMode == SINGLE_TO_STEREO || a < 4)
output[o + Bal[a] + b] = true;
allocation[a] |= 1<<(Bal[a] - 1 - b);
}
}
i += Bal[a];
o += (MpaConversionMode == SINGLE_TO_STEREO || a < 4) ? (Bal[a]<<1) : Bal[a];
}
// copy SCFSI
for (int a=0; a < Bal_length; a++)
{
if (allocation[a] != 0)
{
for (int b=0; b < 2; b++)
{
if (input[i + b])
{
output[o + b] = true;
output[o + b + 2] = true;
scfsi[a] |= 1<<(1 - b);
}
}
i += 2;
o += 4;
}
}
// copy Scalefactors
for (int a=0, b=0; a < Bal_length; a++)
{
if (allocation[a] != 0)
{
switch (scfsi[a])
{
case 0:
b = 18;
break;
case 1:
case 3:
b = 12;
break;
case 2:
b = 6;
}
System.arraycopy(input, i, output, o, b);
System.arraycopy(input, i, output, o + b, b);
i += b;
o += b<<1;
}
}
// copy Samples
for (int x=0; x < 12; x++)
{
for (int a=0, j, k; a < Bal_length; a++)
{
if (allocation[a] != 0)
{
j = Allocation[a][allocation[a]];
k = getbits[j];
if (grouping[j] > 0)
{
System.arraycopy(input, i, output, o, k);
o += k;
if (MpaConversionMode == SINGLE_TO_STEREO || a < 4)
{
System.arraycopy(input, i, output, o, k);
o += k;
}
i += k;
}
else
{
System.arraycopy(input, i, output, o, (3 * k));
o += (3 * k);
if (MpaConversionMode == SINGLE_TO_STEREO || a < 4)
{
System.arraycopy(input, i, output, o, (3 * k));
o += (3 * k);
}
i += (3 * k);
}
}
}
}
} catch (Exception e) {
setError(1);
}
setChannelMode(output, MpaConversionMode < SPLIT_INTO_SINGLE ? (1 & MpaConversionMode) : JSTEREO); //set to stereo/jstereo
setBitRateIndex(output, o, channel); //set BR_index
}
return output;
}
//2channel bitarray to 2 single channel bitarrays
private boolean[][] splitTwoChannel(boolean[] input, int MpaConversionMode)
{
boolean[][] output = new boolean[2][maxBitSize];
System.arraycopy(input, 0, output[0], 0, 32); //copy source frameheader 1:1 L
System.arraycopy(input, 0, output[1], 0, 32); //copy source frameheader 1:1 R
int i = 32;
int[] o = { 32,32 };
int Bal_length = Bal.length;
int[][] allocation = new int[2][Bal_length];
int[][] scfsi = new int[2][Bal_length];
int bound = 32;
if (Audio.getMode() == 1) //source is jointstereo
bound=(Audio.getModeExtension() + 1) * 4;
if (bound == 32)
bound = Bal_length;
try {
//copy BAL
for (int a=0; a < bound; a++)
{
for (int ch=0; ch < 2; ch++)
{
for (int b=0; b < Bal[a]; b++)
{
if (input[i + b])
{
allocation[ch][a] |= 1<<(Bal[a] - 1 - b);
output[ch][o[ch] + b] = true;
}
}
i += Bal[a];
o[ch] += Bal[a];
}
}
for (int a=bound; a < Bal_length; a++)
{
for (int b=0; b < Bal[a]; b++)
{
if (input[i + b])
{
for (int ch=0; ch < 2; ch++)
{
allocation[ch][a] |= 1<<(Bal[a] - 1 - b);
output[ch][o[ch] + b] = true;
}
}
}
i += Bal[a];
for (int ch=0; ch < 2; ch++)
o[ch] += Bal[a];
}
//copy SCFSI
for (int a=0; a < Bal_length; a++)
{
for (int ch=0; ch < 2; ch++)
{
if (allocation[ch][a] != 0)
{
for (int b=0; b < 2; b++)
{
if (input[i + b])
{
scfsi[ch][a] |= 1<<(1 - b);
output[ch][o[ch] + b] = true;
}
}
i += 2;
o[ch] += 2;
}
}
}
//copy Scalefactors
for (int a=0, b=0; a < Bal_length; a++)
{
for (int ch=0; ch < 2; ch++)
{
if (allocation[ch][a] != 0)
{
switch (scfsi[ch][a])
{
case 0:
b = 18;
break;
case 1:
case 3:
b = 12;
break;
case 2:
b = 6;
}
System.arraycopy(input, i, output[ch], o[ch], b);
i += b;
o[ch] += b;
}
}
}
//copy Samples
for (int x=0; x < 12; x++)
{
for (int a=0; a < bound; a++)
{
for (int ch=0, j, k; ch < 2; ch++)
{
if (allocation[ch][a] != 0)
{
j = Allocation[a][allocation[ch][a]];
k = getbits[j];
if (grouping[j] > 0)
{
System.arraycopy(input, i, output[ch], o[ch], k);
i += k;
o[ch] += k;
}
else
{
System.arraycopy(input, i, output[ch], o[ch], (3 * k));
i += (3 * k);
o[ch] += (3 * k);
}
}
}
}
for (int a=bound, j, k; a < Bal_length; a++)
{
if (allocation[0][a] != 0)
{
j = Allocation[a][allocation[0][a]];
k = getbits[j];
if (grouping[j] > 0)
{
for (int ch=0; ch < 2; ch++)
{
System.arraycopy(input, i, output[ch], o[ch], k);
o[ch] += k;
}
i+=k;
}
else
{
for (int ch=0; ch < 2; ch++)
{
System.arraycopy(input, i, output[ch], o[ch], (3 * k));
o[ch] += (3 * k);
}
i += (3 * k);
}
}
}
}
} catch (Exception e) {
setError(2);
}
for (int ch=0; ch < 2; ch++)
{
setChannelMode(output[ch], SINGLE); //set to mono
setBitRateIndex(output[ch], o[ch], ch + 1); //set BR_index
if (getSizeFromIndex(output[ch]) > Sizes[10] || MpaConversionMode == SPLIT_INTO_SINGLE_DOUBLED || MpaConversionMode == SPLIT_DUAL_INTO_SINGLE_DOUBLED)
output[ch] = makeTwoChannel(output[ch], 3, ch + 1);
}
return output;
}
}
/***** options[17]
CommonParsing.setAudioProcessingFlags()
CommonParsing.getAudioProcessingFlags();
* bit 1,0 : if options[10]>=4, not used anymore, but still set
* 00 = std CBR in complete file
* 01 = VBR same mode = same BR
* 10 = VBR each frame/channel its own
* 11 = free
* bit 3,2 :
* 00 = no restart
* 01 = restart due left ch.
* 10 = restart due right ch.
* 11 = restart due both ch.
*
* bit 7,6,5,4 : bitrate value of last frame 2channel
* bit 11,10,9,8 : bitrate value of last frame left
* bit 15,14,13,12 : bitrate value of last frame right
*
* bit 16 : set to 1 if conversion isn't possible, clear befor the next file
* bit 17 free
* bit63..18 MSB : current audioframes number
******/