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:
@@ -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
|
||||
Reference in New Issue
Block a user