audio/mp3: Move side_info_* to Go

This commit is contained in:
Hajime Hoshi 2017-06-13 02:49:15 +09:00
parent 68a2625fd2
commit 3e76a77e6b
4 changed files with 80 additions and 43 deletions

View File

@ -73,6 +73,18 @@ func Get_Bytes(num C.unsigned, data *C.unsigned) C.unsigned {
return C.OK
}
func getBytes(num int) ([]int, error) {
r := make([]int, num)
for i := 0; i < num; i++ {
v := Get_Byte()
if v == eof {
return r, io.EOF
}
r[i] = int(v)
}
return r, nil
}
//export Get_Filepos
func Get_Filepos() C.unsigned {
if len(readerCache) == 0 && readerEOF {

View File

@ -117,13 +117,11 @@ static int Read_Main_L3(void);
static int Set_Main_Pos(unsigned bit_pos);
static unsigned Get_Main_Pos(void);
static unsigned Get_Side_Bits(unsigned number_of_bits);
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);
static void Error(const char *s,int e);
static void Get_Sideinfo(unsigned sideinfo_size);
static void IMDCT_Win(float in[18],float out[36],unsigned block_type);
static void L3_Antialias(unsigned gr,unsigned ch);
static void L3_Frequency_Inversion(unsigned gr,unsigned ch);
@ -463,11 +461,7 @@ static unsigned hsynth_init = 1,synth_init = 1,
g_main_data_vec[2*1024],/* Large static data */
*g_main_data_ptr,/* Pointer into the reservoir */
g_main_data_idx,/* Index into the current byte(0-7) */
g_main_data_top = 0,/* Number of bytes in reservoir(0-1024) */
/* Bit reservoir for side info */
side_info_vec[32+4],
*side_info_ptr, /* Pointer into the reservoir */
side_info_idx; /* Index into the current byte(0-7) */
g_main_data_top = 0;/* Number of bytes in reservoir(0-1024) */
/* Scale factor band indices
*
@ -1090,26 +1084,6 @@ static unsigned Get_Main_Pos(void){
return(pos);
}
/**Description: reads 'number_of_bits' from buffer which contains side_info.
* Parameters: number_of_bits to read(max 16)
* Return value: The bits are returned in the LSB of the return value.
* Author: Krister Lagerström(krister@kmlager.com) **/
static unsigned Get_Side_Bits(unsigned number_of_bits){
unsigned tmp;
/* Form a word of the next four bytes */ //TODO endianness?
tmp =(side_info_ptr[0] << 24) |(side_info_ptr[1] << 16) |
(side_info_ptr[2] << 8) |(side_info_ptr[3] << 0);
/* Remove bits already used */
tmp = tmp << side_info_idx;
/* Remove bits after the desired bits */
tmp = tmp >>(32 - number_of_bits);
/* Update pointers */
side_info_ptr +=(side_info_idx + number_of_bits) >> 3;
side_info_idx =(side_info_idx + number_of_bits) & 0x07;
return(tmp);
}
/**Description: TBD
* Parameters: TBD
* Return value: TBD
@ -1119,22 +1093,6 @@ static void Error(const char *s,int e){
exit(e);
}
/**Description: Reads sideinfo from bitstream into buffer for Get_Side_Bits.
* Parameters: TBD
* Return value: TBD
* Author: Krister Lagerström(krister@kmlager.com) **/
static void Get_Sideinfo(unsigned sideinfo_size){
if(Get_Bytes(sideinfo_size,side_info_vec) != OK) {
ERR("\nCouldn't read sideinfo %d bytes at pos %d\n",
sideinfo_size,Get_Filepos());
return;
}
side_info_ptr = &(side_info_vec[0]);
side_info_idx = 0;
}
/**Description: reinit decoder before playing new song,or seeking current song.
* Parameters: None
* Return value: None

View File

@ -23,6 +23,8 @@ size_t writeToWriter(void* data, int size);
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 Huffman_Decode(unsigned table_num, int32_t* x, int32_t*y, int32_t* v, int32_t* w);

65
audio/mp3/sideinfo.go Normal file
View File

@ -0,0 +1,65 @@
// Copyright 2017 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !js
package mp3
// #include "pdmp3.h"
import "C"
import (
"fmt"
)
// A sideInfo is a bit reservoir for side info
type sideInfo struct {
vec []int
idx int // Index into the current byte(0-7)
}
var theSideInfo sideInfo
//export Get_Sideinfo
func Get_Sideinfo(size C.unsigned) {
var err error
theSideInfo.vec, err = getBytes(int(size))
if err != nil {
g_error = fmt.Errorf("mp3: couldn't read sideinfo %d bytes at pos %d: %v",
size, Get_Filepos(), err)
return
}
theSideInfo.idx = 0
}
//export Get_Side_Bits
func Get_Side_Bits(num C.unsigned) C.unsigned {
// Form a word of the next four bytes
// TODO: endianness?
b := make([]int, 4)
for i := range b {
if len(theSideInfo.vec) > i {
b[i] = theSideInfo.vec[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(theSideInfo.idx)
// Remove bits after the desired bits
tmp = tmp >> (32 - num)
// Update pointers
theSideInfo.vec = theSideInfo.vec[(theSideInfo.idx+int(num))>>3:]
theSideInfo.idx = (theSideInfo.idx + int(num)) & 0x07
return C.unsigned(tmp)
}