mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08: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"
|
"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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user