Decay beeper level to avoid clicks on startup and shutdown

This commit is contained in:
Ivan Izaguirre 2019-10-19 20:33:50 +02:00
parent b89f88d879
commit f511a9d0e0

View File

@ -21,6 +21,7 @@ const (
sampleDurationCycles = 1000000 * apple2.CpuClockMhz / samplingHz sampleDurationCycles = 1000000 * apple2.CpuClockMhz / samplingHz
// each sample on the sound stream is 21.31 cpu cycles approx // each sample on the sound stream is 21.31 cpu cycles approx
maxOutOfSyncMs = 2000 maxOutOfSyncMs = 2000
decayLevel = 128
) )
type sdlSpeaker struct { type sdlSpeaker struct {
@ -28,6 +29,7 @@ type sdlSpeaker struct {
pendingClicks []uint64 pendingClicks []uint64
lastCycle uint64 lastCycle uint64
lastState bool lastState bool
lastLevel C.Uint8
} }
/* /*
@ -40,6 +42,7 @@ func newSDLSpeaker() *sdlSpeaker {
var s sdlSpeaker var s sdlSpeaker
s.clickChannel = make(chan uint64, bufferSize) s.clickChannel = make(chan uint64, bufferSize)
s.pendingClicks = make([]uint64, 0, bufferSize) s.pendingClicks = make([]uint64, 0, bufferSize)
s.lastLevel = decayLevel // Mid position to avoid starting clicks.
return &s return &s
} }
@ -90,7 +93,7 @@ func SpeakerCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
// Build wave // Build wave
var i, p int var i, p int
level := stateToLevel(s.lastState) 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 {
@ -119,10 +122,26 @@ func SpeakerCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
} }
} }
// If the buffer is empty lets decay the signal
if i == 0 {
for level != decayLevel && i < bufferSize {
if i%100 == 0 {
if level > decayLevel {
level--
} else {
level++
}
}
buf[i] = level
i++
}
}
// Complete the buffer if needed // Complete the buffer if needed
for b := i; b < bufferSize; b++ { for b := i; b < bufferSize; b++ {
buf[b] = level buf[b] = 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 remainingClicks := len(s.pendingClicks) - p