mirror of
https://github.com/KrisKennaway/ii-vision.git
synced 2025-01-02 20:29:38 +00:00
Merge branch 'dhgr' of https://github.com/KrisKennaway/ii-vision into dhgr
This commit is contained in:
commit
e3cb6fe7d1
@ -15,11 +15,14 @@ class Audio:
|
|||||||
# TODO: take into account that the available range is slightly offset
|
# TODO: take into account that the available range is slightly offset
|
||||||
# as fraction of total cycle count?
|
# as fraction of total cycle count?
|
||||||
self._tick_range = [4, 66]
|
self._tick_range = [4, 66]
|
||||||
self.cycles_per_tick = 73 # type: int
|
|
||||||
|
|
||||||
# TODO: round to divisor of video frame rate
|
# At 73 cycles/tick, true audio playback sample rate is
|
||||||
self.sample_rate = 14340 # int(1024. * 1024 /
|
# roughly 1024*1024/73 = 14364 Hz (ignoring ACK slow path).
|
||||||
# self.cycles_per_tick)
|
# Typical audio encoding is 44100Hz which is close to 14700*3
|
||||||
|
# Downscaling by 3x gives better results than trying to resample
|
||||||
|
# to a non-divisor. So we cheat a bit and play back the video a tiny
|
||||||
|
# bit (<2%) faster.
|
||||||
|
self.sample_rate = 14700. # type: float
|
||||||
|
|
||||||
self.normalization = (
|
self.normalization = (
|
||||||
normalization or self._normalization()) # type: float
|
normalization or self._normalization()) # type: float
|
||||||
|
@ -7,35 +7,18 @@ import numpy as np
|
|||||||
import screen
|
import screen
|
||||||
|
|
||||||
|
|
||||||
class CycleCounter:
|
|
||||||
"""Counts clock cycles."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.cycles = 0 # type:int
|
|
||||||
|
|
||||||
def tick(self, cycles: int) -> None:
|
|
||||||
"""Advance cycle counter by some number of clock ticks.
|
|
||||||
|
|
||||||
:param cycles: How many clock cycles to advance
|
|
||||||
"""
|
|
||||||
self.cycles += cycles
|
|
||||||
|
|
||||||
def reset(self) -> None:
|
|
||||||
"""Reset cycle counter to 0."""
|
|
||||||
|
|
||||||
self.cycles = 0
|
|
||||||
|
|
||||||
|
|
||||||
class Machine:
|
class Machine:
|
||||||
"""Represents Apple II and player virtual machine state."""
|
"""Represents Apple II and player virtual machine state."""
|
||||||
|
|
||||||
def __init__(self, cycle_counter: CycleCounter,
|
def __init__(
|
||||||
memmap: screen.MemoryMap, update_priority: np.array):
|
self,
|
||||||
|
memmap: screen.MemoryMap,
|
||||||
|
update_priority: np.array
|
||||||
|
):
|
||||||
self.page = 0x20 # type: int
|
self.page = 0x20 # type: int
|
||||||
self.content = 0x7f # type: int
|
self.content = 0x7f # type: int
|
||||||
|
|
||||||
self.memmap = memmap # type: screen.MemoryMap
|
self.memmap = memmap # type: screen.MemoryMap
|
||||||
self.cycle_counter = cycle_counter # type: CycleCounter
|
|
||||||
self.update_priority = update_priority # type: np.array
|
self.update_priority = update_priority # type: np.array
|
||||||
|
|
||||||
def emit(self, opcode: "Opcode") -> Iterator[int]:
|
def emit(self, opcode: "Opcode") -> Iterator[int]:
|
||||||
|
@ -33,19 +33,16 @@ class Movie:
|
|||||||
filename, mode=video_mode, palette=self.palette)
|
filename, mode=video_mode, palette=self.palette)
|
||||||
self.video = video.Video(
|
self.video = video.Video(
|
||||||
self.frame_grabber,
|
self.frame_grabber,
|
||||||
|
ticks_per_second=self.audio.sample_rate,
|
||||||
mode=video_mode,
|
mode=video_mode,
|
||||||
palette=self.palette
|
palette=self.palette
|
||||||
) # type: video.Video
|
) # type: video.Video
|
||||||
|
|
||||||
self.stream_pos = 0 # type: int
|
self.stream_pos = 0 # type: int
|
||||||
|
|
||||||
# TODO: don't use this as well as cycle_counter, it's a relic of when
|
self.ticks = 0 # type: int
|
||||||
# I relied on variable-duration opcodes for frame timings.
|
|
||||||
self.cycles = 0 # type: int
|
|
||||||
self.cycle_counter = machine.CycleCounter()
|
|
||||||
|
|
||||||
self.state = machine.Machine(
|
self.state = machine.Machine(
|
||||||
self.cycle_counter,
|
|
||||||
self.video.memory_map,
|
self.video.memory_map,
|
||||||
self.video.update_priority
|
self.video.update_priority
|
||||||
)
|
)
|
||||||
@ -64,9 +61,13 @@ class Movie:
|
|||||||
yield opcodes.Header(mode=self.video_mode)
|
yield opcodes.Header(mode=self.video_mode)
|
||||||
|
|
||||||
for au in self.audio.audio_stream():
|
for au in self.audio.audio_stream():
|
||||||
self.cycles += self.audio.cycles_per_tick
|
self.ticks += 1
|
||||||
if self.video.tick(self.cycles):
|
if self.video.tick(self.ticks):
|
||||||
|
try:
|
||||||
main, aux = next(video_frames)
|
main, aux = next(video_frames)
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
|
|
||||||
if ((self.video.frame_number - 1) % self.every_n_video_frames
|
if ((self.video.frame_number - 1) % self.every_n_video_frames
|
||||||
== 0):
|
== 0):
|
||||||
print("Starting frame %d" % self.video.frame_number)
|
print("Starting frame %d" % self.video.frame_number)
|
||||||
|
@ -22,14 +22,15 @@ class Video:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
frame_grabber: FrameGrabber,
|
frame_grabber: FrameGrabber,
|
||||||
|
ticks_per_second: int,
|
||||||
mode: VideoMode = VideoMode.HGR,
|
mode: VideoMode = VideoMode.HGR,
|
||||||
palette: Palette = Palette.NTSC,
|
palette: Palette = Palette.NTSC
|
||||||
):
|
):
|
||||||
self.mode = mode # type: VideoMode
|
self.mode = mode # type: VideoMode
|
||||||
self.frame_grabber = frame_grabber # type: FrameGrabber
|
self.frame_grabber = frame_grabber # type: FrameGrabber
|
||||||
self.cycles_per_frame = (
|
self.ticks_per_second = float(ticks_per_second) # type: float
|
||||||
self.CLOCK_SPEED / frame_grabber.input_frame_rate
|
self.ticks_per_frame = (
|
||||||
) # type: float
|
self.ticks_per_second / frame_grabber.input_frame_rate) # type: float
|
||||||
self.frame_number = 0 # type: int
|
self.frame_number = 0 # type: int
|
||||||
self.palette = palette # type: Palette
|
self.palette = palette # type: Palette
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import video_mode
|
|||||||
class TestVideo(unittest.TestCase):
|
class TestVideo(unittest.TestCase):
|
||||||
def test_diff_weights(self):
|
def test_diff_weights(self):
|
||||||
fs = frame_grabber.FrameGrabber(mode=video_mode.VideoMode.DHGR)
|
fs = frame_grabber.FrameGrabber(mode=video_mode.VideoMode.DHGR)
|
||||||
v = video.Video(fs, mode=video_mode.VideoMode.DHGR)
|
v = video.Video(fs, ticks_per_second=10000, mode=video_mode.VideoMode.DHGR)
|
||||||
|
|
||||||
frame = screen.MemoryMap(screen_page=1)
|
frame = screen.MemoryMap(screen_page=1)
|
||||||
frame.page_offset[0, 0] = 0b1111111
|
frame.page_offset[0, 0] = 0b1111111
|
||||||
|
Loading…
Reference in New Issue
Block a user