Kirika/audio/format/mp3/mp3_lame.go
DataHoarder 514a88aec1
Some checks failed
continuous-integration/drone/push Build is failing
Update to Go 1.20
2023-04-09 13:10:30 +02:00

137 lines
2.6 KiB
Go

//go:build !disable_format_mp3 && !disable_codec_lame && cgo
package mp3
/*
#cgo LDFLAGS: -lmp3lame
#include <lame/lame.h>
*/
import "C"
import (
"errors"
"fmt"
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
"github.com/viert/go-lame"
"io"
"runtime"
"unsafe"
)
func (f Format) EncoderDescription() string {
//TODO: move version fetch to viert/go-lame
return fmt.Sprintf("LAME %s (viert/go-lame)", C.GoString(C.get_lame_version()))
}
func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[string]interface{}) error {
var vbr = true
var bitrate = 0
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 "v0":
vbr = true
bitrate = 0
case "v1":
vbr = true
bitrate = 1
case "v2":
vbr = true
bitrate = 2
case "v3":
vbr = true
bitrate = 3
case "v4":
vbr = true
bitrate = 4
case "v5":
vbr = true
bitrate = 5
case "v6":
vbr = true
bitrate = 6
case "v7":
vbr = true
bitrate = 7
case "v8":
vbr = true
bitrate = 8
case "v9":
vbr = true
bitrate = 9
case "320k":
vbr = false
bitrate = 320
case "256k":
vbr = false
bitrate = 256
case "192k":
vbr = false
bitrate = 192
case "128k":
vbr = false
bitrate = 128
default:
return fmt.Errorf("unknown setting bitrate=%s", strVal)
}
} else if intVal, ok = val.(int); ok {
vbr = false
bitrate = intVal
} else if int64Val, ok = val.(int64); ok {
vbr = false
bitrate = int(int64Val)
}
}
}
encoder := lame.NewEncoder(writer)
if encoder == nil {
return errors.New("could not create encoder")
}
defer encoder.Close()
if err := encoder.SetNumChannels(source.GetChannels()); err != nil {
return err
}
if err := encoder.SetInSamplerate(source.GetSampleRate()); err != nil {
return err
}
encoder.SetWriteID3TagAutomatic(false)
if vbr {
if err := encoder.SetVBR(lame.VBRDefault); err != nil {
return err
}
if err := encoder.SetVBRQuality(float64(bitrate)); err != nil {
return err
}
} else {
if err := encoder.SetVBR(lame.VBROff); err != nil {
return err
}
if err := encoder.SetBrate(bitrate); err != nil {
return err
}
}
for block := range source.ToInt16().GetBlocks() {
_, err := encoder.Write(unsafe.Slice((*byte)(unsafe.Pointer(unsafe.SliceData(block))), len(block)*2))
runtime.KeepAlive(block)
if err != nil {
return err
}
}
encoder.Flush()
return nil
}