mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
audio/mp3: Move Read_Audio_L3 to Go
This commit is contained in:
parent
49c95eb69f
commit
746548f5d2
@ -23,8 +23,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/* Bit reservoir for main data */
|
||||
type mainData struct {
|
||||
type mainDataBytes struct {
|
||||
// Large static data
|
||||
vec [2 * 1024]int
|
||||
// Pointer into the reservoir
|
||||
@ -37,7 +36,7 @@ type mainData struct {
|
||||
pos int
|
||||
}
|
||||
|
||||
var theMainData mainData
|
||||
var theMainDataBytes mainDataBytes
|
||||
|
||||
//export Get_Main_Data
|
||||
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)
|
||||
}
|
||||
/* 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
|
||||
// read the main_data bits from the bitstream in case they are needed
|
||||
// for decoding the next frame.
|
||||
@ -54,17 +53,17 @@ func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int {
|
||||
g_error = err
|
||||
return C.ERROR
|
||||
}
|
||||
copy(theMainData.vec[theMainData.top:], b)
|
||||
copy(theMainDataBytes.vec[theMainDataBytes.top:], b)
|
||||
/* Set up pointers */
|
||||
theMainData.ptr = theMainData.vec[0:]
|
||||
theMainData.pos = 0
|
||||
theMainData.idx = 0
|
||||
theMainData.top += int(size)
|
||||
theMainDataBytes.ptr = theMainDataBytes.vec[0:]
|
||||
theMainDataBytes.pos = 0
|
||||
theMainDataBytes.idx = 0
|
||||
theMainDataBytes.top += int(size)
|
||||
return C.ERROR
|
||||
}
|
||||
/* Copy data from previous frames */
|
||||
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 */
|
||||
b, err := getBytes(int(size))
|
||||
@ -72,22 +71,22 @@ func Get_Main_Data(size C.unsigned, begin C.unsigned) C.int {
|
||||
g_error = err
|
||||
return C.ERROR
|
||||
}
|
||||
copy(theMainData.vec[begin:], b)
|
||||
copy(theMainDataBytes.vec[begin:], b)
|
||||
/* Set up pointers */
|
||||
theMainData.ptr = theMainData.vec[0:]
|
||||
theMainData.pos = 0
|
||||
theMainData.idx = 0
|
||||
theMainData.top = int(begin) + int(size)
|
||||
theMainDataBytes.ptr = theMainDataBytes.vec[0:]
|
||||
theMainDataBytes.pos = 0
|
||||
theMainDataBytes.idx = 0
|
||||
theMainDataBytes.top = int(begin) + int(size)
|
||||
return C.OK
|
||||
}
|
||||
|
||||
//export Get_Main_Bit
|
||||
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
|
||||
theMainData.ptr = theMainData.ptr[(theMainData.idx+1)>>3:]
|
||||
theMainData.pos += (theMainData.idx + 1) >> 3
|
||||
theMainData.idx = (theMainData.idx + 1) & 0x07
|
||||
theMainDataBytes.ptr = theMainDataBytes.ptr[(theMainDataBytes.idx+1)>>3:]
|
||||
theMainDataBytes.pos += (theMainDataBytes.idx + 1) >> 3
|
||||
theMainDataBytes.idx = (theMainDataBytes.idx + 1) & 0x07
|
||||
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 */
|
||||
b := make([]int, 4)
|
||||
for i := range b {
|
||||
if len(theMainData.ptr) > i {
|
||||
b[i] = theMainData.ptr[i]
|
||||
if len(theMainDataBytes.ptr) > i {
|
||||
b[i] = theMainDataBytes.ptr[i]
|
||||
}
|
||||
}
|
||||
tmp := (uint32(b[0]) << 24) | (uint32(b[1]) << 16) | (uint32(b[2]) << 8) | (uint32(b[3]) << 0)
|
||||
|
||||
/* Remove bits already used */
|
||||
tmp = tmp << uint(theMainData.idx)
|
||||
tmp = tmp << uint(theMainDataBytes.idx)
|
||||
|
||||
/* Remove bits after the desired bits */
|
||||
tmp = tmp >> (32 - num)
|
||||
|
||||
/* Update pointers */
|
||||
theMainData.ptr = theMainData.ptr[(theMainData.idx+int(num))>>3:]
|
||||
theMainData.pos += (theMainData.idx + int(num)) >> 3
|
||||
theMainData.idx = (theMainData.idx + int(num)) & 0x07
|
||||
theMainDataBytes.ptr = theMainDataBytes.ptr[(theMainDataBytes.idx+int(num))>>3:]
|
||||
theMainDataBytes.pos += (theMainDataBytes.idx + int(num)) >> 3
|
||||
theMainDataBytes.idx = (theMainDataBytes.idx + int(num)) & 0x07
|
||||
|
||||
/* Done */
|
||||
return C.unsigned(tmp)
|
||||
@ -122,16 +121,16 @@ func Get_Main_Bits(num C.unsigned) C.unsigned {
|
||||
|
||||
//export Get_Main_Pos
|
||||
func Get_Main_Pos() C.unsigned {
|
||||
pos := theMainData.pos
|
||||
pos := theMainDataBytes.pos
|
||||
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)
|
||||
}
|
||||
|
||||
//export Set_Main_Pos
|
||||
func Set_Main_Pos(bit_pos C.unsigned) C.int {
|
||||
theMainData.ptr = theMainData.vec[bit_pos>>3:]
|
||||
theMainData.pos = int(bit_pos) >> 3
|
||||
theMainData.idx = int(bit_pos) & 0x7
|
||||
theMainDataBytes.ptr = theMainDataBytes.vec[bit_pos>>3:]
|
||||
theMainDataBytes.pos = int(bit_pos) >> 3
|
||||
theMainDataBytes.idx = int(bit_pos) & 0x7
|
||||
return C.OK
|
||||
}
|
||||
|
@ -11,73 +11,6 @@
|
||||
#include <unistd.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_EOF 0xffffffff
|
||||
#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)
|
||||
#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_raw(unsigned *samples,unsigned nsamples);
|
||||
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;
|
||||
static t_mpeg1_side_info g_side_info; /* < 100 words */
|
||||
static t_mpeg1_main_data g_main_data; /* Large static data(~2500 words) */
|
||||
t_mpeg1_header g_frame_header;
|
||||
t_mpeg1_side_info g_side_info; /* < 100 words */
|
||||
t_mpeg1_main_data g_main_data; /* Large static data(~2500 words) */
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dmp_fr(t_mpeg1_header *hdr){
|
||||
@ -491,84 +420,6 @@ int Decode_L3(void){
|
||||
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
|
||||
this frame is saved for two frames since it might be needed by them.
|
||||
* Parameters: None
|
||||
@ -813,7 +664,6 @@ static void Error(const char *s,int e){
|
||||
* Author: Krister Lagerström(krister@kmlager.com) **/
|
||||
static void Decode_L3_Init_Song(void){
|
||||
hsynth_init = synth_init = 1;
|
||||
//g_main_data_top = 0; /* Clear bit reservoir */
|
||||
}
|
||||
|
||||
/**Description: TBD
|
||||
|
@ -16,6 +16,74 @@
|
||||
#define TRUE 1
|
||||
#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_Bytes(unsigned num, unsigned* data_vec);
|
||||
unsigned Get_Filepos(void);
|
||||
@ -31,8 +99,9 @@ int Set_Main_Pos(unsigned bit_pos);
|
||||
unsigned Get_Main_Bit(void);
|
||||
unsigned Get_Main_Bits(unsigned number_of_bits);
|
||||
|
||||
void Get_Sideinfo(unsigned sideinfo_size);
|
||||
unsigned Get_Side_Bits(unsigned number_of_bits);
|
||||
int Read_Audio_L3(void);
|
||||
static int Read_Header(void) ;
|
||||
static int Read_Main_L3(void);
|
||||
|
||||
void IMDCT_Win(float* in, float* out,unsigned block_type);
|
||||
|
||||
|
@ -17,12 +17,119 @@
|
||||
package mp3
|
||||
|
||||
// #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 (
|
||||
"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
|
||||
type sideInfo struct {
|
||||
vec []int
|
||||
@ -31,8 +138,7 @@ type sideInfo struct {
|
||||
|
||||
var theSideInfo sideInfo
|
||||
|
||||
//export Get_Sideinfo
|
||||
func Get_Sideinfo(size C.unsigned) {
|
||||
func getSideinfo(size int) {
|
||||
var err error
|
||||
theSideInfo.vec, err = getBytes(int(size))
|
||||
if err != nil {
|
||||
@ -43,8 +149,7 @@ func Get_Sideinfo(size C.unsigned) {
|
||||
theSideInfo.idx = 0
|
||||
}
|
||||
|
||||
//export Get_Side_Bits
|
||||
func Get_Side_Bits(num C.unsigned) C.unsigned {
|
||||
func getSideBits(num int) int {
|
||||
// Form a word of the next four bytes
|
||||
// TODO: endianness?
|
||||
b := make([]int, 4)
|
||||
@ -57,9 +162,9 @@ func Get_Side_Bits(num C.unsigned) C.unsigned {
|
||||
// Remove bits already used
|
||||
tmp = tmp << uint(theSideInfo.idx)
|
||||
// Remove bits after the desired bits
|
||||
tmp = tmp >> (32 - num)
|
||||
tmp = tmp >> (32 - uint(num))
|
||||
// Update pointers
|
||||
theSideInfo.vec = theSideInfo.vec[(theSideInfo.idx+int(num))>>3:]
|
||||
theSideInfo.idx = (theSideInfo.idx + int(num)) & 0x07
|
||||
return C.unsigned(tmp)
|
||||
return int(tmp)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user