mirror of
https://github.com/KrisKennaway/ii-vision.git
synced 2025-01-02 05:30:05 +00:00
c00300147e
- Introduce a new Movie() class that multiplexes audio and video. - Every N audio frames we grab a new video frame and begin pulling opcodes from the audio and video streams - Grab frames from the input video using bmp2dhr if the .BIN file does not already exist. Run bmp2dhr in a background thread to not block encoding - move the output byte streaming from Video to Movie - For now, manually clip updates to pages > 56 since the client doesn't support them yet The way we encode video is now: - iterate in descending order over update_priority - begin a new (page, content) opcode - for all of the other offset bytes in that page, compute the error between the candidate content byte and the target content byte - iterate over offsets in order of increasing error and decreasing update_priority to fill out the remaining opcode
61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
import random
|
|
|
|
import numpy as np
|
|
import audioread
|
|
import librosa
|
|
|
|
import opcodes
|
|
import video
|
|
|
|
|
|
class Audio:
|
|
def __init__(
|
|
self, filename: str, normalization: float = 1.0):
|
|
self.filename = filename
|
|
self.normalization = normalization
|
|
|
|
# TODO: take into account that the available range is slightly offset
|
|
# as fraction of total cycle count?
|
|
self._tick_range = [4, 66]
|
|
self.cycles_per_tick = 73
|
|
|
|
# TODO: round to divisor of video frame rate
|
|
self.sample_rate = 14340 # int(1024. * 1024 / self.cycles_per_tick)
|
|
|
|
def audio_stream(self):
|
|
with audioread.audio_open(self.filename) as f:
|
|
for buf in f.read_data(128 * 1024):
|
|
print(f.channels, f.samplerate, f.duration)
|
|
|
|
data = np.frombuffer(buf, dtype='int16').astype(
|
|
'float32').reshape((f.channels, -1), order='F')
|
|
|
|
a = librosa.core.to_mono(data)
|
|
a = librosa.resample(a, f.samplerate,
|
|
self.sample_rate).flatten()
|
|
|
|
a /= 16384 # normalize to -1.0 .. 1.0
|
|
a *= self.normalization
|
|
|
|
# Convert to -16 .. 16
|
|
a = (a * 16).astype(np.int)
|
|
a = np.clip(a, -15, 16)
|
|
|
|
yield from a
|
|
|
|
|
|
def main():
|
|
filename = "Computer Chronicles - 06x05 - The Apple II.mp4"
|
|
|
|
s = video.Video(frame_rate=None)
|
|
au = Audio(filename, normalization=3)
|
|
|
|
with open("out.bin", "wb") as out:
|
|
for b in s.emit_stream(au.encode_audio()):
|
|
out.write(bytearray([b]))
|
|
out.write(bytes(s.done()))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|