Files
icecast-ripper/vendor/github.com/tcolgate/mp3/header.go
Dmitry Andreev b5f23a50b7
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Docker / build (push) Has been cancelled
golangci-lint / lint (push) Has been cancelled
Integrate MP3 duration extraction and silence handling (#6)
* feat: integrate MP3 duration extraction and silence handling

- Added a new dependency on github.com/tcolgate/mp3 for MP3 frame decoding.
- Implemented actual MP3 duration retrieval in the scanRecordings function, falling back to an estimation if retrieval fails.
- Introduced a silent frame asset for generating silence in audio streams.
- Created a silence reader to provide a continuous stream of silent frames.
- Added necessary documentation and licensing for the new MP3 package.
- Updated .gitignore to exclude MP3 files except for the internal data directory.

* feat: update README and improve application configuration and logging

* refactor: remove unused GenerateFileHash function and improve resource cleanup in MP3 and recorder modules
2025-04-13 15:56:22 +03:00

84 lines
2.1 KiB
Go

package mp3
/*
func (this *FrameHeader) Parse(bs []byte) error {
this.Size = 0
this.Samples = 0
this.Duration = 0
if len(bs) < 4 {
return fmt.Errorf("not enough bytes")
}
if bs[0] != 0xFF || (bs[1]&0xE0) != 0xE0 {
return fmt.Errorf("missing sync word, got: %x, %x", bs[0], bs[1])
}
this.Version = Version((bs[1] >> 3) & 0x03)
if this.Version == MPEGReserved {
return fmt.Errorf("reserved mpeg version")
}
this.Layer = Layer(((bs[1] >> 1) & 0x03))
if this.Layer == LayerReserved {
return fmt.Errorf("reserved layer")
}
this.Protection = (bs[1] & 0x01) != 0x01
bitrateIdx := (bs[2] >> 4) & 0x0F
if bitrateIdx == 0x0F {
return fmt.Errorf("invalid bitrate: %v", bitrateIdx)
}
this.Bitrate = bitrates[this.Version][this.Layer][bitrateIdx] * 1000
if this.Bitrate == 0 {
return fmt.Errorf("invalid bitrate: %v", bitrateIdx)
}
sampleRateIdx := (bs[2] >> 2) & 0x03
if sampleRateIdx == 0x03 {
return fmt.Errorf("invalid sample rate: %v", sampleRateIdx)
}
this.SampleRate = sampleRates[this.Version][sampleRateIdx]
this.Pad = ((bs[2] >> 1) & 0x01) == 0x01
this.Private = (bs[2] & 0x01) == 0x01
this.ChannelMode = ChannelMode(bs[3]>>6) & 0x03
// todo: mode extension
this.CopyRight = (bs[3]>>3)&0x01 == 0x01
this.Original = (bs[3]>>2)&0x01 == 0x01
this.Emphasis = Emphasis(bs[3] & 0x03)
if this.Emphasis == EmphReserved {
return fmt.Errorf("reserved emphasis")
}
this.Size = this.size()
this.Samples = this.samples()
this.Duration = this.duration()
return nil
}
func (this *FrameHeader) samples() int {
return samplesPerFrame[this.Version][this.Layer]
}
func (this *FrameHeader) size() int64 {
bps := float64(this.samples()) / 8
fsize := (bps * float64(this.Bitrate)) / float64(this.SampleRate)
if this.Pad {
fsize += float64(slotSize[this.Layer])
}
return int64(fsize)
}
func (this *FrameHeader) duration() time.Duration {
ms := (1000 / float64(this.SampleRate)) * float64(this.samples())
return time.Duration(time.Duration(float64(time.Millisecond) * ms))
}
*/