59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package mp3
|
|
|
|
/*
|
|
#cgo CFLAGS: -I"${SRCDIR}/../../../cgo" -march=native -Ofast -std=c99
|
|
#include "audio.h"
|
|
*/
|
|
import "C"
|
|
import (
|
|
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
|
|
mp3Lib "github.com/kvark128/minimp3"
|
|
"io"
|
|
"unsafe"
|
|
)
|
|
|
|
type Format struct {
|
|
}
|
|
|
|
func NewFormat() Format {
|
|
return Format{}
|
|
}
|
|
|
|
func (f Format) Open(r io.ReadSeekCloser, blockSize int) (*audio.Stream, error) {
|
|
decoder := mp3Lib.NewDecoder(r)
|
|
|
|
_, err := decoder.Read([]byte{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
newChannel := make(chan []float32)
|
|
|
|
go func() {
|
|
defer close(newChannel)
|
|
samples := make([]int16, blockSize*2)
|
|
const SizeofInt16 = int(unsafe.Sizeof(int16(0)))
|
|
byteSlice := unsafe.Slice((*byte)(unsafe.Pointer(&samples[0])), len(samples)*SizeofInt16)
|
|
for {
|
|
n, err := decoder.Read(byteSlice)
|
|
if err != nil {
|
|
return
|
|
}
|
|
n /= SizeofInt16
|
|
|
|
buf := make([]float32, n)
|
|
|
|
//convert 16-bit to f32 samples
|
|
C.audio_int16_to_float32((*C.int16_t)(&samples[0]), C.size_t(n), (*C.float)(&buf[0]), C.int(16))
|
|
|
|
newChannel <- buf
|
|
}
|
|
}()
|
|
|
|
return audio.NewStream(newChannel, decoder.Channels(), float64(decoder.SampleRate()), blockSize), nil
|
|
}
|
|
|
|
func (f Format) Identify(peek []byte, extension string) bool {
|
|
return /*bytes.Compare(peek[:4], []byte{'f', 'L', 'a', 'C'}) == 0 || */ extension == "mp3"
|
|
}
|