mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
audio/mp3: Add frame struct
This commit is contained in:
parent
0e4c949471
commit
cb6e7366e2
@ -28,38 +28,38 @@ var (
|
||||
writer io.Writer
|
||||
)
|
||||
|
||||
func decodeL3() error {
|
||||
func (f *frame) decodeL3() error {
|
||||
out := make([]uint32, 576)
|
||||
// Number of channels(1 for mono and 2 for stereo)
|
||||
nch := 2
|
||||
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel {
|
||||
if f.header.mode == mpeg1ModeSingleChannel {
|
||||
nch = 1
|
||||
}
|
||||
for gr := 0; gr < 2; gr++ {
|
||||
for ch := 0; ch < nch; ch++ {
|
||||
l3Requantize(gr, ch)
|
||||
f.l3Requantize(gr, ch)
|
||||
// Reorder short blocks
|
||||
l3Reorder(gr, ch)
|
||||
f.l3Reorder(gr, ch)
|
||||
}
|
||||
l3Stereo(gr)
|
||||
f.l3Stereo(gr)
|
||||
for ch := 0; ch < nch; ch++ {
|
||||
l3Antialias(gr, ch)
|
||||
f.l3Antialias(gr, ch)
|
||||
// (IMDCT,windowing,overlapp add)
|
||||
l3HybridSynthesis(gr, ch)
|
||||
l3FrequencyInversion(gr, ch)
|
||||
f.l3HybridSynthesis(gr, ch)
|
||||
f.l3FrequencyInversion(gr, ch)
|
||||
// Polyphase subband synthesis
|
||||
l3SubbandSynthesis(gr, ch, out)
|
||||
f.l3SubbandSynthesis(gr, ch, out)
|
||||
}
|
||||
if err := audioWriteRaw(out); err != nil {
|
||||
if err := f.audioWriteRaw(out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func audioWriteRaw(samples []uint32) error {
|
||||
func (f *frame) audioWriteRaw(samples []uint32) error {
|
||||
nch := 2
|
||||
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel {
|
||||
if f.header.mode == mpeg1ModeSingleChannel {
|
||||
nch = 1
|
||||
}
|
||||
s := make([]uint8, len(samples)*2*nch)
|
||||
@ -129,9 +129,9 @@ func decode(r io.Reader, w io.Writer) error {
|
||||
reader = r
|
||||
writer = w
|
||||
for !isEOF() {
|
||||
err := readFrame()
|
||||
f, err := readFrame()
|
||||
if err == nil {
|
||||
if err := decodeL3(); err != nil {
|
||||
if err := f.decodeL3(); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
|
182
audio/mp3/l3.go
182
audio/mp3/l3.go
@ -31,46 +31,46 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func requantizeProcessLong(gr, ch, is_pos, sfb int) {
|
||||
func (f *frame) requantizeProcessLong(gr, ch, is_pos, sfb int) {
|
||||
sf_mult := 0.5
|
||||
if theMPEG1SideInfo.scalefac_scale[gr][ch] != 0 {
|
||||
if f.sideInfo.scalefac_scale[gr][ch] != 0 {
|
||||
sf_mult = 1.0
|
||||
}
|
||||
tmp1 := 1.0
|
||||
// https://github.com/technosaurus/PDMP3/issues/4
|
||||
if sfb < 21 {
|
||||
pf_x_pt := float64(theMPEG1SideInfo.preflag[gr][ch]) * pretab[sfb]
|
||||
tmp1 = math.Pow(2.0, -(sf_mult * (float64(theMPEG1MainData.scalefac_l[gr][ch][sfb]) + pf_x_pt)))
|
||||
pf_x_pt := float64(f.sideInfo.preflag[gr][ch]) * pretab[sfb]
|
||||
tmp1 = math.Pow(2.0, -(sf_mult * (float64(f.mainData.scalefac_l[gr][ch][sfb]) + pf_x_pt)))
|
||||
}
|
||||
tmp2 := math.Pow(2.0, 0.25*(float64(theMPEG1SideInfo.global_gain[gr][ch])-210))
|
||||
tmp2 := math.Pow(2.0, 0.25*(float64(f.sideInfo.global_gain[gr][ch])-210))
|
||||
tmp3 := 0.0
|
||||
if theMPEG1MainData.is[gr][ch][is_pos] < 0.0 {
|
||||
tmp3 = -powtab34[int(-theMPEG1MainData.is[gr][ch][is_pos])]
|
||||
if f.mainData.is[gr][ch][is_pos] < 0.0 {
|
||||
tmp3 = -powtab34[int(-f.mainData.is[gr][ch][is_pos])]
|
||||
} else {
|
||||
tmp3 = powtab34[int(theMPEG1MainData.is[gr][ch][is_pos])]
|
||||
tmp3 = powtab34[int(f.mainData.is[gr][ch][is_pos])]
|
||||
}
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(tmp1 * tmp2 * tmp3)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(tmp1 * tmp2 * tmp3)
|
||||
}
|
||||
|
||||
func requantizeProcessShort(gr, ch, is_pos, sfb, win int) {
|
||||
func (f *frame) requantizeProcessShort(gr, ch, is_pos, sfb, win int) {
|
||||
sf_mult := 0.5
|
||||
if theMPEG1SideInfo.scalefac_scale[gr][ch] != 0 {
|
||||
if f.sideInfo.scalefac_scale[gr][ch] != 0 {
|
||||
sf_mult = 1.0
|
||||
}
|
||||
tmp1 := 1.0
|
||||
// https://github.com/technosaurus/PDMP3/issues/4
|
||||
if sfb < 12 {
|
||||
tmp1 = math.Pow(2.0, -(sf_mult * float64(theMPEG1MainData.scalefac_s[gr][ch][sfb][win])))
|
||||
tmp1 = math.Pow(2.0, -(sf_mult * float64(f.mainData.scalefac_s[gr][ch][sfb][win])))
|
||||
}
|
||||
tmp2 := math.Pow(2.0, 0.25*(float64(theMPEG1SideInfo.global_gain[gr][ch])-210.0-
|
||||
8.0*float64(theMPEG1SideInfo.subblock_gain[gr][ch][win])))
|
||||
tmp2 := math.Pow(2.0, 0.25*(float64(f.sideInfo.global_gain[gr][ch])-210.0-
|
||||
8.0*float64(f.sideInfo.subblock_gain[gr][ch][win])))
|
||||
tmp3 := 0.0
|
||||
if theMPEG1MainData.is[gr][ch][is_pos] < 0 {
|
||||
tmp3 = -powtab34[int(-theMPEG1MainData.is[gr][ch][is_pos])]
|
||||
if f.mainData.is[gr][ch][is_pos] < 0 {
|
||||
tmp3 = -powtab34[int(-f.mainData.is[gr][ch][is_pos])]
|
||||
} else {
|
||||
tmp3 = powtab34[int(theMPEG1MainData.is[gr][ch][is_pos])]
|
||||
tmp3 = powtab34[int(f.mainData.is[gr][ch][is_pos])]
|
||||
}
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(tmp1 * tmp2 * tmp3)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(tmp1 * tmp2 * tmp3)
|
||||
}
|
||||
|
||||
type sfBandIndices struct {
|
||||
@ -95,14 +95,14 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func l3Requantize(gr int, ch int) {
|
||||
func (f *frame) l3Requantize(gr int, ch int) {
|
||||
/* Setup sampling frequency index */
|
||||
sfreq := theMPEG1FrameHeader.sampling_frequency
|
||||
sfreq := f.header.sampling_frequency
|
||||
/* Determine type of block to process */
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) && (theMPEG1SideInfo.block_type[gr][ch] == 2) { /* Short blocks */
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] == 1) && (f.sideInfo.block_type[gr][ch] == 2) { /* Short blocks */
|
||||
/* Check if the first two subbands
|
||||
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
|
||||
if theMPEG1SideInfo.mixed_block_flag[gr][ch] != 0 { /* 2 longbl. sb first */
|
||||
if f.sideInfo.mixed_block_flag[gr][ch] != 0 { /* 2 longbl. sb first */
|
||||
/* First process the 2 long block subbands at the start */
|
||||
sfb := 0
|
||||
next_sfb := sfBandIndicesSet[sfreq].l[sfb+1]
|
||||
@ -111,7 +111,7 @@ func l3Requantize(gr int, ch int) {
|
||||
sfb++
|
||||
next_sfb = sfBandIndicesSet[sfreq].l[sfb+1]
|
||||
}
|
||||
requantizeProcessLong(int(gr), int(ch), i, sfb)
|
||||
f.requantizeProcessLong(gr, ch, i, sfb)
|
||||
}
|
||||
/* And next the remaining,non-zero,bands which uses short blocks */
|
||||
sfb = 3
|
||||
@ -119,7 +119,7 @@ func l3Requantize(gr int, ch int) {
|
||||
win_len := sfBandIndicesSet[sfreq].s[sfb+1] -
|
||||
sfBandIndicesSet[sfreq].s[sfb]
|
||||
|
||||
for i := 36; i < int(theMPEG1SideInfo.count1[gr][ch]); /* i++ done below! */ {
|
||||
for i := 36; i < int(f.sideInfo.count1[gr][ch]); /* i++ done below! */ {
|
||||
/* Check if we're into the next scalefac band */
|
||||
if i == next_sfb { /* Yes */
|
||||
sfb++
|
||||
@ -129,7 +129,7 @@ func l3Requantize(gr int, ch int) {
|
||||
}
|
||||
for win := 0; win < 3; win++ {
|
||||
for j := 0; j < win_len; j++ {
|
||||
requantizeProcessShort(int(gr), int(ch), i, sfb, win)
|
||||
f.requantizeProcessShort(gr, ch, i, sfb, win)
|
||||
i++
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ func l3Requantize(gr int, ch int) {
|
||||
next_sfb := sfBandIndicesSet[sfreq].s[sfb+1] * 3
|
||||
win_len := sfBandIndicesSet[sfreq].s[sfb+1] -
|
||||
sfBandIndicesSet[sfreq].s[sfb]
|
||||
for i := 0; i < int(theMPEG1SideInfo.count1[gr][ch]); /* i++ done below! */ {
|
||||
for i := 0; i < int(f.sideInfo.count1[gr][ch]); /* i++ done below! */ {
|
||||
/* Check if we're into the next scalefac band */
|
||||
if i == next_sfb {
|
||||
sfb++
|
||||
@ -150,7 +150,7 @@ func l3Requantize(gr int, ch int) {
|
||||
}
|
||||
for win := 0; win < 3; win++ {
|
||||
for j := 0; j < win_len; j++ {
|
||||
requantizeProcessShort(int(gr), int(ch), i, sfb, win)
|
||||
f.requantizeProcessShort(gr, ch, i, sfb, win)
|
||||
i++
|
||||
}
|
||||
}
|
||||
@ -159,27 +159,27 @@ func l3Requantize(gr int, ch int) {
|
||||
} else { /* Only long blocks */
|
||||
sfb := 0
|
||||
next_sfb := sfBandIndicesSet[sfreq].l[sfb+1]
|
||||
for i := 0; i < int(theMPEG1SideInfo.count1[gr][ch]); i++ {
|
||||
for i := 0; i < int(f.sideInfo.count1[gr][ch]); i++ {
|
||||
if i == next_sfb {
|
||||
sfb++
|
||||
next_sfb = sfBandIndicesSet[sfreq].l[sfb+1]
|
||||
}
|
||||
requantizeProcessLong(int(gr), int(ch), i, sfb)
|
||||
f.requantizeProcessLong(gr, ch, i, sfb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func l3Reorder(gr int, ch int) {
|
||||
func (f *frame) l3Reorder(gr int, ch int) {
|
||||
re := make([]float32, 576)
|
||||
|
||||
sfreq := theMPEG1FrameHeader.sampling_frequency /* Setup sampling freq index */
|
||||
sfreq := f.header.sampling_frequency /* Setup sampling freq index */
|
||||
/* Only reorder short blocks */
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) && (theMPEG1SideInfo.block_type[gr][ch] == 2) { /* Short blocks */
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] == 1) && (f.sideInfo.block_type[gr][ch] == 2) { /* Short blocks */
|
||||
/* Check if the first two subbands
|
||||
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
|
||||
sfb := 0
|
||||
/* 2 longbl. sb first */
|
||||
if theMPEG1SideInfo.mixed_block_flag[gr][ch] != 0 {
|
||||
if f.sideInfo.mixed_block_flag[gr][ch] != 0 {
|
||||
sfb = 3
|
||||
}
|
||||
next_sfb := sfBandIndicesSet[sfreq].s[sfb+1] * 3
|
||||
@ -193,10 +193,10 @@ func l3Reorder(gr int, ch int) {
|
||||
if i == next_sfb {
|
||||
/* Copy reordered data back to the original vector */
|
||||
for j := 0; j < 3*win_len; j++ {
|
||||
theMPEG1MainData.is[gr][ch][3*sfBandIndicesSet[sfreq].s[sfb]+j] = re[j]
|
||||
f.mainData.is[gr][ch][3*sfBandIndicesSet[sfreq].s[sfb]+j] = re[j]
|
||||
}
|
||||
/* Check if this band is above the rzero region,if so we're done */
|
||||
if i >= theMPEG1SideInfo.count1[gr][ch] {
|
||||
if i >= f.sideInfo.count1[gr][ch] {
|
||||
return
|
||||
}
|
||||
sfb++
|
||||
@ -205,14 +205,14 @@ func l3Reorder(gr int, ch int) {
|
||||
}
|
||||
for win := 0; win < 3; win++ { /* Do the actual reordering */
|
||||
for j := 0; j < win_len; j++ {
|
||||
re[j*3+win] = float32(theMPEG1MainData.is[gr][ch][i])
|
||||
re[j*3+win] = f.mainData.is[gr][ch][i]
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Copy reordered data of last band back to original vector */
|
||||
for j := 0; j < 3*win_len; j++ {
|
||||
theMPEG1MainData.is[gr][ch][3*sfBandIndicesSet[sfreq].s[12]+j] = re[j]
|
||||
f.mainData.is[gr][ch][3*sfBandIndicesSet[sfreq].s[12]+j] = re[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -221,13 +221,13 @@ var (
|
||||
is_ratios = [6]float32{0.000000, 0.267949, 0.577350, 1.000000, 1.732051, 3.732051}
|
||||
)
|
||||
|
||||
func stereoProcessIntensityLong(gr int, sfb int) {
|
||||
func (f *frame) stereoProcessIntensityLong(gr int, sfb int) {
|
||||
is_ratio_l := float32(0)
|
||||
is_ratio_r := float32(0)
|
||||
/* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */
|
||||
is_pos := theMPEG1MainData.scalefac_l[gr][0][sfb]
|
||||
is_pos := f.mainData.scalefac_l[gr][0][sfb]
|
||||
if is_pos != 7 {
|
||||
sfreq := theMPEG1FrameHeader.sampling_frequency /* Setup sampling freq index */
|
||||
sfreq := f.header.sampling_frequency /* Setup sampling freq index */
|
||||
sfb_start := sfBandIndicesSet[sfreq].l[sfb]
|
||||
sfb_stop := sfBandIndicesSet[sfreq].l[sfb+1]
|
||||
if is_pos == 6 { /* tan((6*PI)/12 = PI/2) needs special treatment! */
|
||||
@ -239,22 +239,22 @@ func stereoProcessIntensityLong(gr int, sfb int) {
|
||||
}
|
||||
/* Now decode all samples in this scale factor band */
|
||||
for i := sfb_start; i < sfb_stop; i++ {
|
||||
theMPEG1MainData.is[gr][0][i] *= is_ratio_l
|
||||
theMPEG1MainData.is[gr][1][i] *= is_ratio_r
|
||||
f.mainData.is[gr][0][i] *= is_ratio_l
|
||||
f.mainData.is[gr][1][i] *= is_ratio_r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stereoProcessIntensityShort(gr int, sfb int) {
|
||||
func (f *frame) stereoProcessIntensityShort(gr int, sfb int) {
|
||||
is_ratio_l := float32(0)
|
||||
is_ratio_r := float32(0)
|
||||
sfreq := theMPEG1FrameHeader.sampling_frequency /* Setup sampling freq index */
|
||||
sfreq := f.header.sampling_frequency /* Setup sampling freq index */
|
||||
/* The window length */
|
||||
win_len := sfBandIndicesSet[sfreq].s[sfb+1] - sfBandIndicesSet[sfreq].s[sfb]
|
||||
/* The three windows within the band has different scalefactors */
|
||||
for win := 0; win < 3; win++ {
|
||||
/* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */
|
||||
is_pos := theMPEG1MainData.scalefac_s[gr][0][sfb][win]
|
||||
is_pos := f.mainData.scalefac_s[gr][0][sfb][win]
|
||||
if is_pos != 7 {
|
||||
sfb_start := sfBandIndicesSet[sfreq].s[sfb]*3 + win_len*win
|
||||
sfb_stop := sfb_start + win_len
|
||||
@ -268,75 +268,75 @@ func stereoProcessIntensityShort(gr int, sfb int) {
|
||||
/* Now decode all samples in this scale factor band */
|
||||
for i := sfb_start; i < sfb_stop; i++ {
|
||||
// https://github.com/technosaurus/PDMP3/issues/3
|
||||
theMPEG1MainData.is[gr][0][i] *= is_ratio_l
|
||||
theMPEG1MainData.is[gr][1][i] *= is_ratio_r
|
||||
f.mainData.is[gr][0][i] *= is_ratio_l
|
||||
f.mainData.is[gr][1][i] *= is_ratio_r
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func l3Stereo(gr int) {
|
||||
func (f *frame) l3Stereo(gr int) {
|
||||
/* Do nothing if joint stereo is not enabled */
|
||||
if (theMPEG1FrameHeader.mode != 1) || (theMPEG1FrameHeader.mode_extension == 0) {
|
||||
if (f.header.mode != 1) || (f.header.mode_extension == 0) {
|
||||
return
|
||||
}
|
||||
/* Do Middle/Side("normal") stereo processing */
|
||||
if (theMPEG1FrameHeader.mode_extension & 0x2) != 0 {
|
||||
if (f.header.mode_extension & 0x2) != 0 {
|
||||
/* Determine how many frequency lines to transform */
|
||||
i := 0
|
||||
if theMPEG1SideInfo.count1[gr][0] > theMPEG1SideInfo.count1[gr][1] {
|
||||
if f.sideInfo.count1[gr][0] > f.sideInfo.count1[gr][1] {
|
||||
i = 1
|
||||
}
|
||||
max_pos := int(theMPEG1SideInfo.count1[gr][i])
|
||||
max_pos := int(f.sideInfo.count1[gr][i])
|
||||
/* Do the actual processing */
|
||||
const invSqrt2 = math.Sqrt2 / 2
|
||||
for i := 0; i < max_pos; i++ {
|
||||
left := (theMPEG1MainData.is[gr][0][i] + theMPEG1MainData.is[gr][1][i]) * invSqrt2
|
||||
right := (theMPEG1MainData.is[gr][0][i] - theMPEG1MainData.is[gr][1][i]) * invSqrt2
|
||||
theMPEG1MainData.is[gr][0][i] = left
|
||||
theMPEG1MainData.is[gr][1][i] = right
|
||||
left := (f.mainData.is[gr][0][i] + f.mainData.is[gr][1][i]) * invSqrt2
|
||||
right := (f.mainData.is[gr][0][i] - f.mainData.is[gr][1][i]) * invSqrt2
|
||||
f.mainData.is[gr][0][i] = left
|
||||
f.mainData.is[gr][1][i] = right
|
||||
}
|
||||
}
|
||||
/* Do intensity stereo processing */
|
||||
if (theMPEG1FrameHeader.mode_extension & 0x1) != 0 {
|
||||
if (f.header.mode_extension & 0x1) != 0 {
|
||||
/* Setup sampling frequency index */
|
||||
sfreq := theMPEG1FrameHeader.sampling_frequency
|
||||
sfreq := f.header.sampling_frequency
|
||||
/* First band that is intensity stereo encoded is first band scale factor
|
||||
* band on or above count1 frequency line. N.B.: Intensity stereo coding is
|
||||
* only done for higher subbands, but logic is here for lower subbands. */
|
||||
/* Determine type of block to process */
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][0] == 1) &&
|
||||
(theMPEG1SideInfo.block_type[gr][0] == 2) { /* Short blocks */
|
||||
if (f.sideInfo.win_switch_flag[gr][0] == 1) &&
|
||||
(f.sideInfo.block_type[gr][0] == 2) { /* Short blocks */
|
||||
/* Check if the first two subbands
|
||||
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
|
||||
if theMPEG1SideInfo.mixed_block_flag[gr][0] != 0 { /* 2 longbl. sb first */
|
||||
if f.sideInfo.mixed_block_flag[gr][0] != 0 { /* 2 longbl. sb first */
|
||||
for sfb := 0; sfb < 8; sfb++ { /* First process 8 sfb's at start */
|
||||
/* Is this scale factor band above count1 for the right channel? */
|
||||
if sfBandIndicesSet[sfreq].l[sfb] >= theMPEG1SideInfo.count1[gr][1] {
|
||||
stereoProcessIntensityLong(int(gr), int(sfb))
|
||||
if sfBandIndicesSet[sfreq].l[sfb] >= f.sideInfo.count1[gr][1] {
|
||||
f.stereoProcessIntensityLong(gr, sfb)
|
||||
}
|
||||
}
|
||||
/* And next the remaining bands which uses short blocks */
|
||||
for sfb := 3; sfb < 12; sfb++ {
|
||||
/* Is this scale factor band above count1 for the right channel? */
|
||||
if sfBandIndicesSet[sfreq].s[sfb]*3 >= theMPEG1SideInfo.count1[gr][1] {
|
||||
stereoProcessIntensityShort(int(gr), int(sfb)) /* intensity stereo processing */
|
||||
if sfBandIndicesSet[sfreq].s[sfb]*3 >= f.sideInfo.count1[gr][1] {
|
||||
f.stereoProcessIntensityShort(gr, sfb) /* intensity stereo processing */
|
||||
}
|
||||
}
|
||||
} else { /* Only short blocks */
|
||||
for sfb := 0; sfb < 12; sfb++ {
|
||||
/* Is this scale factor band above count1 for the right channel? */
|
||||
if sfBandIndicesSet[sfreq].s[sfb]*3 >= theMPEG1SideInfo.count1[gr][1] {
|
||||
stereoProcessIntensityShort(int(gr), int(sfb)) /* intensity stereo processing */
|
||||
if sfBandIndicesSet[sfreq].s[sfb]*3 >= f.sideInfo.count1[gr][1] {
|
||||
f.stereoProcessIntensityShort(gr, sfb) /* intensity stereo processing */
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* Only long blocks */
|
||||
for sfb := 0; sfb < 21; sfb++ {
|
||||
/* Is this scale factor band above count1 for the right channel? */
|
||||
if sfBandIndicesSet[sfreq].l[sfb] >= theMPEG1SideInfo.count1[gr][1] {
|
||||
if sfBandIndicesSet[sfreq].l[sfb] >= f.sideInfo.count1[gr][1] {
|
||||
/* Perform the intensity stereo processing */
|
||||
stereoProcessIntensityLong(int(gr), int(sfb))
|
||||
f.stereoProcessIntensityLong(gr, sfb)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,18 +348,18 @@ var (
|
||||
ca = [8]float32{-0.514496, -0.471732, -0.313377, -0.181913, -0.094574, -0.040966, -0.014199, -0.003700}
|
||||
)
|
||||
|
||||
func l3Antialias(gr int, ch int) {
|
||||
func (f *frame) l3Antialias(gr int, ch int) {
|
||||
/* No antialiasing is done for short blocks */
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) &&
|
||||
(theMPEG1SideInfo.block_type[gr][ch] == 2) &&
|
||||
(theMPEG1SideInfo.mixed_block_flag[gr][ch]) == 0 {
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] == 1) &&
|
||||
(f.sideInfo.block_type[gr][ch] == 2) &&
|
||||
(f.sideInfo.mixed_block_flag[gr][ch]) == 0 {
|
||||
return
|
||||
}
|
||||
/* Setup the limit for how many subbands to transform */
|
||||
sblim := 32
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) &&
|
||||
(theMPEG1SideInfo.block_type[gr][ch] == 2) &&
|
||||
(theMPEG1SideInfo.mixed_block_flag[gr][ch] == 1) {
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] == 1) &&
|
||||
(f.sideInfo.block_type[gr][ch] == 2) &&
|
||||
(f.sideInfo.mixed_block_flag[gr][ch] == 1) {
|
||||
sblim = 2
|
||||
}
|
||||
/* Do the actual antialiasing */
|
||||
@ -367,41 +367,41 @@ func l3Antialias(gr int, ch int) {
|
||||
for i := 0; i < 8; i++ {
|
||||
li := 18*sb - 1 - i
|
||||
ui := 18*sb + i
|
||||
lb := theMPEG1MainData.is[gr][ch][li]*cs[i] - theMPEG1MainData.is[gr][ch][ui]*ca[i]
|
||||
ub := theMPEG1MainData.is[gr][ch][ui]*cs[i] + theMPEG1MainData.is[gr][ch][li]*ca[i]
|
||||
theMPEG1MainData.is[gr][ch][li] = lb
|
||||
theMPEG1MainData.is[gr][ch][ui] = ub
|
||||
lb := f.mainData.is[gr][ch][li]*cs[i] - f.mainData.is[gr][ch][ui]*ca[i]
|
||||
ub := f.mainData.is[gr][ch][ui]*cs[i] + f.mainData.is[gr][ch][li]*ca[i]
|
||||
f.mainData.is[gr][ch][li] = lb
|
||||
f.mainData.is[gr][ch][ui] = ub
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var store = [2][32][18]float32{}
|
||||
|
||||
func l3HybridSynthesis(gr int, ch int) {
|
||||
func (f *frame) l3HybridSynthesis(gr int, ch int) {
|
||||
for sb := 0; sb < 32; sb++ { /* Loop through all 32 subbands */
|
||||
/* Determine blocktype for this subband */
|
||||
bt := int(theMPEG1SideInfo.block_type[gr][ch])
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) &&
|
||||
(theMPEG1SideInfo.mixed_block_flag[gr][ch] == 1) && (sb < 2) {
|
||||
bt := int(f.sideInfo.block_type[gr][ch])
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] == 1) &&
|
||||
(f.sideInfo.mixed_block_flag[gr][ch] == 1) && (sb < 2) {
|
||||
bt = 0
|
||||
}
|
||||
/* Do the inverse modified DCT and windowing */
|
||||
in := make([]float32, 18)
|
||||
for i := range in {
|
||||
in[i] = float32(theMPEG1MainData.is[gr][ch][sb*18+i])
|
||||
in[i] = f.mainData.is[gr][ch][sb*18+i]
|
||||
}
|
||||
rawout := imdctWin(in, bt)
|
||||
for i := 0; i < 18; i++ { /* Overlapp add with stored vector into main_data vector */
|
||||
theMPEG1MainData.is[gr][ch][sb*18+i] = rawout[i] + store[ch][sb][i]
|
||||
f.mainData.is[gr][ch][sb*18+i] = rawout[i] + store[ch][sb][i]
|
||||
store[ch][sb][i] = rawout[i+18]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func l3FrequencyInversion(gr int, ch int) {
|
||||
func (f *frame) l3FrequencyInversion(gr int, ch int) {
|
||||
for sb := 1; sb < 32; sb += 2 { //OPT? : for(sb = 18; sb < 576; sb += 36)
|
||||
for i := 1; i < 18; i += 2 {
|
||||
theMPEG1MainData.is[gr][ch][sb*18+i] = -theMPEG1MainData.is[gr][ch][sb*18+i]
|
||||
f.mainData.is[gr][ch][sb*18+i] = -f.mainData.is[gr][ch][sb*18+i]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -551,13 +551,13 @@ var g_synth_dtbl = [512]float32{
|
||||
0.000015259, 0.000015259, 0.000015259, 0.000015259,
|
||||
}
|
||||
|
||||
func l3SubbandSynthesis(gr int, ch int, out []uint32) {
|
||||
func (f *frame) l3SubbandSynthesis(gr int, ch int, out []uint32) {
|
||||
u_vec := make([]float32, 512)
|
||||
s_vec := make([]float32, 32)
|
||||
|
||||
/* Number of channels(1 for mono and 2 for stereo) */
|
||||
nch := 2
|
||||
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel {
|
||||
if f.header.mode == mpeg1ModeSingleChannel {
|
||||
nch = 1
|
||||
}
|
||||
/* Setup the n_win windowing vector and the v_vec intermediate vector */
|
||||
@ -566,7 +566,7 @@ func l3SubbandSynthesis(gr int, ch int, out []uint32) {
|
||||
v_vec[ch][i] = v_vec[ch][i-64]
|
||||
}
|
||||
for i := 0; i < 32; i++ { /* Copy next 32 time samples to a temp vector */
|
||||
s_vec[i] = float32(theMPEG1MainData.is[gr][ch][i*18+ss])
|
||||
s_vec[i] = f.mainData.is[gr][ch][i*18+ss]
|
||||
}
|
||||
for i := 0; i < 64; i++ { /* Matrix multiply input with n_win[][] matrix */
|
||||
sum := float32(0)
|
||||
|
@ -26,18 +26,18 @@ var mpeg1_scalefac_sizes = [16][2]int{
|
||||
{2, 1}, {2, 2}, {2, 3}, {3, 1}, {3, 2}, {3, 3}, {4, 2}, {4, 3},
|
||||
}
|
||||
|
||||
func readMainL3() error {
|
||||
func (f *frame) readMainL3() error {
|
||||
/* Number of channels(1 for mono and 2 for stereo) */
|
||||
nch := 2
|
||||
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel {
|
||||
if f.header.mode == mpeg1ModeSingleChannel {
|
||||
nch = 1
|
||||
}
|
||||
|
||||
/* Calculate header audio data size */
|
||||
framesize := (144*
|
||||
g_mpeg1_bitrates[theMPEG1FrameHeader.layer][theMPEG1FrameHeader.bitrate_index])/
|
||||
g_sampling_frequency[theMPEG1FrameHeader.sampling_frequency] +
|
||||
int(theMPEG1FrameHeader.padding_bit)
|
||||
g_mpeg1_bitrates[f.header.layer][f.header.bitrate_index])/
|
||||
g_sampling_frequency[f.header.sampling_frequency] +
|
||||
int(f.header.padding_bit)
|
||||
|
||||
if framesize > 2000 {
|
||||
return fmt.Errorf("mp3: framesize = %d", framesize)
|
||||
@ -50,7 +50,7 @@ func readMainL3() error {
|
||||
/* 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 theMPEG1FrameHeader.protection_bit == 0 {
|
||||
if f.header.protection_bit == 0 {
|
||||
main_data_size -= 2
|
||||
}
|
||||
/* Assemble main data buffer with data from this frame and the previous
|
||||
@ -58,7 +58,7 @@ func readMainL3() error {
|
||||
* frames that should be used. This buffer is later accessed by the
|
||||
* getMainBits function in the same way as the side info is.
|
||||
*/
|
||||
if err := getMainData(main_data_size, int(theMPEG1SideInfo.main_data_begin)); err != nil {
|
||||
if err := getMainData(main_data_size, int(f.sideInfo.main_data_begin)); err != nil {
|
||||
/* This could be due to not enough data in reservoir */
|
||||
return err
|
||||
}
|
||||
@ -66,12 +66,12 @@ func readMainL3() error {
|
||||
for ch := 0; ch < nch; ch++ {
|
||||
part_2_start := getMainPos()
|
||||
/* Number of bits in the bitstream for the bands */
|
||||
slen1 := mpeg1_scalefac_sizes[theMPEG1SideInfo.scalefac_compress[gr][ch]][0]
|
||||
slen2 := mpeg1_scalefac_sizes[theMPEG1SideInfo.scalefac_compress[gr][ch]][1]
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] != 0) && (theMPEG1SideInfo.block_type[gr][ch] == 2) {
|
||||
if theMPEG1SideInfo.mixed_block_flag[gr][ch] != 0 {
|
||||
slen1 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][0]
|
||||
slen2 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][1]
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] != 0) && (f.sideInfo.block_type[gr][ch] == 2) {
|
||||
if f.sideInfo.mixed_block_flag[gr][ch] != 0 {
|
||||
for sfb := 0; sfb < 8; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1)
|
||||
f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1)
|
||||
}
|
||||
for sfb := 3; sfb < 12; sfb++ {
|
||||
/*slen1 for band 3-5,slen2 for 6-11*/
|
||||
@ -80,7 +80,7 @@ func readMainL3() error {
|
||||
nbits = slen1
|
||||
}
|
||||
for win := 0; win < 3; win++ {
|
||||
theMPEG1MainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits)
|
||||
f.mainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -91,58 +91,58 @@ func readMainL3() error {
|
||||
nbits = slen1
|
||||
}
|
||||
for win := 0; win < 3; win++ {
|
||||
theMPEG1MainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits)
|
||||
f.mainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* block_type == 0 if winswitch == 0 */
|
||||
/* Scale factor bands 0-5 */
|
||||
if (theMPEG1SideInfo.scfsi[ch][0] == 0) || (gr == 0) {
|
||||
if (f.sideInfo.scfsi[ch][0] == 0) || (gr == 0) {
|
||||
for sfb := 0; sfb < 6; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1)
|
||||
f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1)
|
||||
}
|
||||
} else if (theMPEG1SideInfo.scfsi[ch][0] == 1) && (gr == 1) {
|
||||
} else if (f.sideInfo.scfsi[ch][0] == 1) && (gr == 1) {
|
||||
/* Copy scalefactors from granule 0 to granule 1 */
|
||||
for sfb := 0; sfb < 6; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb]
|
||||
f.mainData.scalefac_l[1][ch][sfb] = f.mainData.scalefac_l[0][ch][sfb]
|
||||
}
|
||||
}
|
||||
/* Scale factor bands 6-10 */
|
||||
if (theMPEG1SideInfo.scfsi[ch][1] == 0) || (gr == 0) {
|
||||
if (f.sideInfo.scfsi[ch][1] == 0) || (gr == 0) {
|
||||
for sfb := 6; sfb < 11; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1)
|
||||
f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1)
|
||||
}
|
||||
} else if (theMPEG1SideInfo.scfsi[ch][1] == 1) && (gr == 1) {
|
||||
} else if (f.sideInfo.scfsi[ch][1] == 1) && (gr == 1) {
|
||||
/* Copy scalefactors from granule 0 to granule 1 */
|
||||
for sfb := 6; sfb < 11; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb]
|
||||
f.mainData.scalefac_l[1][ch][sfb] = f.mainData.scalefac_l[0][ch][sfb]
|
||||
}
|
||||
}
|
||||
/* Scale factor bands 11-15 */
|
||||
if (theMPEG1SideInfo.scfsi[ch][2] == 0) || (gr == 0) {
|
||||
if (f.sideInfo.scfsi[ch][2] == 0) || (gr == 0) {
|
||||
for sfb := 11; sfb < 16; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2)
|
||||
f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2)
|
||||
}
|
||||
} else if (theMPEG1SideInfo.scfsi[ch][2] == 1) && (gr == 1) {
|
||||
} else if (f.sideInfo.scfsi[ch][2] == 1) && (gr == 1) {
|
||||
/* Copy scalefactors from granule 0 to granule 1 */
|
||||
for sfb := 11; sfb < 16; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb]
|
||||
f.mainData.scalefac_l[1][ch][sfb] = f.mainData.scalefac_l[0][ch][sfb]
|
||||
}
|
||||
}
|
||||
/* Scale factor bands 16-20 */
|
||||
if (theMPEG1SideInfo.scfsi[ch][3] == 0) || (gr == 0) {
|
||||
if (f.sideInfo.scfsi[ch][3] == 0) || (gr == 0) {
|
||||
for sfb := 16; sfb < 21; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2)
|
||||
f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2)
|
||||
}
|
||||
} else if (theMPEG1SideInfo.scfsi[ch][3] == 1) && (gr == 1) {
|
||||
} else if (f.sideInfo.scfsi[ch][3] == 1) && (gr == 1) {
|
||||
/* Copy scalefactors from granule 0 to granule 1 */
|
||||
for sfb := 16; sfb < 21; sfb++ {
|
||||
theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb]
|
||||
f.mainData.scalefac_l[1][ch][sfb] = f.mainData.scalefac_l[0][ch][sfb]
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Read Huffman coded data. Skip stuffing bits. */
|
||||
if err := readHuffman(part_2_start, gr, ch); err != nil {
|
||||
if err := f.readHuffman(part_2_start, gr, ch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -42,30 +42,31 @@ func readCRC() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func readFrame() error {
|
||||
if err := readHeader(); err != nil {
|
||||
return err
|
||||
func readFrame() (*frame, error) {
|
||||
f := &frame{}
|
||||
if err := f.readHeader(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get CRC word if present
|
||||
if theMPEG1FrameHeader.protection_bit == 0 {
|
||||
if f.header.protection_bit == 0 {
|
||||
if err := readCRC(); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if theMPEG1FrameHeader.layer != mpeg1Layer3 {
|
||||
return fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, theMPEG1FrameHeader.layer)
|
||||
if f.header.layer != mpeg1Layer3 {
|
||||
return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, f.header.layer)
|
||||
}
|
||||
// Get side info
|
||||
if err := readAudioL3(); err != nil {
|
||||
return err
|
||||
if err := f.readAudioL3(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If there's not enough main data in the bit reservoir,
|
||||
// signal to calling function so that decoding isn't done!
|
||||
// Get main data(scalefactors and Huffman coded frequency data)
|
||||
if err := readMainL3(); err != nil {
|
||||
return err
|
||||
if err := f.readMainL3(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func isHeader(header uint32) bool {
|
||||
@ -84,7 +85,7 @@ func isHeader(header uint32) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func readHeader() error {
|
||||
func (f *frame) readHeader() error {
|
||||
/* Get the next four bytes from the bitstream */
|
||||
buf := make([]int, 4)
|
||||
n := 0
|
||||
@ -125,75 +126,75 @@ func readHeader() error {
|
||||
/* If we get here we've found the sync word,and can decode the header
|
||||
* which is in the low 20 bits of the 32-bit sync+header word. */
|
||||
/* Decode the header */
|
||||
theMPEG1FrameHeader.id = int((header & 0x00180000) >> 19)
|
||||
theMPEG1FrameHeader.layer = mpeg1Layer((header & 0x00060000) >> 17)
|
||||
theMPEG1FrameHeader.protection_bit = int((header & 0x00010000) >> 16)
|
||||
theMPEG1FrameHeader.bitrate_index = int((header & 0x0000f000) >> 12)
|
||||
theMPEG1FrameHeader.sampling_frequency = int((header & 0x00000c00) >> 10)
|
||||
theMPEG1FrameHeader.padding_bit = int((header & 0x00000200) >> 9)
|
||||
theMPEG1FrameHeader.private_bit = int((header & 0x00000100) >> 8)
|
||||
theMPEG1FrameHeader.mode = mpeg1Mode((header & 0x000000c0) >> 6)
|
||||
theMPEG1FrameHeader.mode_extension = int((header & 0x00000030) >> 4)
|
||||
theMPEG1FrameHeader.copyright = int((header & 0x00000008) >> 3)
|
||||
theMPEG1FrameHeader.original_or_copy = int((header & 0x00000004) >> 2)
|
||||
theMPEG1FrameHeader.emphasis = int((header & 0x00000003) >> 0)
|
||||
f.header.id = int((header & 0x00180000) >> 19)
|
||||
f.header.layer = mpeg1Layer((header & 0x00060000) >> 17)
|
||||
f.header.protection_bit = int((header & 0x00010000) >> 16)
|
||||
f.header.bitrate_index = int((header & 0x0000f000) >> 12)
|
||||
f.header.sampling_frequency = int((header & 0x00000c00) >> 10)
|
||||
f.header.padding_bit = int((header & 0x00000200) >> 9)
|
||||
f.header.private_bit = int((header & 0x00000100) >> 8)
|
||||
f.header.mode = mpeg1Mode((header & 0x000000c0) >> 6)
|
||||
f.header.mode_extension = int((header & 0x00000030) >> 4)
|
||||
f.header.copyright = int((header & 0x00000008) >> 3)
|
||||
f.header.original_or_copy = int((header & 0x00000004) >> 2)
|
||||
f.header.emphasis = int((header & 0x00000003) >> 0)
|
||||
/* Check for invalid values and impossible combinations */
|
||||
if theMPEG1FrameHeader.id != 3 {
|
||||
if f.header.id != 3 {
|
||||
return fmt.Errorf("mp3: ID must be 3. Header word is 0x%08x at file pos %d",
|
||||
header, getFilepos())
|
||||
}
|
||||
if theMPEG1FrameHeader.bitrate_index == 0 {
|
||||
if f.header.bitrate_index == 0 {
|
||||
return fmt.Errorf("mp3: Free bitrate format NIY! Header word is 0x%08x at file pos %d",
|
||||
header, getFilepos())
|
||||
}
|
||||
if theMPEG1FrameHeader.bitrate_index == 15 {
|
||||
if f.header.bitrate_index == 15 {
|
||||
return fmt.Errorf("mp3: bitrate_index = 15 is invalid! Header word is 0x%08x at file pos %d",
|
||||
header, getFilepos())
|
||||
}
|
||||
if theMPEG1FrameHeader.sampling_frequency == 3 {
|
||||
if f.header.sampling_frequency == 3 {
|
||||
return fmt.Errorf("mp3: sampling_frequency = 3 is invalid! Header word is 0x%08x at file pos %d",
|
||||
header, getFilepos())
|
||||
}
|
||||
if theMPEG1FrameHeader.layer == mpeg1LayerReserved {
|
||||
if f.header.layer == mpeg1LayerReserved {
|
||||
return fmt.Errorf("mp3: layer = %d is invalid! Header word is 0x%08x at file pos %d",
|
||||
mpeg1LayerReserved, header, getFilepos())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readHuffman(part_2_start, gr, ch int) error {
|
||||
func (f *frame) readHuffman(part_2_start, gr, ch int) error {
|
||||
/* Check that there is any data to decode. If not,zero the array. */
|
||||
if theMPEG1SideInfo.part2_3_length[gr][ch] == 0 {
|
||||
if f.sideInfo.part2_3_length[gr][ch] == 0 {
|
||||
for is_pos := 0; is_pos < 576; is_pos++ {
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = 0.0
|
||||
f.mainData.is[gr][ch][is_pos] = 0.0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
/* Calculate bit_pos_end which is the index of the last bit for this part. */
|
||||
bit_pos_end := part_2_start + int(theMPEG1SideInfo.part2_3_length[gr][ch]) - 1
|
||||
bit_pos_end := part_2_start + f.sideInfo.part2_3_length[gr][ch] - 1
|
||||
/* Determine region boundaries */
|
||||
region_1_start := 0
|
||||
region_2_start := 0
|
||||
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) && (theMPEG1SideInfo.block_type[gr][ch] == 2) {
|
||||
if (f.sideInfo.win_switch_flag[gr][ch] == 1) && (f.sideInfo.block_type[gr][ch] == 2) {
|
||||
region_1_start = 36 /* sfb[9/3]*3=36 */
|
||||
region_2_start = 576 /* No Region2 for short block case. */
|
||||
} else {
|
||||
sfreq := theMPEG1FrameHeader.sampling_frequency
|
||||
sfreq := f.header.sampling_frequency
|
||||
region_1_start =
|
||||
sfBandIndicesSet[sfreq].l[theMPEG1SideInfo.region0_count[gr][ch]+1]
|
||||
sfBandIndicesSet[sfreq].l[f.sideInfo.region0_count[gr][ch]+1]
|
||||
region_2_start =
|
||||
sfBandIndicesSet[sfreq].l[theMPEG1SideInfo.region0_count[gr][ch]+
|
||||
theMPEG1SideInfo.region1_count[gr][ch]+2]
|
||||
sfBandIndicesSet[sfreq].l[f.sideInfo.region0_count[gr][ch]+
|
||||
f.sideInfo.region1_count[gr][ch]+2]
|
||||
}
|
||||
/* Read big_values using tables according to region_x_start */
|
||||
for is_pos := 0; is_pos < theMPEG1SideInfo.big_values[gr][ch]*2; is_pos++ {
|
||||
for is_pos := 0; is_pos < f.sideInfo.big_values[gr][ch]*2; is_pos++ {
|
||||
table_num := 0
|
||||
if is_pos < region_1_start {
|
||||
table_num = int(theMPEG1SideInfo.table_select[gr][ch][0])
|
||||
table_num = f.sideInfo.table_select[gr][ch][0]
|
||||
} else if is_pos < region_2_start {
|
||||
table_num = int(theMPEG1SideInfo.table_select[gr][ch][1])
|
||||
table_num = f.sideInfo.table_select[gr][ch][1]
|
||||
} else {
|
||||
table_num = int(theMPEG1SideInfo.table_select[gr][ch][2])
|
||||
table_num = f.sideInfo.table_select[gr][ch][2]
|
||||
}
|
||||
/* Get next Huffman coded words */
|
||||
x, y, _, _, err := huffmanDecode(table_num)
|
||||
@ -201,35 +202,35 @@ func readHuffman(part_2_start, gr, ch int) error {
|
||||
return err
|
||||
}
|
||||
/* In the big_values area there are two freq lines per Huffman word */
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(x)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(x)
|
||||
is_pos++
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(y)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(y)
|
||||
}
|
||||
/* Read small values until is_pos = 576 or we run out of huffman data */
|
||||
table_num := int(theMPEG1SideInfo.count1table_select[gr][ch]) + 32
|
||||
is_pos := int(theMPEG1SideInfo.big_values[gr][ch]) * 2
|
||||
table_num := f.sideInfo.count1table_select[gr][ch] + 32
|
||||
is_pos := f.sideInfo.big_values[gr][ch] * 2
|
||||
for ; (is_pos <= 572) && (getMainPos() <= bit_pos_end); is_pos++ {
|
||||
/* Get next Huffman coded words */
|
||||
x, y, v, w, err := huffmanDecode(table_num)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(v)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(v)
|
||||
is_pos++
|
||||
if is_pos >= 576 {
|
||||
break
|
||||
}
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(w)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(w)
|
||||
is_pos++
|
||||
if is_pos >= 576 {
|
||||
break
|
||||
}
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(x)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(x)
|
||||
is_pos++
|
||||
if is_pos >= 576 {
|
||||
break
|
||||
}
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = float32(y)
|
||||
f.mainData.is[gr][ch][is_pos] = float32(y)
|
||||
}
|
||||
/* Check that we didn't read past the end of this section */
|
||||
if getMainPos() > (bit_pos_end + 1) {
|
||||
@ -237,10 +238,10 @@ func readHuffman(part_2_start, gr, ch int) error {
|
||||
is_pos -= 4
|
||||
}
|
||||
/* Setup count1 which is the index of the first sample in the rzero reg. */
|
||||
theMPEG1SideInfo.count1[gr][ch] = is_pos
|
||||
f.sideInfo.count1[gr][ch] = is_pos
|
||||
/* Zero out the last part if necessary */
|
||||
for ; /* is_pos comes from last for-loop */ is_pos < 576; is_pos++ {
|
||||
theMPEG1MainData.is[gr][ch][is_pos] = 0.0
|
||||
f.mainData.is[gr][ch][is_pos] = 0.0
|
||||
}
|
||||
/* Set the bitpos to point to the next part to read */
|
||||
setMainPos(bit_pos_end + 1)
|
||||
|
@ -38,16 +38,16 @@ var g_mpeg1_bitrates = map[mpeg1Layer][15]int{
|
||||
|
||||
var g_sampling_frequency = [3]int{44100, 48000, 32000}
|
||||
|
||||
func readAudioL3() error {
|
||||
func (f *frame) readAudioL3() error {
|
||||
nch := 2
|
||||
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel {
|
||||
if f.header.mode == mpeg1ModeSingleChannel {
|
||||
nch = 1
|
||||
}
|
||||
/* Calculate header audio data size */
|
||||
framesize := (144*
|
||||
g_mpeg1_bitrates[theMPEG1FrameHeader.layer][theMPEG1FrameHeader.bitrate_index])/
|
||||
g_sampling_frequency[theMPEG1FrameHeader.sampling_frequency] +
|
||||
int(theMPEG1FrameHeader.padding_bit)
|
||||
g_mpeg1_bitrates[f.header.layer][f.header.bitrate_index])/
|
||||
g_sampling_frequency[f.header.sampling_frequency] +
|
||||
int(f.header.padding_bit)
|
||||
if framesize > 2000 {
|
||||
return fmt.Errorf("mp3: framesize = %d\n", framesize)
|
||||
}
|
||||
@ -59,7 +59,7 @@ func readAudioL3() error {
|
||||
/* 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 theMPEG1FrameHeader.protection_bit == 0 {
|
||||
if f.header.protection_bit == 0 {
|
||||
main_data_size -= 2
|
||||
}
|
||||
/* Read sideinfo from bitstream into buffer used by getSideBits() */
|
||||
@ -68,54 +68,54 @@ func readAudioL3() error {
|
||||
}
|
||||
/* Parse audio data */
|
||||
/* Pointer to where we should start reading main data */
|
||||
theMPEG1SideInfo.main_data_begin = getSideBits(9)
|
||||
f.sideInfo.main_data_begin = getSideBits(9)
|
||||
/* Get private bits. Not used for anything. */
|
||||
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel {
|
||||
theMPEG1SideInfo.private_bits = getSideBits(5)
|
||||
if f.header.mode == mpeg1ModeSingleChannel {
|
||||
f.sideInfo.private_bits = getSideBits(5)
|
||||
} else {
|
||||
theMPEG1SideInfo.private_bits = getSideBits(3)
|
||||
f.sideInfo.private_bits = getSideBits(3)
|
||||
}
|
||||
/* Get scale factor selection information */
|
||||
for ch := 0; ch < nch; ch++ {
|
||||
for scfsi_band := 0; scfsi_band < 4; scfsi_band++ {
|
||||
theMPEG1SideInfo.scfsi[ch][scfsi_band] = getSideBits(1)
|
||||
f.sideInfo.scfsi[ch][scfsi_band] = getSideBits(1)
|
||||
}
|
||||
}
|
||||
/* Get the rest of the side information */
|
||||
for gr := 0; gr < 2; gr++ {
|
||||
for ch := 0; ch < nch; ch++ {
|
||||
theMPEG1SideInfo.part2_3_length[gr][ch] = getSideBits(12)
|
||||
theMPEG1SideInfo.big_values[gr][ch] = getSideBits(9)
|
||||
theMPEG1SideInfo.global_gain[gr][ch] = getSideBits(8)
|
||||
theMPEG1SideInfo.scalefac_compress[gr][ch] = getSideBits(4)
|
||||
theMPEG1SideInfo.win_switch_flag[gr][ch] = getSideBits(1)
|
||||
if theMPEG1SideInfo.win_switch_flag[gr][ch] == 1 {
|
||||
theMPEG1SideInfo.block_type[gr][ch] = getSideBits(2)
|
||||
theMPEG1SideInfo.mixed_block_flag[gr][ch] = getSideBits(1)
|
||||
f.sideInfo.part2_3_length[gr][ch] = getSideBits(12)
|
||||
f.sideInfo.big_values[gr][ch] = getSideBits(9)
|
||||
f.sideInfo.global_gain[gr][ch] = getSideBits(8)
|
||||
f.sideInfo.scalefac_compress[gr][ch] = getSideBits(4)
|
||||
f.sideInfo.win_switch_flag[gr][ch] = getSideBits(1)
|
||||
if f.sideInfo.win_switch_flag[gr][ch] == 1 {
|
||||
f.sideInfo.block_type[gr][ch] = getSideBits(2)
|
||||
f.sideInfo.mixed_block_flag[gr][ch] = getSideBits(1)
|
||||
for region := 0; region < 2; region++ {
|
||||
theMPEG1SideInfo.table_select[gr][ch][region] = getSideBits(5)
|
||||
f.sideInfo.table_select[gr][ch][region] = getSideBits(5)
|
||||
}
|
||||
for window := 0; window < 3; window++ {
|
||||
theMPEG1SideInfo.subblock_gain[gr][ch][window] = getSideBits(3)
|
||||
f.sideInfo.subblock_gain[gr][ch][window] = getSideBits(3)
|
||||
}
|
||||
if (theMPEG1SideInfo.block_type[gr][ch] == 2) && (theMPEG1SideInfo.mixed_block_flag[gr][ch] == 0) {
|
||||
theMPEG1SideInfo.region0_count[gr][ch] = 8 /* Implicit */
|
||||
if (f.sideInfo.block_type[gr][ch] == 2) && (f.sideInfo.mixed_block_flag[gr][ch] == 0) {
|
||||
f.sideInfo.region0_count[gr][ch] = 8 /* Implicit */
|
||||
} else {
|
||||
theMPEG1SideInfo.region0_count[gr][ch] = 7 /* Implicit */
|
||||
f.sideInfo.region0_count[gr][ch] = 7 /* Implicit */
|
||||
}
|
||||
/* The standard is wrong on this!!! */ /* Implicit */
|
||||
theMPEG1SideInfo.region1_count[gr][ch] = 20 - theMPEG1SideInfo.region0_count[gr][ch]
|
||||
f.sideInfo.region1_count[gr][ch] = 20 - f.sideInfo.region0_count[gr][ch]
|
||||
} else {
|
||||
for region := 0; region < 3; region++ {
|
||||
theMPEG1SideInfo.table_select[gr][ch][region] = getSideBits(5)
|
||||
f.sideInfo.table_select[gr][ch][region] = getSideBits(5)
|
||||
}
|
||||
theMPEG1SideInfo.region0_count[gr][ch] = getSideBits(4)
|
||||
theMPEG1SideInfo.region1_count[gr][ch] = getSideBits(3)
|
||||
theMPEG1SideInfo.block_type[gr][ch] = 0 /* Implicit */
|
||||
f.sideInfo.region0_count[gr][ch] = getSideBits(4)
|
||||
f.sideInfo.region1_count[gr][ch] = getSideBits(3)
|
||||
f.sideInfo.block_type[gr][ch] = 0 /* Implicit */
|
||||
}
|
||||
theMPEG1SideInfo.preflag[gr][ch] = getSideBits(1)
|
||||
theMPEG1SideInfo.scalefac_scale[gr][ch] = getSideBits(1)
|
||||
theMPEG1SideInfo.count1table_select[gr][ch] = getSideBits(1)
|
||||
f.sideInfo.preflag[gr][ch] = getSideBits(1)
|
||||
f.sideInfo.scalefac_scale[gr][ch] = getSideBits(1)
|
||||
f.sideInfo.count1table_select[gr][ch] = getSideBits(1)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -50,8 +50,6 @@ type mpeg1FrameHeader struct {
|
||||
emphasis int // 2 bits
|
||||
}
|
||||
|
||||
var theMPEG1FrameHeader mpeg1FrameHeader
|
||||
|
||||
// A mpeg1SideInfo is MPEG1 Layer 3 Side Information.
|
||||
// [2][2] means [gr][ch].
|
||||
type mpeg1SideInfo struct {
|
||||
@ -78,8 +76,6 @@ type mpeg1SideInfo struct {
|
||||
count1 [2][2]int // Not in file,calc. by huff.dec.!
|
||||
}
|
||||
|
||||
var theMPEG1SideInfo mpeg1SideInfo
|
||||
|
||||
// A mpeg1MainData is MPEG1 Layer 3 Main Data.
|
||||
type mpeg1MainData struct {
|
||||
scalefac_l [2][2][21]int // 0-4 bits
|
||||
@ -87,4 +83,8 @@ type mpeg1MainData struct {
|
||||
is [2][2][576]float32 // Huffman coded freq. lines
|
||||
}
|
||||
|
||||
var theMPEG1MainData mpeg1MainData
|
||||
type frame struct {
|
||||
header mpeg1FrameHeader
|
||||
sideInfo mpeg1SideInfo
|
||||
mainData mpeg1MainData
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user