//go:build !disable_format_mp3 && !disable_codec_lame // +build !disable_format_mp3,!disable_codec_lame package mp3 import ( "errors" "fmt" "git.gammaspectra.live/S.O.N.G/Kirika/audio" "git.gammaspectra.live/S.O.N.G/Kirika/cgo" "github.com/viert/go-lame" "io" "unsafe" ) func (f Format) Description() string { return "kvark128/minimp3, LAME (viert/go-lame)" } 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 "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.Channels); err != nil { return err } if err := encoder.SetInSamplerate(source.SampleRate); 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.Blocks { samples := cgo.Float32ToInt16(block) _, err := encoder.Write(unsafe.Slice((*byte)(unsafe.Pointer(&samples[0])), len(samples)*2)) if err != nil { return err } } encoder.Flush() return nil }