@@ -128,17 +128,25 @@ Bit0 Sound 1 on[1]/off[0] |
| 128 |
|
128 |
|
| 129 |
*) |
129 |
*) |
| 130 |
|
130 |
|
| 131 |
uses Classes; |
131 |
uses Classes, sdl2; |
| 132 |
|
132 |
|
| 133 |
const |
133 |
const |
| 134 |
SAMPLE_BUFFER_SIZE = 1024; |
134 |
SAMPLE_BUFFER_SIZE = 1024; |
| 135 |
|
135 |
|
| 136 |
type |
136 |
type |
|
|
137 |
PSingle = ^Single; |
| 137 |
TSampleBuffer = record |
138 |
TSampleBuffer = record |
| 138 |
BufferL, BufferR: array[0..SAMPLE_BUFFER_SIZE] of Integer; |
139 |
BufferL, BufferR: array[0..SAMPLE_BUFFER_SIZE] of Integer; |
| 139 |
Cursor: Integer; |
140 |
Cursor: Integer; |
| 140 |
end; |
141 |
end; |
| 141 |
|
142 |
|
|
|
143 |
procedure StartPlayback; |
|
|
144 |
procedure StopPlayback; |
|
|
145 |
procedure LockPlayback; |
|
|
146 |
procedure UnlockPlayback; |
|
|
147 |
|
|
|
148 |
procedure AudioCallback(userdata: Pointer; stream: PUInt8; len: Integer) cdecl; |
|
|
149 |
|
| 142 |
procedure EnableSound; |
150 |
procedure EnableSound; |
| 143 |
procedure DisableSound; |
151 |
procedure DisableSound; |
| 144 |
procedure ResetSound; |
152 |
procedure ResetSound; |
@@ -153,6 +161,8 @@ procedure EndWritingSoundToStream; |
| 153 |
var |
161 |
var |
| 154 |
soundEnable: boolean; |
162 |
soundEnable: boolean; |
| 155 |
sndRegChange: boolean; |
163 |
sndRegChange: boolean; |
|
|
164 |
sndBuffer: ^Single; |
|
|
165 |
sndBytesWritten: Integer; |
| 156 |
snd: array[1..4] of record |
166 |
snd: array[1..4] of record |
| 157 |
// public: |
167 |
// public: |
| 158 |
ChannelOFF: boolean; // (un)mute Channel |
168 |
ChannelOFF: boolean; // (un)mute Channel |
@@ -170,7 +180,7 @@ var |
| 170 |
|
180 |
|
| 171 |
implementation |
181 |
implementation |
| 172 |
|
182 |
|
| 173 |
uses vars, sdl2, htWaveWriter; |
183 |
uses mainloop, vars, htWaveWriter; |
| 174 |
|
184 |
|
| 175 |
const |
185 |
const |
| 176 |
SampleSize = SizeOf(Single)*2; |
186 |
SampleSize = SizeOf(Single)*2; |
@@ -179,7 +189,7 @@ const |
| 179 |
TooFullThreshold: Integer = (playbackFrequency div 10)*sizeof(single); //0.1s |
189 |
TooFullThreshold: Integer = (playbackFrequency div 10)*sizeof(single); //0.1s |
| 180 |
|
190 |
|
| 181 |
var |
191 |
var |
| 182 |
playStream: TSDL_AudioDeviceID; |
192 |
PlayStream: TSDL_AudioDeviceID; |
| 183 |
bufCycles, bufLVal, bufRVal: integer; |
193 |
bufCycles, bufLVal, bufRVal: integer; |
| 184 |
lfsr: Cardinal = 0; |
194 |
lfsr: Cardinal = 0; |
| 185 |
|
195 |
|
@@ -212,7 +222,7 @@ end; |
| 212 |
|
222 |
|
| 213 |
function SoundBufferSize: Integer; |
223 |
function SoundBufferSize: Integer; |
| 214 |
begin |
224 |
begin |
| 215 |
Result := SDL_GetQueuedAudioSize(playStream) |
225 |
Result := SDL_GetQueuedAudioSize(PlayStream) |
| 216 |
end; |
226 |
end; |
| 217 |
|
227 |
|
| 218 |
procedure BeginWritingSoundToStream(Stream: TStream); |
228 |
procedure BeginWritingSoundToStream(Stream: TStream); |
@@ -234,6 +244,34 @@ begin |
| 234 |
WaveWriter.Free; |
244 |
WaveWriter.Free; |
| 235 |
end; |
245 |
end; |
| 236 |
|
246 |
|
|
|
247 |
procedure StartPlayback; |
|
|
248 |
begin |
|
|
249 |
SDL_PauseAudioDevice(PlayStream, 0); |
|
|
250 |
end; |
|
|
251 |
|
|
|
252 |
procedure StopPlayback; |
|
|
253 |
begin |
|
|
254 |
SDL_PauseAudioDevice(PlayStream, 1); |
|
|
255 |
end; |
|
|
256 |
|
|
|
257 |
procedure LockPlayback; |
|
|
258 |
begin |
|
|
259 |
SDL_LockAudioDevice(PlayStream); |
|
|
260 |
end; |
|
|
261 |
|
|
|
262 |
procedure UnlockPlayback; |
|
|
263 |
begin |
|
|
264 |
SDL_UnlockAudioDevice(PlayStream); |
|
|
265 |
end; |
|
|
266 |
|
|
|
267 |
procedure AudioCallback(userdata: Pointer; stream: PUInt8; len: Integer)cdecl; |
|
|
268 |
begin |
|
|
269 |
sndBuffer := PSingle(Stream); |
|
|
270 |
while sndBytesWritten < len do |
|
|
271 |
z80_decode; |
|
|
272 |
sndBytesWritten := 0; |
|
|
273 |
end; |
|
|
274 |
|
| 237 |
procedure EnableSound; |
275 |
procedure EnableSound; |
| 238 |
var |
276 |
var |
| 239 |
Want, Have: TSDL_AudioSpec; |
277 |
Want, Have: TSDL_AudioSpec; |
@@ -249,11 +287,10 @@ begin |
| 249 |
Want.freq := playbackFrequency; |
287 |
Want.freq := playbackFrequency; |
| 250 |
Want.format := AUDIO_F32; |
288 |
Want.format := AUDIO_F32; |
| 251 |
Want.channels := 2; |
289 |
Want.channels := 2; |
| 252 |
Want.samples := 512; //???? |
290 |
Want.samples := 1024; //512; |
| 253 |
Want.callback := nil; |
291 |
Want.callback := @AudioCallback; |
| 254 |
|
292 |
|
| 255 |
PlayStream := SDL_OpenAudioDevice(nil, 0, @Want, @Have, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); |
293 |
PlayStream := SDL_OpenAudioDevice(nil, 0, @Want, @Have, 0); |
| 256 |
SDL_PauseAudioDevice(playStream, 0); |
|
|
| 257 |
|
294 |
|
| 258 |
soundEnable := True; |
295 |
soundEnable := True; |
| 259 |
bufCycles := 0; |
296 |
bufCycles := 0; |
@@ -266,7 +303,7 @@ begin |
| 266 |
if not soundEnable then |
303 |
if not soundEnable then |
| 267 |
exit; |
304 |
exit; |
| 268 |
|
305 |
|
| 269 |
SDL_CloseAudioDevice(playStream); |
306 |
SDL_CloseAudioDevice(PlayStream); |
| 270 |
SDL_Quit; |
307 |
SDL_Quit; |
| 271 |
|
308 |
|
| 272 |
soundEnable := False; |
309 |
soundEnable := False; |
@@ -293,8 +330,14 @@ begin |
| 293 |
buf2[1] := Trunc(buf[1]*High(Smallint)); |
330 |
buf2[1] := Trunc(buf[1]*High(Smallint)); |
| 294 |
WaveWriter.WriteBuf(buf2, SizeOf(Smallint)*2); |
331 |
WaveWriter.WriteBuf(buf2, SizeOf(Smallint)*2); |
| 295 |
end |
332 |
end |
| 296 |
else |
333 |
else begin |
| 297 |
SDL_QueueAudio(playStream, @buf, SampleSize); |
334 |
sndBuffer^ := buf[0]; |
|
|
335 |
Inc(sndBuffer); |
|
|
336 |
sndBuffer^ := buf[1]; |
|
|
337 |
Inc(sndBuffer); |
|
|
338 |
Inc(sndBytesWritten, SampleSize); |
|
|
339 |
//SDL_QueueAudio(PlayStream, @buf, SampleSize); |
|
|
340 |
end; |
| 298 |
end; |
341 |
end; |
| 299 |
end; |
342 |
end; |
| 300 |
|
343 |
|