audio/mp3: Move Read_Audio_L3 to Go

This commit is contained in:
Hajime Hoshi 2017-06-14 02:22:11 +09:00
parent 49c95eb69f
commit 746548f5d2
4 changed files with 215 additions and 192 deletions

View File

@ -23,8 +23,7 @@ import (
"fmt" "fmt"
) )
/* Bit reservoir for main data */ type mainDataBytes struct {
type mainData struct {
// Large static data // Large static data
vec [2 * 1024]int vec [2 * 1024]int
// Pointer into the reservoir // Pointer into the reservoir
@ -37,7 +36,7 @@ type mainData struct {
pos int pos int
} }
var theMainData mainData var theMainDataBytes mainDataBytes
//export Get_Main_Data //export Get_Main_Data
func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int { func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int {
@ -45,7 +44,7 @@ func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int {
g_error = fmt.Errorf("size = %d", size) g_error = fmt.Errorf("size = %d", size)
} }
/* Check that there's data available from previous frames if needed */ /* Check that there's data available from previous frames if needed */
if int(begin) > theMainData.top { if int(begin) > theMainDataBytes.top {
// No,there is not,so we skip decoding this frame,but we have to // No,there is not,so we skip decoding this frame,but we have to
// read the main_data bits from the bitstream in case they are needed // read the main_data bits from the bitstream in case they are needed
// for decoding the next frame. // for decoding the next frame.
@ -54,17 +53,17 @@ func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int {
g_error = err g_error = err
return C.ERROR return C.ERROR
} }
copy(theMainData.vec[theMainData.top:], b) copy(theMainDataBytes.vec[theMainDataBytes.top:], b)
/* Set up pointers */ /* Set up pointers */
theMainData.ptr = theMainData.vec[0:] theMainDataBytes.ptr = theMainDataBytes.vec[0:]
theMainData.pos = 0 theMainDataBytes.pos = 0
theMainData.idx = 0 theMainDataBytes.idx = 0
theMainData.top += int(size) theMainDataBytes.top += int(size)
return C.ERROR return C.ERROR
} }
/* Copy data from previous frames */ /* Copy data from previous frames */
for i := 0; i < int(begin); i++ { for i := 0; i < int(begin); i++ {
theMainData.vec[i] = theMainData.vec[theMainData.top-int(begin)+i] theMainDataBytes.vec[i] = theMainDataBytes.vec[theMainDataBytes.top-int(begin)+i]
} }
/* Read the main_data from file */ /* Read the main_data from file */
b, err := getBytes(int(size)) b, err := getBytes(int(size))
@ -72,22 +71,22 @@ func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int {
g_error = err g_error = err
return C.ERROR return C.ERROR
} }
copy(theMainData.vec[begin:], b) copy(theMainDataBytes.vec[begin:], b)
/* Set up pointers */ /* Set up pointers */
theMainData.ptr = theMainData.vec[0:] theMainDataBytes.ptr = theMainDataBytes.vec[0:]
theMainData.pos = 0 theMainDataBytes.pos = 0
theMainData.idx = 0 theMainDataBytes.idx = 0
theMainData.top = int(begin) + int(size) theMainDataBytes.top = int(begin) + int(size)
return C.OK return C.OK
} }
//export Get_Main_Bit //export Get_Main_Bit
func Get_Main_Bit() C.unsigned { func Get_Main_Bit() C.unsigned {
tmp := uint(theMainData.ptr[0]) >> (7 - uint(theMainData.idx)) tmp := uint(theMainDataBytes.ptr[0]) >> (7 - uint(theMainDataBytes.idx))
tmp &= 0x01 tmp &= 0x01
theMainData.ptr = theMainData.ptr[(theMainData.idx+1)>>3:] theMainDataBytes.ptr = theMainDataBytes.ptr[(theMainDataBytes.idx+1)>>3:]
theMainData.pos += (theMainData.idx + 1) >> 3 theMainDataBytes.pos += (theMainDataBytes.idx + 1) >> 3
theMainData.idx = (theMainData.idx + 1) & 0x07 theMainDataBytes.idx = (theMainDataBytes.idx + 1) & 0x07
return C.unsigned(tmp) return C.unsigned(tmp)
} }
@ -99,22 +98,22 @@ func Get_Main_Bits(num C.unsigned) C.unsigned {
/* Form a word of the next four bytes */ /* Form a word of the next four bytes */
b := make([]int, 4) b := make([]int, 4)
for i := range b { for i := range b {
if len(theMainData.ptr) > i { if len(theMainDataBytes.ptr) > i {
b[i] = theMainData.ptr[i] b[i] = theMainDataBytes.ptr[i]
} }
} }
tmp := (uint32(b[0]) << 24) | (uint32(b[1]) << 16) | (uint32(b[2]) << 8) | (uint32(b[3]) << 0) tmp := (uint32(b[0]) << 24) | (uint32(b[1]) << 16) | (uint32(b[2]) << 8) | (uint32(b[3]) << 0)
/* Remove bits already used */ /* Remove bits already used */
tmp = tmp << uint(theMainData.idx) tmp = tmp << uint(theMainDataBytes.idx)
/* Remove bits after the desired bits */ /* Remove bits after the desired bits */
tmp = tmp >> (32 - num) tmp = tmp >> (32 - num)
/* Update pointers */ /* Update pointers */
theMainData.ptr = theMainData.ptr[(theMainData.idx+int(num))>>3:] theMainDataBytes.ptr = theMainDataBytes.ptr[(theMainDataBytes.idx+int(num))>>3:]
theMainData.pos += (theMainData.idx + int(num)) >> 3 theMainDataBytes.pos += (theMainDataBytes.idx + int(num)) >> 3
theMainData.idx = (theMainData.idx + int(num)) & 0x07 theMainDataBytes.idx = (theMainDataBytes.idx + int(num)) & 0x07
/* Done */ /* Done */
return C.unsigned(tmp) return C.unsigned(tmp)
@ -122,16 +121,16 @@ func Get_Main_Bits(num C.unsigned) C.unsigned {
//export Get_Main_Pos //export Get_Main_Pos
func Get_Main_Pos() C.unsigned { func Get_Main_Pos() C.unsigned {
pos := theMainData.pos pos := theMainDataBytes.pos
pos *= 8 /* Multiply by 8 to get number of bits */ pos *= 8 /* Multiply by 8 to get number of bits */
pos += theMainData.idx /* Add current bit index */ pos += theMainDataBytes.idx /* Add current bit index */
return C.unsigned(pos) return C.unsigned(pos)
} }
//export Set_Main_Pos //export Set_Main_Pos
func Set_Main_Pos(bit_pos C.unsigned) C.int { func Set_Main_Pos(bit_pos C.unsigned) C.int {
theMainData.ptr = theMainData.vec[bit_pos>>3:] theMainDataBytes.ptr = theMainDataBytes.vec[bit_pos>>3:]
theMainData.pos = int(bit_pos) >> 3 theMainDataBytes.pos = int(bit_pos) >> 3
theMainData.idx = int(bit_pos) & 0x7 theMainDataBytes.idx = int(bit_pos) & 0x7
return C.OK return C.OK
} }

View File

@ -11,73 +11,6 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
/* Types used in the frame header */
typedef enum { /* Layer number */
mpeg1_layer_reserved = 0,
mpeg1_layer_3 = 1,
mpeg1_layer_2 = 2,
mpeg1_layer_1 = 3
}
t_mpeg1_layer;
typedef enum { /* Modes */
mpeg1_mode_stereo = 0,
mpeg1_mode_joint_stereo,
mpeg1_mode_dual_channel,
mpeg1_mode_single_channel
}
t_mpeg1_mode;
typedef struct { /* MPEG1 Layer 1-3 frame header */
unsigned id; /* 1 bit */
t_mpeg1_layer layer; /* 2 bits */
unsigned protection_bit; /* 1 bit */
unsigned bitrate_index; /* 4 bits */
unsigned sampling_frequency; /* 2 bits */
unsigned padding_bit; /* 1 bit */
unsigned private_bit; /* 1 bit */
t_mpeg1_mode mode; /* 2 bits */
unsigned mode_extension; /* 2 bits */
unsigned copyright; /* 1 bit */
unsigned original_or_copy; /* 1 bit */
unsigned emphasis; /* 2 bits */
}
t_mpeg1_header;
typedef struct { /* MPEG1 Layer 3 Side Information : [2][2] means [gr][ch] */
unsigned main_data_begin; /* 9 bits */
unsigned private_bits; /* 3 bits in mono,5 in stereo */
unsigned scfsi[2][4]; /* 1 bit */
unsigned part2_3_length[2][2]; /* 12 bits */
unsigned big_values[2][2]; /* 9 bits */
unsigned global_gain[2][2]; /* 8 bits */
unsigned scalefac_compress[2][2]; /* 4 bits */
unsigned win_switch_flag[2][2]; /* 1 bit */
/* if(win_switch_flag[][]) */ //use a union dammit
unsigned block_type[2][2]; /* 2 bits */
unsigned mixed_block_flag[2][2]; /* 1 bit */
unsigned table_select[2][2][3]; /* 5 bits */
unsigned subblock_gain[2][2][3]; /* 3 bits */
/* else */
/* table_select[][][] */
unsigned region0_count[2][2]; /* 4 bits */
unsigned region1_count[2][2]; /* 3 bits */
/* end */
unsigned preflag[2][2]; /* 1 bit */
unsigned scalefac_scale[2][2]; /* 1 bit */
unsigned count1table_select[2][2];/* 1 bit */
unsigned count1[2][2]; /* Not in file,calc. by huff.dec.! */
}
t_mpeg1_side_info;
typedef struct { /* MPEG1 Layer 3 Main Data */
unsigned scalefac_l[2][2][21]; /* 0-4 bits */
unsigned scalefac_s[2][2][12][3]; /* 0-4 bits */
float is[2][2][576]; /* Huffman coded freq. lines */
}
t_mpeg1_main_data;
typedef struct { /* Scale factor band indices,for long and short windows */
unsigned l[23];
unsigned s[14];
}
t_sf_band_indices;
#define C_SYNC 0xffe00000 #define C_SYNC 0xffe00000
#define C_EOF 0xffffffff #define C_EOF 0xffffffff
#define C_PI 3.14159265358979323846 #define C_PI 3.14159265358979323846
@ -107,10 +40,6 @@ static void dmp_samples(t_mpeg1_main_data *md,int gr,int ch,int type);
#define dmp_samples(...) do{}while(0) #define dmp_samples(...) do{}while(0)
#endif #endif
static int Read_Audio_L3(void);
static int Read_Header(void) ;
static int Read_Main_L3(void);
static void audio_write(unsigned *samples,unsigned nsamples,int sample_rate); static void audio_write(unsigned *samples,unsigned nsamples,int sample_rate);
static void audio_write_raw(unsigned *samples,unsigned nsamples); static void audio_write_raw(unsigned *samples,unsigned nsamples);
static void Decode_L3_Init_Song(void); static void Decode_L3_Init_Song(void);
@ -316,9 +245,9 @@ static const t_sf_band_indices g_sf_band_indices[3 /* Sampling freq. */] = {
} }
}; };
static t_mpeg1_header g_frame_header; t_mpeg1_header g_frame_header;
static t_mpeg1_side_info g_side_info; /* < 100 words */ t_mpeg1_side_info g_side_info; /* < 100 words */
static t_mpeg1_main_data g_main_data; /* Large static data(~2500 words) */ t_mpeg1_main_data g_main_data; /* Large static data(~2500 words) */
#ifdef DEBUG #ifdef DEBUG
static void dmp_fr(t_mpeg1_header *hdr){ static void dmp_fr(t_mpeg1_header *hdr){
@ -491,84 +420,6 @@ int Decode_L3(void){
return(OK); /* Done */ return(OK); /* Done */
} }
/**Description: Reads audio and main data from bitstream into a buffer. main
* data is taken from this frame and up to 2 previous frames.
* Parameters: None
* Return value: OK or ERROR if data could not be read,or contains errors.
* Author: Krister Lagerström(krister@kmlager.com) **/
static int Read_Audio_L3(void){
unsigned framesize,sideinfo_size,main_data_size,nch,ch,gr,scfsi_band,region,window;
/* Number of channels(1 for mono and 2 for stereo) */
nch =(g_frame_header.mode == mpeg1_mode_single_channel ? 1 : 2);
/* Calculate header audio data size */
framesize = (144 *
g_mpeg1_bitrates[g_frame_header.layer-1][g_frame_header.bitrate_index]) /
g_sampling_frequency[g_frame_header.sampling_frequency] +
g_frame_header.padding_bit;
if(framesize > 2000) {
ERR("framesize = %d\n",framesize);
return(ERROR);
}
/* Sideinfo is 17 bytes for one channel and 32 bytes for two */
sideinfo_size =(nch == 1 ? 17 : 32);
/* Main data size is the rest of the frame,including ancillary data */
main_data_size = framesize - sideinfo_size - 4 /* sync+header */;
/* CRC is 2 bytes */
if(g_frame_header.protection_bit == 0) main_data_size -= 2;
/* DBG("framesize = %d\n",framesize); */
/* DBG("sideinfo_size = %d\n",sideinfo_size); */
/* DBG("main_data_size = %d\n",main_data_size); */
/* Read sideinfo from bitstream into buffer used by Get_Side_Bits() */
Get_Sideinfo(sideinfo_size);
if(Get_Filepos() == C_EOF) return(ERROR);
/* Parse audio data */
/* Pointer to where we should start reading main data */
g_side_info.main_data_begin = Get_Side_Bits(9);
/* Get private bits. Not used for anything. */
if(g_frame_header.mode == mpeg1_mode_single_channel)
g_side_info.private_bits = Get_Side_Bits(5);
else g_side_info.private_bits = Get_Side_Bits(3);
/* Get scale factor selection information */
for(ch = 0; ch < nch; ch++)
for(scfsi_band = 0; scfsi_band < 4; scfsi_band++)
g_side_info.scfsi[ch][scfsi_band] = Get_Side_Bits(1);
/* Get the rest of the side information */
for(gr = 0; gr < 2; gr++) {
for(ch = 0; ch < nch; ch++) {
g_side_info.part2_3_length[gr][ch] = Get_Side_Bits(12);
g_side_info.big_values[gr][ch] = Get_Side_Bits(9);
g_side_info.global_gain[gr][ch] = Get_Side_Bits(8);
g_side_info.scalefac_compress[gr][ch] = Get_Side_Bits(4);
g_side_info.win_switch_flag[gr][ch] = Get_Side_Bits(1);
if(g_side_info.win_switch_flag[gr][ch] == 1) {
g_side_info.block_type[gr][ch] = Get_Side_Bits(2);
g_side_info.mixed_block_flag[gr][ch] = Get_Side_Bits(1);
for(region = 0; region < 2; region++)
g_side_info.table_select[gr][ch][region] = Get_Side_Bits(5);
for(window = 0; window < 3; window++)
g_side_info.subblock_gain[gr][ch][window] = Get_Side_Bits(3);
if((g_side_info.block_type[gr][ch]==2)&&(g_side_info.mixed_block_flag[gr][ch]==0))
g_side_info.region0_count[gr][ch] = 8; /* Implicit */
else g_side_info.region0_count[gr][ch] = 7; /* Implicit */
/* The standard is wrong on this!!! */ /* Implicit */
g_side_info.region1_count[gr][ch] = 20 - g_side_info.region0_count[gr][ch];
}else{
for(region = 0; region < 3; region++)
g_side_info.table_select[gr][ch][region] = Get_Side_Bits(5);
g_side_info.region0_count[gr][ch] = Get_Side_Bits(4);
g_side_info.region1_count[gr][ch] = Get_Side_Bits(3);
g_side_info.block_type[gr][ch] = 0; /* Implicit */
} /* end if ... */
g_side_info.preflag[gr][ch] = Get_Side_Bits(1);
g_side_info.scalefac_scale[gr][ch] = Get_Side_Bits(1);
g_side_info.count1table_select[gr][ch] = Get_Side_Bits(1);
} /* end for(channel... */
} /* end for(granule... */
return(OK);/* Done */
}
/**Description: Search for next frame and read it into buffer. Main data in /**Description: Search for next frame and read it into buffer. Main data in
this frame is saved for two frames since it might be needed by them. this frame is saved for two frames since it might be needed by them.
* Parameters: None * Parameters: None
@ -813,7 +664,6 @@ static void Error(const char *s,int e){
* Author: Krister Lagerström(krister@kmlager.com) **/ * Author: Krister Lagerström(krister@kmlager.com) **/
static void Decode_L3_Init_Song(void){ static void Decode_L3_Init_Song(void){
hsynth_init = synth_init = 1; hsynth_init = synth_init = 1;
//g_main_data_top = 0; /* Clear bit reservoir */
} }
/**Description: TBD /**Description: TBD

View File

@ -16,6 +16,74 @@
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
/* Types used in the frame header */
typedef enum { /* Layer number */
mpeg1_layer_reserved = 0,
mpeg1_layer_3 = 1,
mpeg1_layer_2 = 2,
mpeg1_layer_1 = 3
}
t_mpeg1_layer;
typedef enum { /* Modes */
mpeg1_mode_stereo = 0,
mpeg1_mode_joint_stereo,
mpeg1_mode_dual_channel,
mpeg1_mode_single_channel
}
t_mpeg1_mode;
typedef struct { /* MPEG1 Layer 1-3 frame header */
unsigned id; /* 1 bit */
t_mpeg1_layer layer; /* 2 bits */
unsigned protection_bit; /* 1 bit */
unsigned bitrate_index; /* 4 bits */
unsigned sampling_frequency; /* 2 bits */
unsigned padding_bit; /* 1 bit */
unsigned private_bit; /* 1 bit */
t_mpeg1_mode mode; /* 2 bits */
unsigned mode_extension; /* 2 bits */
unsigned copyright; /* 1 bit */
unsigned original_or_copy; /* 1 bit */
unsigned emphasis; /* 2 bits */
}
t_mpeg1_header;
typedef struct { /* MPEG1 Layer 3 Side Information : [2][2] means [gr][ch] */
unsigned main_data_begin; /* 9 bits */
unsigned private_bits; /* 3 bits in mono,5 in stereo */
unsigned scfsi[2][4]; /* 1 bit */
unsigned part2_3_length[2][2]; /* 12 bits */
unsigned big_values[2][2]; /* 9 bits */
unsigned global_gain[2][2]; /* 8 bits */
unsigned scalefac_compress[2][2]; /* 4 bits */
unsigned win_switch_flag[2][2]; /* 1 bit */
/* if(win_switch_flag[][]) */ //use a union dammit
unsigned block_type[2][2]; /* 2 bits */
unsigned mixed_block_flag[2][2]; /* 1 bit */
unsigned table_select[2][2][3]; /* 5 bits */
unsigned subblock_gain[2][2][3]; /* 3 bits */
/* else */
/* table_select[][][] */
unsigned region0_count[2][2]; /* 4 bits */
unsigned region1_count[2][2]; /* 3 bits */
/* end */
unsigned preflag[2][2]; /* 1 bit */
unsigned scalefac_scale[2][2]; /* 1 bit */
unsigned count1table_select[2][2];/* 1 bit */
unsigned count1[2][2]; /* Not in file,calc. by huff.dec.! */
}
t_mpeg1_side_info;
typedef struct { /* MPEG1 Layer 3 Main Data */
unsigned scalefac_l[2][2][21]; /* 0-4 bits */
unsigned scalefac_s[2][2][12][3]; /* 0-4 bits */
float is[2][2][576]; /* Huffman coded freq. lines */
}
t_mpeg1_main_data;
typedef struct { /* Scale factor band indices,for long and short windows */
unsigned l[23];
unsigned s[14];
}
t_sf_band_indices;
unsigned Get_Byte(void); unsigned Get_Byte(void);
unsigned Get_Bytes(unsigned num, unsigned* data_vec); unsigned Get_Bytes(unsigned num, unsigned* data_vec);
unsigned Get_Filepos(void); unsigned Get_Filepos(void);
@ -31,8 +99,9 @@ int Set_Main_Pos(unsigned bit_pos);
unsigned Get_Main_Bit(void); unsigned Get_Main_Bit(void);
unsigned Get_Main_Bits(unsigned number_of_bits); unsigned Get_Main_Bits(unsigned number_of_bits);
void Get_Sideinfo(unsigned sideinfo_size); int Read_Audio_L3(void);
unsigned Get_Side_Bits(unsigned number_of_bits); static int Read_Header(void) ;
static int Read_Main_L3(void);
void IMDCT_Win(float* in, float* out,unsigned block_type); void IMDCT_Win(float* in, float* out,unsigned block_type);

View File

@ -17,12 +17,119 @@
package mp3 package mp3
// #include "pdmp3.h" // #include "pdmp3.h"
//
// extern t_mpeg1_header g_frame_header;
// extern t_mpeg1_side_info g_side_info;
// extern t_mpeg1_main_data g_main_data;
import "C" import "C"
import ( import (
"fmt" "fmt"
) )
var g_mpeg1_bitrates = [3][15]int{
{ /* Layer 1 */
0, 32000, 64000, 96000, 128000, 160000, 192000, 224000,
256000, 288000, 320000, 352000, 384000, 416000, 448000,
},
{ /* Layer 2 */
0, 32000, 48000, 56000, 64000, 80000, 96000, 112000,
128000, 160000, 192000, 224000, 256000, 320000, 384000,
},
{ /* Layer 3 */
0, 32000, 40000, 48000, 56000, 64000, 80000, 96000,
112000, 128000, 160000, 192000, 224000, 256000, 320000,
},
}
var g_sampling_frequency = [3]int{44100, 48000, 32000}
//export Read_Audio_L3
func Read_Audio_L3() C.int {
nch := 2
if C.g_frame_header.mode == C.mpeg1_mode_single_channel {
nch = 1
}
/* Calculate header audio data size */
framesize := (144*
g_mpeg1_bitrates[C.g_frame_header.layer-1][C.g_frame_header.bitrate_index])/
g_sampling_frequency[C.g_frame_header.sampling_frequency] +
int(C.g_frame_header.padding_bit)
if framesize > 2000 {
g_error = fmt.Errorf("mp3: framesize = %d\n", framesize)
return C.ERROR
}
/* Sideinfo is 17 bytes for one channel and 32 bytes for two */
sideinfo_size := 32
if nch == 1 {
sideinfo_size = 17
}
/* Main data size is the rest of the frame,including ancillary data */
main_data_size := framesize - sideinfo_size - 4 /* sync+header */
/* CRC is 2 bytes */
if C.g_frame_header.protection_bit == 0 {
main_data_size -= 2
}
/* Read sideinfo from bitstream into buffer used by getSideBits() */
getSideinfo(sideinfo_size)
if Get_Filepos() == eof {
return C.ERROR
}
/* Parse audio data */
/* Pointer to where we should start reading main data */
C.g_side_info.main_data_begin = C.uint(getSideBits(9))
/* Get private bits. Not used for anything. */
if C.g_frame_header.mode == C.mpeg1_mode_single_channel {
C.g_side_info.private_bits = C.uint(getSideBits(5))
} else {
C.g_side_info.private_bits = C.uint(getSideBits(3))
}
/* Get scale factor selection information */
for ch := 0; ch < nch; ch++ {
for scfsi_band := 0; scfsi_band < 4; scfsi_band++ {
C.g_side_info.scfsi[ch][scfsi_band] = C.uint(getSideBits(1))
}
}
/* Get the rest of the side information */
for gr := 0; gr < 2; gr++ {
for ch := 0; ch < nch; ch++ {
C.g_side_info.part2_3_length[gr][ch] = C.uint(getSideBits(12))
C.g_side_info.big_values[gr][ch] = C.uint(getSideBits(9))
C.g_side_info.global_gain[gr][ch] = C.uint(getSideBits(8))
C.g_side_info.scalefac_compress[gr][ch] = C.uint(getSideBits(4))
C.g_side_info.win_switch_flag[gr][ch] = C.uint(getSideBits(1))
if C.g_side_info.win_switch_flag[gr][ch] == 1 {
C.g_side_info.block_type[gr][ch] = C.uint(getSideBits(2))
C.g_side_info.mixed_block_flag[gr][ch] = C.uint(getSideBits(1))
for region := 0; region < 2; region++ {
C.g_side_info.table_select[gr][ch][region] = C.uint(getSideBits(5))
}
for window := 0; window < 3; window++ {
C.g_side_info.subblock_gain[gr][ch][window] = C.uint(getSideBits(3))
}
if (C.g_side_info.block_type[gr][ch] == 2) && (C.g_side_info.mixed_block_flag[gr][ch] == 0) {
C.g_side_info.region0_count[gr][ch] = 8 /* Implicit */
} else {
C.g_side_info.region0_count[gr][ch] = 7 /* Implicit */
}
/* The standard is wrong on this!!! */ /* Implicit */
C.g_side_info.region1_count[gr][ch] = 20 - C.g_side_info.region0_count[gr][ch]
} else {
for region := 0; region < 3; region++ {
C.g_side_info.table_select[gr][ch][region] = C.uint(getSideBits(5))
}
C.g_side_info.region0_count[gr][ch] = C.uint(getSideBits(4))
C.g_side_info.region1_count[gr][ch] = C.uint(getSideBits(3))
C.g_side_info.block_type[gr][ch] = 0 /* Implicit */
}
C.g_side_info.preflag[gr][ch] = C.uint(getSideBits(1))
C.g_side_info.scalefac_scale[gr][ch] = C.uint(getSideBits(1))
C.g_side_info.count1table_select[gr][ch] = C.uint(getSideBits(1))
}
}
return C.OK
}
// A sideInfo is a bit reservoir for side info // A sideInfo is a bit reservoir for side info
type sideInfo struct { type sideInfo struct {
vec []int vec []int
@ -31,8 +138,7 @@ type sideInfo struct {
var theSideInfo sideInfo var theSideInfo sideInfo
//export Get_Sideinfo func getSideinfo(size int) {
func Get_Sideinfo(size C.unsigned) {
var err error var err error
theSideInfo.vec, err = getBytes(int(size)) theSideInfo.vec, err = getBytes(int(size))
if err != nil { if err != nil {
@ -43,8 +149,7 @@ func Get_Sideinfo(size C.unsigned) {
theSideInfo.idx = 0 theSideInfo.idx = 0
} }
//export Get_Side_Bits func getSideBits(num int) int {
func Get_Side_Bits(num C.unsigned) C.unsigned {
// Form a word of the next four bytes // Form a word of the next four bytes
// TODO: endianness? // TODO: endianness?
b := make([]int, 4) b := make([]int, 4)
@ -57,9 +162,9 @@ func Get_Side_Bits(num C.unsigned) C.unsigned {
// Remove bits already used // Remove bits already used
tmp = tmp << uint(theSideInfo.idx) tmp = tmp << uint(theSideInfo.idx)
// Remove bits after the desired bits // Remove bits after the desired bits
tmp = tmp >> (32 - num) tmp = tmp >> (32 - uint(num))
// Update pointers // Update pointers
theSideInfo.vec = theSideInfo.vec[(theSideInfo.idx+int(num))>>3:] theSideInfo.vec = theSideInfo.vec[(theSideInfo.idx+int(num))>>3:]
theSideInfo.idx = (theSideInfo.idx + int(num)) & 0x07 theSideInfo.idx = (theSideInfo.idx + int(num)) & 0x07
return C.unsigned(tmp) return int(tmp)
} }