Sound improvements

This commit is contained in:
Iván Izaguirre 2022-04-18 13:23:04 +02:00
parent 15c38b091d
commit 80977143de
2 changed files with 15 additions and 14 deletions

View File

@ -51,13 +51,14 @@ func (s *sdlSpeaker) Click(cycle uint64) {
case s.clickChannel <- cycle: case s.clickChannel <- cycle:
// Sent // Sent
default: default:
fmt.Printf("Speaker click dropped in channel.\n")
// The channel is full, the click is lost. // The channel is full, the click is lost.
} }
} }
func stateToLevel(state bool) C.Uint8 { func stateToLevel(state bool) C.Uint8 {
if state { if state {
return 255 return 200
} }
return 0 return 0
} }
@ -91,13 +92,14 @@ func SpeakerCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
if pc-s.lastCycle > maxOutOfSyncCycles { if pc-s.lastCycle > maxOutOfSyncCycles {
// Fast forward // Fast forward
s.lastCycle = pc s.lastCycle = pc
fmt.Printf("Speaker fast forward.\n")
} }
} }
// Build wave // Build wave
var i, p int var i, r int
level := s.lastLevel level := s.lastLevel
for p = 0; p < len(s.pendingClicks); p++ { for p := 0; p < len(s.pendingClicks); p++ {
cycle := s.pendingClicks[p] cycle := s.pendingClicks[p]
if cycle < s.lastCycle { if cycle < s.lastCycle {
// Too old, ignore // Too old, ignore
@ -105,20 +107,23 @@ func SpeakerCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
} }
// Fill with samples // Fill with samples
level = stateToLevel(s.lastState)
samplesNeeded := int(float64(cycle-s.lastCycle) / sampleDurationCycles) samplesNeeded := int(float64(cycle-s.lastCycle) / sampleDurationCycles)
if samplesNeeded+i > bufferSize { if samplesNeeded+i > bufferSize {
// Partial fill, to be completed on the next callback
samplesNeeded = bufferSize - i samplesNeeded = bufferSize - i
s.lastCycle = cycle - uint64(float64(samplesNeeded)*sampleDurationCycles)
} else {
s.lastCycle = cycle
s.lastState = !s.lastState
r++ // Remove this pending click
} }
for j := 0; j < samplesNeeded; j++ { for j := 0; j < samplesNeeded; j++ {
buf[i] = level buf[i] = level
i++ i++
} }
// Update state
s.lastCycle = cycle
s.lastState = !s.lastState
level = stateToLevel(s.lastState)
if i == bufferSize { if i == bufferSize {
// Buffer is complete // Buffer is complete
break break
@ -147,11 +152,7 @@ func SpeakerCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
s.lastLevel = level s.lastLevel = level
// Remove processed clicks, store the rest for later // Remove processed clicks, store the rest for later
remainingClicks := len(s.pendingClicks) - p s.pendingClicks = s.pendingClicks[r:]
for r := 0; r < remainingClicks; r++ {
s.pendingClicks[r] = s.pendingClicks[p+r]
}
s.pendingClicks = s.pendingClicks[0:remainingClicks]
} }
func (s *sdlSpeaker) start() { func (s *sdlSpeaker) start() {

View File

@ -32,7 +32,7 @@ func addApple2SoftSwitches(io *ioC0Page) {
io.addSoftSwitchRW(0x00, keySoftSwitch, "KEYBOARD") // Keyboard io.addSoftSwitchRW(0x00, keySoftSwitch, "KEYBOARD") // Keyboard
io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch, "AKD") // Keyboard Strobe io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch, "AKD") // Keyboard Strobe
io.addSoftSwitchR(0x20, notImplementedSoftSwitchR, "TAPEOUT") // Cassette Output io.addSoftSwitchR(0x20, notImplementedSoftSwitchR, "TAPEOUT") // Cassette Output
io.addSoftSwitchR(0x30, speakerSoftSwitch, "SPEAKER") // Speaker io.addSoftSwitchRW(0x30, speakerSoftSwitch, "SPEAKER") // Speaker
io.addSoftSwitchR(0x40, notImplementedSoftSwitchR, "STROBE") // Game connector Strobe io.addSoftSwitchR(0x40, notImplementedSoftSwitchR, "STROBE") // Game connector Strobe
// Note: Some sources indicate that all these cover 16 positions // Note: Some sources indicate that all these cover 16 positions
// for read and write. But the Apple2e takes over some of them, with // for read and write. But the Apple2e takes over some of them, with