Skip to content

Commit

Permalink
Refactor sound ticking to have a tick method
Browse files Browse the repository at this point in the history
  • Loading branch information
Baekalfen committed Sep 18, 2024
1 parent 4937d52 commit 3f5d0c4
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
10 changes: 4 additions & 6 deletions pyboy/core/mb.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ def tick(self):
min(
self.timer._cycles_to_interrupt,
self.lcd._cycles_to_interrupt,
self.sound._cycles_to_interrupt, # TODO: Not implemented
# self.serial.cycles_to_interrupt(),
mode0_cycles
)
Expand All @@ -308,12 +309,7 @@ def tick(self):
#TODO: Support General Purpose DMA
# https://gbdev.io/pandocs/CGB_Registers.html#bit-7--0---general-purpose-dma

# TODO: Unify interface
sclock = self.sound.clock
if self.cgb and self.double_speed:
self.sound.clock = sclock + cycles//2
else:
self.sound.clock = sclock + cycles
self.sound.tick(self.cpu._cycles, self.double_speed)

if self.timer.tick(self.cpu._cycles):
self.cpu.set_interruptflag(INTR_TIMER)
Expand Down Expand Up @@ -377,6 +373,7 @@ def getitem(self, i):
elif i == 0xFF0F:
return self.cpu.interrupts_flag_register
elif 0xFF10 <= i < 0xFF40:
self.sound.tick(self.cpu._cycles, self.double_speed)
return self.sound.get(i - 0xFF10)
elif i == 0xFF40:
return self.lcd.get_lcdc()
Expand Down Expand Up @@ -502,6 +499,7 @@ def setitem(self, i, value):
elif i == 0xFF0F:
self.cpu.interrupts_flag_register = value
elif 0xFF10 <= i < 0xFF40:
self.sound.tick(self.cpu._cycles, self.double_speed)
self.sound.set(i - 0xFF10, value)
elif i == 0xFF40:
self.lcd.set_lcdc(value)
Expand Down
5 changes: 4 additions & 1 deletion pyboy/core/sound.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#

cimport cython
from libc.stdint cimport uint8_t, uint16_t, uint64_t
from libc.stdint cimport int64_t, uint8_t, uint16_t, uint64_t

from pyboy.logging.logging cimport Logger
from pyboy.utils cimport IntIOInterface
Expand All @@ -28,6 +28,8 @@ cdef class Sound:
cdef object audiobuffer
cdef object audiobuffer_p

cdef uint64_t last_cycles
cdef int64_t _cycles_to_interrupt
cdef int clock

cdef bint poweron
Expand All @@ -42,6 +44,7 @@ cdef class Sound:
cdef uint8_t get(self, uint8_t) noexcept nogil
cdef void set(self, uint8_t, uint8_t) noexcept nogil

cdef void tick(self, int64_t, bint) noexcept nogil
@cython.locals(nsamples=int, sample=int, i=int)
cdef void sync(self) noexcept with gil # TODO: nogil
@cython.locals(queued_time=int, samples_per_frame=int)
Expand Down
11 changes: 11 additions & 0 deletions pyboy/core/sound.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def __init__(self, enabled, emulate):
self.audiobuffer = array("b", [0] * 4096) # Over 2 frames
self.audiobuffer_p = c_void_p(self.audiobuffer.buffer_info()[0])

self.last_cycles = 0
self._cycles_to_interrupt = 1 << 16
self.clock = 0

self.poweron = True
Expand Down Expand Up @@ -150,6 +152,15 @@ def set(self, offset, value):
else:
raise IndexError(f"Attempted to write register {offset} in sound memory")

def tick(self, _cycles, double_speed):
cycles = _cycles - self.last_cycles
self.last_cycles = _cycles

if double_speed:
self.clock += cycles // 2
else:
self.clock += cycles

def sync(self):
"""Run the audio for the number of clock cycles stored in self.clock"""
if not self.emulate:
Expand Down

0 comments on commit 3f5d0c4

Please sign in to comment.