func getModeFilter(fh *mp3agic.FrameHeader) uint32 { if fh.Verify() != nil { return 0 } if fh.Channels() == 1 { return FILTER_MONO } return FILTER_STEREO }
func getLayerFilter(fh *mp3agic.FrameHeader) uint32 { if fh.Verify() != nil { return 0 } switch fh.Layer() { case mp3agic.MPEG_LAYER_1: return FILTER_LAYER1 case mp3agic.MPEG_LAYER_2: return FILTER_LAYER2 case mp3agic.MPEG_LAYER_3: return FILTER_LAYER3 } return 0 }
func getSamplingrateFilter(fh *mp3agic.FrameHeader) uint32 { if fh.Verify() != nil { return 0 } switch fh.SampleRate() { case 32000, 16000, 8000: return FILTER_32000HZ case 44100, 22050, 11025: return FILTER_44100HZ case 48000, 24000, 12000: return FILTER_48000HZ } return 0 }
func getMpegFilter(fh *mp3agic.FrameHeader) uint32 { if fh.Verify() != nil { return 0 } switch fh.Version() { case mp3agic.MPEG_VERSION_1_0: return FILTER_MPEG1 case mp3agic.MPEG_VERSION_2_0: return FILTER_MPEG2 case mp3agic.MPEG_VERSION_2_5: return FILTER_MPEG25 } return 0 }
func constructReservoirFrame(dest []byte, header *mp3agic.FrameHeader, minResSize int, absStartSample int64) int { // increase for 10-byte-header inclusion minResSize += 10 h32 := header.getHeader32() | 0x00010000 // switch off CRC usage fh2 := &FrameHeader{} for bri := 1; bri <= 14; bri++ { h32 = (h32 & 0xFFFF0FFF) + (bri << 12) fh2.setHeader32(h32) frameSize := fh2.getFrameSize() sideInfoEnd := fh2.getSideInfoEnd() mainDataBlockSize := frameSize - sideInfoEnd if mainDataBlockSize >= minResSize { dest[0] = byte(h32 >> 24) dest[1] = byte(h32 >> 16) dest[2] = byte(h32 >> 8) dest[3] = byte(h32) fill(dest[4:sideInfoEnd], 0) fill(dest[sideInfoEnd:frameSize], 0x78) // Arrays.fill(dest, 4, sideInfoEnd, (byte) 0); // Arrays.fill(dest, sideInfoEnd, frameSize, (byte) 0x78); copy(dest[sideInfoEnd:], []byte("PCUT")) // dest[sideInfoEnd] = 0x50; // P // dest[sideInfoEnd + 1] = 0x43; // C // dest[sideInfoEnd + 2] = 0x55; // U // dest[sideInfoEnd + 3] = 0x54; // T copy(dest[sideInfoEnd+4:], []byte{ // revision 0 0, // absolute sample start pos byte(uint64(absStartSample) >> 32), byte(uint64(absStartSample) >> 24), byte(uint64(absStartSample) >> 16), byte(uint64(absStartSample) >> 8), byte(uint64(absStartSample))}) return frameSize } } return -1 }
func (m *scannedMp3) scan(ips io.ReadSeeker) os.Error { temp := make([]byte, MAX_MPAFRAME_SIZE) jh := new(MyCountingJunkHandler) mpafp := &mpaFrameParser{ips: ips, junkh: jh} filter := FILTER_LAYER3 var fh *mp3agic.FrameHeader frameCounter := 0 firstFrameFound := false isMPEG1 := false firstkbps := 0 sumMusicFrameSize := 0 //try { for { fh, err := mpafp.getNextFrame(filter, temp, fh) if err != nil && err != os.EOF { return err } frameSize := fh.LengthInBytes() //int frameSize = fh.getFrameSize(); if !firstFrameFound { firstFrameFound = true firstkbps = fh.BitrateInKbps() m.samplesPerFrame = fh.SamplesPerFrame() isMPEG1 = (fh.Version() == mp3agic.MPEG_VERSION_1_0) if isMPEG1 { m.maxRes = 511 } else { m.maxRes = 255 } filter = getFilterFor(fh) m.firstFrameHeader = fh if m.xiltFrame.parse(temp, 0) { if m.xiltFrame.hasXingTag { m.isVBR = true } frameCounter-- if m.xiltFrame.hasLameTag { m.encDelay = m.xiltFrame.encDelay m.encPadding = m.xiltFrame.encPadding } } } else { checkBitRate := true if frameCounter == 0 { checkBitRate = false // first music frame. might be a PCUT-tag // reservoir-filler frame sie := fh.SideInfoEnd() // a pcut frame contains its tag in the first 10 // bytes of the // main data section pcutFrame := (sie+10 <= frameSize) && (temp[sie] == 0x50) && // P (temp[sie+1] == 0x43) && // C (temp[sie+2] == 0x55) && // U (temp[sie+3] == 0x54) // T if pcutFrame { // temp[sie+4] tag revision (always 0 for now) t := int64(temp[sie+5]) // fetch 40 bit start sample t = (t << 8) | int64(temp[sie+6]) t = (t << 8) | int64(temp[sie+7]) t = (t << 8) | int64(temp[sie+8]) t = (t << 8) | int64(temp[sie+9]) m.startSample = t } else { for b := range temp[fh.SideInfoStart():fh.SideInfoEnd()] { if b != 0 { checkBitRate = true break } } } } // we don't want the first "music frame" to be checked // if it's // possibly a PCUT generated reservoir frame if checkBitRate && fh.BitrateInKbps() != firstkbps { m.isVBR = true } } if frameCounter >= 0 { sumMusicFrameSize += frameSize accessFrameRecord(frameCounter) setFrameFileOfs(int(*jh)) setFrameSize(frameSize) sis := fh.SideInfoStart() ofs := sis brPointer := int(temp[ofs]) if isMPEG1 { brPointer = (brPointer << 1) | int((temp[ofs+1]&0x80)>>7) } setBitResPtr(brPointer) setMainDataSectionSize(frameSize - sis - fh.SideInfoSize()) } jh.Inc(frameSize) frameCounter++ } //} //catch (EOFException x) { //} m.musicFrameCount = frameCounter if !firstFrameFound { return os.NewError("no mp3 data found") } var framerate float32 = float32(m.firstFrameHeader.SampleRate()) / float32(m.firstFrameHeader.SamplesPerFrame()) m.avgBitrate = (float32(sumMusicFrameSize) / float32(m.musicFrameCount)) * framerate / 125 /* } finally { try { ips.close(); } catch (IOException x) { } } */ return nil }