42
42
43
43
# TODO: Rework to a time machine interface.
44
44
class PlaybackPlayer (object ):
45
- def __init__ (self , file ):
45
+ def __init__ (self , machine , file ):
46
+ self .__machine = machine
47
+
46
48
assert isinstance (file , RZXFile )
47
49
self ._recording = file
48
50
@@ -55,6 +57,56 @@ def find_recording_info_chunk(self):
55
57
def get_chunks (self ):
56
58
return self ._recording ['chunks' ]
57
59
60
+ def get_playback_samples (self ):
61
+ # TODO: Have a class describing playback state.
62
+ self .playback_frame_count = 0
63
+ self .playback_chunk = 0
64
+ self .playback_sample_values = []
65
+ self .playback_sample_i = 0
66
+
67
+ frame_count = 0
68
+ for chunk_i , chunk in enumerate (self .get_chunks ()):
69
+ if isinstance (chunk , MachineSnapshot ):
70
+ self .__machine .install_snapshot (chunk )
71
+ continue
72
+
73
+ if chunk ['id' ] != 'port_samples' :
74
+ continue
75
+
76
+ self .__machine .ticks_since_int = chunk ['first_tick' ]
77
+
78
+ for frame_i , frame in enumerate (chunk ['frames' ]):
79
+ num_of_fetches , samples = frame
80
+ # print(num_of_fetches, samples)
81
+
82
+ self .__machine .fetches_limit = num_of_fetches
83
+ # print(num_of_fetches, samples, flush=True)
84
+
85
+ # print('START_OF_FRAME', flush=True)
86
+ yield 'START_OF_FRAME'
87
+
88
+ for sample_i , sample in enumerate (samples ):
89
+ # print(self.fetches_limit)
90
+ # fetch = num_of_fetches - self.fetches_limit
91
+ # print('Input at fetch', fetch, 'of', num_of_fetches)
92
+ # TODO: print('read_port 0x%04x 0x%02x' % (addr, n),
93
+ # flush=True)
94
+
95
+ # TODO: Have a class describing playback state.
96
+ self .playback_frame_count = frame_count
97
+ self .playback_chunk = chunk
98
+ self .playback_sample_values = samples
99
+ self .playback_sample_i = sample_i
100
+ # print(frame_count, chunk_i, frame_i, sample_i, sample,
101
+ # flush=True)
102
+
103
+ yield sample
104
+
105
+ # print('END_OF_FRAME', flush=True)
106
+ yield 'END_OF_FRAME'
107
+
108
+ frame_count += 1
109
+
58
110
59
111
# TODO: Eliminate this class. Move everything to Spectrum48.
60
112
class Emulator (Spectrum48 ):
@@ -156,8 +208,8 @@ def __on_input(self, addr):
156
208
raise Error (
157
209
'Too few input samples at frame %d of %d. '
158
210
'Given %d, used %d.' % (
159
- self .playback_frame_count ,
160
- len (self .playback_chunk ['frames' ]),
211
+ self .__playback_player . playback_frame_count ,
212
+ len (self .__playback_player . playback_chunk ['frames' ]),
161
213
len (self .__playback_player .samples ), sample_i ),
162
214
id = 'too_few_input_samples' )
163
215
@@ -222,56 +274,6 @@ def _quit_playback_mode(self):
222
274
self .suppress_interrupts = False
223
275
self .allow_int_after_ei = False
224
276
225
- def __get_playback_samples (self ):
226
- # TODO: Have a class describing playback state.
227
- self .playback_frame_count = 0
228
- self .playback_chunk = 0
229
- self .playback_sample_values = []
230
- self .playback_sample_i = 0
231
-
232
- frame_count = 0
233
- for chunk_i , chunk in enumerate (self .__playback_player .get_chunks ()):
234
- if isinstance (chunk , MachineSnapshot ):
235
- self .install_snapshot (chunk )
236
- continue
237
-
238
- if chunk ['id' ] != 'port_samples' :
239
- continue
240
-
241
- self .ticks_since_int = chunk ['first_tick' ]
242
-
243
- for frame_i , frame in enumerate (chunk ['frames' ]):
244
- num_of_fetches , samples = frame
245
- # print(num_of_fetches, samples)
246
-
247
- self .fetches_limit = num_of_fetches
248
- # print(num_of_fetches, samples, flush=True)
249
-
250
- # print('START_OF_FRAME', flush=True)
251
- yield 'START_OF_FRAME'
252
-
253
- for sample_i , sample in enumerate (samples ):
254
- # print(self.fetches_limit)
255
- # fetch = num_of_fetches - self.fetches_limit
256
- # print('Input at fetch', fetch, 'of', num_of_fetches)
257
- # TODO: print('read_port 0x%04x 0x%02x' % (addr, n),
258
- # flush=True)
259
-
260
- # TODO: Have a class describing playback state.
261
- self .playback_frame_count = frame_count
262
- self .playback_chunk = chunk
263
- self .playback_sample_values = samples
264
- self .playback_sample_i = sample_i
265
- # print(frame_count, chunk_i, frame_i, sample_i, sample,
266
- # flush=True)
267
-
268
- yield sample
269
-
270
- # print('END_OF_FRAME', flush=True)
271
- yield 'END_OF_FRAME'
272
-
273
- frame_count += 1
274
-
275
277
def __run_quantum (self , speed_factor = None ):
276
278
if speed_factor is None :
277
279
speed_factor = self .__speed_factor
@@ -347,8 +349,8 @@ def __run_quantum(self, speed_factor=None):
347
349
# instruction in frame is IN.
348
350
if (self .__playback_player .samples and
349
351
creator_info == self ._SPIN_V0P5_INFO and
350
- self .playback_sample_i + 1 <
351
- len (self .playback_sample_values )):
352
+ self .__playback_player . playback_sample_i + 1 <
353
+ len (self .__playback_player . playback_sample_values )):
352
354
self .fetches_limit = 1
353
355
return
354
356
@@ -359,10 +361,11 @@ def __run_quantum(self, speed_factor=None):
359
361
raise Error (
360
362
'Too many input samples at frame %d of %d. '
361
363
'Given %d, used %d.' % (
362
- self .playback_frame_count ,
363
- len (self .playback_chunk ['frames' ]),
364
+ self .__playback_player .playback_frame_count ,
365
+ len (self .__playback_player .
366
+ playback_chunk ['frames' ]),
364
367
len (self .__playback_player .samples ),
365
- self .playback_sample_i + 1 ),
368
+ self .__playback_player . playback_sample_i + 1 ),
366
369
id = 'too_many_input_samples' )
367
370
368
371
sample = None
@@ -385,7 +388,7 @@ def run(self, duration=None, speed_factor=None):
385
388
self .__run_quantum (speed_factor = speed_factor )
386
389
387
390
def __load_input_recording (self , file ):
388
- self .__playback_player = PlaybackPlayer (file )
391
+ self .__playback_player = PlaybackPlayer (self , file )
389
392
creator_info = self .__playback_player .find_recording_info_chunk ()
390
393
391
394
# SPIN v0.5 alters ROM to implement fast tape loading,
@@ -397,7 +400,8 @@ def __load_input_recording(self, file):
397
400
self .set_breakpoint (0x04d4 )
398
401
399
402
# Process frames in order.
400
- self .__playback_player .samples = self .__get_playback_samples ()
403
+ self .__playback_player .samples = (
404
+ self .__playback_player .get_playback_samples ())
401
405
sample = None
402
406
for sample in self .__playback_player .samples :
403
407
break
0 commit comments