3
3
package audio
4
4
5
5
import (
6
+ "encoding/binary"
6
7
"log"
7
8
"path/filepath"
8
9
"time"
9
10
"unsafe"
10
11
12
+ "github.com/gordonklaus/portaudio"
11
13
"github.com/libretro/ludo/settings"
12
14
"github.com/libretro/ludo/state"
13
15
"github.com/libretro/ludo/utils"
14
- "golang.org/x/mobile/exp/audio/al"
16
+ // "golang.org/x/mobile/exp/audio/al"
15
17
)
16
18
17
- const bufSize = 1024 * 8
19
+ const bufSize = 1024 * 4
20
+ const maxSeLen = 44100 * 8
18
21
19
22
var (
20
- source al.Source
21
- buffers []al.Buffer
22
- rate int32
23
- numBuffers int32
24
- tmpBuf [bufSize ]byte
25
- tmpBufPtr int32
26
- resPtr int32
23
+ // source al.Source
24
+ // buffers []al.Buffer
25
+ // rate int32
26
+ // numBuffers int32
27
+ // tmpBuf [bufSize]byte
28
+ // tmpBufPtr int32
29
+ // resPtr int32
30
+ paBuf [bufSize ]int32
31
+ paSeBuf [maxSeLen ]int32
32
+ paRate float64
33
+ paPtr int64
34
+ paPlayPtr int64
35
+ paSePtr int
36
+ paSeLen int
37
+ // paHost *portaudio.HostApiInfo
38
+ paStream * portaudio.Stream
39
+ paSeStream * portaudio.Stream
27
40
)
28
41
29
42
// Effects are sound effects
30
43
var Effects map [string ]* Effect
31
44
32
45
// SetVolume sets the audio volume
33
- func SetVolume (vol float32 ) {
34
- source .SetGain (vol )
46
+ // func SetVolume(vol float32) {
47
+ // source.SetGain(vol)
48
+ // }
49
+
50
+ // PortAudio Callback
51
+ func paCallback (out []int32 ) {
52
+ for i := range out {
53
+ // if paMark[i] {
54
+ // out[i] = paBuf[i]
55
+ // paMark[i] = false
56
+ if paPlayPtr <= paPtr {
57
+ out [i ] = int32 (settings .Current .AudioVolume * float32 (paBuf [paPlayPtr - (paPlayPtr / bufSize )* bufSize ]))
58
+ paPlayPtr ++
59
+ // if paPtr-paPlayPtr > bufSize/4 {
60
+ // fmt.Println((paPtr - paPlayPtr) / (bufSize / 4))
61
+ // }
62
+ // fmt.Println(paStream.Info().SampleRate)
63
+ } else {
64
+ // out[i] = int32(rand.Int31n(100000000))
65
+ out [i ] = 0
66
+ }
67
+
68
+ }
69
+ }
70
+
71
+ // Create PortAudio parameters
72
+ func NewParameters (out * portaudio.DeviceInfo ) (p portaudio.StreamParameters ) {
73
+ if out != nil {
74
+ p := & p .Output
75
+ p .Device = out
76
+ p .Channels = 2
77
+ if out .MaxOutputChannels < 2 {
78
+ p .Channels = out .MaxOutputChannels
79
+ }
80
+ p .Latency = out .DefaultLowOutputLatency
81
+ }
82
+ p .SampleRate = paRate / 2
83
+ p .FramesPerBuffer = portaudio .FramesPerBufferUnspecified
84
+ return p
35
85
}
36
86
37
87
// Init initializes the audio device
38
88
func Init () {
39
- err := al .OpenDevice ()
40
- if err != nil {
41
- log .Println (err )
89
+ // err := al.OpenDevice()
90
+ // if err != nil {
91
+ // log.Println(err)
92
+ // }
93
+
94
+ err1 := portaudio .Initialize ()
95
+ if err1 != nil {
96
+ log .Println (err1 )
42
97
}
43
98
99
+ paRate = 44100
100
+ paPtr = 0
101
+ paPlayPtr = 0
102
+ paSePtr = 0
103
+ paSeLen = 0
104
+
105
+ // paHost, _ := portaudio.DefaultHostApi()
106
+ // h, _ := portaudio.DefaultHostApi()
107
+ h , _ := portaudio .DefaultOutputDevice ()
108
+ // paStream, _ = portaudio.OpenStream(portaudio.LowLatencyParameters(nil, h.DefaultOutputDevice), func(out []int32) {
109
+ // for i := range out {
110
+ // // if paMark[i] {
111
+ // // out[i] = paBuf[i]
112
+ // // paMark[i] = false
113
+ // if paPlayPtr < paPtr {
114
+ // out[i] = int32(settings.Current.AudioVolume * float32(paBuf[paPlayPtr-(paPlayPtr/bufSize)*bufSize]))
115
+ // paPlayPtr++
116
+ // } else {
117
+ // out[i] = int32(rand.Int31n(100000000))
118
+ // // out[i] = 0
119
+ // }
120
+
121
+ // }
122
+ // })
123
+ // paStream, _ = portaudio.OpenStream(portaudio.LowLatencyParameters(nil, h.DefaultOutputDevice), paCallback)
124
+ // paStream, _ = portaudio.OpenStream(NewParameters(paHost.DefaultOutputDevice), paCallback)
125
+ paStream , _ = portaudio .OpenStream (NewParameters (h ), paCallback )
126
+ paStream .Start ()
127
+ // fmt.Println(portaudio.LowLatencyParameters(nil, h.DefaultOutputDevice).FramesPerBuffer)
128
+
129
+ paSeStream , _ = portaudio .OpenStream (NewParameters (h ), func (out []int32 ) {
130
+ for i := range out {
131
+ if paSePtr < paSeLen {
132
+ out [i ] = int32 (settings .Current .MenuAudioVolume * float32 (paSeBuf [paSePtr ]))
133
+ paSePtr ++
134
+ } else {
135
+ out [i ] = 0
136
+ }
137
+
138
+ }
139
+ })
140
+ paSeStream .Start ()
44
141
Effects = map [string ]* Effect {}
45
142
46
143
assets := settings .Current .AssetsDirectory
@@ -55,18 +152,28 @@ func Init() {
55
152
// Reconfigure initializes the audio package. It sets the number of buffers, the
56
153
// volume and the source for the games.
57
154
func Reconfigure (r int32 ) {
58
- rate = r
59
- numBuffers = 4
60
-
61
- log .Printf ("[OpenAL]: Using %v buffers of %v bytes.\n " , numBuffers , bufSize )
62
-
63
- source = al .GenSources (1 )[0 ]
64
- buffers = al .GenBuffers (int (numBuffers ))
65
- resPtr = numBuffers
66
- tmpBufPtr = 0
67
- tmpBuf = [bufSize ]byte {}
68
-
69
- source .SetGain (settings .Current .AudioVolume )
155
+ // rate = r
156
+ // numBuffers = 4
157
+
158
+ // log.Printf("[OpenAL]: Using %v buffers of %v bytes.\n", numBuffers, bufSize)
159
+
160
+ // source = al.GenSources(1)[0]
161
+ // buffers = al.GenBuffers(int(numBuffers))
162
+ // resPtr = numBuffers
163
+ // tmpBufPtr = 0
164
+ // tmpBuf = [bufSize]byte{}
165
+
166
+ // source.SetGain(settings.Current.AudioVolume)
167
+
168
+ paRate = float64 (r )
169
+ paBuf = [bufSize ]int32 {}
170
+ paPtr = 0
171
+ paPlayPtr = 0
172
+ paStream .Close ()
173
+ h , _ := portaudio .DefaultOutputDevice ()
174
+ // paStream, _ = portaudio.OpenStream(NewParameters(paHost.DefaultOutputDevice), paCallback)
175
+ paStream , _ = portaudio .OpenStream (NewParameters (h ), paCallback )
176
+ paStream .Start ()
70
177
}
71
178
72
179
func min (a , b int32 ) int32 {
@@ -76,38 +183,38 @@ func min(a, b int32) int32 {
76
183
return b
77
184
}
78
185
79
- func alUnqueueBuffers () bool {
80
- val := source .BuffersProcessed ()
81
-
82
- if val <= 0 {
83
- return false
84
- }
85
-
86
- source .UnqueueBuffers (buffers [resPtr :val ]... )
87
- resPtr += val
88
- return true
89
- }
90
-
91
- func alGetBuffer () al.Buffer {
92
- if resPtr == 0 {
93
- for {
94
- if alUnqueueBuffers () {
95
- break
96
- }
97
- time .Sleep (time .Millisecond )
98
- }
99
- }
100
-
101
- resPtr --
102
- return buffers [resPtr ]
103
- }
104
-
105
- func fillInternalBuf (buf []byte ) int32 {
106
- readSize := min (bufSize - tmpBufPtr , int32 (len (buf )))
107
- copy (tmpBuf [tmpBufPtr :], buf [:readSize ])
108
- tmpBufPtr += readSize
109
- return readSize
110
- }
186
+ // func alUnqueueBuffers() bool {
187
+ // val := source.BuffersProcessed()
188
+
189
+ // if val <= 0 {
190
+ // return false
191
+ // }
192
+
193
+ // source.UnqueueBuffers(buffers[resPtr:val]...)
194
+ // resPtr += val
195
+ // return true
196
+ // }
197
+
198
+ // func alGetBuffer() al.Buffer {
199
+ // if resPtr == 0 {
200
+ // for {
201
+ // if alUnqueueBuffers() {
202
+ // break
203
+ // }
204
+ // time.Sleep(time.Millisecond)
205
+ // }
206
+ // }
207
+
208
+ // resPtr--
209
+ // return buffers[resPtr]
210
+ // }
211
+
212
+ // func fillInternalBuf(buf []byte) int32 {
213
+ // readSize := min(bufSize-tmpBufPtr, int32(len(buf)))
214
+ // copy(tmpBuf[tmpBufPtr:], buf[:readSize])
215
+ // tmpBufPtr += readSize
216
+ // return readSize
217
+ // }
111
218
112
219
func write (buf []byte , size int32 ) int32 {
113
220
written := int32 (0 )
@@ -116,27 +223,37 @@ func write(buf []byte, size int32) int32 {
116
223
return size
117
224
}
118
225
119
- for size > 0 {
226
+ time . Sleep ( time . Millisecond * time . Duration (( paPtr - paPlayPtr ) / ( bufSize / 4 ) * 8 ))
120
227
121
- rc := fillInternalBuf (buf [written :])
228
+ mm := int (min (size / 4 , bufSize ))
229
+ for i := 0 ; i < mm ; i ++ {
230
+ p := 4 * (int32 (i ))
231
+ paBuf [paPtr - (paPtr / bufSize )* bufSize ] = int32 (binary .LittleEndian .Uint32 (buf [p : p + 4 ]))
232
+ paPtr ++
233
+ written += 4
234
+ }
122
235
123
- written += rc
124
- size -= rc
236
+ // for size > 0 {
125
237
126
- if tmpBufPtr != bufSize {
127
- break
128
- }
238
+ // rc := fillInternalBuf(buf[written:])
129
239
130
- buffer := alGetBuffer ()
240
+ // written += rc
241
+ // size -= rc
131
242
132
- buffer . BufferData ( al . FormatStereo16 , tmpBuf [:], rate )
133
- tmpBufPtr = 0
134
- source . QueueBuffers ( buffer )
243
+ // if tmpBufPtr != bufSize {
244
+ // break
245
+ // }
135
246
136
- if source .State () != al .Playing {
137
- al .PlaySources (source )
138
- }
139
- }
247
+ // buffer := alGetBuffer()
248
+
249
+ // buffer.BufferData(al.FormatStereo16, tmpBuf[:], rate)
250
+ // tmpBufPtr = 0
251
+ // source.QueueBuffers(buffer)
252
+
253
+ // if source.State() != al.Playing {
254
+ // al.PlaySources(source)
255
+ // }
256
+ // }
140
257
141
258
return written
142
259
}
0 commit comments