Added the MusePack (MPC) engine to our repository - it's the one use in the

WinAMP plugin and is licensed under the LGPL. I've already ported it to BeOS,
so it does compile without warnings.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6124 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-01-18 03:04:27 +00:00
parent d551902916
commit 8267ce8bbc
18 changed files with 4388 additions and 0 deletions
@@ -0,0 +1,14 @@
SubDir OBOS_TOP src add-ons media plugins musepack mpc ;
StaticLibrary musepack :
bitstream.cpp
huffsv46.cpp
huffsv7.cpp
idtag.cpp
in_mpc.cpp
mpc_dec.cpp
requant.cpp
synth_filter.cpp
;
LinkSharedOSLibs musepack : be libmedia.so ;
@@ -0,0 +1,166 @@
#include <stdlib.h>
#include "bitstream.h"
/* C O N S T A N T S */
const unsigned int mask [33] = {
0x00000000, 0x00000001, 0x00000003, 0x00000007,
0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
0xFFFFFFFF
};
/* F U N C T I O N S */
// resets bitstream decoding
void
MPC_decoder::Reset_BitstreamDecode ( void )
{
dword = 0;
pos = 0;
Zaehler = 0;
WordsRead = 0;
}
// reports the number of read bits
unsigned int
MPC_decoder::BitsRead ( void )
{
return 32*WordsRead + pos;
}
// read desired number of bits out of the bitstream
unsigned int
MPC_decoder::Bitstream_read ( const unsigned int bits )
{
unsigned int out = dword;
pos += bits;
if (pos<32)
{
out >>= (32-pos);
}
else
{
dword = Speicher[Zaehler=(Zaehler+1)&MEMMASK];
pos -= 32;
if (pos)
{
out <<= pos;
out |= dword >> (32-pos);
}
++WordsRead;
}
return out & mask[bits];
}
// decode huffman
int
MPC_decoder::Huffman_Decode ( const HuffmanTyp* Table )
{
// load preview and decode
unsigned int code = dword << pos;
if (pos>18) code |= Speicher[(Zaehler+1)&MEMMASK] >> (32-pos);
while (code < Table->Code) Table++;
// set the new position within bitstream without performing a dummy-read
if ((pos += Table->Length)>=32)
{
pos -= 32;
dword = Speicher[Zaehler=(Zaehler+1)&MEMMASK];
++WordsRead;
}
return Table->Value;
}
// faster huffman through previewing less bits
int
MPC_decoder::Huffman_Decode_fast ( const HuffmanTyp* Table )
{
// load preview and decode
unsigned int code = dword << pos;
if (pos>22) code |= Speicher[(Zaehler+1)&MEMMASK] >> (32-pos);
while (code < Table->Code) Table++;
// set the new position within bitstream without performing a dummy-read
if ((pos += Table->Length)>=32)
{
pos -= 32;
dword = Speicher[Zaehler=(Zaehler+1)&MEMMASK];
++WordsRead;
}
return Table->Value;
}
// even faster huffman through previewing even less bits
int
MPC_decoder::Huffman_Decode_faster ( const HuffmanTyp* Table )
{
// load preview and decode
unsigned int code = dword << pos;
if (pos>27) code |= Speicher[(Zaehler+1)&MEMMASK] >> (32-pos);
while (code < Table->Code) Table++;
// set the new position within bitstream without performing a dummy-read
if ((pos += Table->Length)>=32)
{
pos -= 32;
dword = Speicher[Zaehler=(Zaehler+1)&MEMMASK];
++WordsRead;
}
return Table->Value;
}
// decode SCFI-bundle (sv4,5,6)
void
MPC_decoder::SCFI_Bundle_read ( const HuffmanTyp* Table, int* SCFI, int* DSCF )
{
// load preview and decode
unsigned int code = dword << pos;
if (pos>26) code |= Speicher[(Zaehler+1)&MEMMASK] >> (32-pos);
while (code < Table->Code) Table++;
// set the new position within bitstream without performing a dummy-read
if ((pos += Table->Length)>=32)
{
pos -= 32;
dword = Speicher[Zaehler=(Zaehler+1)&MEMMASK];
++WordsRead;
}
*SCFI = Table->Value >> 1;
*DSCF = Table->Value & 1;
}
static int
cmpfn ( const void* p1, const void* p2 )
{
if ( ((const MPC_decoder::HuffmanTyp*) p1)->Code < ((const MPC_decoder::HuffmanTyp*) p2)->Code ) return +1;
if ( ((const MPC_decoder::HuffmanTyp*) p1)->Code > ((const MPC_decoder::HuffmanTyp*) p2)->Code ) return -1;
return 0;
}
// sort huffman-tables by codeword
// offset resulting value
void
MPC_decoder::Resort_HuffTables ( const unsigned int elements, HuffmanTyp* Table, const int offset )
{
unsigned int i;
for ( i = 0; i < elements; i++ ) {
Table[i].Code <<= 32 - Table[i].Length;
Table[i].Value = i - offset;
}
qsort ( Table, elements, sizeof(*Table), cmpfn );
}
/* end of bitstream.c */
@@ -0,0 +1,6 @@
#ifndef _bitstream_decode_h_
#define _bitstream_decode_h_
#include "mpc_dec.h"
#endif
@@ -0,0 +1,230 @@
#include <stdio.h>
#include "huffsv46.h"
#include "requant.h"
void
MPC_decoder::Huffman_SV6_Decoder ( void )
{
Huffman_SV6_Encoder ();
Resort_HuffTables( 16, Region_A , 0);
Resort_HuffTables( 8, Region_B , 0);
Resort_HuffTables( 4, Region_C , 0);
Resort_HuffTables( 8, SCFI_Bundle , 0);
Resort_HuffTables( 13, DSCF_Entropie , 6);
Resort_HuffTables( 3, Entropie_1 , Dc[1]);
Resort_HuffTables( 5, Entropie_2 , Dc[2]);
Resort_HuffTables( 7, Entropie_3 , Dc[3]);
Resort_HuffTables( 9, Entropie_4 , Dc[4]);
Resort_HuffTables( 15, Entropie_5 , Dc[5]);
Resort_HuffTables( 31, Entropie_6 , Dc[6]);
Resort_HuffTables( 63, Entropie_7 , Dc[7]);
}
void MPC_decoder::Huffman_SV6_Encoder ( void )
{
// SCFI-bundle
SCFI_Bundle[7].Code= 1; SCFI_Bundle[7].Length= 1;
SCFI_Bundle[3].Code= 1; SCFI_Bundle[3].Length= 2;
SCFI_Bundle[5].Code= 0; SCFI_Bundle[5].Length= 3;
SCFI_Bundle[1].Code= 7; SCFI_Bundle[1].Length= 5;
SCFI_Bundle[2].Code= 6; SCFI_Bundle[2].Length= 5;
SCFI_Bundle[4].Code= 4; SCFI_Bundle[4].Length= 5;
SCFI_Bundle[0].Code= 11; SCFI_Bundle[0].Length= 6;
SCFI_Bundle[6].Code= 10; SCFI_Bundle[6].Length= 6;
// region A (subbands 0..10)
Region_A[ 1].Code= 1; Region_A[ 1].Length= 1;
Region_A[ 2].Code= 0; Region_A[ 2].Length= 2;
Region_A[ 0].Code= 2; Region_A[ 0].Length= 3;
Region_A[ 3].Code= 15; Region_A[ 3].Length= 5;
Region_A[ 5].Code= 13; Region_A[ 5].Length= 5;
Region_A[ 6].Code= 12; Region_A[ 6].Length= 5;
Region_A[ 4].Code= 29; Region_A[ 4].Length= 6;
Region_A[ 7].Code= 57; Region_A[ 7].Length= 7;
Region_A[ 8].Code= 113; Region_A[ 8].Length= 8;
Region_A[ 9].Code= 225; Region_A[ 9].Length= 9;
Region_A[10].Code= 449; Region_A[10].Length= 10;
Region_A[11].Code= 897; Region_A[11].Length= 11;
Region_A[12].Code= 1793; Region_A[12].Length= 12;
Region_A[13].Code= 3585; Region_A[13].Length= 13;
Region_A[14].Code= 7169; Region_A[14].Length= 14;
Region_A[15].Code= 7168; Region_A[15].Length= 14;
// region B (subbands 11..22)
Region_B[1].Code= 1; Region_B[1].Length= 1;
Region_B[0].Code= 1; Region_B[0].Length= 2;
Region_B[2].Code= 1; Region_B[2].Length= 3;
Region_B[3].Code= 1; Region_B[3].Length= 4;
Region_B[4].Code= 1; Region_B[4].Length= 5;
Region_B[5].Code= 1; Region_B[5].Length= 6;
Region_B[6].Code= 1; Region_B[6].Length= 7;
Region_B[7].Code= 0; Region_B[7].Length= 7;
// region C (subbands 23..31)
Region_C[0].Code= 1; Region_C[0].Length= 1;
Region_C[1].Code= 1; Region_C[1].Length= 2;
Region_C[2].Code= 1; Region_C[2].Length= 3;
Region_C[3].Code= 0; Region_C[3].Length= 3;
// DSCF
DSCF_Entropie[ 6].Code= 0; DSCF_Entropie[ 6].Length= 2;
DSCF_Entropie[ 7].Code= 7; DSCF_Entropie[ 7].Length= 3;
DSCF_Entropie[ 5].Code= 4; DSCF_Entropie[ 5].Length= 3;
DSCF_Entropie[ 8].Code= 3; DSCF_Entropie[ 8].Length= 3;
DSCF_Entropie[ 9].Code= 13; DSCF_Entropie[ 9].Length= 4;
DSCF_Entropie[ 4].Code= 11; DSCF_Entropie[ 4].Length= 4;
DSCF_Entropie[10].Code= 10; DSCF_Entropie[10].Length= 4;
DSCF_Entropie[ 2].Code= 4; DSCF_Entropie[ 2].Length= 4;
DSCF_Entropie[11].Code= 25; DSCF_Entropie[11].Length= 5;
DSCF_Entropie[ 3].Code= 24; DSCF_Entropie[ 3].Length= 5;
DSCF_Entropie[ 1].Code= 11; DSCF_Entropie[ 1].Length= 5;
DSCF_Entropie[12].Code= 21; DSCF_Entropie[12].Length= 6;
DSCF_Entropie[ 0].Code= 20; DSCF_Entropie[ 0].Length= 6;
// first quantizer
Entropie_1[1].Code= 1; Entropie_1[1].Length= 1;
Entropie_1[0].Code= 1; Entropie_1[0].Length= 2;
Entropie_1[2].Code= 0; Entropie_1[2].Length= 2;
// second quantizer
Entropie_2[2].Code= 3; Entropie_2[2].Length= 2;
Entropie_2[3].Code= 1; Entropie_2[3].Length= 2;
Entropie_2[1].Code= 0; Entropie_2[1].Length= 2;
Entropie_2[4].Code= 5; Entropie_2[4].Length= 3;
Entropie_2[0].Code= 4; Entropie_2[0].Length= 3;
// third quantizer
Entropie_3[3].Code= 3; Entropie_3[3].Length= 2;
Entropie_3[2].Code= 1; Entropie_3[2].Length= 2;
Entropie_3[4].Code= 0; Entropie_3[4].Length= 2;
Entropie_3[1].Code= 5; Entropie_3[1].Length= 3;
Entropie_3[5].Code= 9; Entropie_3[5].Length= 4;
Entropie_3[0].Code= 17; Entropie_3[0].Length= 5;
Entropie_3[6].Code= 16; Entropie_3[6].Length= 5;
// forth quantizer
Entropie_4[4].Code= 0; Entropie_4[4].Length= 2;
Entropie_4[5].Code= 6; Entropie_4[5].Length= 3;
Entropie_4[3].Code= 5; Entropie_4[3].Length= 3;
Entropie_4[6].Code= 4; Entropie_4[6].Length= 3;
Entropie_4[2].Code= 3; Entropie_4[2].Length= 3;
Entropie_4[7].Code= 15; Entropie_4[7].Length= 4;
Entropie_4[1].Code= 14; Entropie_4[1].Length= 4;
Entropie_4[0].Code= 5; Entropie_4[0].Length= 4;
Entropie_4[8].Code= 4; Entropie_4[8].Length= 4;
// fifth quantizer
Entropie_5[7 ].Code= 4; Entropie_5[7 ].Length= 3;
Entropie_5[8 ].Code= 3; Entropie_5[8 ].Length= 3;
Entropie_5[6 ].Code= 2; Entropie_5[6 ].Length= 3;
Entropie_5[9 ].Code= 0; Entropie_5[9 ].Length= 3;
Entropie_5[5 ].Code= 15; Entropie_5[5 ].Length= 4;
Entropie_5[4 ].Code= 13; Entropie_5[4 ].Length= 4;
Entropie_5[10].Code= 12; Entropie_5[10].Length= 4;
Entropie_5[11].Code= 10; Entropie_5[11].Length= 4;
Entropie_5[3 ].Code= 3; Entropie_5[3 ].Length= 4;
Entropie_5[12].Code= 2; Entropie_5[12].Length= 4;
Entropie_5[2 ].Code= 29; Entropie_5[2 ].Length= 5;
Entropie_5[1 ].Code= 23; Entropie_5[1 ].Length= 5;
Entropie_5[13].Code= 22; Entropie_5[13].Length= 5;
Entropie_5[0 ].Code= 57; Entropie_5[0 ].Length= 6;
Entropie_5[14].Code= 56; Entropie_5[14].Length= 6;
// sixth quantizer
Entropie_6[15].Code= 9; Entropie_6[15].Length= 4;
Entropie_6[16].Code= 8; Entropie_6[16].Length= 4;
Entropie_6[14].Code= 7; Entropie_6[14].Length= 4;
Entropie_6[18].Code= 6; Entropie_6[18].Length= 4;
Entropie_6[17].Code= 5; Entropie_6[17].Length= 4;
Entropie_6[12].Code= 3; Entropie_6[12].Length= 4;
Entropie_6[13].Code= 2; Entropie_6[13].Length= 4;
Entropie_6[19].Code= 0; Entropie_6[19].Length= 4;
Entropie_6[11].Code= 31; Entropie_6[11].Length= 5;
Entropie_6[20].Code= 30; Entropie_6[20].Length= 5;
Entropie_6[10].Code= 29; Entropie_6[10].Length= 5;
Entropie_6[9 ].Code= 27; Entropie_6[9 ].Length= 5;
Entropie_6[21].Code= 26; Entropie_6[21].Length= 5;
Entropie_6[22].Code= 25; Entropie_6[22].Length= 5;
Entropie_6[8 ].Code= 24; Entropie_6[8 ].Length= 5;
Entropie_6[7 ].Code= 23; Entropie_6[7 ].Length= 5;
Entropie_6[23].Code= 21; Entropie_6[23].Length= 5;
Entropie_6[6 ].Code= 9; Entropie_6[6 ].Length= 5;
Entropie_6[24].Code= 3; Entropie_6[24].Length= 5;
Entropie_6[25].Code= 57; Entropie_6[25].Length= 6;
Entropie_6[5 ].Code= 56; Entropie_6[5 ].Length= 6;
Entropie_6[4 ].Code= 45; Entropie_6[4 ].Length= 6;
Entropie_6[26].Code= 41; Entropie_6[26].Length= 6;
Entropie_6[2 ].Code= 40; Entropie_6[2 ].Length= 6;
Entropie_6[27].Code= 17; Entropie_6[27].Length= 6;
Entropie_6[28].Code= 16; Entropie_6[28].Length= 6;
Entropie_6[3 ].Code= 5; Entropie_6[3 ].Length= 6;
Entropie_6[29].Code= 89; Entropie_6[29].Length= 7;
Entropie_6[1 ].Code= 88; Entropie_6[1 ].Length= 7;
Entropie_6[30].Code= 9; Entropie_6[30].Length= 7;
Entropie_6[0 ].Code= 8; Entropie_6[0 ].Length= 7;
// seventh quantizer
Entropie_7[25].Code= 0; Entropie_7[25].Length= 5;
Entropie_7[37].Code= 1; Entropie_7[37].Length= 5;
Entropie_7[62].Code= 16; Entropie_7[62].Length= 8;
Entropie_7[ 0].Code= 17; Entropie_7[ 0].Length= 8;
Entropie_7[ 3].Code= 9; Entropie_7[ 3].Length= 7;
Entropie_7[ 5].Code= 10; Entropie_7[ 5].Length= 7;
Entropie_7[ 6].Code= 11; Entropie_7[ 6].Length= 7;
Entropie_7[38].Code= 3; Entropie_7[38].Length= 5;
Entropie_7[35].Code= 4; Entropie_7[35].Length= 5;
Entropie_7[33].Code= 5; Entropie_7[33].Length= 5;
Entropie_7[24].Code= 6; Entropie_7[24].Length= 5;
Entropie_7[27].Code= 7; Entropie_7[27].Length= 5;
Entropie_7[26].Code= 8; Entropie_7[26].Length= 5;
Entropie_7[12].Code= 18; Entropie_7[12].Length= 6;
Entropie_7[50].Code= 19; Entropie_7[50].Length= 6;
Entropie_7[29].Code= 10; Entropie_7[29].Length= 5;
Entropie_7[31].Code= 11; Entropie_7[31].Length= 5;
Entropie_7[36].Code= 12; Entropie_7[36].Length= 5;
Entropie_7[34].Code= 13; Entropie_7[34].Length= 5;
Entropie_7[28].Code= 14; Entropie_7[28].Length= 5;
Entropie_7[49].Code= 30; Entropie_7[49].Length= 6;
Entropie_7[56].Code= 62; Entropie_7[56].Length= 7;
Entropie_7[ 7].Code= 63; Entropie_7[ 7].Length= 7;
Entropie_7[32].Code= 16; Entropie_7[32].Length= 5;
Entropie_7[30].Code= 17; Entropie_7[30].Length= 5;
Entropie_7[13].Code= 36; Entropie_7[13].Length= 6;
Entropie_7[55].Code= 74; Entropie_7[55].Length= 7;
Entropie_7[61].Code= 150; Entropie_7[61].Length= 8;
Entropie_7[ 1].Code= 151; Entropie_7[ 1].Length= 8;
Entropie_7[14].Code= 38; Entropie_7[14].Length= 6;
Entropie_7[48].Code= 39; Entropie_7[48].Length= 6;
Entropie_7[ 4].Code= 80; Entropie_7[ 4].Length= 7;
Entropie_7[58].Code= 81; Entropie_7[58].Length= 7;
Entropie_7[47].Code= 41; Entropie_7[47].Length= 6;
Entropie_7[15].Code= 42; Entropie_7[15].Length= 6;
Entropie_7[16].Code= 43; Entropie_7[16].Length= 6;
Entropie_7[54].Code= 88; Entropie_7[54].Length= 7;
Entropie_7[ 8].Code= 89; Entropie_7[ 8].Length= 7;
Entropie_7[17].Code= 45; Entropie_7[17].Length= 6;
Entropie_7[46].Code= 46; Entropie_7[46].Length= 6;
Entropie_7[45].Code= 47; Entropie_7[45].Length= 6;
Entropie_7[53].Code= 96; Entropie_7[53].Length= 7;
Entropie_7[ 9].Code= 97; Entropie_7[ 9].Length= 7;
Entropie_7[43].Code= 49; Entropie_7[43].Length= 6;
Entropie_7[19].Code= 50; Entropie_7[19].Length= 6;
Entropie_7[18].Code= 51; Entropie_7[18].Length= 6;
Entropie_7[44].Code= 52; Entropie_7[44].Length= 6;
Entropie_7[ 2].Code= 212; Entropie_7[ 2].Length= 8;
Entropie_7[60].Code= 213; Entropie_7[60].Length= 8;
Entropie_7[10].Code= 107; Entropie_7[10].Length= 7;
Entropie_7[42].Code= 54; Entropie_7[42].Length= 6;
Entropie_7[41].Code= 55; Entropie_7[41].Length= 6;
Entropie_7[20].Code= 56; Entropie_7[20].Length= 6;
Entropie_7[21].Code= 57; Entropie_7[21].Length= 6;
Entropie_7[52].Code= 116; Entropie_7[52].Length= 7;
Entropie_7[51].Code= 117; Entropie_7[51].Length= 7;
Entropie_7[40].Code= 59; Entropie_7[40].Length= 6;
Entropie_7[22].Code= 60; Entropie_7[22].Length= 6;
Entropie_7[23].Code= 61; Entropie_7[23].Length= 6;
Entropie_7[39].Code= 62; Entropie_7[39].Length= 6;
Entropie_7[11].Code= 126; Entropie_7[11].Length= 7;
Entropie_7[57].Code= 254; Entropie_7[57].Length= 8;
Entropie_7[59].Code= 255; Entropie_7[59].Length= 8;
}
@@ -0,0 +1,6 @@
#ifndef _huff_old_h_
#define _huff_old_h_
#include "bitstream.h"
#endif
@@ -0,0 +1,462 @@
#include "huffsv7.h"
#include "requant.h"
void
MPC_decoder::Huffman_SV7_Decoder ( void )
{
Huffman_SV7_Encoder ();
Resort_HuffTables(10, &HuffHdr[0] , 5);
Resort_HuffTables( 4, &HuffSCFI[0] , 0);
Resort_HuffTables(16, &HuffDSCF[0] , 7);
Resort_HuffTables(27, &HuffQ1[0][0] , 0);
Resort_HuffTables(27, &HuffQ1[1][0] , 0);
Resort_HuffTables(25, &HuffQ2[0][0] , 0);
Resort_HuffTables(25, &HuffQ2[1][0] , 0);
Resort_HuffTables( 7, &HuffQ3[0][0] , Dc[3]);
Resort_HuffTables( 7, &HuffQ3[1][0] , Dc[3]);
Resort_HuffTables( 9, &HuffQ4[0][0] , Dc[4]);
Resort_HuffTables( 9, &HuffQ4[1][0] , Dc[4]);
Resort_HuffTables(15, &HuffQ5[0][0] , Dc[5]);
Resort_HuffTables(15, &HuffQ5[1][0] , Dc[5]);
Resort_HuffTables(31, &HuffQ6[0][0] , Dc[6]);
Resort_HuffTables(31, &HuffQ6[1][0] , Dc[6]);
Resort_HuffTables(63, &HuffQ7[0][0] , Dc[7]);
Resort_HuffTables(63, &HuffQ7[1][0] , Dc[7]);
}
void
MPC_decoder::Huffman_SV7_Encoder ( void )
{
/***************************** SCFI *******************************/
HuffSCFI[0].Code = 2; HuffSCFI[0].Length = 3;
HuffSCFI[1].Code = 1; HuffSCFI[1].Length = 1;
HuffSCFI[2].Code = 3; HuffSCFI[2].Length = 3;
HuffSCFI[3].Code = 0; HuffSCFI[3].Length = 2;
/***************************** DSCF *******************************/
HuffDSCF[ 0].Code = 32; HuffDSCF[ 0].Length = 6;
HuffDSCF[ 1].Code = 4; HuffDSCF[ 1].Length = 5;
HuffDSCF[ 2].Code = 17; HuffDSCF[ 2].Length = 5;
HuffDSCF[ 3].Code = 30; HuffDSCF[ 3].Length = 5;
HuffDSCF[ 4].Code = 13; HuffDSCF[ 4].Length = 4;
HuffDSCF[ 5].Code = 0; HuffDSCF[ 5].Length = 3;
HuffDSCF[ 6].Code = 3; HuffDSCF[ 6].Length = 3;
HuffDSCF[ 7].Code = 9; HuffDSCF[ 7].Length = 4;
HuffDSCF[ 8].Code = 5; HuffDSCF[ 8].Length = 3;
HuffDSCF[ 9].Code = 2; HuffDSCF[ 9].Length = 3;
HuffDSCF[10].Code = 14; HuffDSCF[10].Length = 4;
HuffDSCF[11].Code = 3; HuffDSCF[11].Length = 4;
HuffDSCF[12].Code = 31; HuffDSCF[12].Length = 5;
HuffDSCF[13].Code = 5; HuffDSCF[13].Length = 5;
HuffDSCF[14].Code = 33; HuffDSCF[14].Length = 6;
HuffDSCF[15].Code = 12; HuffDSCF[15].Length = 4;
/************************* frame-header ***************************/
/***************** differential quantizer indizes *****************/
HuffHdr[0].Code = 92; HuffHdr[0].Length = 8;
HuffHdr[1].Code = 47; HuffHdr[1].Length = 7;
HuffHdr[2].Code = 10; HuffHdr[2].Length = 5;
HuffHdr[3].Code = 4; HuffHdr[3].Length = 4;
HuffHdr[4].Code = 0; HuffHdr[4].Length = 2;
HuffHdr[5].Code = 1; HuffHdr[5].Length = 1;
HuffHdr[6].Code = 3; HuffHdr[6].Length = 3;
HuffHdr[7].Code = 22; HuffHdr[7].Length = 6;
HuffHdr[8].Code = 187; HuffHdr[8].Length = 9;
HuffHdr[9].Code = 186; HuffHdr[9].Length = 9;
/********************** 3-step quantizer **************************/
/********************* 3 bundled samples **************************/
//less shaped, book 0
HuffQ1[0][ 0].Code = 54; HuffQ1[0][ 0].Length = 6;
HuffQ1[0][ 1].Code = 9; HuffQ1[0][ 1].Length = 5;
HuffQ1[0][ 2].Code = 32; HuffQ1[0][ 2].Length = 6;
HuffQ1[0][ 3].Code = 5; HuffQ1[0][ 3].Length = 5;
HuffQ1[0][ 4].Code = 10; HuffQ1[0][ 4].Length = 4;
HuffQ1[0][ 5].Code = 7; HuffQ1[0][ 5].Length = 5;
HuffQ1[0][ 6].Code = 52; HuffQ1[0][ 6].Length = 6;
HuffQ1[0][ 7].Code = 0; HuffQ1[0][ 7].Length = 5;
HuffQ1[0][ 8].Code = 35; HuffQ1[0][ 8].Length = 6;
HuffQ1[0][ 9].Code = 10; HuffQ1[0][ 9].Length = 5;
HuffQ1[0][10].Code = 6; HuffQ1[0][10].Length = 4;
HuffQ1[0][11].Code = 4; HuffQ1[0][11].Length = 5;
HuffQ1[0][12].Code = 11; HuffQ1[0][12].Length = 4;
HuffQ1[0][13].Code = 7; HuffQ1[0][13].Length = 3;
HuffQ1[0][14].Code = 12; HuffQ1[0][14].Length = 4;
HuffQ1[0][15].Code = 3; HuffQ1[0][15].Length = 5;
HuffQ1[0][16].Code = 7; HuffQ1[0][16].Length = 4;
HuffQ1[0][17].Code = 11; HuffQ1[0][17].Length = 5;
HuffQ1[0][18].Code = 34; HuffQ1[0][18].Length = 6;
HuffQ1[0][19].Code = 1; HuffQ1[0][19].Length = 5;
HuffQ1[0][20].Code = 53; HuffQ1[0][20].Length = 6;
HuffQ1[0][21].Code = 6; HuffQ1[0][21].Length = 5;
HuffQ1[0][22].Code = 9; HuffQ1[0][22].Length = 4;
HuffQ1[0][23].Code = 2; HuffQ1[0][23].Length = 5;
HuffQ1[0][24].Code = 33; HuffQ1[0][24].Length = 6;
HuffQ1[0][25].Code = 8; HuffQ1[0][25].Length = 5;
HuffQ1[0][26].Code = 55; HuffQ1[0][26].Length = 6;
//more shaped, book 1
HuffQ1[1][ 0].Code = 103; HuffQ1[1][ 0].Length = 8;
HuffQ1[1][ 1].Code = 62; HuffQ1[1][ 1].Length = 7;
HuffQ1[1][ 2].Code = 225; HuffQ1[1][ 2].Length = 9;
HuffQ1[1][ 3].Code = 55; HuffQ1[1][ 3].Length = 7;
HuffQ1[1][ 4].Code = 3; HuffQ1[1][ 4].Length = 4;
HuffQ1[1][ 5].Code = 52; HuffQ1[1][ 5].Length = 7;
HuffQ1[1][ 6].Code = 101; HuffQ1[1][ 6].Length = 8;
HuffQ1[1][ 7].Code = 60; HuffQ1[1][ 7].Length = 7;
HuffQ1[1][ 8].Code = 227; HuffQ1[1][ 8].Length = 9;
HuffQ1[1][ 9].Code = 24; HuffQ1[1][ 9].Length = 6;
HuffQ1[1][10].Code = 0; HuffQ1[1][10].Length = 4;
HuffQ1[1][11].Code = 61; HuffQ1[1][11].Length = 7;
HuffQ1[1][12].Code = 4; HuffQ1[1][12].Length = 4;
HuffQ1[1][13].Code = 1; HuffQ1[1][13].Length = 1;
HuffQ1[1][14].Code = 5; HuffQ1[1][14].Length = 4;
HuffQ1[1][15].Code = 63; HuffQ1[1][15].Length = 7;
HuffQ1[1][16].Code = 1; HuffQ1[1][16].Length = 4;
HuffQ1[1][17].Code = 59; HuffQ1[1][17].Length = 7;
HuffQ1[1][18].Code = 226; HuffQ1[1][18].Length = 9;
HuffQ1[1][19].Code = 57; HuffQ1[1][19].Length = 7;
HuffQ1[1][20].Code = 100; HuffQ1[1][20].Length = 8;
HuffQ1[1][21].Code = 53; HuffQ1[1][21].Length = 7;
HuffQ1[1][22].Code = 2; HuffQ1[1][22].Length = 4;
HuffQ1[1][23].Code = 54; HuffQ1[1][23].Length = 7;
HuffQ1[1][24].Code = 224; HuffQ1[1][24].Length = 9;
HuffQ1[1][25].Code = 58; HuffQ1[1][25].Length = 7;
HuffQ1[1][26].Code = 102; HuffQ1[1][26].Length = 8;
/********************** 5-step quantizer **************************/
/********************* 2 bundled samples **************************/
//less shaped, book 0
HuffQ2[0][ 0].Code = 89; HuffQ2[0][ 0].Length = 7;
HuffQ2[0][ 1].Code = 47; HuffQ2[0][ 1].Length = 6;
HuffQ2[0][ 2].Code = 15; HuffQ2[0][ 2].Length = 5;
HuffQ2[0][ 3].Code = 0; HuffQ2[0][ 3].Length = 5;
HuffQ2[0][ 4].Code = 91; HuffQ2[0][ 4].Length = 7;
HuffQ2[0][ 5].Code = 4; HuffQ2[0][ 5].Length = 5;
HuffQ2[0][ 6].Code = 6; HuffQ2[0][ 6].Length = 4;
HuffQ2[0][ 7].Code = 13; HuffQ2[0][ 7].Length = 4;
HuffQ2[0][ 8].Code = 4; HuffQ2[0][ 8].Length = 4;
HuffQ2[0][ 9].Code = 5; HuffQ2[0][ 9].Length = 5;
HuffQ2[0][10].Code = 20; HuffQ2[0][10].Length = 5;
HuffQ2[0][11].Code = 12; HuffQ2[0][11].Length = 4;
HuffQ2[0][12].Code = 4; HuffQ2[0][12].Length = 3;
HuffQ2[0][13].Code = 15; HuffQ2[0][13].Length = 4;
HuffQ2[0][14].Code = 14; HuffQ2[0][14].Length = 5;
HuffQ2[0][15].Code = 3; HuffQ2[0][15].Length = 5;
HuffQ2[0][16].Code = 3; HuffQ2[0][16].Length = 4;
HuffQ2[0][17].Code = 14; HuffQ2[0][17].Length = 4;
HuffQ2[0][18].Code = 5; HuffQ2[0][18].Length = 4;
HuffQ2[0][19].Code = 1; HuffQ2[0][19].Length = 5;
HuffQ2[0][20].Code = 90; HuffQ2[0][20].Length = 7;
HuffQ2[0][21].Code = 2; HuffQ2[0][21].Length = 5;
HuffQ2[0][22].Code = 21; HuffQ2[0][22].Length = 5;
HuffQ2[0][23].Code = 46; HuffQ2[0][23].Length = 6;
HuffQ2[0][24].Code = 88; HuffQ2[0][24].Length = 7;
//more shaped, book 1
HuffQ2[1][ 0].Code = 921; HuffQ2[1][ 0].Length = 10;
HuffQ2[1][ 1].Code = 113; HuffQ2[1][ 1].Length = 7;
HuffQ2[1][ 2].Code = 51; HuffQ2[1][ 2].Length = 6;
HuffQ2[1][ 3].Code = 231; HuffQ2[1][ 3].Length = 8;
HuffQ2[1][ 4].Code = 922; HuffQ2[1][ 4].Length = 10;
HuffQ2[1][ 5].Code = 104; HuffQ2[1][ 5].Length = 7;
HuffQ2[1][ 6].Code = 30; HuffQ2[1][ 6].Length = 5;
HuffQ2[1][ 7].Code = 0; HuffQ2[1][ 7].Length = 3;
HuffQ2[1][ 8].Code = 29; HuffQ2[1][ 8].Length = 5;
HuffQ2[1][ 9].Code = 105; HuffQ2[1][ 9].Length = 7;
HuffQ2[1][10].Code = 50; HuffQ2[1][10].Length = 6;
HuffQ2[1][11].Code = 1; HuffQ2[1][11].Length = 3;
HuffQ2[1][12].Code = 2; HuffQ2[1][12].Length = 2;
HuffQ2[1][13].Code = 3; HuffQ2[1][13].Length = 3;
HuffQ2[1][14].Code = 49; HuffQ2[1][14].Length = 6;
HuffQ2[1][15].Code = 107; HuffQ2[1][15].Length = 7;
HuffQ2[1][16].Code = 27; HuffQ2[1][16].Length = 5;
HuffQ2[1][17].Code = 2; HuffQ2[1][17].Length = 3;
HuffQ2[1][18].Code = 31; HuffQ2[1][18].Length = 5;
HuffQ2[1][19].Code = 112; HuffQ2[1][19].Length = 7;
HuffQ2[1][20].Code = 920; HuffQ2[1][20].Length = 10;
HuffQ2[1][21].Code = 106; HuffQ2[1][21].Length = 7;
HuffQ2[1][22].Code = 48; HuffQ2[1][22].Length = 6;
HuffQ2[1][23].Code = 114; HuffQ2[1][23].Length = 7;
HuffQ2[1][24].Code = 923; HuffQ2[1][24].Length = 10;
/********************** 7-step quantizer **************************/
/*********************** single samples ***************************/
//less shaped, book 0
HuffQ3[0][0].Code = 12; HuffQ3[0][0].Length = 4;
HuffQ3[0][1].Code = 4; HuffQ3[0][1].Length = 3;
HuffQ3[0][2].Code = 0; HuffQ3[0][2].Length = 2;
HuffQ3[0][3].Code = 1; HuffQ3[0][3].Length = 2;
HuffQ3[0][4].Code = 7; HuffQ3[0][4].Length = 3;
HuffQ3[0][5].Code = 5; HuffQ3[0][5].Length = 3;
HuffQ3[0][6].Code = 13; HuffQ3[0][6].Length = 4;
//more shaped, book 1
HuffQ3[1][0].Code = 4; HuffQ3[1][0].Length = 5;
HuffQ3[1][1].Code = 3; HuffQ3[1][1].Length = 4;
HuffQ3[1][2].Code = 2; HuffQ3[1][2].Length = 2;
HuffQ3[1][3].Code = 3; HuffQ3[1][3].Length = 2;
HuffQ3[1][4].Code = 1; HuffQ3[1][4].Length = 2;
HuffQ3[1][5].Code = 0; HuffQ3[1][5].Length = 3;
HuffQ3[1][6].Code = 5; HuffQ3[1][6].Length = 5;
/********************** 9-step quantizer **************************/
/*********************** single samples ***************************/
//less shaped, book 0
HuffQ4[0][0].Code = 5; HuffQ4[0][0].Length = 4;
HuffQ4[0][1].Code = 0; HuffQ4[0][1].Length = 3;
HuffQ4[0][2].Code = 4; HuffQ4[0][2].Length = 3;
HuffQ4[0][3].Code = 6; HuffQ4[0][3].Length = 3;
HuffQ4[0][4].Code = 7; HuffQ4[0][4].Length = 3;
HuffQ4[0][5].Code = 5; HuffQ4[0][5].Length = 3;
HuffQ4[0][6].Code = 3; HuffQ4[0][6].Length = 3;
HuffQ4[0][7].Code = 1; HuffQ4[0][7].Length = 3;
HuffQ4[0][8].Code = 4; HuffQ4[0][8].Length = 4;
//more shaped, book 1
HuffQ4[1][0].Code = 9; HuffQ4[1][0].Length = 5;
HuffQ4[1][1].Code = 12; HuffQ4[1][1].Length = 4;
HuffQ4[1][2].Code = 3; HuffQ4[1][2].Length = 3;
HuffQ4[1][3].Code = 0; HuffQ4[1][3].Length = 2;
HuffQ4[1][4].Code = 2; HuffQ4[1][4].Length = 2;
HuffQ4[1][5].Code = 7; HuffQ4[1][5].Length = 3;
HuffQ4[1][6].Code = 13; HuffQ4[1][6].Length = 4;
HuffQ4[1][7].Code = 5; HuffQ4[1][7].Length = 4;
HuffQ4[1][8].Code = 8; HuffQ4[1][8].Length = 5;
/********************* 15-step quantizer **************************/
/*********************** single samples ***************************/
//less shaped, book 0
HuffQ5[0][ 0].Code = 57; HuffQ5[0][ 0].Length = 6;
HuffQ5[0][ 1].Code = 23; HuffQ5[0][ 1].Length = 5;
HuffQ5[0][ 2].Code = 8; HuffQ5[0][ 2].Length = 4;
HuffQ5[0][ 3].Code = 10; HuffQ5[0][ 3].Length = 4;
HuffQ5[0][ 4].Code = 13; HuffQ5[0][ 4].Length = 4;
HuffQ5[0][ 5].Code = 0; HuffQ5[0][ 5].Length = 3;
HuffQ5[0][ 6].Code = 2; HuffQ5[0][ 6].Length = 3;
HuffQ5[0][ 7].Code = 3; HuffQ5[0][ 7].Length = 3;
HuffQ5[0][ 8].Code = 1; HuffQ5[0][ 8].Length = 3;
HuffQ5[0][ 9].Code = 15; HuffQ5[0][ 9].Length = 4;
HuffQ5[0][10].Code = 12; HuffQ5[0][10].Length = 4;
HuffQ5[0][11].Code = 9; HuffQ5[0][11].Length = 4;
HuffQ5[0][12].Code = 29; HuffQ5[0][12].Length = 5;
HuffQ5[0][13].Code = 22; HuffQ5[0][13].Length = 5;
HuffQ5[0][14].Code = 56; HuffQ5[0][14].Length = 6;
//more shaped, book 1
HuffQ5[1][ 0].Code = 229; HuffQ5[1][ 0].Length = 8;
HuffQ5[1][ 1].Code = 56; HuffQ5[1][ 1].Length = 6;
HuffQ5[1][ 2].Code = 7; HuffQ5[1][ 2].Length = 5;
HuffQ5[1][ 3].Code = 2; HuffQ5[1][ 3].Length = 4;
HuffQ5[1][ 4].Code = 0; HuffQ5[1][ 4].Length = 3;
HuffQ5[1][ 5].Code = 3; HuffQ5[1][ 5].Length = 3;
HuffQ5[1][ 6].Code = 5; HuffQ5[1][ 6].Length = 3;
HuffQ5[1][ 7].Code = 6; HuffQ5[1][ 7].Length = 3;
HuffQ5[1][ 8].Code = 4; HuffQ5[1][ 8].Length = 3;
HuffQ5[1][ 9].Code = 2; HuffQ5[1][ 9].Length = 3;
HuffQ5[1][10].Code = 15; HuffQ5[1][10].Length = 4;
HuffQ5[1][11].Code = 29; HuffQ5[1][11].Length = 5;
HuffQ5[1][12].Code = 6; HuffQ5[1][12].Length = 5;
HuffQ5[1][13].Code = 115; HuffQ5[1][13].Length = 7;
HuffQ5[1][14].Code = 228; HuffQ5[1][14].Length = 8;
/********************* 31-step quantizer **************************/
/*********************** single samples ***************************/
//less shaped, book 0
HuffQ6[0][ 0].Code = 65; HuffQ6[0][ 0].Length = 7;
HuffQ6[0][ 1].Code = 6; HuffQ6[0][ 1].Length = 6;
HuffQ6[0][ 2].Code = 44; HuffQ6[0][ 2].Length = 6;
HuffQ6[0][ 3].Code = 45; HuffQ6[0][ 3].Length = 6;
HuffQ6[0][ 4].Code = 59; HuffQ6[0][ 4].Length = 6;
HuffQ6[0][ 5].Code = 13; HuffQ6[0][ 5].Length = 5;
HuffQ6[0][ 6].Code = 17; HuffQ6[0][ 6].Length = 5;
HuffQ6[0][ 7].Code = 19; HuffQ6[0][ 7].Length = 5;
HuffQ6[0][ 8].Code = 23; HuffQ6[0][ 8].Length = 5;
HuffQ6[0][ 9].Code = 21; HuffQ6[0][ 9].Length = 5;
HuffQ6[0][10].Code = 26; HuffQ6[0][10].Length = 5;
HuffQ6[0][11].Code = 30; HuffQ6[0][11].Length = 5;
HuffQ6[0][12].Code = 0; HuffQ6[0][12].Length = 4;
HuffQ6[0][13].Code = 2; HuffQ6[0][13].Length = 4;
HuffQ6[0][14].Code = 5; HuffQ6[0][14].Length = 4;
HuffQ6[0][15].Code = 7; HuffQ6[0][15].Length = 4;
HuffQ6[0][16].Code = 3; HuffQ6[0][16].Length = 4;
HuffQ6[0][17].Code = 4; HuffQ6[0][17].Length = 4;
HuffQ6[0][18].Code = 31; HuffQ6[0][18].Length = 5;
HuffQ6[0][19].Code = 28; HuffQ6[0][19].Length = 5;
HuffQ6[0][20].Code = 25; HuffQ6[0][20].Length = 5;
HuffQ6[0][21].Code = 27; HuffQ6[0][21].Length = 5;
HuffQ6[0][22].Code = 24; HuffQ6[0][22].Length = 5;
HuffQ6[0][23].Code = 20; HuffQ6[0][23].Length = 5;
HuffQ6[0][24].Code = 18; HuffQ6[0][24].Length = 5;
HuffQ6[0][25].Code = 12; HuffQ6[0][25].Length = 5;
HuffQ6[0][26].Code = 2; HuffQ6[0][26].Length = 5;
HuffQ6[0][27].Code = 58; HuffQ6[0][27].Length = 6;
HuffQ6[0][28].Code = 33; HuffQ6[0][28].Length = 6;
HuffQ6[0][29].Code = 7; HuffQ6[0][29].Length = 6;
HuffQ6[0][30].Code = 64; HuffQ6[0][30].Length = 7;
//more shaped, book 1
HuffQ6[1][ 0].Code = 6472; HuffQ6[1][ 0].Length = 13;
HuffQ6[1][ 1].Code = 6474; HuffQ6[1][ 1].Length = 13;
HuffQ6[1][ 2].Code = 808; HuffQ6[1][ 2].Length = 10;
HuffQ6[1][ 3].Code = 405; HuffQ6[1][ 3].Length = 9;
HuffQ6[1][ 4].Code = 203; HuffQ6[1][ 4].Length = 8;
HuffQ6[1][ 5].Code = 102; HuffQ6[1][ 5].Length = 7;
HuffQ6[1][ 6].Code = 49; HuffQ6[1][ 6].Length = 6;
HuffQ6[1][ 7].Code = 9; HuffQ6[1][ 7].Length = 5;
HuffQ6[1][ 8].Code = 15; HuffQ6[1][ 8].Length = 5;
HuffQ6[1][ 9].Code = 31; HuffQ6[1][ 9].Length = 5;
HuffQ6[1][10].Code = 2; HuffQ6[1][10].Length = 4;
HuffQ6[1][11].Code = 6; HuffQ6[1][11].Length = 4;
HuffQ6[1][12].Code = 8; HuffQ6[1][12].Length = 4;
HuffQ6[1][13].Code = 11; HuffQ6[1][13].Length = 4;
HuffQ6[1][14].Code = 13; HuffQ6[1][14].Length = 4;
HuffQ6[1][15].Code = 0; HuffQ6[1][15].Length = 3;
HuffQ6[1][16].Code = 14; HuffQ6[1][16].Length = 4;
HuffQ6[1][17].Code = 10; HuffQ6[1][17].Length = 4;
HuffQ6[1][18].Code = 9; HuffQ6[1][18].Length = 4;
HuffQ6[1][19].Code = 5; HuffQ6[1][19].Length = 4;
HuffQ6[1][20].Code = 3; HuffQ6[1][20].Length = 4;
HuffQ6[1][21].Code = 30; HuffQ6[1][21].Length = 5;
HuffQ6[1][22].Code = 14; HuffQ6[1][22].Length = 5;
HuffQ6[1][23].Code = 8; HuffQ6[1][23].Length = 5;
HuffQ6[1][24].Code = 48; HuffQ6[1][24].Length = 6;
HuffQ6[1][25].Code = 103; HuffQ6[1][25].Length = 7;
HuffQ6[1][26].Code = 201; HuffQ6[1][26].Length = 8;
HuffQ6[1][27].Code = 200; HuffQ6[1][27].Length = 8;
HuffQ6[1][28].Code = 1619; HuffQ6[1][28].Length = 11;
HuffQ6[1][29].Code = 6473; HuffQ6[1][29].Length = 13;
HuffQ6[1][30].Code = 6475; HuffQ6[1][30].Length = 13;
/********************* 63-step quantizer **************************/
/*********************** single samples ***************************/
//less shaped, book 0
HuffQ7[0][ 0].Code = 103; HuffQ7[0][ 0].Length = 8; /* 0.003338 - 01100111 */
HuffQ7[0][ 1].Code = 153; HuffQ7[0][ 1].Length = 8; /* 0.003766 - 10011001 */
HuffQ7[0][ 2].Code = 181; HuffQ7[0][ 2].Length = 8; /* 0.004715 - 10110101 */
HuffQ7[0][ 3].Code = 233; HuffQ7[0][ 3].Length = 8; /* 0.005528 - 11101001 */
HuffQ7[0][ 4].Code = 64; HuffQ7[0][ 4].Length = 7; /* 0.006677 - 1000000 */
HuffQ7[0][ 5].Code = 65; HuffQ7[0][ 5].Length = 7; /* 0.007041 - 1000001 */
HuffQ7[0][ 6].Code = 77; HuffQ7[0][ 6].Length = 7; /* 0.007733 - 1001101 */
HuffQ7[0][ 7].Code = 81; HuffQ7[0][ 7].Length = 7; /* 0.008296 - 1010001 */
HuffQ7[0][ 8].Code = 91; HuffQ7[0][ 8].Length = 7; /* 0.009295 - 1011011 */
HuffQ7[0][ 9].Code = 113; HuffQ7[0][ 9].Length = 7; /* 0.010814 - 1110001 */
HuffQ7[0][10].Code = 112; HuffQ7[0][10].Length = 7; /* 0.010807 - 1110000 */
HuffQ7[0][11].Code = 24; HuffQ7[0][11].Length = 6; /* 0.012748 - 011000 */
HuffQ7[0][12].Code = 29; HuffQ7[0][12].Length = 6; /* 0.013390 - 011101 */
HuffQ7[0][13].Code = 35; HuffQ7[0][13].Length = 6; /* 0.014224 - 100011 */
HuffQ7[0][14].Code = 37; HuffQ7[0][14].Length = 6; /* 0.015201 - 100101 */
HuffQ7[0][15].Code = 41; HuffQ7[0][15].Length = 6; /* 0.016642 - 101001 */
HuffQ7[0][16].Code = 44; HuffQ7[0][16].Length = 6; /* 0.017292 - 101100 */
HuffQ7[0][17].Code = 46; HuffQ7[0][17].Length = 6; /* 0.018647 - 101110 */
HuffQ7[0][18].Code = 51; HuffQ7[0][18].Length = 6; /* 0.020473 - 110011 */
HuffQ7[0][19].Code = 49; HuffQ7[0][19].Length = 6; /* 0.020152 - 110001 */
HuffQ7[0][20].Code = 54; HuffQ7[0][20].Length = 6; /* 0.021315 - 110110 */
HuffQ7[0][21].Code = 55; HuffQ7[0][21].Length = 6; /* 0.021358 - 110111 */
HuffQ7[0][22].Code = 57; HuffQ7[0][22].Length = 6; /* 0.021700 - 111001 */
HuffQ7[0][23].Code = 60; HuffQ7[0][23].Length = 6; /* 0.022449 - 111100 */
HuffQ7[0][24].Code = 0; HuffQ7[0][24].Length = 5; /* 0.023063 - 00000 */
HuffQ7[0][25].Code = 2; HuffQ7[0][25].Length = 5; /* 0.023854 - 00010 */
HuffQ7[0][26].Code = 10; HuffQ7[0][26].Length = 5; /* 0.025481 - 01010 */
HuffQ7[0][27].Code = 5; HuffQ7[0][27].Length = 5; /* 0.024867 - 00101 */
HuffQ7[0][28].Code = 9; HuffQ7[0][28].Length = 5; /* 0.025352 - 01001 */
HuffQ7[0][29].Code = 6; HuffQ7[0][29].Length = 5; /* 0.025074 - 00110 */
HuffQ7[0][30].Code = 13; HuffQ7[0][30].Length = 5; /* 0.025745 - 01101 */
HuffQ7[0][31].Code = 7; HuffQ7[0][31].Length = 5; /* 0.025195 - 00111 */
HuffQ7[0][32].Code = 11; HuffQ7[0][32].Length = 5; /* 0.025502 - 01011 */
HuffQ7[0][33].Code = 15; HuffQ7[0][33].Length = 5; /* 0.026251 - 01111 */
HuffQ7[0][34].Code = 8; HuffQ7[0][34].Length = 5; /* 0.025260 - 01000 */
HuffQ7[0][35].Code = 4; HuffQ7[0][35].Length = 5; /* 0.024418 - 00100 */
HuffQ7[0][36].Code = 3; HuffQ7[0][36].Length = 5; /* 0.023983 - 00011 */
HuffQ7[0][37].Code = 1; HuffQ7[0][37].Length = 5; /* 0.023697 - 00001 */
HuffQ7[0][38].Code = 63; HuffQ7[0][38].Length = 6; /* 0.023041 - 111111 */
HuffQ7[0][39].Code = 62; HuffQ7[0][39].Length = 6; /* 0.022656 - 111110 */
HuffQ7[0][40].Code = 61; HuffQ7[0][40].Length = 6; /* 0.022549 - 111101 */
HuffQ7[0][41].Code = 53; HuffQ7[0][41].Length = 6; /* 0.021151 - 110101 */
HuffQ7[0][42].Code = 59; HuffQ7[0][42].Length = 6; /* 0.022042 - 111011 */
HuffQ7[0][43].Code = 52; HuffQ7[0][43].Length = 6; /* 0.020837 - 110100 */
HuffQ7[0][44].Code = 48; HuffQ7[0][44].Length = 6; /* 0.019446 - 110000 */
HuffQ7[0][45].Code = 47; HuffQ7[0][45].Length = 6; /* 0.019189 - 101111 */
HuffQ7[0][46].Code = 43; HuffQ7[0][46].Length = 6; /* 0.017177 - 101011 */
HuffQ7[0][47].Code = 42; HuffQ7[0][47].Length = 6; /* 0.017035 - 101010 */
HuffQ7[0][48].Code = 39; HuffQ7[0][48].Length = 6; /* 0.015287 - 100111 */
HuffQ7[0][49].Code = 36; HuffQ7[0][49].Length = 6; /* 0.014559 - 100100 */
HuffQ7[0][50].Code = 33; HuffQ7[0][50].Length = 6; /* 0.014117 - 100001 */
HuffQ7[0][51].Code = 28; HuffQ7[0][51].Length = 6; /* 0.012776 - 011100 */
HuffQ7[0][52].Code = 117; HuffQ7[0][52].Length = 7; /* 0.011107 - 1110101 */
HuffQ7[0][53].Code = 101; HuffQ7[0][53].Length = 7; /* 0.010636 - 1100101 */
HuffQ7[0][54].Code = 100; HuffQ7[0][54].Length = 7; /* 0.009751 - 1100100 */
HuffQ7[0][55].Code = 80; HuffQ7[0][55].Length = 7; /* 0.008132 - 1010000 */
HuffQ7[0][56].Code = 69; HuffQ7[0][56].Length = 7; /* 0.007091 - 1000101 */
HuffQ7[0][57].Code = 68; HuffQ7[0][57].Length = 7; /* 0.007084 - 1000100 */
HuffQ7[0][58].Code = 50; HuffQ7[0][58].Length = 7; /* 0.006277 - 0110010 */
HuffQ7[0][59].Code = 232; HuffQ7[0][59].Length = 8; /* 0.005386 - 11101000 */
HuffQ7[0][60].Code = 180; HuffQ7[0][60].Length = 8; /* 0.004408 - 10110100 */
HuffQ7[0][61].Code = 152; HuffQ7[0][61].Length = 8; /* 0.003759 - 10011000 */
HuffQ7[0][62].Code = 102; HuffQ7[0][62].Length = 8; /* 0.003160 - 01100110 */
//more shaped, book 1
HuffQ7[1][ 0].Code = 14244; HuffQ7[1][ 0].Length = 14; /* 0.000059 - 11011110100100 */
HuffQ7[1][ 1].Code = 14253; HuffQ7[1][ 1].Length = 14; /* 0.000098 - 11011110101101 */
HuffQ7[1][ 2].Code = 14246; HuffQ7[1][ 2].Length = 14; /* 0.000078 - 11011110100110 */
HuffQ7[1][ 3].Code = 14254; HuffQ7[1][ 3].Length = 14; /* 0.000111 - 11011110101110 */
HuffQ7[1][ 4].Code = 3562; HuffQ7[1][ 4].Length = 12; /* 0.000320 - 110111101010 */
HuffQ7[1][ 5].Code = 752; HuffQ7[1][ 5].Length = 10; /* 0.000920 - 1011110000 */
HuffQ7[1][ 6].Code = 753; HuffQ7[1][ 6].Length = 10; /* 0.001057 - 1011110001 */
HuffQ7[1][ 7].Code = 160; HuffQ7[1][ 7].Length = 9; /* 0.001403 - 010100000 */
HuffQ7[1][ 8].Code = 162; HuffQ7[1][ 8].Length = 9; /* 0.001579 - 010100010 */
HuffQ7[1][ 9].Code = 444; HuffQ7[1][ 9].Length = 9; /* 0.002486 - 110111100 */
HuffQ7[1][10].Code = 122; HuffQ7[1][10].Length = 8; /* 0.003772 - 01111010 */
HuffQ7[1][11].Code = 223; HuffQ7[1][11].Length = 8; /* 0.005710 - 11011111 */
HuffQ7[1][12].Code = 60; HuffQ7[1][12].Length = 7; /* 0.006858 - 0111100 */
HuffQ7[1][13].Code = 73; HuffQ7[1][13].Length = 7; /* 0.008033 - 1001001 */
HuffQ7[1][14].Code = 110; HuffQ7[1][14].Length = 7; /* 0.009827 - 1101110 */
HuffQ7[1][15].Code = 14; HuffQ7[1][15].Length = 6; /* 0.012601 - 001110 */
HuffQ7[1][16].Code = 24; HuffQ7[1][16].Length = 6; /* 0.013194 - 011000 */
HuffQ7[1][17].Code = 25; HuffQ7[1][17].Length = 6; /* 0.013938 - 011001 */
HuffQ7[1][18].Code = 34; HuffQ7[1][18].Length = 6; /* 0.015693 - 100010 */
HuffQ7[1][19].Code = 37; HuffQ7[1][19].Length = 6; /* 0.017846 - 100101 */
HuffQ7[1][20].Code = 54; HuffQ7[1][20].Length = 6; /* 0.020078 - 110110 */
HuffQ7[1][21].Code = 3; HuffQ7[1][21].Length = 5; /* 0.022975 - 00011 */
HuffQ7[1][22].Code = 9; HuffQ7[1][22].Length = 5; /* 0.025631 - 01001 */
HuffQ7[1][23].Code = 11; HuffQ7[1][23].Length = 5; /* 0.027021 - 01011 */
HuffQ7[1][24].Code = 16; HuffQ7[1][24].Length = 5; /* 0.031465 - 10000 */
HuffQ7[1][25].Code = 19; HuffQ7[1][25].Length = 5; /* 0.034244 - 10011 */
HuffQ7[1][26].Code = 21; HuffQ7[1][26].Length = 5; /* 0.035921 - 10101 */
HuffQ7[1][27].Code = 24; HuffQ7[1][27].Length = 5; /* 0.037938 - 11000 */
HuffQ7[1][28].Code = 26; HuffQ7[1][28].Length = 5; /* 0.039595 - 11010 */
HuffQ7[1][29].Code = 29; HuffQ7[1][29].Length = 5; /* 0.041546 - 11101 */
HuffQ7[1][30].Code = 31; HuffQ7[1][30].Length = 5; /* 0.042623 - 11111 */
HuffQ7[1][31].Code = 2; HuffQ7[1][31].Length = 4; /* 0.045180 - 0010 */
HuffQ7[1][32].Code = 0; HuffQ7[1][32].Length = 4; /* 0.043151 - 0000 */
HuffQ7[1][33].Code = 30; HuffQ7[1][33].Length = 5; /* 0.042538 - 11110 */
HuffQ7[1][34].Code = 28; HuffQ7[1][34].Length = 5; /* 0.041422 - 11100 */
HuffQ7[1][35].Code = 25; HuffQ7[1][35].Length = 5; /* 0.039145 - 11001 */
HuffQ7[1][36].Code = 22; HuffQ7[1][36].Length = 5; /* 0.036691 - 10110 */
HuffQ7[1][37].Code = 20; HuffQ7[1][37].Length = 5; /* 0.034955 - 10100 */
HuffQ7[1][38].Code = 14; HuffQ7[1][38].Length = 5; /* 0.029155 - 01110 */
HuffQ7[1][39].Code = 13; HuffQ7[1][39].Length = 5; /* 0.027921 - 01101 */
HuffQ7[1][40].Code = 8; HuffQ7[1][40].Length = 5; /* 0.025553 - 01000 */
HuffQ7[1][41].Code = 6; HuffQ7[1][41].Length = 5; /* 0.023093 - 00110 */
HuffQ7[1][42].Code = 2; HuffQ7[1][42].Length = 5; /* 0.021200 - 00010 */
HuffQ7[1][43].Code = 46; HuffQ7[1][43].Length = 6; /* 0.018134 - 101110 */
HuffQ7[1][44].Code = 35; HuffQ7[1][44].Length = 6; /* 0.015824 - 100011 */
HuffQ7[1][45].Code = 31; HuffQ7[1][45].Length = 6; /* 0.014701 - 011111 */
HuffQ7[1][46].Code = 21; HuffQ7[1][46].Length = 6; /* 0.013187 - 010101 */
HuffQ7[1][47].Code = 15; HuffQ7[1][47].Length = 6; /* 0.012776 - 001111 */
HuffQ7[1][48].Code = 95; HuffQ7[1][48].Length = 7; /* 0.009664 - 1011111 */
HuffQ7[1][49].Code = 72; HuffQ7[1][49].Length = 7; /* 0.007922 - 1001000 */
HuffQ7[1][50].Code = 41; HuffQ7[1][50].Length = 7; /* 0.006838 - 0101001 */
HuffQ7[1][51].Code = 189; HuffQ7[1][51].Length = 8; /* 0.005024 - 10111101 */
HuffQ7[1][52].Code = 123; HuffQ7[1][52].Length = 8; /* 0.003830 - 01111011 */
HuffQ7[1][53].Code = 377; HuffQ7[1][53].Length = 9; /* 0.002232 - 101111001 */
HuffQ7[1][54].Code = 161; HuffQ7[1][54].Length = 9; /* 0.001566 - 010100001 */
HuffQ7[1][55].Code = 891; HuffQ7[1][55].Length = 10; /* 0.001383 - 1101111011 */
HuffQ7[1][56].Code = 327; HuffQ7[1][56].Length = 10; /* 0.000900 - 0101000111 */
HuffQ7[1][57].Code = 326; HuffQ7[1][57].Length = 10; /* 0.000790 - 0101000110 */
HuffQ7[1][58].Code = 3560; HuffQ7[1][58].Length = 12; /* 0.000254 - 110111101000 */
HuffQ7[1][59].Code = 14255; HuffQ7[1][59].Length = 14; /* 0.000117 - 11011110101111 */
HuffQ7[1][60].Code = 14247; HuffQ7[1][60].Length = 14; /* 0.000085 - 11011110100111 */
HuffQ7[1][61].Code = 14252; HuffQ7[1][61].Length = 14; /* 0.000085 - 11011110101100 */
HuffQ7[1][62].Code = 14245; HuffQ7[1][62].Length = 14; /* 0.000065 - 11011110100101 */
}
@@ -0,0 +1,6 @@
#ifndef _huff_new_h_
#define _huff_new_h
#include "bitstream.h"
#endif
@@ -0,0 +1,887 @@
#include <DataIO.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include "in_mpc.h"
#include "idtag.h"
#include "mpc_dec.h"
static const char ListSeparator[] = { "; " };
/* V A R I A B L E S */
static const char* GenreList [] = {
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
"Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
"Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
"Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
"Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
"Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
"Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
"Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
"Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
"Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
"Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
"New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
"Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
"Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",
"Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
"Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
"Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
"Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
"Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
"Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
"Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
"Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
"Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat",
"Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
"Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
"SynthPop",
};
// free tagdata from memory
void
StreamInfo::Clear()
{
size_t i;
if ( tagitems != NULL ) {
for ( i = 0; i < tagitem_count; i++ ) {
if ( tagitems[i].Item ) free ( tagitems[i].Item );
if ( tagitems[i].Value ) free ( tagitems[i].Value );
}
free ( tagitems );
tagitems = NULL;
}
if ( filename ) {
free ( filename );
filename = NULL;
}
tagitem_count = 0;
tagtype = (tag_t)0;
}
StreamInfo::StreamInfo ()
{
memset ( &simple, 0, sizeof (simple) );
tagitem_count = 0;
tagtype = (tag_t)0;
tagitems = NULL;
filename = NULL;
}
void
StreamInfo::SetFilename ( const char *fn )
{
if ( filename ) free ( filename );
filename = strdup ( fn );
}
const char *
StreamInfo::GetFilename ()
{
return filename ? filename : "";
}
// return pointer to value in tag field
static char *
TagValue(const char* item, const StreamInfo* Info)
{
size_t i;
for ( i = 0; i < Info->tagitem_count; i++ ) {
// Are items case sensitive?
if (!strcasecmp(item, Info->tagitems[i].Item))
return (char*)Info->tagitems[i].Value;
}
return 0;
}
// add new field to tagdata
static int
NewTagField(const char* item, const size_t itemsize, const char* value,
const size_t valuesize, const unsigned int flags, StreamInfo* Info,
const enum tag_rel reliability)
{
size_t itemnum = Info->tagitem_count++;
// no real error handling yet
Info->tagitems = (TagItem*) realloc ( Info->tagitems, Info->tagitem_count * sizeof (TagItem) );
if ( Info->tagitems == NULL ) {
Info->tagitem_count = 0;
return 1;
}
Info->tagitems[itemnum].Item = (char*)malloc ( itemsize + 1 );
if ( Info->tagitems[itemnum].Item == NULL ) { // couldn't allocate memory, revert to original items
Info->tagitems = (TagItem*) realloc ( Info->tagitems, --Info->tagitem_count * sizeof (TagItem) );
return 1;
}
Info->tagitems[itemnum].Value = (char*)malloc ( valuesize + 1 );
if ( Info->tagitems[itemnum].Value == NULL ) { // couldn't allocate memory, revert to original items
free ( Info->tagitems[itemnum].Item );
Info->tagitems = (TagItem*) realloc ( Info->tagitems, --Info->tagitem_count * sizeof (TagItem) );
return 1;
}
memcpy ( Info->tagitems[itemnum].Item , item , itemsize );
memcpy ( Info->tagitems[itemnum].Value, value, valuesize );
Info->tagitems[itemnum].Item [itemsize] = '\0';
Info->tagitems[itemnum].Value[valuesize] = '\0';
Info->tagitems[itemnum].ItemSize = itemsize;
Info->tagitems[itemnum].ValueSize = valuesize;
Info->tagitems[itemnum].Flags = flags;
Info->tagitems[itemnum].Reliability = reliability;
return 0;
}
// replace old value in tagdata field
static int
ReplaceTagField(const char* value, const size_t valuesize, const unsigned int flags,
StreamInfo* Info, size_t itemnum, const enum tag_rel reliability)
{
// no real error handling yet
free ( Info->tagitems[itemnum].Value );
Info->tagitems[itemnum].Value = (char*)malloc ( valuesize + 1 );
if ( Info->tagitems[itemnum].Value == NULL ) // couldn't allocate memory
return 1;
memcpy ( Info->tagitems[itemnum].Value, value, valuesize );
Info->tagitems[itemnum].Value[valuesize] = '\0';
Info->tagitems[itemnum].ValueSize = valuesize;
Info->tagitems[itemnum].Flags = flags;
Info->tagitems[itemnum].Reliability = reliability;
return 0;
}
#if 0
// insert item to tagdata. calls either new or replace
static int
InsertTagField(const char* item, size_t itemsize, const char* value,
size_t valuesize, const unsigned int flags, StreamInfo* Info)
{
size_t i;
if ( itemsize == 0 ) itemsize = strlen ( item ); // autodetect size
if ( valuesize == 0 ) valuesize = strlen ( value ); // autodetect size
for ( i = 0; i < Info->tagitem_count; i++ ) {
// are items case sensitive?
if (!strcasecmp(item, Info->tagitems[i].Item)) // replace value of first item found
return ReplaceTagField ( value, valuesize, flags, Info, i, (tag_rel)0 );
}
return NewTagField ( item, itemsize, value, valuesize, flags, Info, (tag_rel)0 );// insert new field
}
#endif
// insert item to tagdata but only if reliability > previous tag's reliability
static int
InsertTagFieldLonger(const char* item, size_t itemsize, const char* value,
size_t valuesize, const unsigned int flags, StreamInfo* Info,
const enum tag_rel reliability)
{
size_t i;
if ( itemsize == 0 ) itemsize = strlen ( item ); // autodetect size
if ( valuesize == 0 ) valuesize = strlen ( value ); // autodetect size
for ( i = 0; i < Info->tagitem_count; i++ ) {
// are items case sensitive?
if (!strcasecmp(item, Info->tagitems[i].Item)) {
if ( reliability > Info->tagitems[i].Reliability ) // replace value of first item found
return ReplaceTagField ( value, valuesize, flags, Info, i, reliability );
else
return 0;
}
}
return NewTagField ( item, itemsize, value, valuesize, flags, Info, reliability ); // insert new field
}
#if 0
// Convert UNICODE to UTF-8
// Return number of bytes written
static int
unicodeToUtf8(const uint16/*WCHAR*/* lpWideCharStr, char* lpMultiByteStr, int cwcChars)
{
const unsigned short* pwc = (unsigned short *)lpWideCharStr;
unsigned char* pmb = (unsigned char *)lpMultiByteStr;
const unsigned short* pwce;
size_t cBytes = 0;
if ( cwcChars >= 0 ) {
pwce = pwc + cwcChars;
} else {
pwce = (unsigned short *)((size_t)-1);
}
while ( pwc < pwce ) {
unsigned short wc = *pwc++;
if ( wc < 0x00000080 ) {
*pmb++ = (char)wc;
cBytes++;
} else
if ( wc < 0x00000800 ) {
*pmb++ = (char)(0xC0 | ((wc >> 6) & 0x1F));
cBytes++;
*pmb++ = (char)(0x80 | (wc & 0x3F));
cBytes++;
} else
if ( wc < 0x00010000 ) {
*pmb++ = (char)(0xE0 | ((wc >> 12) & 0x0F));
cBytes++;
*pmb++ = (char)(0x80 | ((wc >> 6) & 0x3F));
cBytes++;
*pmb++ = (char)(0x80 | (wc & 0x3F));
cBytes++;
}
if ( wc == L'\0' )
return cBytes;
}
return cBytes;
}
// Convert UTF-8 coded string to UNICODE
// Return number of characters converted
static int
utf8ToUnicode(const char* lpMultiByteStr, uint16/*WCHAR*/* lpWideCharStr, int cmbChars)
{
const unsigned char* pmb = (unsigned char *)lpMultiByteStr;
unsigned short* pwc = (unsigned short *)lpWideCharStr;
const unsigned char* pmbe;
size_t cwChars = 0;
if ( cmbChars >= 0 ) {
pmbe = pmb + cmbChars;
} else {
pmbe = (unsigned char *)((size_t)-1);
}
while ( pmb < pmbe ) {
char mb = *pmb++;
unsigned int cc = 0;
unsigned int wc;
while ( (cc < 7) && (mb & (1 << (7 - cc)))) {
cc++;
}
if ( cc == 1 || cc > 6 ) // illegal character combination for UTF-8
continue;
if ( cc == 0 ) {
wc = mb;
} else {
wc = (mb & ((1 << (7 - cc)) - 1)) << ((cc - 1) * 6);
while ( --cc > 0 ) {
if ( pmb == pmbe ) // reached end of the buffer
return cwChars;
mb = *pmb++;
if ( ((mb >> 6) & 0x03) != 2 ) // not part of multibyte character
return cwChars;
wc |= (mb & 0x3F) << ((cc - 1) * 6);
}
}
if ( wc & 0xFFFF0000 )
wc = L'?';
*pwc++ = wc;
cwChars++;
if ( wc == L'\0' )
return cwChars;
}
return cwChars;
}
#endif
// convert Windows ANSI to UTF-8
static int
ConvertANSIToUTF8(const char *ansi, char *utf8)
{
// ToDo:
return 0;
}
#if 0
static int
ConvertTagFieldToUTF8(StreamInfo *Info, size_t itemnum)
{
// ToDo:
return 0;
}
#endif
// replace list separator characters in tag field
static int
ReplaceListSeparator(const char* old_sep, const char* new_sep, StreamInfo* Info,
size_t itemnum)
{
unsigned char* new_value;
unsigned char* p;
size_t os_len;
size_t ns_len;
size_t count;
size_t new_len;
size_t i;
int error;
if ( Info->tagitems[itemnum].Flags & 1<<1 ) // data in binary
return 0;
os_len = strlen ( old_sep );
ns_len = strlen ( new_sep );
if ( os_len == 0 ) os_len = 1; // allow null character
if ( ns_len == 0 ) ns_len = 1;
if ( Info->tagitems[itemnum].Value == NULL || // nothing to do
Info->tagitems[itemnum].ValueSize == 0 )
return 0;
count = 0;
for ( i = 0; i < Info->tagitems[itemnum].ValueSize - os_len + 1; i++ ) {
if ( memcmp ( Info->tagitems[itemnum].Value+i, old_sep, os_len ) == 0 )
count++;
}
if ( count == 0 )
return 0;
new_len = Info->tagitems[itemnum].ValueSize - (count * os_len) + (count * ns_len);
if ( (new_value = (unsigned char *)malloc ( new_len )) == NULL )
return 1;
p = new_value;
for ( i = 0; i < Info->tagitems[itemnum].ValueSize; i++ ) {
if ( i + os_len - 1 >= Info->tagitems[itemnum].ValueSize ||
memcmp ( Info->tagitems[itemnum].Value+i, old_sep, os_len ) != 0 ) {
*p++ = Info->tagitems[itemnum].Value[i];
} else {
memcpy ( p, new_sep, ns_len );
p += ns_len;
i += os_len - 1;
}
}
error = ReplaceTagField ( (const char*)new_value, new_len, Info->tagitems[itemnum].Flags, Info, itemnum, Info->tagitems[itemnum].Reliability );
free ( new_value );
return error;
}
static int
GenreToInteger(const char *GenreStr)
{
size_t i;
for ( i = 0; i < sizeof(GenreList) / sizeof(*GenreList); i++ ) {
if (!strcasecmp(GenreStr, GenreList[i]))
return i;
}
return -1;
}
static void
GenreToString(char *GenreStr, const unsigned int genre)
{
GenreStr [0] = '\0';
if ( genre < NO_GENRES )
strcpy ( GenreStr, GenreList [genre] );
}
/*
* Copies src to dst. Copying is stopped at `\0' char is detected or if
* len chars are copied.
* Trailing blanks are removed and the string is `\0` terminated.
*/
static void
memcpy_crop(char* dst, const char* src, size_t len)
{
size_t i;
for ( i = 0; i < len; i++ )
if ( src[i] != '\0' )
dst[i] = src[i];
else
break;
// dst[i] points behind the string contents
while ( i > 0 && dst [i-1] == ' ' )
i--;
dst [i] = '\0';
}
#if 0
// replaces % sequences with real characters
static void
fix_percentage_sequences(char *string)
{
char temp[PATH_MAX];
char* t = temp;
char* s = string;
int value;
int b1, b2; //, b3, b4;
int v1, v2; //, v3, v4;
do {
value = *s++;
if ( value == '%' ) {
if ( *s != '\0' ) b1 = *s++;
else b1 = '\0';
if ( *s != '\0' ) b2 = *s++;
else b2 = '\0';
if ( ((b1 >= '0' && b1 <= '9') || (b1 >= 'A' && b1 <= 'F')) &&
((b2 >= '0' && b2 <= '9') || (b2 >= 'A' && b2 <= 'F')) ) {
if ( b1 <= '9' ) v1 = b1 - '0';
else v1 = b1 - 'A' + 10;
if ( b2 <= '9' ) v2 = b2 - '0';
else v2 = b2 - 'A' + 10;
if ( v1 == 0 && v2 == 0 ) { // %00xx
/*
if ( *s != '\0' ) b1 = *s++;
else b1 = '\0';
if ( *s != '\0' ) b2 = *s++;
else b2 = '\0';
if ( *s != '\0' ) b3 = *s++;
else b2 = '\0';
if ( *s != '\0' ) b4 = *s++;
else b4 = '\0';
if ( b1 <= '9' ) v1 = b1 - '0';
else v1 = b1 - 'A' + 10;
if ( b2 <= '9' ) v2 = b2 - '0';
else v2 = b2 - 'A' + 10;
if ( b3 <= '9' ) v3 = b3 - '0';
else v3 = b3 - 'A' + 10;
if ( b4 <= '9' ) v4 = b4 - '0';
else v4 = b4 - 'A' + 10;
if ( v1 != 0 || v2 != 0 ) {
*t++ = ' '; // no multibyte support, unknown character
} else { // %0000+xxxx+
*t++ = ' ';
while ( *s && ((*s >= '0' && *s <= '9') || (*s >= 'A' && *s <= 'F')) )
s++;
}
*/
*t++ = ' ';
while ( *s && ((*s >= '0' && *s <= '9') || (*s >= 'A' && *s <= 'F')) )
s++;
} else { // %xx
*t++ = (v1 << 4) + v2;
}
} else { // %aa
*t++ = '%';
*t++ = b1;
*t++ = b2;
}
} else {
*t++ = value;
}
} while ( value != '\0' );
strcpy ( string, temp );
}
#endif
// searches and reads a ID3v1 tag
int StreamInfo::ReadID3v1Tag(BPositionIO *stream)
{
/* unsigned */char tmp [128];
/* unsigned */char value [32];
char utf8[32*2];
if (stream->Seek(simple.TagOffset - sizeof(tmp), SEEK_SET) < B_OK)
return 0;
if (stream->Read(tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
// check for id3-tag
if (memcmp(tmp, "TAG", 3) != 0)
return 0;
memcpy_crop ( value, tmp + 3, 30 );
if ( value[0] != '\0' ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_TITLE , 0, utf8, 0, 0, this, ID3v1 );
}
memcpy_crop ( value, tmp + 33, 30 );
if ( value[0] != '\0' ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_ARTIST , 0, utf8, 0, 0, this, ID3v1 );
}
memcpy_crop ( value, tmp + 63, 30 );
if ( value[0] != '\0' ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_ALBUM , 0, utf8, 0, 0, this, ID3v1 );
}
memcpy_crop ( value, tmp + 93, 4 );
if ( value[0] != '\0' ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_YEAR , 0, utf8, 0, 0, this, ID3v1 );
}
memcpy_crop ( value, tmp + 97, 30 );
if ( value[0] != '\0' ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_COMMENT, 0, utf8, 0, 0, this, ID3v1 );
}
if ( tmp[125] == 0 ) {
sprintf ( value, "%d", tmp[126] );
if ( value[0] != '\0' && atoi (value) != 0 ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_TRACK, 0, utf8, 0, 0, this, ID3v1 );
}
}
GenreToString ( value, tmp[127] );
if ( value[0] != '\0' ) {
ConvertANSIToUTF8 ( value, utf8 );
InsertTagFieldLonger ( APE_TAG_FIELD_GENRE , 0, utf8, 0, 0, this, ID3v1 );
}
simple.TagOffset -= 128;
tagtype = ID3v1_tag;
return 0;
}
struct APETagFooterStruct {
unsigned char ID [8]; // should equal 'APETAGEX'
unsigned char Version [4]; // 1000 = version 1.0, 2000 = version 2.0
unsigned char Length [4]; // complete size of the tag, including footer, excluding header
unsigned char TagCount [4]; // number of fields in the tag
unsigned char Flags [4]; // tag flags (none currently defined)
unsigned char Reserved [8]; // reserved for later use
};
static unsigned long
Read_LE_Uint32 ( const unsigned char* p )
{
return ((unsigned long)p[0] << 0) |
((unsigned long)p[1] << 8) |
((unsigned long)p[2] << 16) |
((unsigned long)p[3] << 24);
}
/*static void
Write_LE_Uint32 ( unsigned char* p, const unsigned long value )
{
p[0] = (unsigned char) (value >> 0);
p[1] = (unsigned char) (value >> 8);
p[2] = (unsigned char) (value >> 16);
p[3] = (unsigned char) (value >> 24);
}
*/
int
StreamInfo::ReadAPE1Tag(BPositionIO *stream)
{
unsigned long vsize;
unsigned long isize;
unsigned long flags;
/*unsigned */char* buff;
/*unsigned */char* p;
/*unsigned */char* end;
char* utf8;
struct APETagFooterStruct T;
unsigned long TagLen;
unsigned long TagCount;
if (stream->Seek(simple.TagOffset - sizeof T, SEEK_SET) < B_OK)
return 0;
if (stream->Read(&T, sizeof T) != sizeof T)
return 0;
if ( memcmp ( T.ID, "APETAGEX", sizeof T.ID ) != 0 )
return 0;
if ( Read_LE_Uint32 (T.Version) != 1000 )
return 0;
TagLen = Read_LE_Uint32 (T.Length);
if ( TagLen <= sizeof T )
return 0;
if (stream->Seek(simple.TagOffset - TagLen, SEEK_SET ) < B_OK)
return 0;
buff = (char *)malloc ( TagLen );
if ( buff == NULL )
return 1;
if (stream->Read(buff, TagLen - sizeof(T)) != ssize_t(TagLen - sizeof(T))) {
free(buff);
return 0;
}
TagCount = Read_LE_Uint32 (T.TagCount);
end = buff + TagLen - sizeof (T);
for ( p = buff; p < end /*&& *p */ && TagCount--; ) {
vsize = Read_LE_Uint32 ( (unsigned char *) p ); p += 4;
flags = Read_LE_Uint32 ( (unsigned char *) p ); p += 4;
isize = strlen(p);
if ( vsize > 0 ) {
if ( (utf8 = (char*)malloc ( (vsize + 1) * 3 )) == NULL ) {
free ( buff );
return 1;
}
ConvertANSIToUTF8 ( p + isize + 1, utf8 );
InsertTagFieldLonger ( p, isize, utf8, 0, 0, this, APE1 ); // flags not used with APE 1.0
free ( utf8 );
}
p += isize + 1 + vsize;
}
simple.TagOffset -= TagLen;
tagtype = APE1_tag;
free(buff);
return 0;
}
int
StreamInfo::ReadAPE2Tag(BPositionIO *stream)
{
unsigned long vsize;
unsigned long isize;
unsigned long flags;
/*unsigned */char* buff;
/*unsigned */char* p;
/*unsigned */char* end;
struct APETagFooterStruct T;
unsigned long TagLen;
unsigned long TagCount;
size_t i;
if (stream->Seek(simple.TagOffset - sizeof(T), SEEK_SET) < B_OK)
return 0;
if (stream->Read(&T, sizeof(T)) != sizeof(T))
return 0;
if (memcmp(T.ID, "APETAGEX", sizeof(T.ID)) != 0)
return 0;
if (Read_LE_Uint32(T.Version) != 2000)
return 0;
TagLen = Read_LE_Uint32(T.Length);
if (TagLen <= sizeof(T))
return 0;
if (stream->Seek(simple.TagOffset - TagLen, SEEK_SET) < B_OK)
return 0;
buff = (char *)malloc(TagLen);
if (buff == NULL)
return 1;
if (stream->Read(buff, TagLen - sizeof(T)) != ssize_t(TagLen - sizeof(T))) {
free(buff);
return 0;
}
TagCount = Read_LE_Uint32(T.TagCount);
end = buff + TagLen - sizeof(T);
for (p = buff; p < end /*&& *p */ && TagCount--;) {
vsize = Read_LE_Uint32((unsigned char *)p); p += 4;
flags = Read_LE_Uint32((unsigned char *)p); p += 4;
isize = strlen(p);
if (vsize > 0)
InsertTagFieldLonger(p, isize, p + isize + 1, vsize, flags, this, APE2);
p += isize + 1 + vsize;
}
simple.TagOffset -= TagLen;
tagtype = APE2_tag;
free (buff);
for (i = 0; i < tagitem_count; i++) {
if (ReplaceListSeparator("\0", ListSeparator, this, i) != 0)
return 2;
}
if (Read_LE_Uint32(T.Flags) & 1<<31) { // Tag contains header
simple.TagOffset -= sizeof (T);
} else { // Check if footer was incorrect
if (stream->Seek(simple.TagOffset - sizeof(T), SEEK_SET ) < B_OK)
return 0;
if (stream->Read(&T, sizeof(T)) != sizeof(T))
return 0;
if (memcmp(T.ID, "APETAGEX", sizeof(T.ID)) != 0)
return 0;
if (Read_LE_Uint32(T.Version) != 2000)
return 0;
if (Read_LE_Uint32(T.Flags) & 1<<29 ) // This is header
simple.TagOffset -= sizeof(T);
}
return 0;
}
bool
_validForID3(const char *string, int maxsize)
{
const unsigned char* p = (unsigned char *)string;
while (*p) {
// only ASCII characters are reliable in ID3v1
if (*p++ >= 0x80)
return false;
}
return ( ((char*)p - string) <= maxsize );
}
// checks if ID3v1 tag can store all tag information
// return 0 if can, 1 if can't
int
CheckID3V1TagDataLoss(const StreamInfo *Info)
{
const char *id3v1_items[] = {
APE_TAG_FIELD_TITLE, // 0
APE_TAG_FIELD_ARTIST, // 1
APE_TAG_FIELD_ALBUM, // 2
APE_TAG_FIELD_YEAR, // 3
APE_TAG_FIELD_COMMENT, // 4
APE_TAG_FIELD_TRACK, // 5
APE_TAG_FIELD_GENRE // 6
};
char* value;
size_t i, j;
if ( (value = TagValue ( APE_TAG_FIELD_TRACK, Info )) ) {
char* p = value;
while ( *p ) {
if ( *p < '0' || *p > '9' ) return 1; // not a number
p++;
}
if ( atoi (value) < 0 || // number won't fit in byte
atoi (value) > 255 )
return 1;
}
if ( ( value = TagValue ( APE_TAG_FIELD_GENRE, Info )) ) {
if ( value[0] != '\0' && (unsigned int)GenreToInteger (value) >= NO_GENRES ) // non-standard genre
return 1;
}
for ( i = 0; i < Info->tagitem_count; i++ ) {
bool bFound = false;
for ( j = 0; j < sizeof (id3v1_items) / sizeof (*id3v1_items); j++ ) {
if (!strcasecmp(Info->tagitems[i].Item, id3v1_items[j])) {
int maxlen;
switch ( j ) {
case 3: // Year
maxlen = 4;
break;
case 4: // Comment
value = TagValue ( APE_TAG_FIELD_TRACK, Info );
if ( value && strcmp ( value, "" ) != 0 )
maxlen = 28;
else
maxlen = 30;
break;
default:
maxlen = 30;
break;
}
if ( !_validForID3 ( Info->tagitems[i].Value, maxlen ) )
return 1;
bFound = TRUE;
break;
}
}
if ( !bFound ) return 1; // field not possible in ID3v1
}
return 0;
}
// scan file for all supported tags and read them
int
StreamInfo::ReadTags(BPositionIO *fp)
{
off_t TagOffs;
do {
TagOffs = simple.TagOffset;
ReadAPE1Tag(fp);
ReadAPE2Tag(fp);
ReadID3v1Tag(fp);
} while (TagOffs != simple.TagOffset);
return 0;
}
// searches for a ID3v2-tag and reads the length (in bytes) of it
// -1 on errors of any kind
long
JumpID3v2(BPositionIO *fp)
{
unsigned char tmp [10];
unsigned int Unsynchronisation; // ID3v2.4-flag
unsigned int ExtHeaderPresent; // ID3v2.4-flag
unsigned int ExperimentalFlag; // ID3v2.4-flag
unsigned int FooterPresent; // ID3v2.4-flag
long ret;
fp->Read(tmp, sizeof(tmp));
// check id3-tag
if (memcmp(tmp, "ID3", 3) != 0)
return 0;
// read flags
Unsynchronisation = tmp[5] & 0x80;
ExtHeaderPresent = tmp[5] & 0x40;
ExperimentalFlag = tmp[5] & 0x20;
FooterPresent = tmp[5] & 0x10;
if ( tmp[5] & 0x0F )
return -1; // not (yet???) allowed
if ( (tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80 )
return -1; // not allowed
// read HeaderSize (syncsave: 4 * $0xxxxxxx = 28 significant bits)
ret = tmp[6] << 21;
ret += tmp[7] << 14;
ret += tmp[8] << 7;
ret += tmp[9] ;
ret += 10;
if (FooterPresent)
ret += 10;
return ret;
}
@@ -0,0 +1,110 @@
#ifndef _idtag_h_
#define _idtag_h_
#include <sys/types.h>
class BPositionIO;
class StreamInfo;
/* D E F I N E S */
#define NO_GENRES 148
// APE Tag item names
#define APE_TAG_FIELD_TITLE "Title"
#define APE_TAG_FIELD_SUBTITLE "Subtitle"
#define APE_TAG_FIELD_ARTIST "Artist"
#define APE_TAG_FIELD_ALBUM "Album"
#define APE_TAG_FIELD_DEBUTALBUM "Debut Album"
#define APE_TAG_FIELD_PUBLISHER "Publisher"
#define APE_TAG_FIELD_CONDUCTOR "Conductor"
#define APE_TAG_FIELD_COMPOSER "Composer"
#define APE_TAG_FIELD_COMMENT "Comment"
#define APE_TAG_FIELD_YEAR "Year"
#define APE_TAG_FIELD_RECORDDATE "Record Date"
#define APE_TAG_FIELD_RECORDLOCATION "Record Location"
#define APE_TAG_FIELD_TRACK "Track"
#define APE_TAG_FIELD_GENRE "Genre"
#define APE_TAG_FIELD_COVER_ART_FRONT "Cover Art (front)"
#define APE_TAG_FIELD_NOTES "Notes"
#define APE_TAG_FIELD_LYRICS "Lyrics"
#define APE_TAG_FIELD_COPYRIGHT "Copyright"
#define APE_TAG_FIELD_PUBLICATIONRIGHT "Publicationright"
#define APE_TAG_FIELD_FILE "File"
#define APE_TAG_FIELD_MEDIA "Media"
#define APE_TAG_FIELD_EANUPC "EAN/UPC"
#define APE_TAG_FIELD_ISRC "ISRC"
#define APE_TAG_FIELD_RELATED_URL "Related"
#define APE_TAG_FIELD_ABSTRACT_URL "Abstract"
#define APE_TAG_FIELD_BIBLIOGRAPHY_URL "Bibliography"
#define APE_TAG_FIELD_BUY_URL "Buy URL"
#define APE_TAG_FIELD_ARTIST_URL "Artist URL"
#define APE_TAG_FIELD_PUBLISHER_URL "Publisher URL"
#define APE_TAG_FIELD_FILE_URL "File URL"
#define APE_TAG_FIELD_COPYRIGHT_URL "Copyright URL"
#define APE_TAG_FIELD_INDEX "Index"
#define APE_TAG_FIELD_INTROPLAY "Introplay"
#define APE_TAG_FIELD_MJ_METADATA "Media Jukebox Metadata"
#define APE_TAG_FIELD_DUMMY "Dummy"
enum tag_t {
auto_tag = -1,
no_tag = 0,
ID3v1_tag = 1,
APE1_tag = 2,
APE2_tag = 3,
Ogg_tag = 4,
ID3v2 = 16,
guessed_tag = 255,
};
// reliability of tag information
enum tag_rel {
guess = 1,
ID3v1 = 10,
APE1 = 19,
APE2 = 20
};
/* V A R I A B L E S */
//extern const char* GenreList []; // holds the genres available for ID3
/* F U N C T I O N S */
// Function that tries to guess tag information from filename
//int GuessTag ( const char* filename, StreamInfo* Info );
// Read tag data
//int ReadID3v1Tag ( FILE* fp, StreamInfo* Info ); // reads ID3v1 tag
//int ReadAPE1Tag ( FILE* fp, StreamInfo* Info ); // reads APE 1.0 tag
//int ReadAPE2Tag ( FILE* fp, StreamInfo* Info ); // reads APE 2.0 tag
//int ReadTags ( FILE* fp, StreamInfo* Info ); // reads all tags from file
// Calculates start of file
long JumpID3v2 ( BPositionIO *file );
/*
// add new field to tagdata
int NewTagField ( const char* item, const size_t itemsize, const char* value, const size_t valuesize, const unsigned int flags, StreamInfo* Info, const enum tag_rel reliability );
// replace old value in tagdata field
int ReplaceTagField ( const char* value, const size_t valuesize, const unsigned int flags, StreamInfo* Info, size_t itemnum, const enum tag_rel reliability );
// Free all tag fields from memory
//void FreeTagFields ( StreamInfo* Info );//obsolete, use StreamInfo::Clear()
// insert item to tagdata. calls either new or replace
int InsertTagField ( const char* item, size_t itemsize, const char* value, size_t valuesize, const unsigned int flags, StreamInfo* Info );
// insert item to tagdata but only if reliability > previous tag's reliability
int InsertTagFieldLonger ( const char* item, size_t itemsize, const char* value, size_t valuesize, const unsigned int flags, StreamInfo* Info, const enum tag_rel reliability );
// Copy item to dest, maximum length to copy is count
int CopyTagValue ( char* dest, const char* item, const StreamInfo* Info, size_t count );
// Return pointer to item or NULL on error
char* TagValue ( const char* item, const StreamInfo* Info );
int GenreToInteger ( const char* GenreStr);
*/
#endif
@@ -0,0 +1,207 @@
/* Winamp plugin for ".mpc Musepack", based on miniSDK by Nullsoft */
/* by Andree Buschmann, contact: [email protected] */
/* --------- ".mpc Musepack" is a registered trademark ---------- */
#include <DataIO.h>
/************************ DEFINES ************************/
//#define WINAMP
//#define WM_WA_MPEG_EOF (WM_USER + 2) // post this to the main window at end of file
//#define NCH_MAX 2 // number of channels (only stereo!)
//#define BPS 16 // bits per sample (only 16 bps!)
//#define BYTES 4 // = (NCH_MAX*(BPS/8)) -> number of bytes needed for one stereo/16bit-sample
//#define M_PI 3.141592653589793238462643383276
// 2nd "*2" for reconstruction of exact filelength
/*********************** INCLUDES ************************/
#include "in_mpc.h"
#include "mpc_dec.h"
#include "idtag.h"
#include <stdio.h>
//SettingsMPC PluginSettings; // AB: PluginSettings holds the parameters for the plugin-configuration
static const char*
Stringify ( unsigned int profile ) // profile is 0...15, where 7...13 is used
{
static const char na [] = "n.a.";
static const char* Names [] = {
na, "'Unstable/Experimental'", na, na,
na, "below 'Telephone'", "below 'Telephone'", "'Telephone'",
"'Thumb'", "'Radio'", "'Standard'", "'Xtreme'",
"'Insane'", "'BrainDead'", "above 'BrainDead'", "above 'BrainDead'"
};
return profile >= sizeof(Names)/sizeof(*Names) ? na : Names [profile];
}
// read information from SV8 header
int StreamInfo::ReadHeaderSV8 ( BPositionIO* fp )
{
// Update (simple.StreamVersion);
return 0;
}
// read information from SV7 header
int StreamInfo::ReadHeaderSV7 ( BPositionIO* fp )
{
const long samplefreqs [4] = { 44100, 48000, 37800, 32000 };
unsigned int HeaderData [8];
unsigned short EstimatedPeakTitle = 0;
if (simple.StreamVersion > 0x71) {
// Update (simple.StreamVersion);
return 0;
}
if (fp->Seek(simple.HeaderPosition, SEEK_SET ) < B_OK) // seek to header start
return ERROR_CODE_FILE;
if (fp->Read(HeaderData, sizeof(HeaderData)) != sizeof HeaderData)
return ERROR_CODE_FILE;
simple.Bitrate = 0;
simple.Frames = HeaderData[1];
simple.IS = 0;
simple.MS = (HeaderData[2] >> 30) & 0x0001;
simple.MaxBand = (HeaderData[2] >> 24) & 0x003F;
simple.BlockSize = 1;
simple.Profile = (HeaderData[2] << 8) >> 28;
simple.ProfileName = Stringify ( simple.Profile );
simple.SampleFreq = samplefreqs [(HeaderData[2]>>16) & 0x0003];
EstimatedPeakTitle = HeaderData[2] & 0xFFFF; // read the ReplayGain data
simple.GainTitle = (HeaderData[3] >> 16) & 0xFFFF;
simple.PeakTitle = HeaderData[3] & 0xFFFF;
simple.GainAlbum = (HeaderData[4] >> 16) & 0xFFFF;
simple.PeakAlbum = HeaderData[4] & 0xFFFF;
simple.IsTrueGapless = (HeaderData[5] >> 31) & 0x0001; // true gapless: used?
simple.LastFrameSamples = (HeaderData[5] >> 20) & 0x07FF; // true gapless: valid samples for last frame
simple.EncoderVersion = (HeaderData[6] >> 24) & 0x00FF;
if ( simple.EncoderVersion == 0 ) {
sprintf ( simple.Encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05" );
} else {
switch ( simple.EncoderVersion % 10 ) {
case 0:
sprintf ( simple.Encoder, "Release %u.%u", simple.EncoderVersion/100, simple.EncoderVersion/10%10 );
break;
case 2: case 4: case 6: case 8:
sprintf ( simple.Encoder, "Beta %u.%02u", simple.EncoderVersion/100, simple.EncoderVersion%100 );
break;
default:
sprintf ( simple.Encoder, "--Alpha-- %u.%02u", simple.EncoderVersion/100, simple.EncoderVersion%100 );
break;
}
}
if ( simple.PeakTitle == 0 ) // there is no correct PeakTitle contained within header
simple.PeakTitle = (unsigned short)(EstimatedPeakTitle * 1.18);
if ( simple.PeakAlbum == 0 )
simple.PeakAlbum = simple.PeakTitle; // no correct PeakAlbum, use PeakTitle
//simple.SampleFreq = 44100; // AB: used by all files up to SV7
simple.Channels = 2;
return ERROR_CODE_OK;
}
// read information from SV4-SV6 header
int
StreamInfo::ReadHeaderSV6(BPositionIO *fp)
{
unsigned int HeaderData [8];
if (fp->Seek(simple.HeaderPosition, SEEK_SET ) < B_OK) // seek to header start
return ERROR_CODE_FILE;
if (fp->Read(HeaderData, sizeof HeaderData) != sizeof HeaderData)
return ERROR_CODE_FILE;
simple.Bitrate = (HeaderData[0] >> 23) & 0x01FF; // read the file-header (SV6 and below)
simple.IS = (HeaderData[0] >> 22) & 0x0001;
simple.MS = (HeaderData[0] >> 21) & 0x0001;
simple.StreamVersion = (HeaderData[0] >> 11) & 0x03FF;
simple.MaxBand = (HeaderData[0] >> 6) & 0x001F;
simple.BlockSize = (HeaderData[0] ) & 0x003F;
simple.Profile = 0;
simple.ProfileName = Stringify(~0);
if ( simple.StreamVersion >= 5 )
simple.Frames = HeaderData[1]; // 32 bit
else
simple.Frames = (HeaderData[1]>>16); // 16 bit
simple.GainTitle = 0; // not supported
simple.PeakTitle = 0;
simple.GainAlbum = 0;
simple.PeakAlbum = 0;
simple.LastFrameSamples = 0;
simple.IsTrueGapless = 0;
simple.EncoderVersion = 0;
simple.Encoder[0] = '\0';
if ( simple.StreamVersion == 7 ) return ERROR_CODE_SV7BETA; // are there any unsupported parameters used?
if ( simple.Bitrate != 0 ) return ERROR_CODE_CBR;
if ( simple.IS != 0 ) return ERROR_CODE_IS;
if ( simple.BlockSize != 1 ) return ERROR_CODE_BLOCKSIZE;
if ( simple.StreamVersion < 6 ) // Bugfix: last frame was invalid for up to SV5
simple.Frames -= 1;
simple.SampleFreq = 44100; // AB: used by all files up to SV7
simple.Channels = 2;
if ( simple.StreamVersion < 4 || simple.StreamVersion > 7 )
return ERROR_CODE_INVALIDSV;
return ERROR_CODE_OK;
}
// reads file header and tags
int StreamInfo::ReadStreamInfo ( BPositionIO* fp)
{
unsigned int HeaderData[1];
int Error = 0;
//memset ( &simple, 0, sizeof (BasicData) ); // Reset Info-Data
if ( (simple.HeaderPosition = JumpID3v2 (fp)) < 0 ) // get header position
return ERROR_CODE_FILE;
if (fp->Seek(simple.HeaderPosition, SEEK_SET) < B_OK) // seek to first byte of mpc data
return ERROR_CODE_FILE;
if (fp->Read(HeaderData, sizeof HeaderData) != sizeof HeaderData)
return ERROR_CODE_FILE;
if (fp->Seek(0L, SEEK_END) < B_OK) // get filelength
return ERROR_CODE_FILE;
simple.TotalFileLength = fp->Position();
simple.TagOffset = simple.TotalFileLength;
if ( memcmp ( HeaderData, "MP+", 3 ) == 0 ) { // check version
simple.StreamVersion = HeaderData[0] >> 24;
if ( (simple.StreamVersion & 15) >= 8 ) // StreamVersion 8
Error = ReadHeaderSV8 ( fp );
else if ( (simple.StreamVersion & 15) == 7 ) // StreamVersion 7
Error = ReadHeaderSV7 ( fp );
} else { // StreamVersion 4-6
Error = ReadHeaderSV6 ( fp );
}
ReadTags(fp);
simple.PCMSamples = 1152 * simple.Frames - 576; // estimation, exact value needs too much time
if ( simple.PCMSamples > 0 )
simple.AverageBitrate = (simple.TagOffset - simple.HeaderPosition) * 8. * simple.SampleFreq / simple.PCMSamples;
else
simple.AverageBitrate = 0;
return Error;
}
/* end of in_mpc.c */
@@ -0,0 +1,111 @@
#ifndef _in_mpc_h_
#define _in_mpc_h_
#include <SupportDefs.h>
#include <sys/types.h>
#include "idtag.h"
class BPositionIO;
/************************ DEFINES *************************/
#define VERSION "0.97f"
// error codes
#define ERROR_CODE_OK 0
#define ERROR_CODE_FILE -1
#define ERROR_CODE_SV7BETA 1
#define ERROR_CODE_CBR 2
#define ERROR_CODE_IS 3
#define ERROR_CODE_BLOCKSIZE 4
#define ERROR_CODE_INVALIDSV 5
/************************ TYPEDEF *************************/
typedef struct {
char* Item; // Name of item (ASCII)
char* Value; // Value of item (UTF-8)
unsigned int Flags; // Flags
size_t ItemSize; // Length of name (bytes)
size_t ValueSize; // Length of value (bytes)
enum tag_rel Reliability; // Reliability of information
} TagItem;
class StreamInfo {
private:
char *filename;
public: // ahem fixme
typedef long off_t;
typedef struct {
double SampleFreq;
unsigned int Channels;
off_t HeaderPosition; // byte position of header
unsigned int StreamVersion; // Streamversion of current file
unsigned int Bitrate; // bitrate of current file (bps)
double AverageBitrate; // Average bitrate in bits/sec
unsigned int Frames; // number of frames contained
int64 PCMSamples;
unsigned int MaxBand; // maximum band-index used (0...31)
unsigned int IS; // Intensity Stereo (0: off, 1: on)
unsigned int MS; // Mid/Side Stereo (0: off, 1: on)
unsigned int BlockSize; // only needed for SV4...SV6 -> not supported
unsigned int Profile; // quality profile
const char* ProfileName;
// ReplayGain related data
short GainTitle;
short GainAlbum;
unsigned short PeakAlbum;
unsigned short PeakTitle;
// true gapless stuff
unsigned int IsTrueGapless; // is true gapless used?
unsigned int LastFrameSamples; // number of valid samples within last frame
unsigned int EncoderVersion; // version of encoder used
char Encoder[256];
off_t TagOffset;
off_t TotalFileLength;
} BasicData;
BasicData simple;
size_t tagitem_count;
TagItem* tagitems;
enum tag_t tagtype;
public:
StreamInfo ();
~StreamInfo () { Clear (); }
void SetFilename ( const char * );
const char *GetFilename ();
void Clear ();
int ReadStreamInfo (BPositionIO *stream);
private:
//fixme: add writetag here too
int ReadHeaderSV6 ( BPositionIO *file );
int ReadHeaderSV7 ( BPositionIO *file );
int ReadHeaderSV8 ( BPositionIO *file );
int ReadTags ( BPositionIO *file ); // reads all tags from file
int ReadID3v1Tag ( BPositionIO *file ); // reads ID3v1 tag
int ReadAPE1Tag ( BPositionIO *file ); // reads APE 1.0 tag
int ReadAPE2Tag ( BPositionIO *file ); // reads APE 2.0 tag
};
typedef struct {
int EQbyMPC;
int EQdB;
unsigned int UpdateBitrate; // 0 = average, >0 average over such a number of frames
int MaxBrokenFrames;
int SkipTrackOnError;
int ReplayGainMode;
int ReplayGainHeadroom;
int DitherUsed;
} SettingsMPC;
/************************ GLOBALS *************************/
//extern SettingsMPC PluginSettings;
#endif
@@ -0,0 +1,45 @@
#ifndef MPP_MINIMAX_H
#define MPP_MINIMAX_H
#if defined __GNUC__ && defined __cplusplus
# define maxi(A,B) ( (A) >? (B) )
# define mini(A,B) ( (A) <? (B) )
# define maxd(A,B) ( (A) >? (B) )
# define mind(A,B) ( (A) <? (B) )
# define maxf(A,B) ( (A) >? (B) )
# define minf(A,B) ( (A) <? (B) )
# define absi(A) abs (A)
# define absf(A) fabsf (A)
# define absd(A) fabs (A)
#elif defined __GNUC__
# define maxi(A,B) ( (A) > (B) ? (A) : (B) )
# define mini(A,B) ( (A) < (B) ? (A) : (B) )
# define maxd(A,B) ( (A) > (B) ? (A) : (B) )
# define mind(A,B) ( (A) < (B) ? (A) : (B) )
# define maxf(A,B) ( (A) > (B) ? (A) : (B) )
# define minf(A,B) ( (A) < (B) ? (A) : (B) )
# define absi(A) abs (A)
# define absf(A) fabsf (A)
# define absd(A) fabs (A)
#else
# define maxi(A,B) ( (A) > (B) ? (A) : (B) )
# define mini(A,B) ( (A) < (B) ? (A) : (B) )
# define maxd(A,B) ( (A) > (B) ? (A) : (B) )
# define mind(A,B) ( (A) < (B) ? (A) : (B) )
# define maxf(A,B) ( (A) > (B) ? (A) : (B) )
# define minf(A,B) ( (A) < (B) ? (A) : (B) )
# define absi(A) ( (A) >= 0 ? (A) : -(A) )
# define absf(A) ( (A) >= 0.f ? (A) : -(A) )
# define absd(A) ( (A) >= 0. ? (A) : -(A) )
#endif /* GNUC && C++ */
#endif /* MPP_MINIMAX_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,238 @@
#ifndef _mpp_dec_h_
#define _mpp_dec_h_
#include <sys/types.h>
#ifndef _in_mpc_h_
class StreamInfo;
#endif
#define _inline inline
#define TO_FLOAT 1
#define TO_PCM 2
#ifndef MPC_DECODE
#define MPC_DECODE TO_FLOAT // decode to 32 bit floats ( -1.000...+1.000 )
//#define MPC_DECODE TO_PCM // decode to 16 bit PCM ( -32768...+32767 )
#endif
#if MPC_DECODE == TO_FLOAT
#define MPC_SAMPLE_FORMAT float
#define MPC_SAMPLE_BPS 32
#define MPC_SAMPLE_TYPE "FLOAT"
#elif MPC_DECODE == TO_PCM
#define MPC_SAMPLE_FORMAT short
#define MPC_SAMPLE_BPS 16
#define MPC_SAMPLE_TYPE "PCM"
#else
#error MPC_DECODE incorrect or undefined.
#endif
#define EQ_TAP 13 // length of FIR filter for EQ
#define DELAY ((EQ_TAP + 1) / 2) // delay of FIR
#define FIR_BANDS 4 // number of subbands to be FIR filtered
#define MEMSIZE 16384 // overall buffer size
#define MEMSIZE2 (MEMSIZE/2) // size of one buffer
#define MEMMASK (MEMSIZE-1)
#define V_MEM 2304
#define FRAMELEN (36 * 32) // samples per frame
#define SYNTH_DELAY 481
class Reader {
public:
virtual size_t read ( void *ptr, size_t size ) = 0;
virtual size_t write ( void *ptr, size_t size ) = 0;
virtual int seek ( int offset, int origin ) = 0;
virtual long tell () = 0;
virtual void seteof ( size_t ofs ) {};
virtual ~Reader () {}
virtual int canwrite () { return 0; }; // is writing supported or not
};
class MPC_decoder {
private:
Reader *m_reader;
public:
MPC_decoder ( Reader *r );
~MPC_decoder ();
void SetStreamInfo ( StreamInfo *si );
int FileInit ();
void ScaleOutput ( double factor );
float ProcessReplayGain ( int mode, StreamInfo *info );
void perform_EQ ( void );
int DECODE ( MPC_SAMPLE_FORMAT *buffer );
void UpdateBuffer ( unsigned int RING );
int perform_jump ( int seek_needed );
void RESET_Synthesis ( void );
void RESET_Globals ( void );
unsigned int BitsRead ( void );
private:
void RESET_Y ( void );
void Lese_Bitstrom_SV6 ( void );
void Lese_Bitstrom_SV7 ( void );
void Requantisierung ( const int Last_Band );
public:
typedef struct {
int L [36];
int R [36];
} QuantTyp;
typedef struct {
unsigned int Code;
unsigned int Length;
int Value;
} HuffmanTyp;
public:
unsigned int Speicher [MEMSIZE]; // read-buffer
unsigned int dword; // actually decoded 32bit-word
unsigned int pos; // bit-position within dword
unsigned int Zaehler; // actual index within read-buffer
unsigned int FwdJumpInfo;
unsigned int ActDecodePos;
unsigned int FrameWasValid;
unsigned int DecodedFrames;
unsigned int LastFrame;
unsigned int LastBitsRead;
unsigned int OverallFrames;
int SectionBitrate; // average bitrate for short section
int SampleRate; // Sample frequency
int NumberOfConsecutiveBrokenFrames; // counter for consecutive broken frames
private:
unsigned int StreamVersion; // version of bitstream
unsigned int MS_used; // MS-coding used ?
int Max_Band;
unsigned int MPCHeaderPos; // AB: needed to support ID3v2
//unsigned int OverallFrames;
//unsigned int DecodedFrames;
unsigned int LastValidSamples;
unsigned int TrueGaplessPresent;
unsigned int EQ_activated;
unsigned int WordsRead; // counts amount of decoded dwords
unsigned short* SeekTable;
/*static*/ unsigned int __r1;
/*static*/ unsigned int __r2;
unsigned long clips;
private:
float EQ_gain [ 32 - FIR_BANDS ];
float EQ_Filter [ FIR_BANDS ][ EQ_TAP ];
int SCF_Index_L [32] [3];
int SCF_Index_R [32] [3]; // holds scalefactor-indices
QuantTyp Q [32]; // holds quantized samples
int Res_L [32];
int Res_R [32]; // holds the chosen quantizer for each subband
int DSCF_Flag_L [32];
int DSCF_Flag_R [32]; // differential SCF used?
int SCFI_L [32];
int SCFI_R [32]; // describes order of transmitted SCF
int DSCF_Reference_L [32];
int DSCF_Reference_R [32]; // holds last frames SCF
int MS_Flag[32]; // MS used?
float SAVE_L [DELAY] [32]; // buffer for ...
float SAVE_R [DELAY] [32]; // ... upper subbands
float FirSave_L [FIR_BANDS] [EQ_TAP];// buffer for ...
float FirSave_R [FIR_BANDS] [EQ_TAP];// ... lowest subbands
HuffmanTyp HuffHdr [10];
HuffmanTyp HuffSCFI [ 4];
HuffmanTyp HuffDSCF [16];
HuffmanTyp* HuffQ [2] [8];
HuffmanTyp HuffQ1 [2] [3*3*3];
HuffmanTyp HuffQ2 [2] [5*5];
HuffmanTyp HuffQ3 [2] [ 7];
HuffmanTyp HuffQ4 [2] [ 9];
HuffmanTyp HuffQ5 [2] [15];
HuffmanTyp HuffQ6 [2] [31];
HuffmanTyp HuffQ7 [2] [63];
const HuffmanTyp* SampleHuff [18];
HuffmanTyp SCFI_Bundle [ 8];
HuffmanTyp DSCF_Entropie [13];
HuffmanTyp Region_A [16];
HuffmanTyp Region_B [ 8];
HuffmanTyp Region_C [ 4];
HuffmanTyp Entropie_1 [ 3];
HuffmanTyp Entropie_2 [ 5];
HuffmanTyp Entropie_3 [ 7];
HuffmanTyp Entropie_4 [ 9];
HuffmanTyp Entropie_5 [15];
HuffmanTyp Entropie_6 [31];
HuffmanTyp Entropie_7 [63];
float V_L [V_MEM + 960];
float V_R [V_MEM + 960];
float Y_L [36] [32];
float Y_R [36] [32];
float SCF [256]; // holds adapted scalefactors (for clipping prevention)
unsigned int Q_bit [32]; // holds amount of bits to save chosen quantizer (SV6)
unsigned int Q_res [32] [16]; // holds conversion: index -> quantizer (SV6)
private: // functions
void Reset_BitstreamDecode ( void );
unsigned int Bitstream_read ( const unsigned int );
int Huffman_Decode ( const HuffmanTyp* ); // works with maximum lengths up to 14
int Huffman_Decode_fast ( const HuffmanTyp* ); // works with maximum lengths up to 10
int Huffman_Decode_faster ( const HuffmanTyp* ); // works with maximum lengths up to 5
void SCFI_Bundle_read ( const HuffmanTyp*, int*, int* );
void Calculate_New_V ( const float* Sample, float* V );
void Vectoring_float ( float* Data, const float* V );
void Vectoring ( short* Data, const float* V );
void Vectoring_dithered ( short* Data, const float* V, const float* dither );
void GenerateDither_old ( float* p, size_t len );
void GenerateDither ( float* p, size_t len );
void Reset_V ( void );
void Synthese_Filter_float ( float* dst );
void Synthese_Filter_opt ( short* dst );
void Synthese_Filter_dithered ( short* dst );
unsigned int random_int ( void );
void EQSet ( int on, char data[10], int preamp );
void Helper1 ( unsigned long bitpos );
void Helper2 ( unsigned long bitpos );
void Helper3 ( unsigned long bitpos, long* buffoffs );
void Huffman_SV6_Encoder ( void );
void Huffman_SV6_Decoder ( void );
void Huffman_SV7_Encoder ( void );
void Huffman_SV7_Decoder ( void );
void initialisiere_Quantisierungstabellen ( void );
void Quantisierungsmodes ( void ); // conversion: index -> quantizer (bitstream reading)
void Resort_HuffTables ( const unsigned int elements, HuffmanTyp* Table, const int offset );
private:
_inline int f_read ( void *ptr, size_t size) { return m_reader->read (ptr, size); };
_inline int f_seek ( int offset, int origin) { return m_reader->seek (offset, origin); };
};
#endif
@@ -0,0 +1,82 @@
#include <math.h>
#include "requant.h"
/* C O N S T A N T S */
// bits per sample for chosen quantizer
const unsigned int Res_bit [18] = {
0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
};
// coefficients for requantization
// 65536/step bzw. 65536/(2*D+1)
const float __Cc [1 + 18] = {
111.285962475327f, // 32768/2/255*sqrt(3)
65536.000000000000f, 21845.333333333332f, 13107.200000000001f, 9362.285714285713f,
7281.777777777777f, 4369.066666666666f, 2114.064516129032f, 1040.253968253968f,
516.031496062992f, 257.003921568627f, 128.250489236790f, 64.062561094819f,
32.015632633121f, 16.003907203907f, 8.000976681723f, 4.000244155527f,
2.000061037018f, 1.000015259021f
};
// offset for requantization
// 2*D+1 = steps of quantizer
const int __Dc [1 + 18] = {
2,
0, 1, 2, 3, 4, 7, 15, 31, 63,
127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767
};
/* F U N C T I O N S */
void
MPC_decoder::ScaleOutput ( double factor )
{
int n;
double f1 = factor;
double f2 = factor;
// handles +1.58...-98.41 dB, where's scf[n] / scf[n-1] = 1.20050805774840750476
for ( n = 0; n <= 128; n++ ) {
SCF [(unsigned char)(1+n)] = (float) f1;
SCF [(unsigned char)(1-n)] = (float) f2;
f1 *= 0.83298066476582673961;
f2 *= 1/0.83298066476582673961;
}
}
void
MPC_decoder::Quantisierungsmodes ( void ) // conversion: index -> quantizer (bitstream reading)
{ // conversion: quantizer -> index (bitstream writing)
int Band = 0;
int i;
do {
Q_bit [Band] = 4;
for ( i = 0; i < 16-1; i++ )
Q_res [Band] [i] = i;
Q_res [Band][i] = 17;
Band++;
} while ( Band < 11 );
do {
Q_bit [Band] = 3;
for ( i = 0; i < 8-1; i++ )
Q_res [Band] [i] = i;
Q_res [Band] [i] = 17;
Band++;
} while ( Band < 23 );
do {
Q_bit [Band] = 2;
for ( i = 0; i < 4-1; i++ )
Q_res [Band] [i] = i;
Q_res [Band] [i] = 17;
Band++;
} while ( Band < 32 );
}
void
MPC_decoder::initialisiere_Quantisierungstabellen ( void )
{
Quantisierungsmodes ();
ScaleOutput ( 1.0 );
}
@@ -0,0 +1,14 @@
#ifndef _requant_h
#define _requant_h_
#include "mpc_dec.h"
/* C O N S T A N T S */
extern const unsigned int Res_bit [18]; // bits per sample for chosen quantizer
extern const float __Cc [1 + 18]; // coefficients for requantization
extern const int __Dc [1 + 18]; // offset for requantization
#define Cc (__Cc + 1)
#define Dc (__Dc + 1)
#endif
@@ -0,0 +1,531 @@
#include <math.h>
#include <string.h>
#include "synth_filter.h"
#include "mpc_dec.h"
// unsigned long clips = 0;
/* C O N S T A N T S */
#undef _
#define _(value) (float)(value##.##L / 0x10000)
const float Di_opt [32] [16] = {
{ _( 0), _( -29), _( 213), _( -459), _( 2037), _(-5153), _( 6574), _(-37489), _(75038), _(37489), _(6574), _( 5153), _(2037), _( 459), _(213), _(29) },
{ _( -1), _( -31), _( 218), _( -519), _( 2000), _(-5517), _( 5959), _(-39336), _(74992), _(35640), _(7134), _( 4788), _(2063), _( 401), _(208), _(26) },
{ _( -1), _( -35), _( 222), _( -581), _( 1952), _(-5879), _( 5288), _(-41176), _(74856), _(33791), _(7640), _( 4425), _(2080), _( 347), _(202), _(24) },
{ _( -1), _( -38), _( 225), _( -645), _( 1893), _(-6237), _( 4561), _(-43006), _(74630), _(31947), _(8092), _( 4063), _(2087), _( 294), _(196), _(21) },
{ _( -1), _( -41), _( 227), _( -711), _( 1822), _(-6589), _( 3776), _(-44821), _(74313), _(30112), _(8492), _( 3705), _(2085), _( 244), _(190), _(19) },
{ _( -1), _( -45), _( 228), _( -779), _( 1739), _(-6935), _( 2935), _(-46617), _(73908), _(28289), _(8840), _( 3351), _(2075), _( 197), _(183), _(17) },
{ _( -1), _( -49), _( 228), _( -848), _( 1644), _(-7271), _( 2037), _(-48390), _(73415), _(26482), _(9139), _( 3004), _(2057), _( 153), _(176), _(16) },
{ _( -2), _( -53), _( 227), _( -919), _( 1535), _(-7597), _( 1082), _(-50137), _(72835), _(24694), _(9389), _( 2663), _(2032), _( 111), _(169), _(14) },
{ _( -2), _( -58), _( 224), _( -991), _( 1414), _(-7910), _( 70), _(-51853), _(72169), _(22929), _(9592), _( 2330), _(2001), _( 72), _(161), _(13) },
{ _( -2), _( -63), _( 221), _(-1064), _( 1280), _(-8209), _( -998), _(-53534), _(71420), _(21189), _(9750), _( 2006), _(1962), _( 36), _(154), _(11) },
{ _( -2), _( -68), _( 215), _(-1137), _( 1131), _(-8491), _( -2122), _(-55178), _(70590), _(19478), _(9863), _( 1692), _(1919), _( 2), _(147), _(10) },
{ _( -3), _( -73), _( 208), _(-1210), _( 970), _(-8755), _( -3300), _(-56778), _(69679), _(17799), _(9935), _( 1388), _(1870), _( -29), _(139), _( 9) },
{ _( -3), _( -79), _( 200), _(-1283), _( 794), _(-8998), _( -4533), _(-58333), _(68692), _(16155), _(9966), _( 1095), _(1817), _( -57), _(132), _( 8) },
{ _( -4), _( -85), _( 189), _(-1356), _( 605), _(-9219), _( -5818), _(-59838), _(67629), _(14548), _(9959), _( 814), _(1759), _( -83), _(125), _( 7) },
{ _( -4), _( -91), _( 177), _(-1428), _( 402), _(-9416), _( -7154), _(-61289), _(66494), _(12980), _(9916), _( 545), _(1698), _(-106), _(117), _( 7) },
{ _( -5), _( -97), _( 163), _(-1498), _( 185), _(-9585), _( -8540), _(-62684), _(65290), _(11455), _(9838), _( 288), _(1634), _(-127), _(111), _( 6) },
{ _( -5), _(-104), _( 146), _(-1567), _( -45), _(-9727), _( -9975), _(-64019), _(64019), _( 9975), _(9727), _( 45), _(1567), _(-146), _(104), _( 5) },
{ _( -6), _(-111), _( 127), _(-1634), _( -288), _(-9838), _(-11455), _(-65290), _(62684), _( 8540), _(9585), _( -185), _(1498), _(-163), _( 97), _( 5) },
{ _( -7), _(-117), _( 106), _(-1698), _( -545), _(-9916), _(-12980), _(-66494), _(61289), _( 7154), _(9416), _( -402), _(1428), _(-177), _( 91), _( 4) },
{ _( -7), _(-125), _( 83), _(-1759), _( -814), _(-9959), _(-14548), _(-67629), _(59838), _( 5818), _(9219), _( -605), _(1356), _(-189), _( 85), _( 4) },
{ _( -8), _(-132), _( 57), _(-1817), _(-1095), _(-9966), _(-16155), _(-68692), _(58333), _( 4533), _(8998), _( -794), _(1283), _(-200), _( 79), _( 3) },
{ _( -9), _(-139), _( 29), _(-1870), _(-1388), _(-9935), _(-17799), _(-69679), _(56778), _( 3300), _(8755), _( -970), _(1210), _(-208), _( 73), _( 3) },
{ _(-10), _(-147), _( -2), _(-1919), _(-1692), _(-9863), _(-19478), _(-70590), _(55178), _( 2122), _(8491), _(-1131), _(1137), _(-215), _( 68), _( 2) },
{ _(-11), _(-154), _( -36), _(-1962), _(-2006), _(-9750), _(-21189), _(-71420), _(53534), _( 998), _(8209), _(-1280), _(1064), _(-221), _( 63), _( 2) },
{ _(-13), _(-161), _( -72), _(-2001), _(-2330), _(-9592), _(-22929), _(-72169), _(51853), _( -70), _(7910), _(-1414), _( 991), _(-224), _( 58), _( 2) },
{ _(-14), _(-169), _(-111), _(-2032), _(-2663), _(-9389), _(-24694), _(-72835), _(50137), _(-1082), _(7597), _(-1535), _( 919), _(-227), _( 53), _( 2) },
{ _(-16), _(-176), _(-153), _(-2057), _(-3004), _(-9139), _(-26482), _(-73415), _(48390), _(-2037), _(7271), _(-1644), _( 848), _(-228), _( 49), _( 1) },
{ _(-17), _(-183), _(-197), _(-2075), _(-3351), _(-8840), _(-28289), _(-73908), _(46617), _(-2935), _(6935), _(-1739), _( 779), _(-228), _( 45), _( 1) },
{ _(-19), _(-190), _(-244), _(-2085), _(-3705), _(-8492), _(-30112), _(-74313), _(44821), _(-3776), _(6589), _(-1822), _( 711), _(-227), _( 41), _( 1) },
{ _(-21), _(-196), _(-294), _(-2087), _(-4063), _(-8092), _(-31947), _(-74630), _(43006), _(-4561), _(6237), _(-1893), _( 645), _(-225), _( 38), _( 1) },
{ _(-24), _(-202), _(-347), _(-2080), _(-4425), _(-7640), _(-33791), _(-74856), _(41176), _(-5288), _(5879), _(-1952), _( 581), _(-222), _( 35), _( 1) },
{ _(-26), _(-208), _(-401), _(-2063), _(-4788), _(-7134), _(-35640), _(-74992), _(39336), _(-5959), _(5517), _(-2000), _( 519), _(-218), _( 31), _( 1) }
};
#undef _
/* F U N K T I O N E N */
void
MPC_decoder::Reset_V ( void )
{
memset ( V_L, 0, sizeof V_L );
memset ( V_R, 0, sizeof V_R );
}
void
MPC_decoder::Calculate_New_V ( const float* Sample, float* V )
{
// Calculating new V-buffer values for left channel
// calculate new V-values (ISO-11172-3, p. 39)
// based upon fast-MDCT algorithm by Byeong Gi Lee
/*static*/ float A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15;
/*static*/ float B00, B01, B02, B03, B04, B05, B06, B07, B08, B09, B10, B11, B12, B13, B14, B15;
float tmp;
A00 = Sample[ 0] + Sample[31];
A01 = Sample[ 1] + Sample[30];
A02 = Sample[ 2] + Sample[29];
A03 = Sample[ 3] + Sample[28];
A04 = Sample[ 4] + Sample[27];
A05 = Sample[ 5] + Sample[26];
A06 = Sample[ 6] + Sample[25];
A07 = Sample[ 7] + Sample[24];
A08 = Sample[ 8] + Sample[23];
A09 = Sample[ 9] + Sample[22];
A10 = Sample[10] + Sample[21];
A11 = Sample[11] + Sample[20];
A12 = Sample[12] + Sample[19];
A13 = Sample[13] + Sample[18];
A14 = Sample[14] + Sample[17];
A15 = Sample[15] + Sample[16];
B00 = A00 + A15;
B01 = A01 + A14;
B02 = A02 + A13;
B03 = A03 + A12;
B04 = A04 + A11;
B05 = A05 + A10;
B06 = A06 + A09;
B07 = A07 + A08;
B08 = (A00 - A15) * 0.5024192929f;
B09 = (A01 - A14) * 0.5224986076f;
B10 = (A02 - A13) * 0.5669440627f;
B11 = (A03 - A12) * 0.6468217969f;
B12 = (A04 - A11) * 0.7881546021f;
B13 = (A05 - A10) * 1.0606776476f;
B14 = (A06 - A09) * 1.7224471569f;
B15 = (A07 - A08) * 5.1011486053f;
A00 = B00 + B07;
A01 = B01 + B06;
A02 = B02 + B05;
A03 = B03 + B04;
A04 = (B00 - B07) * 0.5097956061f;
A05 = (B01 - B06) * 0.6013448834f;
A06 = (B02 - B05) * 0.8999761939f;
A07 = (B03 - B04) * 2.5629155636f;
A08 = B08 + B15;
A09 = B09 + B14;
A10 = B10 + B13;
A11 = B11 + B12;
A12 = (B08 - B15) * 0.5097956061f;
A13 = (B09 - B14) * 0.6013448834f;
A14 = (B10 - B13) * 0.8999761939f;
A15 = (B11 - B12) * 2.5629155636f;
B00 = A00 + A03;
B01 = A01 + A02;
B02 = (A00 - A03) * 0.5411961079f;
B03 = (A01 - A02) * 1.3065630198f;
B04 = A04 + A07;
B05 = A05 + A06;
B06 = (A04 - A07) * 0.5411961079f;
B07 = (A05 - A06) * 1.3065630198f;
B08 = A08 + A11;
B09 = A09 + A10;
B10 = (A08 - A11) * 0.5411961079f;
B11 = (A09 - A10) * 1.3065630198f;
B12 = A12 + A15;
B13 = A13 + A14;
B14 = (A12 - A15) * 0.5411961079f;
B15 = (A13 - A14) * 1.3065630198f;
A00 = B00 + B01;
A01 = (B00 - B01) * 0.7071067691f;
A02 = B02 + B03;
A03 = (B02 - B03) * 0.7071067691f;
A04 = B04 + B05;
A05 = (B04 - B05) * 0.7071067691f;
A06 = B06 + B07;
A07 = (B06 - B07) * 0.7071067691f;
A08 = B08 + B09;
A09 = (B08 - B09) * 0.7071067691f;
A10 = B10 + B11;
A11 = (B10 - B11) * 0.7071067691f;
A12 = B12 + B13;
A13 = (B12 - B13) * 0.7071067691f;
A14 = B14 + B15;
A15 = (B14 - B15) * 0.7071067691f;
V[48] = -A00;
V[ 0] = A01;
V[40] = -A02 - (V[ 8] = A03);
V[36] = -((V[ 4] = A05 + (V[12] = A07)) + A06);
V[44] = - A04 - A06 - A07;
V[ 6] = (V[10] = A11 + (V[14] = A15)) + A13;
V[38] = (V[34] = -(V[ 2] = A09 + A13 + A15) - A14) + A09 - A10 - A11;
V[46] = (tmp = -(A12 + A14 + A15)) - A08;
V[42] = tmp - A10 - A11;
A00 = (Sample[ 0] - Sample[31]) * 0.5006030202f;
A01 = (Sample[ 1] - Sample[30]) * 0.5054709315f;
A02 = (Sample[ 2] - Sample[29]) * 0.5154473186f;
A03 = (Sample[ 3] - Sample[28]) * 0.5310425758f;
A04 = (Sample[ 4] - Sample[27]) * 0.5531039238f;
A05 = (Sample[ 5] - Sample[26]) * 0.5829349756f;
A06 = (Sample[ 6] - Sample[25]) * 0.6225041151f;
A07 = (Sample[ 7] - Sample[24]) * 0.6748083234f;
A08 = (Sample[ 8] - Sample[23]) * 0.7445362806f;
A09 = (Sample[ 9] - Sample[22]) * 0.8393496275f;
A10 = (Sample[10] - Sample[21]) * 0.9725682139f;
A11 = (Sample[11] - Sample[20]) * 1.1694399118f;
A12 = (Sample[12] - Sample[19]) * 1.4841645956f;
A13 = (Sample[13] - Sample[18]) * 2.0577809811f;
A14 = (Sample[14] - Sample[17]) * 3.4076085091f;
A15 = (Sample[15] - Sample[16]) *10.1900081635f;
B00 = A00 + A15;
B01 = A01 + A14;
B02 = A02 + A13;
B03 = A03 + A12;
B04 = A04 + A11;
B05 = A05 + A10;
B06 = A06 + A09;
B07 = A07 + A08;
B08 = (A00 - A15) * 0.5024192929f;
B09 = (A01 - A14) * 0.5224986076f;
B10 = (A02 - A13) * 0.5669440627f;
B11 = (A03 - A12) * 0.6468217969f;
B12 = (A04 - A11) * 0.7881546021f;
B13 = (A05 - A10) * 1.0606776476f;
B14 = (A06 - A09) * 1.7224471569f;
B15 = (A07 - A08) * 5.1011486053f;
A00 = B00 + B07;
A01 = B01 + B06;
A02 = B02 + B05;
A03 = B03 + B04;
A04 = (B00 - B07) * 0.5097956061f;
A05 = (B01 - B06) * 0.6013448834f;
A06 = (B02 - B05) * 0.8999761939f;
A07 = (B03 - B04) * 2.5629155636f;
A08 = B08 + B15;
A09 = B09 + B14;
A10 = B10 + B13;
A11 = B11 + B12;
A12 = (B08 - B15) * 0.5097956061f;
A13 = (B09 - B14) * 0.6013448834f;
A14 = (B10 - B13) * 0.8999761939f;
A15 = (B11 - B12) * 2.5629155636f;
B00 = A00 + A03;
B01 = A01 + A02;
B02 = (A00 - A03) * 0.5411961079f;
B03 = (A01 - A02) * 1.3065630198f;
B04 = A04 + A07;
B05 = A05 + A06;
B06 = (A04 - A07) * 0.5411961079f;
B07 = (A05 - A06) * 1.3065630198f;
B08 = A08 + A11;
B09 = A09 + A10;
B10 = (A08 - A11) * 0.5411961079f;
B11 = (A09 - A10) * 1.3065630198f;
B12 = A12 + A15;
B13 = A13 + A14;
B14 = (A12 - A15) * 0.5411961079f;
B15 = (A13 - A14) * 1.3065630198f;
A00 = B00 + B01;
A01 = (B00 - B01) * 0.7071067691f;
A02 = B02 + B03;
A03 = (B02 - B03) * 0.7071067691f;
A04 = B04 + B05;
A05 = (B04 - B05) * 0.7071067691f;
A06 = B06 + B07;
A07 = (B06 - B07) * 0.7071067691f;
A08 = B08 + B09;
A09 = (B08 - B09) * 0.7071067691f;
A10 = B10 + B11;
A11 = (B10 - B11) * 0.7071067691f;
A12 = B12 + B13;
A13 = (B12 - B13) * 0.7071067691f;
A14 = B14 + B15;
A15 = (B14 - B15) * 0.7071067691f;
// mehrfach verwendete Ausdrücke: A04+A06+A07, A09+A13+A15
V[ 5] = (V[11] = (V[13] = A07 + (V[15] = A15)) + A11) + A05 + A13;
V[ 7] = (V[ 9] = A03 + A11 + A15) + A13;
V[33] = -(V[ 1] = A01 + A09 + A13 + A15) - A14;
V[35] = -(V[ 3] = A05 + A07 + A09 + A13 + A15) - A06 - A14;
V[37] = (tmp = -(A10 + A11 + A13 + A14 + A15)) - A05 - A06 - A07;
V[39] = tmp - A02 - A03; // abhängig vom Befehl drüber
V[41] = (tmp += A13 - A12) - A02 - A03; // abhängig vom Befehl 2 drüber
V[43] = tmp - A04 - A06 - A07; // abhängig von Befehlen 1 und 3 drüber
V[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00;
V[45] = tmp - A04 - A06 - A07; // abhängig vom Befehl drüber
V[32] = -V[ 0];
V[31] = -V[ 1];
V[30] = -V[ 2];
V[29] = -V[ 3];
V[28] = -V[ 4];
V[27] = -V[ 5];
V[26] = -V[ 6];
V[25] = -V[ 7];
V[24] = -V[ 8];
V[23] = -V[ 9];
V[22] = -V[10];
V[21] = -V[11];
V[20] = -V[12];
V[19] = -V[13];
V[18] = -V[14];
V[17] = -V[15];
V[63] = V[33];
V[62] = V[34];
V[61] = V[35];
V[60] = V[36];
V[59] = V[37];
V[58] = V[38];
V[57] = V[39];
V[56] = V[40];
V[55] = V[41];
V[54] = V[42];
V[53] = V[43];
V[52] = V[44];
V[51] = V[45];
V[50] = V[46];
V[49] = V[47];
}
void
MPC_decoder::Vectoring_float ( float* Data, const float* V )
{
const float* D = (float*) Di_opt;
double Sum;
int k;
//int tmp;
for ( k = 0; k < 32; k++, D += 16, V++ ) {
Sum = ( V[ 0]*D[ 0] + V[ 96]*D[ 1] + V[128]*D[ 2] + V[224]*D[ 3]
+ V[256]*D[ 4] + V[352]*D[ 5] + V[384]*D[ 6] + V[480]*D[ 7]
+ V[512]*D[ 8] + V[608]*D[ 9] + V[640]*D[10] + V[736]*D[11]
+ V[768]*D[12] + V[864]*D[13] + V[896]*D[14] + V[992]*D[15] ); // + 0xFF8000;
//ftol ( Sum, *Data ); // copy to PCM (ftol mit Sättigung, +0xFF8000 gehört bereits dazu)
*Data = (float)(Sum * (1.0/32768.0));
Data += 2;
}
}
void
MPC_decoder::Synthese_Filter_float ( float* OutData )
{
int n;
float* V;
const float* Y;
/********* left channel ********/
memmove ( V_L + V_MEM, V_L, 960 * sizeof(float) );
V = V_L + V_MEM;
Y = Y_L [0];
for ( n = 0; n < 36; n++, OutData += 64, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
Vectoring_float ( OutData, V );
}
// set pointer to OutData[1] for filling right channel
OutData -= 2*1152 - 1;
/******** right channel ********/
memmove ( V_R + V_MEM, V_R, 960 * sizeof(float) );
V = V_R + V_MEM;
Y = Y_R [0];
for ( n = 0; n < 36; n++, OutData += 64, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
Vectoring_float ( OutData, V );
}
}
void
MPC_decoder::Vectoring ( short* Data, const float* V )
{
const float* D = (float*) Di_opt;
float Sum;
int k;
int tmp;
for ( k = 0; k < 32; k++, D += 16, V++ ) {
Sum = V[ 0]*D[ 0] + V[ 96]*D[ 1] + V[128]*D[ 2] + V[224]*D[ 3]
+ V[256]*D[ 4] + V[352]*D[ 5] + V[384]*D[ 6] + V[480]*D[ 7]
+ V[512]*D[ 8] + V[608]*D[ 9] + V[640]*D[10] + V[736]*D[11]
+ V[768]*D[12] + V[864]*D[13] + V[896]*D[14] + V[992]*D[15] + 0xFF8000;
ftol ( Sum, *Data ); // copy to PCM (ftol mit Sättigung, +0xFF8000 gehört bereits dazu)
Data += 2;
}
}
void
MPC_decoder::Synthese_Filter_opt ( short* OutData )
{
int n;
float* V;
const float* Y;
/********* left channel ********/
memmove ( V_L + V_MEM, V_L, 960 * sizeof(float) );
V = V_L + V_MEM;
Y = Y_L [0];
for ( n = 0; n < 36; n++, OutData += 64, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
Vectoring ( OutData, V );
}
// set pointer to OutData[1] for filling right channel
OutData -= 2*1152 - 1;
/******** right channel ********/
memmove ( V_R + V_MEM, V_R, 960 * sizeof(float) );
V = V_R + V_MEM;
Y = Y_R [0];
for ( n = 0; n < 36; n++, OutData += 64, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
Vectoring ( OutData, V );
}
}
/*******************************************/
/* */
/* dithered synthesis */
/* */
/*******************************************/
static const unsigned char Parity [256] = { // parity
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
};
/*
* This is a simple random number generator with good quality for audio purposes.
* It consists of two polycounters with opposite rotation direction and different
* periods. The periods are coprime, so the total period is the product of both.
*
* -------------------------------------------------------------------------------------------------
* +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
* | -------------------------------------------------------------------------------------------------
* | | | | | | |
* | +--+--+--+-XOR-+--------+
* | |
* +--------------------------------------------------------------------------------------+
*
* -------------------------------------------------------------------------------------------------
* |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
* ------------------------------------------------------------------------------------------------- |
* | | | | |
* +--+----XOR----+--+ |
* | |
* +----------------------------------------------------------------------------------------+
*
*
* The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
* which gives a period of 18.410.713.077.675.721.215. The result is the
* XORed values of both generators.
*/
unsigned int
MPC_decoder::random_int ( void )
{
#if 1
unsigned int t1, t2, t3, t4;
t3 = t1 = __r1; t4 = t2 = __r2; // Parity calculation is done via table lookup, this is also available
t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable
t1 = Parity [t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations.
t1 <<= 31; t2 = Parity [t2];
return (__r1 = (t3 >> 1) | t1 ) ^ (__r2 = (t4 + t4) | t2 );
#else
return (__r1 = (__r1 >> 1) | ((unsigned int)Parity [__r1 & 0xF5] << 31) ) ^
(__r2 = (__r2 << 1) | (unsigned int)Parity [(__r2 >> 25) & 0x63] );
#endif
}
// generates triangular dither
void
MPC_decoder::GenerateDither_old ( float* p, size_t len )
{
while (len--)
*p++ = ( (float)(int)random_int() + (float)(int)random_int() ) * (1.f/65536.f/65536.f);
}
void
MPC_decoder::GenerateDither ( float* p, size_t len )
{
/*static*/ int last = 0;
int tmp;
while (len--) {
tmp = (int) random_int();
*p++ = ((float)tmp - last) * (1.f/65536.f/65536.f);
last = tmp;
}
}
// dithered vectoring
void
MPC_decoder::Vectoring_dithered ( short* Data, const float* V, const float* dither )
{
const float* D = (float*) Di_opt;
float Sum;
int k;
int tmp;
for ( k = 0; k < 32; k++, D += 16, V++ ) {
Sum = V[ 0]*D[ 0] + V[ 96]*D[ 1] + V[128]*D[ 2] + V[224]*D[ 3]
+ V[256]*D[ 4] + V[352]*D[ 5] + V[384]*D[ 6] + V[480]*D[ 7]
+ V[512]*D[ 8] + V[608]*D[ 9] + V[640]*D[10] + V[736]*D[11]
+ V[768]*D[12] + V[864]*D[13] + V[896]*D[14] + V[992]*D[15] + *dither++ + 0xFF8000 ;
ftol ( Sum, *Data ); // copy to PCM (ftol mit Sättigung, +0xFF8000 gehört bereits dazu)
Data += 2;
}
}
// dithered synthesis
void
MPC_decoder::Synthese_Filter_dithered ( short* OutData )
{
int n;
float* V;
float DitherData [36 * 32];
const float* Y;
GenerateDither ( DitherData, 32*36 );
/********* left channel ********/
memmove ( V_L + V_MEM, V_L, 960 * sizeof(float) );
V = V_L + V_MEM;
Y = Y_L [0];
for ( n = 0; n < 36; n++, OutData += 64, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
Vectoring_dithered ( OutData, V, DitherData + 32*n );
}
// set pointer to OutData[1] for filling right channel
OutData -= 2*1152 - 1;
/******** right channel ********/
memmove ( V_R + V_MEM, V_R, 960 * sizeof(float) );
V = V_R + V_MEM;
Y = Y_R [0];
for ( n = 0; n < 36; n++, OutData += 64, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
Vectoring_dithered ( OutData, V, DitherData + 32*n );
}
}
/* end of synth_filter.c */
@@ -0,0 +1,14 @@
#ifndef _synth_filter_h_
#define _synth_filter_h_
#include "mpc_dec.h"
/* D E F I N E S */
#define ftol(A,B) \
{ tmp = *(int*) & A - 0x4B7F8000; \
if ( tmp != (short)tmp ) \
tmp = (tmp>>31) ^ 0x7FFF, clips++; \
B = (short) tmp; \
}
#endif