audio/mp3: Add frame struct

This commit is contained in:
Hajime Hoshi 2017-06-17 18:42:43 +09:00
parent 0e4c949471
commit cb6e7366e2
6 changed files with 227 additions and 226 deletions

View File

@ -28,38 +28,38 @@ var (
writer io.Writer writer io.Writer
) )
func decodeL3() error { func (f *frame) decodeL3() error {
out := make([]uint32, 576) out := make([]uint32, 576)
// Number of channels(1 for mono and 2 for stereo) // Number of channels(1 for mono and 2 for stereo)
nch := 2 nch := 2
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel { if f.header.mode == mpeg1ModeSingleChannel {
nch = 1 nch = 1
} }
for gr := 0; gr < 2; gr++ { for gr := 0; gr < 2; gr++ {
for ch := 0; ch < nch; ch++ { for ch := 0; ch < nch; ch++ {
l3Requantize(gr, ch) f.l3Requantize(gr, ch)
// Reorder short blocks // Reorder short blocks
l3Reorder(gr, ch) f.l3Reorder(gr, ch)
} }
l3Stereo(gr) f.l3Stereo(gr)
for ch := 0; ch < nch; ch++ { for ch := 0; ch < nch; ch++ {
l3Antialias(gr, ch) f.l3Antialias(gr, ch)
// (IMDCT,windowing,overlapp add) // (IMDCT,windowing,overlapp add)
l3HybridSynthesis(gr, ch) f.l3HybridSynthesis(gr, ch)
l3FrequencyInversion(gr, ch) f.l3FrequencyInversion(gr, ch)
// Polyphase subband synthesis // 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 err
} }
} }
return nil return nil
} }
func audioWriteRaw(samples []uint32) error { func (f *frame) audioWriteRaw(samples []uint32) error {
nch := 2 nch := 2
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel { if f.header.mode == mpeg1ModeSingleChannel {
nch = 1 nch = 1
} }
s := make([]uint8, len(samples)*2*nch) s := make([]uint8, len(samples)*2*nch)
@ -129,9 +129,9 @@ func decode(r io.Reader, w io.Writer) error {
reader = r reader = r
writer = w writer = w
for !isEOF() { for !isEOF() {
err := readFrame() f, err := readFrame()
if err == nil { if err == nil {
if err := decodeL3(); err != nil { if err := f.decodeL3(); err != nil {
return err return err
} }
continue continue

View File

@ -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 sf_mult := 0.5
if theMPEG1SideInfo.scalefac_scale[gr][ch] != 0 { if f.sideInfo.scalefac_scale[gr][ch] != 0 {
sf_mult = 1.0 sf_mult = 1.0
} }
tmp1 := 1.0 tmp1 := 1.0
// https://github.com/technosaurus/PDMP3/issues/4 // https://github.com/technosaurus/PDMP3/issues/4
if sfb < 21 { if sfb < 21 {
pf_x_pt := float64(theMPEG1SideInfo.preflag[gr][ch]) * pretab[sfb] pf_x_pt := float64(f.sideInfo.preflag[gr][ch]) * pretab[sfb]
tmp1 = math.Pow(2.0, -(sf_mult * (float64(theMPEG1MainData.scalefac_l[gr][ch][sfb]) + pf_x_pt))) 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 tmp3 := 0.0
if theMPEG1MainData.is[gr][ch][is_pos] < 0.0 { if f.mainData.is[gr][ch][is_pos] < 0.0 {
tmp3 = -powtab34[int(-theMPEG1MainData.is[gr][ch][is_pos])] tmp3 = -powtab34[int(-f.mainData.is[gr][ch][is_pos])]
} else { } 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 sf_mult := 0.5
if theMPEG1SideInfo.scalefac_scale[gr][ch] != 0 { if f.sideInfo.scalefac_scale[gr][ch] != 0 {
sf_mult = 1.0 sf_mult = 1.0
} }
tmp1 := 1.0 tmp1 := 1.0
// https://github.com/technosaurus/PDMP3/issues/4 // https://github.com/technosaurus/PDMP3/issues/4
if sfb < 12 { 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- tmp2 := math.Pow(2.0, 0.25*(float64(f.sideInfo.global_gain[gr][ch])-210.0-
8.0*float64(theMPEG1SideInfo.subblock_gain[gr][ch][win]))) 8.0*float64(f.sideInfo.subblock_gain[gr][ch][win])))
tmp3 := 0.0 tmp3 := 0.0
if theMPEG1MainData.is[gr][ch][is_pos] < 0 { if f.mainData.is[gr][ch][is_pos] < 0 {
tmp3 = -powtab34[int(-theMPEG1MainData.is[gr][ch][is_pos])] tmp3 = -powtab34[int(-f.mainData.is[gr][ch][is_pos])]
} else { } 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 { 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 */ /* Setup sampling frequency index */
sfreq := theMPEG1FrameHeader.sampling_frequency sfreq := f.header.sampling_frequency
/* Determine type of block to process */ /* 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 /* Check if the first two subbands
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */ *(=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 */ /* First process the 2 long block subbands at the start */
sfb := 0 sfb := 0
next_sfb := sfBandIndicesSet[sfreq].l[sfb+1] next_sfb := sfBandIndicesSet[sfreq].l[sfb+1]
@ -111,7 +111,7 @@ func l3Requantize(gr int, ch int) {
sfb++ sfb++
next_sfb = sfBandIndicesSet[sfreq].l[sfb+1] 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 */ /* And next the remaining,non-zero,bands which uses short blocks */
sfb = 3 sfb = 3
@ -119,7 +119,7 @@ func l3Requantize(gr int, ch int) {
win_len := sfBandIndicesSet[sfreq].s[sfb+1] - win_len := sfBandIndicesSet[sfreq].s[sfb+1] -
sfBandIndicesSet[sfreq].s[sfb] 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 */ /* Check if we're into the next scalefac band */
if i == next_sfb { /* Yes */ if i == next_sfb { /* Yes */
sfb++ sfb++
@ -129,7 +129,7 @@ func l3Requantize(gr int, ch int) {
} }
for win := 0; win < 3; win++ { for win := 0; win < 3; win++ {
for j := 0; j < win_len; j++ { for j := 0; j < win_len; j++ {
requantizeProcessShort(int(gr), int(ch), i, sfb, win) f.requantizeProcessShort(gr, ch, i, sfb, win)
i++ i++
} }
} }
@ -140,7 +140,7 @@ func l3Requantize(gr int, ch int) {
next_sfb := sfBandIndicesSet[sfreq].s[sfb+1] * 3 next_sfb := sfBandIndicesSet[sfreq].s[sfb+1] * 3
win_len := sfBandIndicesSet[sfreq].s[sfb+1] - win_len := sfBandIndicesSet[sfreq].s[sfb+1] -
sfBandIndicesSet[sfreq].s[sfb] 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 */ /* Check if we're into the next scalefac band */
if i == next_sfb { if i == next_sfb {
sfb++ sfb++
@ -150,7 +150,7 @@ func l3Requantize(gr int, ch int) {
} }
for win := 0; win < 3; win++ { for win := 0; win < 3; win++ {
for j := 0; j < win_len; j++ { for j := 0; j < win_len; j++ {
requantizeProcessShort(int(gr), int(ch), i, sfb, win) f.requantizeProcessShort(gr, ch, i, sfb, win)
i++ i++
} }
} }
@ -159,27 +159,27 @@ func l3Requantize(gr int, ch int) {
} else { /* Only long blocks */ } else { /* Only long blocks */
sfb := 0 sfb := 0
next_sfb := sfBandIndicesSet[sfreq].l[sfb+1] 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 { if i == next_sfb {
sfb++ sfb++
next_sfb = sfBandIndicesSet[sfreq].l[sfb+1] 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) 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 */ /* 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 /* Check if the first two subbands
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */ *(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
sfb := 0 sfb := 0
/* 2 longbl. sb first */ /* 2 longbl. sb first */
if theMPEG1SideInfo.mixed_block_flag[gr][ch] != 0 { if f.sideInfo.mixed_block_flag[gr][ch] != 0 {
sfb = 3 sfb = 3
} }
next_sfb := sfBandIndicesSet[sfreq].s[sfb+1] * 3 next_sfb := sfBandIndicesSet[sfreq].s[sfb+1] * 3
@ -193,10 +193,10 @@ func l3Reorder(gr int, ch int) {
if i == next_sfb { if i == next_sfb {
/* Copy reordered data back to the original vector */ /* Copy reordered data back to the original vector */
for j := 0; j < 3*win_len; j++ { 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 */ /* 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 return
} }
sfb++ sfb++
@ -205,14 +205,14 @@ func l3Reorder(gr int, ch int) {
} }
for win := 0; win < 3; win++ { /* Do the actual reordering */ for win := 0; win < 3; win++ { /* Do the actual reordering */
for j := 0; j < win_len; j++ { 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++ i++
} }
} }
} }
/* Copy reordered data of last band back to original vector */ /* Copy reordered data of last band back to original vector */
for j := 0; j < 3*win_len; j++ { 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} 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_l := float32(0)
is_ratio_r := float32(0) is_ratio_r := float32(0)
/* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */ /* 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 { 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_start := sfBandIndicesSet[sfreq].l[sfb]
sfb_stop := sfBandIndicesSet[sfreq].l[sfb+1] sfb_stop := sfBandIndicesSet[sfreq].l[sfb+1]
if is_pos == 6 { /* tan((6*PI)/12 = PI/2) needs special treatment! */ 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 */ /* Now decode all samples in this scale factor band */
for i := sfb_start; i < sfb_stop; i++ { for i := sfb_start; i < sfb_stop; i++ {
theMPEG1MainData.is[gr][0][i] *= is_ratio_l f.mainData.is[gr][0][i] *= is_ratio_l
theMPEG1MainData.is[gr][1][i] *= is_ratio_r 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_l := float32(0)
is_ratio_r := 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 */ /* The window length */
win_len := sfBandIndicesSet[sfreq].s[sfb+1] - sfBandIndicesSet[sfreq].s[sfb] win_len := sfBandIndicesSet[sfreq].s[sfb+1] - sfBandIndicesSet[sfreq].s[sfb]
/* The three windows within the band has different scalefactors */ /* The three windows within the band has different scalefactors */
for win := 0; win < 3; win++ { for win := 0; win < 3; win++ {
/* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */ /* 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 { if is_pos != 7 {
sfb_start := sfBandIndicesSet[sfreq].s[sfb]*3 + win_len*win sfb_start := sfBandIndicesSet[sfreq].s[sfb]*3 + win_len*win
sfb_stop := sfb_start + win_len 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 */ /* Now decode all samples in this scale factor band */
for i := sfb_start; i < sfb_stop; i++ { for i := sfb_start; i < sfb_stop; i++ {
// https://github.com/technosaurus/PDMP3/issues/3 // https://github.com/technosaurus/PDMP3/issues/3
theMPEG1MainData.is[gr][0][i] *= is_ratio_l f.mainData.is[gr][0][i] *= is_ratio_l
theMPEG1MainData.is[gr][1][i] *= is_ratio_r 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 */ /* 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 return
} }
/* Do Middle/Side("normal") stereo processing */ /* 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 */ /* Determine how many frequency lines to transform */
i := 0 i := 0
if theMPEG1SideInfo.count1[gr][0] > theMPEG1SideInfo.count1[gr][1] { if f.sideInfo.count1[gr][0] > f.sideInfo.count1[gr][1] {
i = 1 i = 1
} }
max_pos := int(theMPEG1SideInfo.count1[gr][i]) max_pos := int(f.sideInfo.count1[gr][i])
/* Do the actual processing */ /* Do the actual processing */
const invSqrt2 = math.Sqrt2 / 2 const invSqrt2 = math.Sqrt2 / 2
for i := 0; i < max_pos; i++ { for i := 0; i < max_pos; i++ {
left := (theMPEG1MainData.is[gr][0][i] + theMPEG1MainData.is[gr][1][i]) * invSqrt2 left := (f.mainData.is[gr][0][i] + f.mainData.is[gr][1][i]) * invSqrt2
right := (theMPEG1MainData.is[gr][0][i] - theMPEG1MainData.is[gr][1][i]) * invSqrt2 right := (f.mainData.is[gr][0][i] - f.mainData.is[gr][1][i]) * invSqrt2
theMPEG1MainData.is[gr][0][i] = left f.mainData.is[gr][0][i] = left
theMPEG1MainData.is[gr][1][i] = right f.mainData.is[gr][1][i] = right
} }
} }
/* Do intensity stereo processing */ /* Do intensity stereo processing */
if (theMPEG1FrameHeader.mode_extension & 0x1) != 0 { if (f.header.mode_extension & 0x1) != 0 {
/* Setup sampling frequency index */ /* 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 /* 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 * 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. */ * only done for higher subbands, but logic is here for lower subbands. */
/* Determine type of block to process */ /* Determine type of block to process */
if (theMPEG1SideInfo.win_switch_flag[gr][0] == 1) && if (f.sideInfo.win_switch_flag[gr][0] == 1) &&
(theMPEG1SideInfo.block_type[gr][0] == 2) { /* Short blocks */ (f.sideInfo.block_type[gr][0] == 2) { /* Short blocks */
/* Check if the first two subbands /* Check if the first two subbands
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */ *(=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 */ for sfb := 0; sfb < 8; sfb++ { /* First process 8 sfb's at start */
/* Is this scale factor band above count1 for the right channel? */ /* 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] {
stereoProcessIntensityLong(int(gr), int(sfb)) f.stereoProcessIntensityLong(gr, sfb)
} }
} }
/* And next the remaining bands which uses short blocks */ /* And next the remaining bands which uses short blocks */
for sfb := 3; sfb < 12; sfb++ { for sfb := 3; sfb < 12; sfb++ {
/* Is this scale factor band above count1 for the right channel? */ /* Is this scale factor band above count1 for the right channel? */
if sfBandIndicesSet[sfreq].s[sfb]*3 >= theMPEG1SideInfo.count1[gr][1] { if sfBandIndicesSet[sfreq].s[sfb]*3 >= f.sideInfo.count1[gr][1] {
stereoProcessIntensityShort(int(gr), int(sfb)) /* intensity stereo processing */ f.stereoProcessIntensityShort(gr, sfb) /* intensity stereo processing */
} }
} }
} else { /* Only short blocks */ } else { /* Only short blocks */
for sfb := 0; sfb < 12; sfb++ { for sfb := 0; sfb < 12; sfb++ {
/* Is this scale factor band above count1 for the right channel? */ /* Is this scale factor band above count1 for the right channel? */
if sfBandIndicesSet[sfreq].s[sfb]*3 >= theMPEG1SideInfo.count1[gr][1] { if sfBandIndicesSet[sfreq].s[sfb]*3 >= f.sideInfo.count1[gr][1] {
stereoProcessIntensityShort(int(gr), int(sfb)) /* intensity stereo processing */ f.stereoProcessIntensityShort(gr, sfb) /* intensity stereo processing */
} }
} }
} }
} else { /* Only long blocks */ } else { /* Only long blocks */
for sfb := 0; sfb < 21; sfb++ { for sfb := 0; sfb < 21; sfb++ {
/* Is this scale factor band above count1 for the right channel? */ /* 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 */ /* 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} 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 */ /* No antialiasing is done for short blocks */
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) && if (f.sideInfo.win_switch_flag[gr][ch] == 1) &&
(theMPEG1SideInfo.block_type[gr][ch] == 2) && (f.sideInfo.block_type[gr][ch] == 2) &&
(theMPEG1SideInfo.mixed_block_flag[gr][ch]) == 0 { (f.sideInfo.mixed_block_flag[gr][ch]) == 0 {
return return
} }
/* Setup the limit for how many subbands to transform */ /* Setup the limit for how many subbands to transform */
sblim := 32 sblim := 32
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) && if (f.sideInfo.win_switch_flag[gr][ch] == 1) &&
(theMPEG1SideInfo.block_type[gr][ch] == 2) && (f.sideInfo.block_type[gr][ch] == 2) &&
(theMPEG1SideInfo.mixed_block_flag[gr][ch] == 1) { (f.sideInfo.mixed_block_flag[gr][ch] == 1) {
sblim = 2 sblim = 2
} }
/* Do the actual antialiasing */ /* Do the actual antialiasing */
@ -367,41 +367,41 @@ func l3Antialias(gr int, ch int) {
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
li := 18*sb - 1 - i li := 18*sb - 1 - i
ui := 18*sb + i ui := 18*sb + i
lb := theMPEG1MainData.is[gr][ch][li]*cs[i] - theMPEG1MainData.is[gr][ch][ui]*ca[i] lb := f.mainData.is[gr][ch][li]*cs[i] - f.mainData.is[gr][ch][ui]*ca[i]
ub := theMPEG1MainData.is[gr][ch][ui]*cs[i] + theMPEG1MainData.is[gr][ch][li]*ca[i] ub := f.mainData.is[gr][ch][ui]*cs[i] + f.mainData.is[gr][ch][li]*ca[i]
theMPEG1MainData.is[gr][ch][li] = lb f.mainData.is[gr][ch][li] = lb
theMPEG1MainData.is[gr][ch][ui] = ub f.mainData.is[gr][ch][ui] = ub
} }
} }
} }
var store = [2][32][18]float32{} 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 */ for sb := 0; sb < 32; sb++ { /* Loop through all 32 subbands */
/* Determine blocktype for this subband */ /* Determine blocktype for this subband */
bt := int(theMPEG1SideInfo.block_type[gr][ch]) bt := int(f.sideInfo.block_type[gr][ch])
if (theMPEG1SideInfo.win_switch_flag[gr][ch] == 1) && if (f.sideInfo.win_switch_flag[gr][ch] == 1) &&
(theMPEG1SideInfo.mixed_block_flag[gr][ch] == 1) && (sb < 2) { (f.sideInfo.mixed_block_flag[gr][ch] == 1) && (sb < 2) {
bt = 0 bt = 0
} }
/* Do the inverse modified DCT and windowing */ /* Do the inverse modified DCT and windowing */
in := make([]float32, 18) in := make([]float32, 18)
for i := range in { 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) rawout := imdctWin(in, bt)
for i := 0; i < 18; i++ { /* Overlapp add with stored vector into main_data vector */ 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] 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 sb := 1; sb < 32; sb += 2 { //OPT? : for(sb = 18; sb < 576; sb += 36)
for i := 1; i < 18; i += 2 { 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, 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) u_vec := make([]float32, 512)
s_vec := make([]float32, 32) s_vec := make([]float32, 32)
/* Number of channels(1 for mono and 2 for stereo) */ /* Number of channels(1 for mono and 2 for stereo) */
nch := 2 nch := 2
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel { if f.header.mode == mpeg1ModeSingleChannel {
nch = 1 nch = 1
} }
/* Setup the n_win windowing vector and the v_vec intermediate vector */ /* 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] v_vec[ch][i] = v_vec[ch][i-64]
} }
for i := 0; i < 32; i++ { /* Copy next 32 time samples to a temp vector */ 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 */ for i := 0; i < 64; i++ { /* Matrix multiply input with n_win[][] matrix */
sum := float32(0) sum := float32(0)

View File

@ -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}, {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) */ /* Number of channels(1 for mono and 2 for stereo) */
nch := 2 nch := 2
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel { if f.header.mode == mpeg1ModeSingleChannel {
nch = 1 nch = 1
} }
/* Calculate header audio data size */ /* Calculate header audio data size */
framesize := (144* framesize := (144*
g_mpeg1_bitrates[theMPEG1FrameHeader.layer][theMPEG1FrameHeader.bitrate_index])/ g_mpeg1_bitrates[f.header.layer][f.header.bitrate_index])/
g_sampling_frequency[theMPEG1FrameHeader.sampling_frequency] + g_sampling_frequency[f.header.sampling_frequency] +
int(theMPEG1FrameHeader.padding_bit) int(f.header.padding_bit)
if framesize > 2000 { if framesize > 2000 {
return fmt.Errorf("mp3: framesize = %d", framesize) 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 is the rest of the frame,including ancillary data */
main_data_size := framesize - sideinfo_size - 4 /* sync+header */ main_data_size := framesize - sideinfo_size - 4 /* sync+header */
/* CRC is 2 bytes */ /* CRC is 2 bytes */
if theMPEG1FrameHeader.protection_bit == 0 { if f.header.protection_bit == 0 {
main_data_size -= 2 main_data_size -= 2
} }
/* Assemble main data buffer with data from this frame and the previous /* 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 * frames that should be used. This buffer is later accessed by the
* getMainBits function in the same way as the side info is. * 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 */ /* This could be due to not enough data in reservoir */
return err return err
} }
@ -66,12 +66,12 @@ func readMainL3() error {
for ch := 0; ch < nch; ch++ { for ch := 0; ch < nch; ch++ {
part_2_start := getMainPos() part_2_start := getMainPos()
/* Number of bits in the bitstream for the bands */ /* Number of bits in the bitstream for the bands */
slen1 := mpeg1_scalefac_sizes[theMPEG1SideInfo.scalefac_compress[gr][ch]][0] slen1 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][0]
slen2 := mpeg1_scalefac_sizes[theMPEG1SideInfo.scalefac_compress[gr][ch]][1] slen2 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][1]
if (theMPEG1SideInfo.win_switch_flag[gr][ch] != 0) && (theMPEG1SideInfo.block_type[gr][ch] == 2) { if (f.sideInfo.win_switch_flag[gr][ch] != 0) && (f.sideInfo.block_type[gr][ch] == 2) {
if theMPEG1SideInfo.mixed_block_flag[gr][ch] != 0 { if f.sideInfo.mixed_block_flag[gr][ch] != 0 {
for sfb := 0; sfb < 8; sfb++ { 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++ { for sfb := 3; sfb < 12; sfb++ {
/*slen1 for band 3-5,slen2 for 6-11*/ /*slen1 for band 3-5,slen2 for 6-11*/
@ -80,7 +80,7 @@ func readMainL3() error {
nbits = slen1 nbits = slen1
} }
for win := 0; win < 3; win++ { 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 { } else {
@ -91,58 +91,58 @@ func readMainL3() error {
nbits = slen1 nbits = slen1
} }
for win := 0; win < 3; win++ { 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 */ } else { /* block_type == 0 if winswitch == 0 */
/* Scale factor bands 0-5 */ /* 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++ { 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 */ /* Copy scalefactors from granule 0 to granule 1 */
for sfb := 0; sfb < 6; sfb++ { 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 */ /* 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++ { 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 */ /* Copy scalefactors from granule 0 to granule 1 */
for sfb := 6; sfb < 11; sfb++ { 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 */ /* 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++ { 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 */ /* Copy scalefactors from granule 0 to granule 1 */
for sfb := 11; sfb < 16; sfb++ { 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 */ /* 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++ { 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 */ /* Copy scalefactors from granule 0 to granule 1 */
for sfb := 16; sfb < 21; sfb++ { 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. */ /* 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 return err
} }
} }

View File

@ -42,30 +42,31 @@ func readCRC() error {
return nil return nil
} }
func readFrame() error { func readFrame() (*frame, error) {
if err := readHeader(); err != nil { f := &frame{}
return err if err := f.readHeader(); err != nil {
return nil, err
} }
// Get CRC word if present // Get CRC word if present
if theMPEG1FrameHeader.protection_bit == 0 { if f.header.protection_bit == 0 {
if err := readCRC(); err != nil { if err := readCRC(); err != nil {
return err return nil, err
} }
} }
if theMPEG1FrameHeader.layer != mpeg1Layer3 { if f.header.layer != mpeg1Layer3 {
return fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, theMPEG1FrameHeader.layer) return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, f.header.layer)
} }
// Get side info // Get side info
if err := readAudioL3(); err != nil { if err := f.readAudioL3(); err != nil {
return err return nil, err
} }
// If there's not enough main data in the bit reservoir, // If there's not enough main data in the bit reservoir,
// signal to calling function so that decoding isn't done! // signal to calling function so that decoding isn't done!
// Get main data(scalefactors and Huffman coded frequency data) // Get main data(scalefactors and Huffman coded frequency data)
if err := readMainL3(); err != nil { if err := f.readMainL3(); err != nil {
return err return nil, err
} }
return nil return f, nil
} }
func isHeader(header uint32) bool { func isHeader(header uint32) bool {
@ -84,7 +85,7 @@ func isHeader(header uint32) bool {
return true return true
} }
func readHeader() error { func (f *frame) readHeader() error {
/* Get the next four bytes from the bitstream */ /* Get the next four bytes from the bitstream */
buf := make([]int, 4) buf := make([]int, 4)
n := 0 n := 0
@ -125,75 +126,75 @@ func readHeader() error {
/* If we get here we've found the sync word,and can decode the header /* 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. */ * which is in the low 20 bits of the 32-bit sync+header word. */
/* Decode the header */ /* Decode the header */
theMPEG1FrameHeader.id = int((header & 0x00180000) >> 19) f.header.id = int((header & 0x00180000) >> 19)
theMPEG1FrameHeader.layer = mpeg1Layer((header & 0x00060000) >> 17) f.header.layer = mpeg1Layer((header & 0x00060000) >> 17)
theMPEG1FrameHeader.protection_bit = int((header & 0x00010000) >> 16) f.header.protection_bit = int((header & 0x00010000) >> 16)
theMPEG1FrameHeader.bitrate_index = int((header & 0x0000f000) >> 12) f.header.bitrate_index = int((header & 0x0000f000) >> 12)
theMPEG1FrameHeader.sampling_frequency = int((header & 0x00000c00) >> 10) f.header.sampling_frequency = int((header & 0x00000c00) >> 10)
theMPEG1FrameHeader.padding_bit = int((header & 0x00000200) >> 9) f.header.padding_bit = int((header & 0x00000200) >> 9)
theMPEG1FrameHeader.private_bit = int((header & 0x00000100) >> 8) f.header.private_bit = int((header & 0x00000100) >> 8)
theMPEG1FrameHeader.mode = mpeg1Mode((header & 0x000000c0) >> 6) f.header.mode = mpeg1Mode((header & 0x000000c0) >> 6)
theMPEG1FrameHeader.mode_extension = int((header & 0x00000030) >> 4) f.header.mode_extension = int((header & 0x00000030) >> 4)
theMPEG1FrameHeader.copyright = int((header & 0x00000008) >> 3) f.header.copyright = int((header & 0x00000008) >> 3)
theMPEG1FrameHeader.original_or_copy = int((header & 0x00000004) >> 2) f.header.original_or_copy = int((header & 0x00000004) >> 2)
theMPEG1FrameHeader.emphasis = int((header & 0x00000003) >> 0) f.header.emphasis = int((header & 0x00000003) >> 0)
/* Check for invalid values and impossible combinations */ /* 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", return fmt.Errorf("mp3: ID must be 3. Header word is 0x%08x at file pos %d",
header, getFilepos()) 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", return fmt.Errorf("mp3: Free bitrate format NIY! Header word is 0x%08x at file pos %d",
header, getFilepos()) 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", return fmt.Errorf("mp3: bitrate_index = 15 is invalid! Header word is 0x%08x at file pos %d",
header, getFilepos()) 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", return fmt.Errorf("mp3: sampling_frequency = 3 is invalid! Header word is 0x%08x at file pos %d",
header, getFilepos()) 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", return fmt.Errorf("mp3: layer = %d is invalid! Header word is 0x%08x at file pos %d",
mpeg1LayerReserved, header, getFilepos()) mpeg1LayerReserved, header, getFilepos())
} }
return nil 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. */ /* 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++ { 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 return nil
} }
/* Calculate bit_pos_end which is the index of the last bit for this part. */ /* 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 */ /* Determine region boundaries */
region_1_start := 0 region_1_start := 0
region_2_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_1_start = 36 /* sfb[9/3]*3=36 */
region_2_start = 576 /* No Region2 for short block case. */ region_2_start = 576 /* No Region2 for short block case. */
} else { } else {
sfreq := theMPEG1FrameHeader.sampling_frequency sfreq := f.header.sampling_frequency
region_1_start = 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 = region_2_start =
sfBandIndicesSet[sfreq].l[theMPEG1SideInfo.region0_count[gr][ch]+ sfBandIndicesSet[sfreq].l[f.sideInfo.region0_count[gr][ch]+
theMPEG1SideInfo.region1_count[gr][ch]+2] f.sideInfo.region1_count[gr][ch]+2]
} }
/* Read big_values using tables according to region_x_start */ /* 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 table_num := 0
if is_pos < region_1_start { 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 { } 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 { } else {
table_num = int(theMPEG1SideInfo.table_select[gr][ch][2]) table_num = f.sideInfo.table_select[gr][ch][2]
} }
/* Get next Huffman coded words */ /* Get next Huffman coded words */
x, y, _, _, err := huffmanDecode(table_num) x, y, _, _, err := huffmanDecode(table_num)
@ -201,35 +202,35 @@ func readHuffman(part_2_start, gr, ch int) error {
return err return err
} }
/* In the big_values area there are two freq lines per Huffman word */ /* 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++ 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 */ /* Read small values until is_pos = 576 or we run out of huffman data */
table_num := int(theMPEG1SideInfo.count1table_select[gr][ch]) + 32 table_num := f.sideInfo.count1table_select[gr][ch] + 32
is_pos := int(theMPEG1SideInfo.big_values[gr][ch]) * 2 is_pos := f.sideInfo.big_values[gr][ch] * 2
for ; (is_pos <= 572) && (getMainPos() <= bit_pos_end); is_pos++ { for ; (is_pos <= 572) && (getMainPos() <= bit_pos_end); is_pos++ {
/* Get next Huffman coded words */ /* Get next Huffman coded words */
x, y, v, w, err := huffmanDecode(table_num) x, y, v, w, err := huffmanDecode(table_num)
if err != nil { if err != nil {
return err return err
} }
theMPEG1MainData.is[gr][ch][is_pos] = float32(v) f.mainData.is[gr][ch][is_pos] = float32(v)
is_pos++ is_pos++
if is_pos >= 576 { if is_pos >= 576 {
break break
} }
theMPEG1MainData.is[gr][ch][is_pos] = float32(w) f.mainData.is[gr][ch][is_pos] = float32(w)
is_pos++ is_pos++
if is_pos >= 576 { if is_pos >= 576 {
break break
} }
theMPEG1MainData.is[gr][ch][is_pos] = float32(x) f.mainData.is[gr][ch][is_pos] = float32(x)
is_pos++ is_pos++
if is_pos >= 576 { if is_pos >= 576 {
break 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 */ /* Check that we didn't read past the end of this section */
if getMainPos() > (bit_pos_end + 1) { if getMainPos() > (bit_pos_end + 1) {
@ -237,10 +238,10 @@ func readHuffman(part_2_start, gr, ch int) error {
is_pos -= 4 is_pos -= 4
} }
/* Setup count1 which is the index of the first sample in the rzero reg. */ /* 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 */ /* Zero out the last part if necessary */
for ; /* is_pos comes from last for-loop */ is_pos < 576; is_pos++ { 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 */ /* Set the bitpos to point to the next part to read */
setMainPos(bit_pos_end + 1) setMainPos(bit_pos_end + 1)

View File

@ -38,16 +38,16 @@ var g_mpeg1_bitrates = map[mpeg1Layer][15]int{
var g_sampling_frequency = [3]int{44100, 48000, 32000} var g_sampling_frequency = [3]int{44100, 48000, 32000}
func readAudioL3() error { func (f *frame) readAudioL3() error {
nch := 2 nch := 2
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel { if f.header.mode == mpeg1ModeSingleChannel {
nch = 1 nch = 1
} }
/* Calculate header audio data size */ /* Calculate header audio data size */
framesize := (144* framesize := (144*
g_mpeg1_bitrates[theMPEG1FrameHeader.layer][theMPEG1FrameHeader.bitrate_index])/ g_mpeg1_bitrates[f.header.layer][f.header.bitrate_index])/
g_sampling_frequency[theMPEG1FrameHeader.sampling_frequency] + g_sampling_frequency[f.header.sampling_frequency] +
int(theMPEG1FrameHeader.padding_bit) int(f.header.padding_bit)
if framesize > 2000 { if framesize > 2000 {
return fmt.Errorf("mp3: framesize = %d\n", framesize) 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 is the rest of the frame,including ancillary data */
main_data_size := framesize - sideinfo_size - 4 /* sync+header */ main_data_size := framesize - sideinfo_size - 4 /* sync+header */
/* CRC is 2 bytes */ /* CRC is 2 bytes */
if theMPEG1FrameHeader.protection_bit == 0 { if f.header.protection_bit == 0 {
main_data_size -= 2 main_data_size -= 2
} }
/* Read sideinfo from bitstream into buffer used by getSideBits() */ /* Read sideinfo from bitstream into buffer used by getSideBits() */
@ -68,54 +68,54 @@ func readAudioL3() error {
} }
/* Parse audio data */ /* Parse audio data */
/* Pointer to where we should start reading main 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. */ /* Get private bits. Not used for anything. */
if theMPEG1FrameHeader.mode == mpeg1ModeSingleChannel { if f.header.mode == mpeg1ModeSingleChannel {
theMPEG1SideInfo.private_bits = getSideBits(5) f.sideInfo.private_bits = getSideBits(5)
} else { } else {
theMPEG1SideInfo.private_bits = getSideBits(3) f.sideInfo.private_bits = getSideBits(3)
} }
/* Get scale factor selection information */ /* Get scale factor selection information */
for ch := 0; ch < nch; ch++ { for ch := 0; ch < nch; ch++ {
for scfsi_band := 0; scfsi_band < 4; scfsi_band++ { 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 */ /* Get the rest of the side information */
for gr := 0; gr < 2; gr++ { for gr := 0; gr < 2; gr++ {
for ch := 0; ch < nch; ch++ { for ch := 0; ch < nch; ch++ {
theMPEG1SideInfo.part2_3_length[gr][ch] = getSideBits(12) f.sideInfo.part2_3_length[gr][ch] = getSideBits(12)
theMPEG1SideInfo.big_values[gr][ch] = getSideBits(9) f.sideInfo.big_values[gr][ch] = getSideBits(9)
theMPEG1SideInfo.global_gain[gr][ch] = getSideBits(8) f.sideInfo.global_gain[gr][ch] = getSideBits(8)
theMPEG1SideInfo.scalefac_compress[gr][ch] = getSideBits(4) f.sideInfo.scalefac_compress[gr][ch] = getSideBits(4)
theMPEG1SideInfo.win_switch_flag[gr][ch] = getSideBits(1) f.sideInfo.win_switch_flag[gr][ch] = getSideBits(1)
if theMPEG1SideInfo.win_switch_flag[gr][ch] == 1 { if f.sideInfo.win_switch_flag[gr][ch] == 1 {
theMPEG1SideInfo.block_type[gr][ch] = getSideBits(2) f.sideInfo.block_type[gr][ch] = getSideBits(2)
theMPEG1SideInfo.mixed_block_flag[gr][ch] = getSideBits(1) f.sideInfo.mixed_block_flag[gr][ch] = getSideBits(1)
for region := 0; region < 2; region++ { 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++ { 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) { if (f.sideInfo.block_type[gr][ch] == 2) && (f.sideInfo.mixed_block_flag[gr][ch] == 0) {
theMPEG1SideInfo.region0_count[gr][ch] = 8 /* Implicit */ f.sideInfo.region0_count[gr][ch] = 8 /* Implicit */
} else { } else {
theMPEG1SideInfo.region0_count[gr][ch] = 7 /* Implicit */ f.sideInfo.region0_count[gr][ch] = 7 /* Implicit */
} }
/* The standard is wrong on this!!! */ /* 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 { } else {
for region := 0; region < 3; region++ { 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) f.sideInfo.region0_count[gr][ch] = getSideBits(4)
theMPEG1SideInfo.region1_count[gr][ch] = getSideBits(3) f.sideInfo.region1_count[gr][ch] = getSideBits(3)
theMPEG1SideInfo.block_type[gr][ch] = 0 /* Implicit */ f.sideInfo.block_type[gr][ch] = 0 /* Implicit */
} }
theMPEG1SideInfo.preflag[gr][ch] = getSideBits(1) f.sideInfo.preflag[gr][ch] = getSideBits(1)
theMPEG1SideInfo.scalefac_scale[gr][ch] = getSideBits(1) f.sideInfo.scalefac_scale[gr][ch] = getSideBits(1)
theMPEG1SideInfo.count1table_select[gr][ch] = getSideBits(1) f.sideInfo.count1table_select[gr][ch] = getSideBits(1)
} }
} }
return nil return nil

View File

@ -50,8 +50,6 @@ type mpeg1FrameHeader struct {
emphasis int // 2 bits emphasis int // 2 bits
} }
var theMPEG1FrameHeader mpeg1FrameHeader
// A mpeg1SideInfo is MPEG1 Layer 3 Side Information. // A mpeg1SideInfo is MPEG1 Layer 3 Side Information.
// [2][2] means [gr][ch]. // [2][2] means [gr][ch].
type mpeg1SideInfo struct { type mpeg1SideInfo struct {
@ -78,8 +76,6 @@ type mpeg1SideInfo struct {
count1 [2][2]int // Not in file,calc. by huff.dec.! count1 [2][2]int // Not in file,calc. by huff.dec.!
} }
var theMPEG1SideInfo mpeg1SideInfo
// A mpeg1MainData is MPEG1 Layer 3 Main Data. // A mpeg1MainData is MPEG1 Layer 3 Main Data.
type mpeg1MainData struct { type mpeg1MainData struct {
scalefac_l [2][2][21]int // 0-4 bits 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 is [2][2][576]float32 // Huffman coded freq. lines
} }
var theMPEG1MainData mpeg1MainData type frame struct {
header mpeg1FrameHeader
sideInfo mpeg1SideInfo
mainData mpeg1MainData
}