OnlineLibrary

Форк
0
120 строк · 3.8 Кб
1
package minimp3
2

3
//#define MINIMP3_IMPLEMENTATION
4
//#include <minimp3.h>
5
import "C"
6

7
import (
8
	"errors"
9
	"io"
10
	"unsafe"
11
)
12

13
const maxSamplesPerFrame = 1152 * 2
14

15
// Decoder decode the mp3 stream by minimp3
16
type Decoder struct {
17
	src                  io.ReadSeeker
18
	mp3, pcm             []byte
19
	mp3Length, pcmLength int
20
	lastError            error
21
	decode               C.mp3dec_t
22
	info                 C.mp3dec_frame_info_t
23
}
24

25
// NewDecoder creates and returns a new mp3 decoder with the default internal buffer size.
26
func NewDecoder(src io.ReadSeeker) *Decoder {
27
	d := &Decoder{
28
		src: src,
29
		mp3: make([]byte, 1024*16),
30
		pcm: make([]byte, maxSamplesPerFrame*C.sizeof_mp3d_sample_t),
31
	}
32

33
	C.mp3dec_init(&d.decode)
34
	return d
35
}
36

37
// Read copies the decoded audio data from the internal buffer to p and returns the number of bytes copied.
38
// If the internal buffer is empty, then Read first tries to read mp3 data from the source and decode it.
39
// 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.
40
func (d *Decoder) Read(p []byte) (int, error) {
41
	for d.pcmLength == 0 {
42
		// If possible, fill the mp3 buffer completely
43
		for d.mp3Length < len(d.mp3) && d.lastError == nil {
44
			n, err := d.src.Read(d.mp3[d.mp3Length:])
45
			d.mp3Length += n
46
			d.lastError = err
47
		}
48

49
		samples := C.mp3dec_decode_frame(&d.decode,
50
			(*C.uint8_t)(unsafe.SliceData(d.mp3)), C.int(d.mp3Length),
51
			(*C.mp3d_sample_t)(unsafe.Pointer(&d.pcm[0])), &d.info)
52

53
		if d.info.frame_bytes == 0 {
54
			return 0, d.lastError
55
		}
56

57
		d.mp3Length = copy(d.mp3, d.mp3[d.info.frame_bytes:d.mp3Length])
58
		d.pcmLength = int(samples * d.info.channels * C.sizeof_mp3d_sample_t)
59
	}
60

61
	n := copy(p, d.pcm[:d.pcmLength])
62
	// If there is any data left in the pcm buffer, then move it to the beginning of the buffer
63
	copy(d.pcm, d.pcm[n:d.pcmLength])
64
	d.pcmLength -= n
65
	return n, nil
66
}
67

68
// Seek sets a new position for reading audio data.
69
// At least one decoded frame is required to set a new position.
70
// If there are no decoded frames, then Seek will return an error.
71
func (d *Decoder) Seek(offset int64, whence int) (int64, error) {
72
	mp3BytesPerMsec := int64(d.info.bitrate_kbps) / 8
73
	pcmBytesPerMsec := int64(d.info.channels*C.sizeof_mp3d_sample_t*d.info.hz) / 1000
74

75
	if mp3BytesPerMsec == 0 || pcmBytesPerMsec == 0 {
76
		// There is no information about audio data. Probably not a single frame has been decoded yet
77
		return 0, errors.New("no frame available")
78
	}
79

80
	var mp3Offset int64
81
	if whence == io.SeekCurrent {
82
		// If seeking is performed from the current position, then be aware of buffered audio data
83
		offset -= int64(d.pcmLength)
84
		mp3Offset = offset / pcmBytesPerMsec * mp3BytesPerMsec
85
		mp3Offset -= int64(d.mp3Length)
86
	} else {
87
		// If seeking is performed from the beginning or the end, then the buffered data does not matter
88
		mp3Offset = offset / pcmBytesPerMsec * mp3BytesPerMsec
89
	}
90

91
	// Internal buffers must always be cleared, regardless of the result of calling the Seek method
92
	d.mp3Length = 0
93
	d.pcmLength = 0
94

95
	mp3Pos, err := d.src.Seek(mp3Offset, whence)
96
	if err != nil {
97
		return 0, err
98
	}
99

100
	pcmPos := mp3Pos / mp3BytesPerMsec * pcmBytesPerMsec
101
	return pcmPos, nil
102
}
103

104
// SampleRate returns the sample rate of the last decoded frame.
105
// If no frames have been decoded yet, then it will return 0.
106
func (d *Decoder) SampleRate() int {
107
	return int(d.info.hz)
108
}
109

110
// Channels returns the number of channels of the last decoded frame.
111
// If no frames have been decoded yet, then it will return 0.
112
func (d *Decoder) Channels() int {
113
	return int(d.info.channels)
114
}
115

116
// Bitrate returns the mp3 bitrate of the last decoded frame.
117
// If no frames have been decoded yet, then it will return 0.
118
func (d *Decoder) Bitrate() int {
119
	return int(d.info.bitrate_kbps)
120
}
121

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.