Added libvorbis encoder/decoder

This commit is contained in:
DataHoarder 2022-07-28 15:01:20 +02:00
parent bae67a1c75
commit 4cf595927e
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
7 changed files with 204 additions and 25 deletions

View file

@ -27,7 +27,7 @@ steps:
- submodules/LFS
commands:
- apk update
- apk add --no-cache git gcc g++ musl-dev bash autoconf automake cmake make libtool gettext openssl-dev flac-dev opus-dev opusfile-dev libopusenc-dev libsamplerate-dev lame-dev libebur128-dev fdk-aac-dev --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community
- apk add --no-cache git gcc g++ musl-dev bash autoconf automake cmake make libtool gettext openssl-dev flac-dev opus-dev opusfile-dev libopusenc-dev libvorbis-dev libsamplerate-dev lame-dev libebur128-dev fdk-aac-dev --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community
- 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 -p 1 -failfast -timeout 20m -cover -gcflags=-d=checkptr -v ./...
---
@ -72,6 +72,7 @@ steps:
- git clone --depth 1 --branch v1.3.5 https://gitlab.xiph.org/xiph/ogg.git && cd ogg && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --branch master https://gitlab.xiph.org/xiph/opus.git && cd opus && ./autogen.sh && ./configure --enable-float-approx --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 --branch v0.12 https://gitlab.xiph.org/xiph/opusfile.git && cd opusfile && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 --branch v1.3.7 https://gitlab.xiph.org/xiph/vorbis.git && cd vorbis && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 --branch 1.3.4 https://gitlab.xiph.org/xiph/flac.git && cd flac && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 https://gitlab.xiph.org/xiph/libopusenc.git && cd libopusenc && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 https://github.com/mstorsjo/fdk-aac.git && cd fdk-aac && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make -j$(nproc) && make install && cd ..
@ -93,7 +94,7 @@ steps:
commands:
- apk update
- apk add --no-cache git gcc musl-dev pkgconfig
- go test -p 1 -failfast -timeout 20m -cover -gcflags=-d=checkptr -v -tags=disable_codec_libfdk_aac,disable_codec_lame,disable_codec_tta,disable_codec_libflac ./...
- go test -p 1 -failfast -timeout 20m -cover -gcflags=-d=checkptr -v -tags=disable_codec_libfdk_aac,disable_codec_lame,disable_codec_tta,disable_codec_libflac,disable_codec_libvorbis ./...
- name: test-cgo-disable-formats
image: golang:1.18-alpine
volumes:
@ -156,6 +157,7 @@ steps:
- git clone --depth 1 --branch v1.3.5 https://gitlab.xiph.org/xiph/ogg.git && cd ogg && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --branch master https://gitlab.xiph.org/xiph/opus.git && cd opus && ./autogen.sh && ./configure --enable-float-approx --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 --branch v0.12 https://gitlab.xiph.org/xiph/opusfile.git && cd opusfile && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 --branch v1.3.7 https://gitlab.xiph.org/xiph/vorbis.git && cd vorbis && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 --branch 1.3.4 https://gitlab.xiph.org/xiph/flac.git && cd flac && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 https://gitlab.xiph.org/xiph/libopusenc.git && cd libopusenc && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make && make install && cd ..
- git clone --depth 1 https://github.com/mstorsjo/fdk-aac.git && cd fdk-aac && ./autogen.sh && ./configure --prefix /drone/src/build_deps && make -j$(nproc) && make install && cd ..
@ -183,7 +185,7 @@ steps:
commands:
- apk update
- apk add --no-cache git gcc musl-dev pkgconfig
- go test -p 1 -failfast -timeout 20m -cover -gcflags=-d=checkptr -v -tags=disable_codec_libfdk_aac,disable_codec_lame,disable_codec_tta,disable_codec_libflac ./...
- go test -p 1 -failfast -timeout 20m -cover -gcflags=-d=checkptr -v -tags=disable_codec_libfdk_aac,disable_codec_lame,disable_codec_tta,disable_codec_libflac,disable_codec_libvorbis ./...
- name: test-cgo-disable-formats
image: golang:1.18-alpine
volumes:

View file

@ -18,8 +18,8 @@ Collection of audio utilities for decoding/encoding/processing files and streams
| **FLAC** | [FLAC](https://xiph.org/flac/format.html), [Ogg](https://xiph.org/flac/ogg_mapping.html) | ✅ | `int32` | ✅ | 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, [flacgo](https://git.gammaspectra.live/S.O.N.G/flacgo) decoder/encoder will be used. |
| **TTA** | [TTA](https://www.tausoft.org/en/true_audio_codec_format/) | ✅ | `int32` | ✅ | Decoding/encoding via [S.O.N.G/go-tta](https://git.gammaspectra.live/S.O.N.G/go-tta). |
| **MP3** | [MP3](http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html) | ✅ | `2ch. int16` | ✅ | 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) | ✅ | `int16` | ✅ | 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). Linked Ogg streams of different channel count are not supported. |
| **Vorbis** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | `float32` | ❌ | Decoding by [jfreymuth/vorbis](https://github.com/jfreymuth/vorbis) via [jfreymuth/oggvorbis](https://github.com/jfreymuth/oggvorbis). |
| **Opus** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | `int16` | ✅ | 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).<br/>Linked Ogg streams of different channel count are not supported. |
| **Vorbis** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | `float32` | ✅ | Decoding/encoding by [libvorbis](https://github.com/xiph/vorbis) via [go-vorbis](https://git.gammaspectra.live/S.O.N.G/go-vorbis).<br/>If [go-vorbis](https://git.gammaspectra.live/S.O.N.G/go-vorbis) is disabled, [jfreymuth/vorbis](https://github.com/jfreymuth/vorbis) via [jfreymuth/oggvorbis](https://github.com/jfreymuth/oggvorbis) decoder will be used.<br/>Linked Ogg streams of different channel count are not supported. |
| **AAC** | [ADTS](https://wiki.multimedia.cx/index.php/ADTS), ADIF*, MP4** | ✅ | `int16` | ✅ | Adjustable encoding bitrate and mode (LC, HEv1, HEv2).<br/>Decoding/encoding by [FDK-AAC](https://github.com/mstorsjo/fdk-aac) via [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac).<br/>If [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac) codec is disabled, [VisualOn AAC encoder](https://github.com/gen2brain/aac-go) will be used for limited encoding support.<br/>*ADIF only supported on encoding.<br/>**MP4 only supported on encoding, and fragmented MP4 currently. |
| **ALAC** | MP4* | ✅ | `int32` | ✅ | Decoding/encoding by [libalac](https://git.gammaspectra.live/S.O.N.G/alac) via [go-alac](https://git.gammaspectra.live/S.O.N.G/go-alac).<br/>Disabled by default.<br/>*MP4 encoding only supported on fragmented MP4 currently. |
@ -27,15 +27,15 @@ Collection of audio utilities for decoding/encoding/processing files and streams
Only output from Kirika's own encoders is supported.
| Container | Packetizer | Keep Mode | Sample Numbers | Offset | Notes |
|:---------:|:----------:|:---------:|:--------------:|:------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **FLAC** | ✅ | ✅ | ✅ | ✅ | Uses custom Kirika packetizer. |
| **TTA** | ❌ | - | - | - | |
| **MP3** | ✅ | ✅ | ✅ | ✅ | Uses [sssgun/mp3](https://github.com/sssgun/mp3) as a frame parser. |
| **Ogg** | ✅ | ✅ | ✅* | ✅ | Uses custom Kirika packetizer.<br/>*Sample numbers (absolute granule position in Ogg) depend on underlying codec implementing it.<br/>Has been tested as working for Opus |
| **ADTS** | ✅ | ✅ | ✅ | ✅ | Uses [edgeware/mp4ff](https://github.com/edgeware/mp4ff) for its ADTS frame parser. |
| **MP4** | ❌ | - | - | - | |
| **ADIF** | ❌ | - | - | - | |
| Container | Packetizer | Keep Mode | Sample Numbers | Offset | Notes |
|:---------:|:----------:|:---------:|:--------------:|:------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **FLAC** | ✅ | ✅ | ✅ | ✅ | Uses custom Kirika packetizer. |
| **TTA** | ❌ | - | - | - | |
| **MP3** | ✅ | ✅ | ✅ | ✅ | Uses [sssgun/mp3](https://github.com/sssgun/mp3) as a frame parser. |
| **Ogg** | ✅ | ✅ | ✅* | ✅ | Uses custom Kirika packetizer.<br/>*Sample numbers (absolute granule position in Ogg) depend on underlying codec implementing it.<br/>Has been tested as working for Opus, FLAC |
| **ADTS** | ✅ | ✅ | ✅ | ✅ | Uses [edgeware/mp4ff](https://github.com/edgeware/mp4ff) for its ADTS frame parser. |
| **MP4** | ❌ | - | - | - | |
| **ADIF** | ❌ | - | - | - | |
## Dependencies
### Go >= 1.18
@ -60,6 +60,11 @@ make
sudo make install
```
### [libvorbis](https://gitlab.xiph.org/xiph/vorbis) (required by [go-vorbis](https://git.gammaspectra.live/S.O.N.G/go-vorbis))
```shell
sudo apt install libvorbis-dev
```
### [FDK AAC Codec Library](https://github.com/mstorsjo/fdk-aac) (required by [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac))
```shell
sudo apt install libfdk-aac-dev
@ -140,6 +145,12 @@ This tag disables the [libFLAC](https://gitlab.xiph.org/xiph/flac) support for d
If this tag is enabled, yet `flac` support remains enabled, [flacgo](https://git.gammaspectra.live/S.O.N.G/flacgo) FLAC decoder/encoder will be used.
### disable_codec_libvorbis
This tag disables the [libvorbis](https://gitlab.xiph.org/xiph/vorbis) support for decoding/encoding Vorbis.
If this tag is enabled, yet `vorbis` support remains enabled, [jfreymuth/vorbis](https://github.com/jfreymuth/vorbis) via [jfreymuth/oggvorbis](https://github.com/jfreymuth/oggvorbis) Vorbis decoder 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.
@ -190,6 +201,8 @@ Subdependencies that are not cgo-based are denoted in cursive.
| [xiph/opusfile](https://gitlab.xiph.org/xiph/opusfile) | C | [BSD 3-Clause](https://gitlab.xiph.org/xiph/opusfile/-/blob/master/COPYINGG) | Can be linked by cgo as a shared library. |
| [xiph/ogg](https://gitlab.xiph.org/xiph/ogg) | C | [BSD 3-Clause](https://gitlab.xiph.org/xiph/ogg/-/blob/master/COPYING) | Can be linked by cgo as a shared library. |
| [xiph/libopusenc](https://gitlab.xiph.org/xiph/libopusenc) | C | [BSD 3-Clause](https://gitlab.xiph.org/xiph/libopusenc/-/blob/master/COPYING) | Can be linked by cgo as a shared library. |
| [S.O.N.G/go-vorbis](https://git.gammaspectra.live/S.O.N.G/go-vorbis) | Go | [BSD 2-Clause](https://git.gammaspectra.live/S.O.N.G/go-vorbis/src/branch/v2/LICENSE) | |
| [xiph/vorbis](https://gitlab.xiph.org/xiph/vorbis) | C | [BSD 3-Clause](https://gitlab.xiph.org/xiph/vorbis/-/blob/master/COPYING) | Can be linked by cgo as a shared library. |
| [S.O.N.G/go-tta](https://git.gammaspectra.live/S.O.N.G/go-tta) | Go | [LGPL v3](https://git.gammaspectra.live/S.O.N.G/go-tta/src/branch/master/LICENSE) | |
| [S.O.N.G/goflac](https://git.gammaspectra.live/S.O.N.G/goflac) | Go | [BSD 3-Clause](https://git.gammaspectra.live/S.O.N.G/goflac/src/branch/master/LICENSE) | |
| [xiph/flac](https://gitlab.xiph.org/xiph/flac) | C | [BSD 3-Clause](https://gitlab.xiph.org/xiph/flac/-/blob/master/COPYING.Xiph) | Read extra license details on the [official site](https://xiph.org/flac/license.html).<br/>Can be linked by cgo as a shared library. |

View file

@ -1,11 +1,12 @@
//go:build !disable_format_vorbis
//go:build !disable_format_vorbis && !disable_codec_libvorbis && cgo
package vorbis
import (
"bytes"
"fmt"
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
libvorbis "github.com/jfreymuth/oggvorbis"
libvorbis "git.gammaspectra.live/S.O.N.G/go-vorbis"
"io"
)
@ -21,38 +22,95 @@ func (f Format) Name() string {
}
func (f Format) DecoderDescription() string {
return "jfreymuth/oggvorvis"
return fmt.Sprintf("%s (S.O.N.G/go-vorbis)", libvorbis.Version())
}
func (f Format) EncoderDescription() string {
return f.DecoderDescription()
}
func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
reader, err := libvorbis.NewReader(r)
reader, err := libvorbis.NewSeekCloserDecoder(r)
if err != nil {
return nil, err
}
source := audio.NewSource[float32](16, reader.Channels(), reader.SampleRate())
info := reader.Information()
source := audio.NewSource[float32](16, int(info.Rate), info.Channels)
go func() {
defer source.Close()
defer reader.Close()
for {
buffer := make([]float32, 8192)
n, err := reader.Read(buffer)
buf, channelCount, err := reader.ReadFloat()
if err != nil {
return
}
if n > 0 {
source.IngestFloat32(buffer[:n])
if info.Channels != channelCount {
//Channel count changed!
return
}
source.IngestFloat32(buf)
}
}()
return source, nil
}
func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[string]interface{}) error {
var bitrate = 128
if options != nil {
var val interface{}
var ok bool
var intVal int
var int64Val int64
var strVal string
if val, ok = options["bitrate"]; ok {
if strVal, ok = val.(string); ok {
switch strVal {
case "256k":
bitrate = 256
case "192k":
bitrate = 192
case "128k":
bitrate = 128
default:
return fmt.Errorf("unknown setting bitrate=%s", strVal)
}
} else if intVal, ok = val.(int); ok {
bitrate = intVal
} else if int64Val, ok = val.(int64); ok {
bitrate = int(int64Val)
}
}
}
encoder, err := libvorbis.NewEncoderCBR(writer, source.GetChannels(), source.GetSampleRate(), -1, int64(bitrate*1000), -1)
if err != nil {
return err
}
defer encoder.Close()
for block := range source.ToFloat32().GetBlocks() {
err = encoder.WriteFloat(block)
if err != nil {
return err
}
}
encoder.Flush()
return nil
}
func (f Format) Identify(peek []byte, extension string) bool {
return bytes.Compare(peek[:4], []byte{'O', 'g', 'g', 'S'}) == 0 || extension == "vorbis" || extension == "ogg"
}

View file

@ -0,0 +1,58 @@
//go:build !disable_format_vorbis && (disable_codec_libvorbis || !cgo)
package vorbis
import (
"bytes"
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
libvorbis "github.com/jfreymuth/oggvorbis"
"io"
)
type Format struct {
}
func NewFormat() Format {
return Format{}
}
func (f Format) Name() string {
return "vorbis"
}
func (f Format) DecoderDescription() string {
return "jfreymuth/oggvorvis"
}
func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
reader, err := libvorbis.NewReader(r)
if err != nil {
return nil, err
}
source := audio.NewSource[float32](16, reader.SampleRate(), reader.Channels())
go func() {
defer source.Close()
for {
buffer := make([]float32, 8192)
n, err := reader.Read(buffer)
if err != nil {
return
}
if n > 0 {
source.IngestFloat32(buffer[:n])
}
}
}()
return source, nil
}
func (f Format) Identify(peek []byte, extension string) bool {
return bytes.Compare(peek[:4], []byte{'O', 'g', 'g', 'S'}) == 0 || extension == "vorbis" || extension == "ogg"
}

View file

@ -0,0 +1,45 @@
//go:build !disable_format_vorbis && !disable_codec_libvorbis && cgo
package vorbis
import (
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format/flac"
"git.gammaspectra.live/S.O.N.G/Kirika/test"
"os"
"testing"
)
func TestEncodeVorbis(t *testing.T) {
fp, err := os.Open(test.TestSingleSample24)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, err := flac.NewFormat().Open(fp)
if err != nil {
t.Error(err)
return
}
target, err := os.CreateTemp("/tmp", "encode_test_*.vorbis")
if err != nil {
t.Error(err)
return
}
defer func() {
name := target.Name()
target.Close()
os.Remove(name)
}()
options := make(map[string]interface{})
options["bitrate"] = "128k"
err = NewFormat().Encode(source, target, options)
if err != nil {
t.Error(err)
return
}
}

1
go.mod
View file

@ -9,6 +9,7 @@ require (
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220515171305-ffb0aafe2a61
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220721130634-3d5460c48ab6
git.gammaspectra.live/S.O.N.G/go-tta v0.2.1-0.20220226150007-096de1072bd6
git.gammaspectra.live/S.O.N.G/go-vorbis v0.0.0-20220728124510-303b3425eec0
git.gammaspectra.live/S.O.N.G/goflac v0.0.0-20220515172202-6e490998d2a0
github.com/aam335/aac-go v0.0.0-20200408070016-52c23bd38988
github.com/dh1tw/gosamplerate v0.1.2

2
go.sum
View file

@ -10,6 +10,8 @@ git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220721130634-3d5460c48ab6 h1:xWv02
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220721130634-3d5460c48ab6/go.mod h1:vkoHSHVM9p6vAUmXAik0gvaLcIfiQYrD6bQqVpOulUk=
git.gammaspectra.live/S.O.N.G/go-tta v0.2.1-0.20220226150007-096de1072bd6 h1:ITVVisbHPnUclp3PBkCbXFeBhOCBcOjPdgjJ9wRH3TI=
git.gammaspectra.live/S.O.N.G/go-tta v0.2.1-0.20220226150007-096de1072bd6/go.mod h1:cobkT8u8vq/+ngLy+feKS2M2ZT2HoCec5riA/0Cex3Q=
git.gammaspectra.live/S.O.N.G/go-vorbis v0.0.0-20220728124510-303b3425eec0 h1:kZA/fy9BhBgNGjY8OlQbIR4xkq9fmIeRQ+sXZ+m9Ic4=
git.gammaspectra.live/S.O.N.G/go-vorbis v0.0.0-20220728124510-303b3425eec0/go.mod h1:EZl7z0vfpaiu0ykpEkk6dh59XxBgWxAh4QPCCnkhICE=
git.gammaspectra.live/S.O.N.G/goflac v0.0.0-20220515172202-6e490998d2a0 h1:imcnwHUqaAJzws41B8sCSp/sUmVranNjAX205Jr4Jc0=
git.gammaspectra.live/S.O.N.G/goflac v0.0.0-20220515172202-6e490998d2a0/go.mod h1:/po1QgOh3xynbvi4sxdY6Iw8m5WPJfGGmry2boZD8fs=
github.com/aam335/aac-go v0.0.0-20200408070016-52c23bd38988 h1:DZeJTINv0mpfBVfDtQz9vWOn/Uwj3IiA9uP5UJnClZE=