blob: e1b06d683666c7b510df639a9ea52d3ae6c21bb6 [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossumb7e3cc11993-05-06 16:06:44 +00002
Guido van Rossum9f42f4f1993-05-10 15:07:20 +00003# Video bag of tricks: record video(+audio) in various formats and modes
Guido van Rossumb7e3cc11993-05-06 16:06:44 +00004
Guido van Rossumc5a14331993-05-07 11:20:07 +00005# XXX To do:
6# - audio
Guido van Rossumc5a14331993-05-07 11:20:07 +00007# - improve user interface
8# - help button?
9# - command line options to set initial settings
10# - save settings in a file
11# - ...?
Guido van Rossumbc6d3c31993-05-07 09:37:42 +000012
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000013import sys
Guido van Rossum9f42f4f1993-05-10 15:07:20 +000014import time
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000015import getopt
16import string
17import os
Guido van Rossumc5a14331993-05-07 11:20:07 +000018sts = os.system('makemap') # Must be before "import fl" to work
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000019import sgi
20import gl
21import GL
22import DEVICE
23import fl
24import FL
25import flp
26import watchcursor
27import sv
28import SV
29import VFile
30import VGrabber
31import imageop
Guido van Rossum9f42f4f1993-05-10 15:07:20 +000032sys.path.append('/ufs/jack/src/av/vcr')
Guido van Rossumf6d80321993-06-10 13:40:51 +000033import VCR
Jack Jansen78991fd1993-07-23 11:59:25 +000034try:
35 import cl
Jack Jansen78991fd1993-07-23 11:59:25 +000036except ImportError:
37 cl = None
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000038
39ARROW = 0
40WATCH = 1
41watchcursor.defwatch(WATCH)
42
43def main():
Guido van Rossumc5a14331993-05-07 11:20:07 +000044## fl.set_graphics_mode(0, 1)
Guido van Rossum21a3ff91993-12-17 15:11:41 +000045 vb = VideoBagOfTricks()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000046 while 1:
47 dummy = fl.do_forms()
48 [dummy]
49
50StopCapture = 'StopCapture'
51
Guido van Rossum9f42f4f1993-05-10 15:07:20 +000052VideoFormatLabels = ['Video off', 'rgb8', 'grey8', 'grey4', 'grey2', \
Jack Jansen78991fd1993-07-23 11:59:25 +000053 'grey2 dith', 'mono dith', 'mono thresh', 'rgb24', 'rgb24-jpeg', \
54 'compress']
Guido van Rossum9f42f4f1993-05-10 15:07:20 +000055VideoFormats = ['', 'rgb8', 'grey', 'grey4', 'grey2', \
Jack Jansen78991fd1993-07-23 11:59:25 +000056 'grey2', 'mono', 'mono', 'rgb', 'jpeg', 'compress']
Guido van Rossum9f42f4f1993-05-10 15:07:20 +000057
58VideoModeLabels = ['Continuous', 'Burst', 'Single frame', 'VCR sync']
59[VM_CONT, VM_BURST, VM_SINGLE, VM_VCR] = range(1, 5)
60
61AudioFormatLabels = ['Audio off', \
62 '16 bit mono', '16 bit stereo', '8 bit mono', '8 bit stereo']
63[A_OFF, A_16_MONO, A_16_STEREO, A_8_MONO, A_8_STEREO] = range(1, 6)
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000064
Jack Jansen672754a1993-06-08 12:52:41 +000065VcrSpeedLabels = ['normal', '1/3', '1/5', '1/10', '1/30', 'single-step']
66VcrSpeeds = [None, 5, 4, 3, 2, 1, 0]
67
68RgbSizeLabels = ['full', 'quarter', 'sixteenth']
69
Jack Jansen78991fd1993-07-23 11:59:25 +000070# init file stuff:
71if os.environ.has_key('HOME'):
72 HOME=os.environ['HOME']
73else:
74 HOME='.'
75VB_INIT_FILE=HOME + '/.Vb_init'
76
77VB_INIT_KEYS=['vfile', 'vmode', 'mono_thresh', 'vformat', 'comp_scheme', \
78 'rgb24_size', 'afile', 'aformat']
79
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000080class VideoBagOfTricks:
81
Guido van Rossum9f42f4f1993-05-10 15:07:20 +000082 # Init/close stuff
83
Guido van Rossum21a3ff91993-12-17 15:11:41 +000084 def __init__(self):
Jack Jansen672754a1993-06-08 12:52:41 +000085 self.window = None
Guido van Rossumb7e3cc11993-05-06 16:06:44 +000086 formdef = flp.parse_form('VbForm', 'form')
87 flp.create_full_form(self, formdef)
88 self.setdefaults()
Jack Jansen78991fd1993-07-23 11:59:25 +000089 if self.vmode <> VM_CONT:
90 self.g_cont.hide_object()
91 if self.vmode <> VM_BURST:
92 self.g_burst.hide_object()
93 if self.vmode <> VM_SINGLE:
94 self.g_single.hide_object()
95 if self.vmode <> VM_VCR:
96 self.g_vcr.hide_object()
97 if self.vformat <> 'compress':
98 self.g_compress.hide_object()
99
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000100 self.openvideo()
101 self.makewindow()
102 self.bindvideo()
Jack Jansen78991fd1993-07-23 11:59:25 +0000103 if self.use_24:
104 self.optfullsizewindow()
Guido van Rossumc5a14331993-05-07 11:20:07 +0000105 self.showform()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000106 fl.set_event_call_back(self.do_event)
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000107
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000108 def close(self):
109 self.close_video()
110 self.close_audio()
Jack Jansen78991fd1993-07-23 11:59:25 +0000111 self.savedefaults()
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000112 raise SystemExit, 0
113
Guido van Rossumc5a14331993-05-07 11:20:07 +0000114 def showform(self):
115 # Get position of video window
116 gl.winset(self.window)
117 x, y = gl.getorigin()
118 width, height = gl.getsize()
119 # Calculate position of form window
120 x1 = x + width + 10
121 x2 = x1 + int(self.form.w) - 1
122 y2 = y + height - 1
123 y1 = y2 - int(self.form.h) + 1
124 # Position and show form window
125 gl.prefposition(x1, x2, y1, y2)
Guido van Rossum43df8621993-06-11 15:48:39 +0000126 self.form.show_form(FL.PLACE_FREE, FL.TRUE, 'Vb Control')
Guido van Rossumc5a14331993-05-07 11:20:07 +0000127
Jack Jansen78991fd1993-07-23 11:59:25 +0000128 def getdefaultdefaults(self):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000129 # Video defaults
130 self.vfile = 'film.video'
131 self.vmode = VM_CONT
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000132 self.mono_thresh = 128
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000133 self.vformat = 'rgb8'
Jack Jansen78991fd1993-07-23 11:59:25 +0000134 self.comp_scheme = 'Uncompressed'
135 self.rgb24_size = 1
136 # Missing: drop, rate, maxmem, nframes, rate, vcrspeed
137 # Audio defaults:
138 self.afile = 'film.aiff'
139 self.aformat = A_OFF
140
141 def getdefaults(self):
142 self.getdefaultdefaults()
143 # XXXX Read defaults file and override.
144 try:
145 fp = open(VB_INIT_FILE, 'r')
146 except IOError:
147 print 'Vb: no init file'
148 self.initcont = {}
149 return
150 data = fp.read(1000000)
151 try:
152 self.initcont = eval(data)
153 except:
154 print 'Vb: Ill-formatted init file'
155 self.initcont = {}
156 for k in self.initcont.keys():
157 if hasattr(self, k):
158 setattr(self, k, self.initcont[k])
159
160 def savedefaults(self):
161 newdb = {}
162 for k in VB_INIT_KEYS:
163 newdb[k] = getattr(self, k)
164 if newdb <> self.initcont:
165 try:
166 fp = open(VB_INIT_FILE, 'w')
167 except IOError:
168 print 'Vb: Cannot create', VB_INIT_FILE
169 return
170 fp.write(`newdb`)
171 fp.close()
172
173 def setdefaults(self):
174 self.getdefaults()
175 self.vcr = None
176 self.vout = None
177 self.capturing = 0
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000178 self.c_vformat.clear_choice()
179 for label in VideoFormatLabels:
180 self.c_vformat.addto_choice(label)
181 self.c_vformat.set_choice(1 + VideoFormats.index(self.vformat))
182 self.c_vmode.clear_choice()
183 for label in VideoModeLabels:
184 self.c_vmode.addto_choice(label)
185 self.c_vmode.set_choice(self.vmode)
186 self.get_vformat()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000187 self.b_drop.set_button(1)
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000188 self.in_rate.set_input('2')
189 self.in_maxmem.set_input('1.0')
190 self.in_nframes.set_input('0')
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000191 self.in_nframes_vcr.set_input('1')
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000192 self.in_rate_vcr.set_input('1')
Jack Jansen672754a1993-06-08 12:52:41 +0000193 self.c_vcrspeed.clear_choice()
194 for label in VcrSpeedLabels:
195 self.c_vcrspeed.addto_choice(label)
196 self.c_vcrspeed.set_choice(4)
197 self.c_rgb24_size.clear_choice()
198 for label in RgbSizeLabels:
199 self.c_rgb24_size.addto_choice(label)
Jack Jansen78991fd1993-07-23 11:59:25 +0000200 self.c_rgb24_size.set_choice(self.rgb24_size)
201 if cl:
Guido van Rossum1554b7b1998-10-09 13:26:29 +0000202 algs = cl.QueryAlgorithms(cl.VIDEO)
Jack Jansen78991fd1993-07-23 11:59:25 +0000203 self.all_comp_schemes = []
204 for i in range(0, len(algs), 2):
Guido van Rossum1554b7b1998-10-09 13:26:29 +0000205 if algs[i+1] in (cl.COMPRESSOR, cl.CODEC):
Jack Jansen78991fd1993-07-23 11:59:25 +0000206 self.all_comp_schemes.append(algs[i])
207 self.c_cformat.clear_choice()
208 for label in self.all_comp_schemes:
209 self.c_cformat.addto_choice(label)
210 i = self.all_comp_schemes.index(self.comp_scheme)
211 self.c_cformat.set_choice(i+1)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000212 # Audio defaults
213 self.aout = None
214 self.aport = None
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000215 self.c_aformat.clear_choice()
216 for label in AudioFormatLabels:
217 self.c_aformat.addto_choice(label)
218 self.c_aformat.set_choice(self.aformat)
219 self.get_aformat()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000220
221 def openvideo(self):
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000222 try:
223 self.video = sv.OpenVideo()
224 except sv.error, msg:
225 print 'Error opening video:', msg
226 self.video = None
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000227 param = [SV.BROADCAST, SV.PAL]
228 if self.video: self.video.GetParam(param)
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000229 if param[1] == SV.PAL:
230 x = SV.PAL_XMAX
231 y = SV.PAL_YMAX
232 elif param[1] == SV.NTSC:
233 x = SV.NTSC_XMAX
234 y = SV.NTSC_YMAX
235 else:
236 print 'Unknown video standard:', param[1]
237 sys.exit(1)
238 self.maxx, self.maxy = x, y
Guido van Rossum43df8621993-06-11 15:48:39 +0000239 self.curx = 256
240 self.cury = 256*3/4
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000241
242 def makewindow(self):
243 x, y = self.maxx, self.maxy
244 gl.foreground()
245 gl.maxsize(x, y)
246 gl.keepaspect(x, y)
247 gl.stepunit(8, 6)
Guido van Rossum43df8621993-06-11 15:48:39 +0000248 width = self.curx
249 height = self.cury
250 if width and height:
251 # Place the window at (150, 150) from top left
252 # (the video board likes this location...)
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000253 x1 = 150
Guido van Rossum43df8621993-06-11 15:48:39 +0000254 x2 = x1+width-1
255 SCRHEIGHT = 768
256 y2 = SCRHEIGHT-1-150
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000257 y1 = y2-height+1
258 gl.prefposition(x1, x2, y1, y2)
Guido van Rossum43df8621993-06-11 15:48:39 +0000259 self.window = gl.winopen('Vb video')
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000260 self.settitle()
261 if width:
262 gl.maxsize(x, y)
263 gl.keepaspect(x, y)
264 gl.stepunit(8, 6)
265 gl.winconstraints()
266 gl.qdevice(DEVICE.LEFTMOUSE)
267 gl.qdevice(DEVICE.WINQUIT)
268 gl.qdevice(DEVICE.WINSHUT)
269
Jack Jansen672754a1993-06-08 12:52:41 +0000270 def optfullsizewindow(self):
271 if not self.window:
272 return
273 gl.winset(self.window)
Guido van Rossum43df8621993-06-11 15:48:39 +0000274 if self.use_24:
275 x, y = self.maxx, self.maxy
276 else:
277 x, y = self.curx, self.cury
Guido van Rossum2055ee81993-06-11 14:13:13 +0000278 left, bottom = gl.getorigin()
279 width, height = gl.getsize()
280 bottom = bottom+height-y
281 gl.prefposition(left, left+x-1, bottom, bottom+y-1)
Jack Jansen672754a1993-06-08 12:52:41 +0000282 gl.winconstraints()
Guido van Rossum43df8621993-06-11 15:48:39 +0000283 if not self.use_24:
284 gl.keepaspect(x, y)
285 gl.stepunit(8, 6)
286 gl.maxsize(self.maxx, self.maxy)
287 gl.winconstraints()
Jack Jansen672754a1993-06-08 12:52:41 +0000288 self.bindvideo()
289
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000290 def bindvideo(self):
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000291 if not self.video: return
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000292 x, y = gl.getsize()
Guido van Rossum43df8621993-06-11 15:48:39 +0000293 if not self.use_24:
294 self.curx, self.cury = x, y
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000295 self.video.SetSize(x, y)
296 drop = self.b_drop.get_button()
297 if drop:
298 param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF]
299 else:
300 param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON]
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000301 if self.rgb:
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000302 param = param+[SV.COLOR, SV.DEFAULT_COLOR, \
303 SV.DITHER, 1, \
304 SV.INPUT_BYPASS, 0]
305 else:
306 param = param+[SV.COLOR, SV.MONO, SV.DITHER, 0, \
307 SV.INPUT_BYPASS, 1]
308 self.video.BindGLWindow(self.window, SV.IN_REPLACE)
309 self.video.SetParam(param)
310
311 def rebindvideo(self):
312 gl.winset(self.window)
313 self.bindvideo()
314
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000315 def reset(self):
316 self.close_video()
317 self.close_audio()
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000318 if self.vcr:
319 try:
320 ok = self.vcr.still()
321 except VCR.error:
322 pass
323 self.vcr = None
324 self.b_capture.set_button(0)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000325
326 # Event handler (catches resize of video window)
327
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000328 def do_event(self, dev, val):
329 #print 'Event:', dev, val
330 if dev in (DEVICE.WINSHUT, DEVICE.WINQUIT):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000331 self.close()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000332 if dev == DEVICE.REDRAW and val == self.window:
333 self.rebindvideo()
334 self.settitle()
335
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000336 # Video controls: format, mode, file
337
338 def cb_vformat(self, *args):
339 self.reset()
340 self.get_vformat()
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000341 if self.mono_use_thresh:
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000342 s = `self.mono_thresh`
343 s = fl.show_input('Please enter mono threshold', s)
344 if s:
345 try:
346 self.mono_thresh = string.atoi(s)
347 except string.atoi_error:
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000348 fl.show_message('Bad input, using', \
349 `self.mono_thresh`, '')
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000350 self.rebindvideo()
351
Jack Jansen78991fd1993-07-23 11:59:25 +0000352 def cb_cformat(self, *args):
353 i = self.c_cformat.get_choice()
354 self.comp_scheme = self.all_comp_schemes[i-1]
355
356
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000357 def cb_vmode(self, *args):
Guido van Rossumc17c84f1993-05-10 15:45:49 +0000358 if self.vcr:
359 self.vcr = None
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000360 self.vmode = self.c_vmode.get_choice()
361 self.form.freeze_form()
362 self.g_cont.hide_object()
363 self.g_burst.hide_object()
364 self.g_single.hide_object()
365 self.g_vcr.hide_object()
366 if self.vmode == VM_CONT:
367 self.g_cont.show_object()
368 elif self.vmode == VM_BURST:
369 self.g_burst.show_object()
370 elif self.vmode == VM_SINGLE:
371 self.g_single.show_object()
372 elif self.vmode == VM_VCR:
373 self.g_vcr.show_object()
374 self.form.unfreeze_form()
375
376 def cb_vfile(self, *args):
377 filename = self.vfile
378 hd, tl = os.path.split(filename)
379 filename = fl.file_selector('Video save file:', hd, '', tl)
380 if filename:
381 self.reset()
382 hd, tl = os.path.split(filename)
383 if hd == os.getcwd():
384 filename = tl
385 self.vfile = filename
386
387 # Video mode specific video controls
388
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000389 def cb_rate(self, *args):
390 pass
391
392 def cb_drop(self, *args):
393 self.rebindvideo()
394
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000395 def cb_maxmem(self, *args):
396 pass
397
398 def cb_nframes(self, *args):
399 pass
400
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000401 def cb_fps(self, *args):
402 pass
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000403
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000404 def cb_nframes_vcr(self, *args):
405 pass
406
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000407 def cb_rate_vcr(self, *args):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000408 pass
409
Jack Jansen672754a1993-06-08 12:52:41 +0000410 def cb_vcrspeed(self, *args):
411 pass
412
413 def cb_rgb24_size(self, *args):
414 i = self.c_rgb24_size.get_choice()
415 if i:
416 self.rgb24_size = i
417
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000418 # Audio controls: format, file
419
420 def cb_aformat(self, *args):
421 self.get_aformat()
422
423 def cb_afile(self, *args):
424 filename = self.afile
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000425 hd, tl = os.path.split(filename)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000426 filename = fl.file_selector('Audio save file:', hd, '', tl)
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000427 if filename:
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000428 self.reset()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000429 hd, tl = os.path.split(filename)
430 if hd == os.getcwd():
431 filename = tl
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000432 self.afile = filename
433
434 # General controls: capture, reset, play, quit
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000435
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000436 def cb_capture(self, *args):
Guido van Rossumc5a14331993-05-07 11:20:07 +0000437 if self.capturing:
438 raise StopCapture
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000439 if not self.b_capture.get_button():
440 return
441 if not self.video or not self.vformat:
442 gl.ringbell()
443 return
444 if self.vmode == VM_CONT:
445 self.cont_capture()
446 elif self.vmode == VM_BURST:
447 self.burst_capture()
448 elif self.vmode == VM_SINGLE:
Jack Jansen672754a1993-06-08 12:52:41 +0000449 self.single_capture(None, None)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000450 elif self.vmode == VM_VCR:
451 self.vcr_capture()
452
453 def cb_reset(self, *args):
454 self.reset()
Guido van Rossumc5a14331993-05-07 11:20:07 +0000455
456 def cb_play(self, *args):
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000457 self.reset()
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000458 sts = os.system('Vplay -q ' + self.vfile + ' &')
Guido van Rossumc5a14331993-05-07 11:20:07 +0000459
460 def cb_quit(self, *args):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000461 self.close()
462
463 # Capture routines
Guido van Rossumc5a14331993-05-07 11:20:07 +0000464
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000465 def burst_capture(self):
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000466 self.setwatch()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000467 gl.winset(self.window)
468 x, y = gl.getsize()
Jack Jansen672754a1993-06-08 12:52:41 +0000469 if self.use_24:
470 fl.show_message('Sorry, no 24 bit continuous capture yet', '', '')
471 return
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000472 vformat = SV.RGB8_FRAMES
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000473 nframes = self.getint(self.in_nframes, 0)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000474 if nframes == 0:
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000475 maxmem = self.getint(self.in_maxmem, 1.0)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000476 memsize = int(maxmem * 1024 * 1024)
Guido van Rossum54618501993-10-26 10:23:14 +0000477 nframes = self.calcnframes(memsize)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000478 info = (vformat, x, y, nframes, 1)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000479 try:
480 info2, data, bitvec = self.video.CaptureBurst(info)
481 except sv.error, msg:
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000482 self.b_capture.set_button(0)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000483 self.setarrow()
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000484 fl.show_message('Capture error:', str(msg), '')
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000485 return
Guido van Rossumc5a14331993-05-07 11:20:07 +0000486 if info <> info2: print info, '<>', info2
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000487 self.save_burst(info2, data, bitvec)
488 self.setarrow()
489
Guido van Rossum54618501993-10-26 10:23:14 +0000490 def calcnframes(self, memsize):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000491 gl.winset(self.window)
492 x, y = gl.getsize()
493 pixels = x*y
494 pixels = pixels/2 # XXX always assume fields
495 if self.mono or self.grey:
496 n = memsize/pixels
497 else:
498 n = memsize/(4*pixels)
499 return max(1, n)
500
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000501 def save_burst(self, info, data, bitvec):
502 (vformat, x, y, nframes, rate) = info
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000503 self.open_if_closed()
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000504 fieldsize = x*y/2
505 nskipped = 0
506 realframeno = 0
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000507 tpf = 1000 / 50.0 # XXX
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000508 for frameno in range(0, nframes*2):
509 if frameno <> 0 and \
510 bitvec[frameno] == bitvec[frameno-1]:
511 nskipped = nskipped + 1
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000512 continue
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000513 #
514 # Save field.
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000515 # XXX Works only for fields and top-to-bottom
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000516 #
517 start = frameno*fieldsize
518 field = data[start:start+fieldsize]
519 realframeno = realframeno + 1
520 fn = int(realframeno*tpf)
521 if not self.write_frame(fn, field):
522 break
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000523
524 def cont_capture(self):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000525 saved_label = self.b_capture.label
526 self.b_capture.label = 'Stop\n' + saved_label
527 self.open_if_closed()
528 self.init_cont()
529 fps = 59.64 # Fields per second
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000530 # XXX (fps of Indigo monitor, not of PAL or NTSC!)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000531 tpf = 1000.0 / fps # Time per field in msec
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000532 self.capturing = 1
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000533 self.start_audio()
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000534 while 1:
535 try:
536 void = fl.check_forms()
537 except StopCapture:
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000538 break
539 try:
540 cd, id = self.video.GetCaptureData()
541 except sv.error:
542 sgi.nap(1)
543 continue
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000544 id = id + 2*self.rate
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000545 data = cd.InterleaveFields(1)
546 cd.UnlockCaptureData()
547 t = id*tpf
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000548 if not self.write_frame(t, data):
Guido van Rossume17c6c31993-05-06 16:27:25 +0000549 break
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000550 self.stop_audio()
Guido van Rossume17c6c31993-05-06 16:27:25 +0000551 self.capturing = 0
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000552 self.end_cont()
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000553 if self.aout:
554 # If recording audio, can't capture multiple sequences
555 self.reset()
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000556 self.b_capture.label = saved_label
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000557
Jack Jansen672754a1993-06-08 12:52:41 +0000558 def single_capture(self, stepfunc, timecode):
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000559 self.open_if_closed()
560 self.init_cont()
561 while 1:
562 try:
563 cd, id = self.video.GetCaptureData()
564 break
565 except sv.error:
566 pass
567 sgi.nap(1)
Jack Jansen672754a1993-06-08 12:52:41 +0000568 if stepfunc: # This might step the video
569 d=stepfunc() # to the next frame
570 if not self.use_24:
571 data = cd.InterleaveFields(1)
572 else:
573 x, y = self.vout.getsize()
Jack Jansen78991fd1993-07-23 11:59:25 +0000574 if self.use_compress:
575 if self.rgb24_size == 1:
576 data = cd.YUVtoYUV422DC(0)
577 elif self.rgb24_size == 2:
578 data = cd.YUVtoYUV422DC_quarter(1)
579 x = x/2
580 y = y/2
581 elif self.rgb24_size == 3:
582 data = cd.YUVtoYUV422DC_sixteenth(1)
583 x = x/4
584 y = y/4
Jack Jansen672754a1993-06-08 12:52:41 +0000585 else:
Jack Jansen78991fd1993-07-23 11:59:25 +0000586 data = cd.YUVtoRGB(1)
587 if self.maxx*self.maxy*4 <> len(data):
588 print 'maxx,maxy,exp,got=', self.maxx,
589 print self.maxy,self.maxx*self.maxy*4,
590 print len(data)
591 fl.showmessage('Wrong sized data')
592 return 0
593 if self.rgb24_size <> 1:
594 data = imageop.scale(data, 4, \
595 self.maxx, self.maxy, x, y)
Jack Jansen672754a1993-06-08 12:52:41 +0000596 if self.use_jpeg:
597 import jpeg
598 data = jpeg.compress(data, x, y, 4)
Jack Jansen78991fd1993-07-23 11:59:25 +0000599 if self.use_compress:
600 data = self.compressor.Compress(1, data)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000601 cd.UnlockCaptureData()
602 self.end_cont()
Jack Jansen672754a1993-06-08 12:52:41 +0000603 if timecode == None:
604 timecode = (self.nframes+1) * (1000/25)
605 return self.write_frame(timecode, data)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000606
607 def vcr_capture(self):
608 if not self.vcr:
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000609 try:
Guido van Rossum2055ee81993-06-11 14:13:13 +0000610 print 'Connecting to VCR ...'
Guido van Rossum21a3ff91993-12-17 15:11:41 +0000611 self.vcr = VCR.VCR()
Guido van Rossum2055ee81993-06-11 14:13:13 +0000612 print 'Waiting for VCR to come online ...'
Jack Jansen78991fd1993-07-23 11:59:25 +0000613 self.vcr.initvcr()
Guido van Rossum2055ee81993-06-11 14:13:13 +0000614 print 'Preparing VCR ...'
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000615 if not (self.vcr.fmmode('dnr') and \
616 self.vcr.dmcontrol('digital slow')):
617 self.vcr_error('digital slow failed')
618 return
Guido van Rossum2055ee81993-06-11 14:13:13 +0000619 print 'VCR OK.'
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000620 except VCR.error, msg:
Guido van Rossumc17c84f1993-05-10 15:45:49 +0000621 self.vcr = None
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000622 self.vcr_error(msg)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000623 return
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000624 if not self.vcr.still():
625 self.vcr_error('still failed')
626 return
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000627 self.open_if_closed()
628 rate = self.getint(self.in_rate_vcr, 1)
629 rate = max(rate, 1)
Jack Jansen672754a1993-06-08 12:52:41 +0000630 vcrspeed = self.c_vcrspeed.get_choice()
631 vcrspeed = VcrSpeeds[vcrspeed]
632 if vcrspeed == 0:
633 stepfunc = self.vcr.step
634 else:
635 stepfunc = None
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000636 self.speed_factor = rate
Jack Jansen672754a1993-06-08 12:52:41 +0000637 addr = start_addr = self.vcr.sense()
638 if not self.single_capture(None, 0):
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000639 return
640 print 'captured %02d:%02d:%02d:%02d' % self.vcr.addr2tc(addr)
641 count = self.getint(self.in_nframes_vcr, 1) - 1
642 if count <= 0:
643 while rate > 0:
644 if not self.vcr.step():
645 self.vcr_error('step failed')
646 here = self.vcr.sense()
647 if here > addr:
648 rate = rate - (here - addr)
649 addr = here
650 return
Guido van Rossum2055ee81993-06-11 14:13:13 +0000651 if not self.vcr.fwdshuttle(vcrspeed):
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000652 self.vcr_error('fwd shuttle failed')
653 return
654 cycle = 0
655 while count > 0:
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000656 try:
657 here = self.vcr.sense()
658 except VCR.error, msg:
659 self.vcr_error(msg)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000660 break
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000661 if here <> addr:
662 if here <> addr+1:
663 print 'Missed', here-addr-1,
664 print 'frame' + 's'*(here-addr-1 <> 1)
665 cycle = (cycle+1) % rate
666 if cycle == 0:
Jack Jansen672754a1993-06-08 12:52:41 +0000667 tc = (here-start_addr)*40
668 if not self.single_capture(stepfunc, \
669 tc):
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000670 break
671 print 'captured %02d:%02d:%02d:%02d' \
672 % self.vcr.addr2tc(here)
673 count = count -1
674 addr = here
675 if self.vcr and not self.vcr.still():
676 self.vcr_error('still failed')
677
678 def vcr_error(self, msg):
679 self.reset()
680 fl.show_message('VCR error:', str(msg), '')
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000681
682 # Init/end continuous capture mode
683
684 def init_cont(self):
685 qsize = 1
686 if self.vmode == VM_CONT:
687 self.rate = self.getint(self.in_rate, 2)
688 else:
689 self.rate = 2
690 x, y = self.vout.getsize()
Jack Jansen672754a1993-06-08 12:52:41 +0000691 if self.use_24:
692 info = (SV.YUV411_FRAMES, x, y, qsize, self.rate)
693 else:
694 info = (SV.RGB8_FRAMES, x, y, qsize, self.rate)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000695 info2 = self.video.InitContinuousCapture(info)
696 if info2 <> info:
697 # XXX This is really only debug info
698 print 'Info mismatch: requested', info, 'got', info2
699
700 def end_cont(self):
701 self.video.EndContinuousCapture()
702
703 # Misc stuff
704
705 def settitle(self):
706 gl.winset(self.window)
707 x, y = gl.getsize()
Guido van Rossum43df8621993-06-11 15:48:39 +0000708 title = 'Vb ' + self.vfile + ' (%dx%d)' % (x, y)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000709 gl.wintitle(title)
710
711 def get_vformat(self):
712 i = self.c_vformat.get_choice()
713 label = VideoFormatLabels[i-1]
714 format = VideoFormats[i-1]
Jack Jansen78991fd1993-07-23 11:59:25 +0000715 if format == 'compress' and cl == None:
716 fl.show_message('Sorry, no compression library support')
717 format = ''
718 label = 'Video off'
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000719 self.vformat = format
720 if self.vformat == '':
721 self.form.freeze_form()
722 self.g_video.hide_object()
723 self.g_cont.hide_object()
724 self.g_burst.hide_object()
725 self.g_single.hide_object()
726 self.form.unfreeze_form()
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000727 else:
728 self.g_video.show_object()
729 if self.vmode == VM_CONT:
730 self.g_cont.show_object()
731 elif self.vmode == VM_BURST:
732 self.g_burst.show_object()
733 elif self.vmode == VM_SINGLE:
734 self.g_single.show_object()
Guido van Rossumc5a14331993-05-07 11:20:07 +0000735 #
Jack Jansen78991fd1993-07-23 11:59:25 +0000736 self.rgb = (format[:3] == 'rgb' or format == 'compress')
Guido van Rossumc5a14331993-05-07 11:20:07 +0000737 self.mono = (format == 'mono')
738 self.grey = (format[:4] == 'grey')
Jack Jansen78991fd1993-07-23 11:59:25 +0000739 self.use_24 = (format in ('rgb', 'jpeg', 'compress'))
740 if self.use_24:
Jack Jansen672754a1993-06-08 12:52:41 +0000741 self.g_rgb24.show_object()
742 else:
743 self.g_rgb24.hide_object()
744 self.use_jpeg = (format == 'jpeg')
Guido van Rossumc5a14331993-05-07 11:20:07 +0000745 self.mono_use_thresh = (label == 'mono thresh')
Jack Jansen78991fd1993-07-23 11:59:25 +0000746 self.use_compress = (format == 'compress')
747 if self.use_compress:
748 self.g_compress.show_object()
749 else:
750 self.g_compress.hide_object()
Guido van Rossumc5a14331993-05-07 11:20:07 +0000751 s = format[4:]
Jack Jansen78991fd1993-07-23 11:59:25 +0000752 if self.grey and s:
Guido van Rossumc5a14331993-05-07 11:20:07 +0000753 self.greybits = string.atoi(s)
754 else:
755 self.greybits = 8
756 if label == 'grey2 dith':
757 self.greybits = -2
758 #
759 convertor = None
760 if self.grey:
761 if self.greybits == 2:
762 convertor = imageop.grey2grey2
763 elif self.greybits == 4:
764 convertor = imageop.grey2grey4
765 elif self.greybits == -2:
766 convertor = imageop.dither2grey2
767 self.convertor = convertor
Jack Jansen672754a1993-06-08 12:52:41 +0000768 self.optfullsizewindow()
Guido van Rossumc5a14331993-05-07 11:20:07 +0000769
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000770 def get_aformat(self):
771 self.reset()
772 self.aformat = self.c_aformat.get_choice()
773 if self.aformat == A_OFF:
774 self.g_audio.hide_object()
775 else:
776 self.g_audio.show_object()
777
Jack Jansen78991fd1993-07-23 11:59:25 +0000778 def init_compressor(self, w, h):
779 self.compressor = None
Guido van Rossum1554b7b1998-10-09 13:26:29 +0000780 scheme = cl.QuerySchemeFromName(cl.VIDEO, self.comp_scheme)
Jack Jansen78991fd1993-07-23 11:59:25 +0000781 self.compressor = cl.OpenCompressor(scheme)
Guido van Rossum1554b7b1998-10-09 13:26:29 +0000782 parambuf = [cl.IMAGE_WIDTH, w, \
783 cl.IMAGE_HEIGHT, h, \
784 cl.ORIGINAL_FORMAT, cl.YUV422DC]
Jack Jansen78991fd1993-07-23 11:59:25 +0000785 self.compressor.SetParams(parambuf)
786 return self.compressor.Compress(0, '')
787
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000788 def open_if_closed(self):
789 if not self.vout:
790 self.open_video()
791 if not self.aout:
792 self.open_audio()
793
794 # File I/O handling
795
796 def open_video(self):
797 self.close_video()
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000798 gl.winset(self.window)
799 x, y = gl.getsize()
Jack Jansen672754a1993-06-08 12:52:41 +0000800 if self.use_24:
801 if self.rgb24_size == 2:
802 x, y = x/2, y/2
Jack Jansen78991fd1993-07-23 11:59:25 +0000803 elif self.rgb24_size == 3:
Jack Jansen672754a1993-06-08 12:52:41 +0000804 x, y = x/4, y/4
Guido van Rossum21a3ff91993-12-17 15:11:41 +0000805 vout = VFile.VoutFile(self.vfile)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000806 vout.setformat(self.vformat)
Jack Jansen78991fd1993-07-23 11:59:25 +0000807 if self.vformat == 'compress':
808 cheader = self.init_compressor(x, y)
809 vout.setcompressheader(cheader)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000810 vout.setsize(x, y)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000811 if self.vmode == VM_BURST:
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000812 vout.setpf((1, -2))
813 vout.writeheader()
814 self.vout = vout
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000815 self.nframes = 0
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000816 self.speed_factor = 1
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000817 self.t_nframes.label = `self.nframes`
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000818
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000819 def write_frame(self, t, data):
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000820 t = t * self.speed_factor
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000821 if not self.vout:
822 gl.ringbell()
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000823 return 0
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000824 if self.convertor:
825 data = self.convertor(data, len(data), 1)
826 elif self.mono:
827 if self.mono_use_thresh:
828 data = imageop.grey2mono(data, \
829 len(data), 1,\
830 self.mono_thresh)
831 else:
832 data = imageop.dither2mono(data, \
833 len(data), 1)
834 try:
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000835 self.vout.writeframe(int(t), data, None)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000836 except IOError, msg:
Guido van Rossumad4fcd41993-05-11 18:36:54 +0000837 self.reset()
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000838 if msg == (0, 'Error 0'):
839 msg = 'disk full??'
840 fl.show_message('IOError', str(msg), '')
841 return 0
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000842 self.nframes = self.nframes + 1
843 self.t_nframes.label = `self.nframes`
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000844 return 1
845
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000846 def close_video(self):
847 if not self.vout:
848 return
849 self.nframes = 0
850 self.t_nframes.label = ''
Guido van Rossumc5a14331993-05-07 11:20:07 +0000851 try:
852 self.vout.close()
853 except IOError, msg:
854 if msg == (0, 'Error 0'):
855 msg = 'disk full??'
856 fl.show_message('IOError', str(msg), '')
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000857 self.vout = None
Jack Jansen78991fd1993-07-23 11:59:25 +0000858 self.compressor = None
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000859
860 # Watch cursor handling
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000861
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000862 def setwatch(self):
863 gl.winset(self.form.window)
864 gl.setcursor(WATCH, 0, 0)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000865 gl.winset(self.window)
866 gl.setcursor(WATCH, 0, 0)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000867
868 def setarrow(self):
869 gl.winset(self.form.window)
870 gl.setcursor(ARROW, 0, 0)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000871 gl.winset(self.window)
872 gl.setcursor(ARROW, 0, 0)
Guido van Rossumbc6d3c31993-05-07 09:37:42 +0000873
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000874 # Numeric field handling
875
876 def getint(self, field, default):
877 try:
878 value = string.atoi(field.get_input())
879 except string.atoi_error:
880 value = default
881 field.set_input(`value`)
882 return value
883
884 def getfloat(self, field, default):
885 try:
886 value = float(eval(field.get_input()))
887 except:
888 value = float(default)
Guido van Rossumc17c84f1993-05-10 15:45:49 +0000889 field.set_input(`value`)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000890 return value
891
892 # Audio stuff
893
894 def open_audio(self):
895 if self.aformat == A_OFF:
896 return
897 import aifc
898 import al
899 import AL
900 import thread
901 self.close_audio()
902 params = [AL.INPUT_RATE, 0]
903 al.getparams(AL.DEFAULT_DEVICE, params)
904 rate = params[1]
905 self.aout = aifc.open(self.afile, 'w')
906 if self.aformat in (A_16_STEREO, A_8_STEREO):
907 nch = AL.STEREO
908 else:
909 nch = AL.MONO
910 if self.aformat in (A_16_STEREO, A_16_MONO):
911 width = AL.SAMPLE_16
912 else:
913 width = AL.SAMPLE_8
914 self.aout.setnchannels(nch)
915 self.aout.setsampwidth(width)
916 self.aout.setframerate(rate)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000917 c = al.newconfig()
918 c.setqueuesize(8000)
919 c.setchannels(nch)
920 c.setwidth(width)
921 self.aport = al.openport('Vb audio record', 'r', c)
922 self.audio_stop = 0
923 self.audio_ok = 0
924 self.audio_busy = 1
925 thread.start_new_thread(self.record_audio, ())
926
927 def start_audio(self):
928 if self.aformat == A_OFF:
929 return
930 self.audio_ok = 1
931
932 def record_audio(self, *args):
933 # This function runs in a separate thread
934 # Currently no semaphores are used
935 while not self.audio_stop:
936 data = self.aport.readsamps(4000)
937 if self.audio_ok:
Guido van Rossumf6d80321993-06-10 13:40:51 +0000938 self.aout.writeframes(data)
Guido van Rossum9f42f4f1993-05-10 15:07:20 +0000939 data = None
940 self.audio_busy = 0
941
942 def stop_audio(self):
943 self.audio_ok = 0
944
945 def close_audio(self):
946 if self.aout:
947 self.audio_ok = 0
948 self.audio_stop = 1
949 while self.audio_busy:
950 time.sleep(0.1)
951 self.aout.close()
952 self.aout = None
953 if self.aport:
954 self.aport.closeport()
955 self.aport = None
956
Guido van Rossumb7e3cc11993-05-06 16:06:44 +0000957
958try:
959 main()
960except KeyboardInterrupt:
961 print '[Interrupt]'
962 sys.exit(1)