Use native float32 output

This commit is contained in:
DataHoarder 2022-12-01 09:47:34 +01:00
parent 2dbf75f65b
commit 9103da68c3
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk

View file

@ -2,6 +2,7 @@ package minimp3
/*
#define MINIMP3_IMPLEMENTATION
#define MINIMP3_FLOAT_OUTPUT
#include "minimp3.h"
*/
import "C"
@ -17,7 +18,8 @@ const maxSamplesPerFrame = 1152 * 2
// Decoder decode the mp3 stream by minimp3
type Decoder struct {
source io.Reader
mp3, pcm []byte
mp3 []byte
pcm []float32
mp3Length, pcmLength int
lastError error
decode C.mp3dec_t
@ -29,17 +31,17 @@ func NewDecoder(source io.Reader) *Decoder {
d := &Decoder{
source: source,
mp3: make([]byte, 1024*16),
pcm: make([]byte, maxSamplesPerFrame*C.sizeof_short),
pcm: make([]float32, maxSamplesPerFrame),
}
C.mp3dec_init(&d.decode)
return d
}
// Read copies the decoded audio data from the internal buffer to p and returns the number of bytes copied.
// Read copies the decoded audio data from the internal buffer to p and returns the number of items copied.
// If the internal buffer is empty, then Read first tries to read mp3 data from the source and decode it.
// If len(p) == 0, then Read will return zero bytes, but if the internal buffer is empty, then before that it will still try to decode one frame and fill the internal buffer.
func (d *Decoder) Read(p []byte) (int, error) {
func (d *Decoder) Read(p []float32) (int, error) {
for d.pcmLength == 0 {
// If possible, fill the mp3 buffer completely
for d.mp3Length < len(d.mp3) && d.lastError == nil {
@ -58,14 +60,14 @@ func (d *Decoder) Read(p []byte) (int, error) {
}
d.mp3Length = copy(d.mp3, d.mp3[d.info.frame_bytes:d.mp3Length])
d.pcmLength = int(samples * d.info.channels * C.sizeof_short)
d.pcmLength = int(samples * d.info.channels * C.sizeof_float)
}
n := copy(p, d.pcm[:d.pcmLength])
n := copy(p, d.pcm[:d.pcmLength/C.sizeof_float])
// If there is any data left in the pcm buffer, then move it to the beginning of the buffer
copy(d.pcm, d.pcm[n:d.pcmLength])
d.pcmLength -= n
return n, nil
copy(d.pcm, d.pcm[n:d.pcmLength/C.sizeof_float])
d.pcmLength -= n * C.sizeof_float
return n / C.sizeof_float, nil
}
// Seek sets a new position for reading audio data.
@ -80,7 +82,7 @@ func (d *Decoder) Seek(offset int64, whence int) (int64, error) {
}
mp3BytesPerMsec := int64(d.info.bitrate_kbps) / 8
pcmBytesPerMsec := int64(d.info.channels*C.sizeof_short*d.info.hz) / 1000
pcmBytesPerMsec := int64(d.info.channels*C.sizeof_float*d.info.hz) / 1000
if mp3BytesPerMsec == 0 || pcmBytesPerMsec == 0 {
// There is no information about audio data. Probably not a single frame has been decoded yet