OnlineLibrary
124 строки · 2.6 Кб
1package sonic
2
3//#include <sonic.h>
4import "C"
5
6import (
7"errors"
8"io"
9"runtime"
10"unsafe"
11)
12
13type Stream struct {
14sampleSize int
15stream C.sonicStream
16}
17
18func NewStream(sampleRate, numChannels int) *Stream {
19sonicStream := C.sonicCreateStream(C.int(sampleRate), C.int(numChannels))
20if sonicStream == nil {
21panic("sonicCreateStream returned NULL")
22}
23
24s := &Stream{
25sampleSize: numChannels * C.sizeof_short,
26stream: sonicStream,
27}
28
29runtime.SetFinalizer(s, func(s *Stream) { C.sonicDestroyStream(s.stream) })
30return s
31}
32
33func (s *Stream) Write(data []byte) (int, error) {
34nSamples := len(data) / s.sampleSize
35if nSamples == 0 {
36return 0, nil
37}
38ok := C.sonicWriteShortToStream(s.stream, (*C.short)(unsafe.Pointer(&data[0])), C.int(nSamples))
39if ok == 0 {
40return 0, errors.New("memory realloc failed")
41}
42return nSamples * s.sampleSize, nil
43}
44
45func (s *Stream) Read(data []byte) (int, error) {
46nSamples := len(data) / s.sampleSize
47if nSamples == 0 {
48return 0, io.ErrShortBuffer
49}
50readSamples := C.sonicReadShortFromStream(s.stream, (*C.short)(unsafe.Pointer(&data[0])), C.int(nSamples))
51if readSamples == 0 {
52return 0, io.EOF
53}
54return int(readSamples) * s.sampleSize, nil
55}
56
57func (s *Stream) SamplesAvailable() int {
58nSamples := C.sonicSamplesAvailable(s.stream)
59return int(nSamples)
60}
61
62func (s *Stream) Speed() float64 {
63speed := C.sonicGetSpeed(s.stream)
64return float64(speed)
65}
66
67func (s *Stream) SetSpeed(speed float64) {
68C.sonicSetSpeed(s.stream, C.float(speed))
69}
70
71func (s *Stream) Pitch() float64 {
72pitch := C.sonicGetPitch(s.stream)
73return float64(pitch)
74}
75
76func (s *Stream) SetPitch(pitch float64) {
77C.sonicSetPitch(s.stream, C.float(pitch))
78}
79
80func (s *Stream) Rate() float64 {
81rate := C.sonicGetRate(s.stream)
82return float64(rate)
83}
84
85func (s *Stream) SetRate(rate float64) {
86C.sonicSetRate(s.stream, C.float(rate))
87}
88
89func (s *Stream) Volume() float64 {
90volume := C.sonicGetVolume(s.stream)
91return float64(volume)
92}
93
94func (s *Stream) SetVolume(volume float64) {
95C.sonicSetVolume(s.stream, C.float(volume))
96}
97
98func (s *Stream) NumChannels() int {
99numChannels := C.sonicGetNumChannels(s.stream)
100return int(numChannels)
101}
102
103func (s *Stream) SetNumChannels(numChannels int) {
104C.sonicSetNumChannels(s.stream, C.int(numChannels))
105}
106
107func (s *Stream) ChordPitch() bool {
108if C.sonicGetChordPitch(s.stream) == 0 {
109return false
110}
111return true
112}
113
114func (s *Stream) SetChordPitch(useChordPitch bool) {
115if useChordPitch {
116C.sonicSetChordPitch(s.stream, C.int(1))
117} else {
118C.sonicSetChordPitch(s.stream, C.int(0))
119}
120}
121
122func (s *Stream) Flush() int {
123return int(C.sonicFlushStream(s.stream))
124}
125