Added alternate go FLAC decoder

This commit is contained in:
DataHoarder 2022-05-19 17:00:06 +02:00
parent 205692c01c
commit aa67533e41
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
6 changed files with 152 additions and 8 deletions

View file

@ -19,7 +19,7 @@ steps:
- git clone --depth 1 https://gitlab.xiph.org/xiph/libopusenc.git && cd libopusenc && ./autogen.sh && ./configure --prefix /usr && make && make install && cd ..
- git clone --depth 1 https://git.gammaspectra.live/S.O.N.G/alac.git && cd alac && autoreconf -fi && ./configure --prefix /usr && make && make install && cd ..
- go test -cover -v ./...
- go test -cover -v -tags=disable_codec_libfdk-aac,disable_codec_lame,disable_codec_tta,enable_codec_libalac ./...
- go test -cover -v -tags=disable_codec_libfdk-aac,disable_codec_lame,disable_codec_tta,disable_codec_libflac,enable_codec_libalac ./...
- go test -cover -v -tags=disable_format_aac,disable_format_alac,disable_format_mp3,disable_format_opus,disable_format_tta,disable_format_vorbis ./...
---
kind: pipeline

View file

@ -15,7 +15,7 @@ Collection of audio utilities for decoding/encoding files and streams.
| Codec | Containers | Decoder | Analyzer | Encoder | Notes |
|:----------:|:----------------------------------------------------------------------------------------:|:-------:|:--------:|:-------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **FLAC** | [FLAC](https://xiph.org/flac/format.html), [Ogg](https://xiph.org/flac/ogg_mapping.html) | ✅ | ✅ | ✅ | Adjustable encoding compression level and block size.<br/>Decoding/encoding by [libFLAC](https://github.com/xiph/flac) via [goflac](https://git.gammaspectra.live/S.O.N.G/goflac). |
| **FLAC** | [FLAC](https://xiph.org/flac/format.html), [Ogg](https://xiph.org/flac/ogg_mapping.html) | ✅ | ✅ | ✅ | Adjustable encoding compression level and block size.<br/>Decoding/encoding by [libFLAC](https://github.com/xiph/flac) via [goflac](https://git.gammaspectra.live/S.O.N.G/goflac).<br/>If [goflac](https://git.gammaspectra.live/S.O.N.G/goflac) codec is disabled, [mewkiz/flac](https://github.com/mewkiz/flac) decoder will be used. |
| **TTA** | [TTA](https://www.tausoft.org/en/true_audio_codec_format/) | ✅ | ✅ | ✅ | Decoding/encoding via [go-tta](https://git.gammaspectra.live/S.O.N.G/go-tta). |
| **MP3** | [MP3](http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html) | ✅ | - | ✅ | Adjustable encoding bitrate and mode.<br/>Decoding via [minimp3](https://github.com/kvark128/minimp3), encoding by [LAME](https://lame.sourceforge.io/) via [go-lame](https://github.com/viert/go-lame). |
| **Opus** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | - | ✅ | Adjustable encoding bitrate.<br/>Decoding/encoding by [libopus](https://github.com/xiph/opus) via [go-pus](https://git.gammaspectra.live/S.O.N.G/go-pus). |
@ -112,6 +112,12 @@ This tag disables the [libfdk-aac](https://git.gammaspectra.live/S.O.N.G/go-fdka
If this tag is enabled, yet `aac` support remains enabled, an AAC encoder (but not decoder) will be built with the [VisualOn AAC encoder](https://github.com/gen2brain/aac-go) bindings, which are vastly worse.
### disable_codec_libflac
This tag disables the [libFLAC](https://gitlab.xiph.org/xiph/flac) support for decoding/encoding FLAC.
If this tag is enabled, yet `flac` support remains enabled, [mewkiz/flac](https://github.com/mewkiz/flac) FLAC decoder (but not encoder) will be used.
### disable_codec_lame
This tag disables the [LAME](https://github.com/viert/go-lame) support for encoding MP3. This is available for specific problems with the LGPL v2 license that conflicts with your needs or policy.

138
audio/format/flac/goflac.go Normal file
View file

@ -0,0 +1,138 @@
//go:build !disable_format_flac && disable_codec_libflac
// +build !disable_format_flac,disable_codec_libflac
package flac
import (
"bytes"
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format"
"git.gammaspectra.live/S.O.N.G/Kirika/cgo"
libflac "github.com/mewkiz/flac"
"io"
)
type Format struct {
}
func NewFormat() Format {
return Format{}
}
func (f Format) Name() string {
return "flac"
}
func (f Format) Description() string {
return "github.com/mewkiz/flac"
}
func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
decoder, err := libflac.New(r)
if err != nil {
return audio.Source{}, err
}
newChannel := make(chan []float32)
go func() {
defer close(newChannel)
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]
}
newChannel <- cgo.Int32ToFloat32(buffer, bitDepth)
frameNumber++
}
}()
return audio.Source{
Channels: int(decoder.Info.NChannels),
SampleRate: int(decoder.Info.SampleRate),
Blocks: newChannel,
}, nil
}
func (f Format) OpenAnalyzer(r io.ReadSeekCloser) (audio.Source, format.AnalyzerChannel, error) {
decoder, err := libflac.New(r)
if err != nil {
return audio.Source{}, nil, err
}
newChannel := make(chan []float32)
analyzerChannel := make(format.AnalyzerChannel)
go func() {
defer close(newChannel)
defer close(analyzerChannel)
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]
}
newChannel <- cgo.Int32ToFloat32(buffer, bitDepth)
analyzerChannel <- &format.AnalyzerPacket{
Samples: buffer,
Channels: channels,
BitDepth: bitDepth,
SampleRate: int(decoder.Info.SampleRate),
}
frameNumber++
}
}()
return audio.Source{
Channels: int(decoder.Info.NChannels),
SampleRate: int(decoder.Info.SampleRate),
Blocks: newChannel,
}, analyzerChannel, nil
}
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"
}

View file

@ -1,5 +1,5 @@
//go:build !disable_format_flac
// +build !disable_format_flac
//go:build !disable_format_flac && !disable_codec_libflac
// +build !disable_format_flac,!disable_codec_libflac
package flac

View file

@ -1,5 +1,5 @@
//go:build !disable_format_alac
// +build !disable_format_alac
//go:build !disable_format_flac && !disable_codec_libflac
// +build !disable_format_flac,!disable_codec_libflac
package flac

View file

@ -1,5 +1,5 @@
//go:build !disable_format_flac
// +build !disable_format_flac
//go:build !disable_format_flac && !disable_codec_libflac
// +build !disable_format_flac,!disable_codec_libflac
package packetizer