DataHoarder
09f3cf3b56
All checks were successful
continuous-integration/drone/push Build is passing
79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
//go:build !disable_format_flac && (disable_codec_libflac || !cgo)
|
|
|
|
package flac
|
|
|
|
import (
|
|
"bytes"
|
|
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
|
|
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format"
|
|
libflac "github.com/mewkiz/flac"
|
|
"io"
|
|
)
|
|
|
|
type Format struct {
|
|
}
|
|
|
|
func NewFormat() Format {
|
|
return Format{}
|
|
}
|
|
|
|
func (f Format) Name() string {
|
|
return "flac"
|
|
}
|
|
|
|
func (f Format) DecoderDescription() string {
|
|
return "mewkiz/flac"
|
|
}
|
|
|
|
func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
|
|
decoder, err := libflac.New(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
source := audio.NewSource[int32](int(decoder.Info.BitsPerSample), int(decoder.Info.SampleRate), int(decoder.Info.NChannels))
|
|
|
|
go func() {
|
|
defer source.Close()
|
|
defer decoder.Close()
|
|
|
|
frameNumber := 0
|
|
|
|
for {
|
|
currentFrame, err := decoder.ParseNext()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
bitDepth := int(decoder.Info.BitsPerSample)
|
|
channels := int(decoder.Info.NChannels)
|
|
|
|
if currentFrame.BitsPerSample != 0 {
|
|
bitDepth = int(currentFrame.BitsPerSample)
|
|
}
|
|
if len(currentFrame.Subframes) != 0 {
|
|
channels = len(currentFrame.Subframes)
|
|
}
|
|
|
|
buffer := make([]int32, len(currentFrame.Subframes[0].Samples)*channels)
|
|
for i := range buffer {
|
|
buffer[i] = currentFrame.Subframes[i%channels].Samples[i/channels]
|
|
}
|
|
|
|
source.IngestInt32(buffer, bitDepth)
|
|
|
|
frameNumber++
|
|
}
|
|
}()
|
|
|
|
return source, nil
|
|
}
|
|
|
|
func (f Format) OpenAnalyzer(r io.ReadSeekCloser) (audio.Source, format.AnalyzerChannel, error) {
|
|
return format.NewAnalyzerChannel(f.Open(r))
|
|
}
|
|
|
|
func (f Format) Identify(peek []byte, extension string) bool {
|
|
return bytes.Compare(peek[:4], []byte{'f', 'L', 'a', 'C'}) == 0 || (bytes.Compare(peek[:3], []byte{'I', 'D', '3'}) == 0 && extension != "mp3") || extension == "flac"
|
|
}
|