Initial revision
diff --git a/Lib/lib-stdwin/StripChart.py b/Lib/lib-stdwin/StripChart.py
new file mode 100644
index 0000000..2021cc4
--- /dev/null
+++ b/Lib/lib-stdwin/StripChart.py
@@ -0,0 +1,67 @@
+# Module 'StripChart'
+
+
+import rect
+from Buttons import *
+from Resize import *
+
+
+class StripChart() = LabelAppearance(), NoReactivity(), NoResize():
+ #
+ def define(self, (win, bounds, scale)):
+ self.init_appearance(win, bounds)
+ self.init_reactivity()
+ self.init_resize()
+ self.ydata = []
+ self.scale = scale
+ self.resetbounds()
+ return self
+ #
+ def setbounds(self, bounds):
+ LabelAppearance.setbounds(self, bounds)
+ self.resetbounds()
+ #
+ def resetbounds(self):
+ (left, top), (right, bottom) = self.bounds
+ self.width = right-left
+ self.height = bottom-top
+ excess = len(self.ydata) - self.width
+ if excess > 0:
+ del self.ydata[:excess]
+ elif excess < 0:
+ while len(self.ydata) < self.width:
+ self.ydata.insert(0, 0)
+ #
+ def append(self, y):
+ self.ydata.append(y)
+ excess = len(self.ydata) - self.width
+ if excess > 0:
+ del self.ydata[:excess]
+ if not self.limbo:
+ self.win.scroll(self.bounds, (-excess, 0))
+ if not self.limbo:
+ (left, top), (right, bottom) = self.bounds
+ i = len(self.ydata)
+ area = (left+i-1, top), (left+i, bottom)
+ self.draw(self.win.begindrawing(), area)
+ #
+ def draw(self, (d, area)):
+ self.limbo = 0
+ area = rect.intersect(area, self.bounds)
+ if area = rect.empty:
+ return
+ d.cliprect(area)
+ d.erase(self.bounds)
+ (a_left, a_top), (a_right, a_bottom) = area
+ (left, top), (right, bottom) = self.bounds
+ height = bottom - top
+ i1 = a_left - left
+ i2 = a_right - left
+ for i in range(max(0, i1), min(len(self.ydata), i2)):
+ split = bottom-self.ydata[i]*height/self.scale
+ d.paint((left+i, split), (left+i+1, bottom))
+ if not self.enabled:
+ self.flipenable(d)
+ if self.hilited:
+ self.fliphilite(d)
+ d.noclip()
diff --git a/Lib/lib-stdwin/VUMeter.py b/Lib/lib-stdwin/VUMeter.py
new file mode 100644
index 0000000..65c018b
--- /dev/null
+++ b/Lib/lib-stdwin/VUMeter.py
@@ -0,0 +1,46 @@
+# Module VUMeter
+
+import audio
+from StripChart import StripChart
+
+K = 1024
+Rates = [0, 32*K, 16*K, 8*K]
+
+class VUMeter() = StripChart():
+ #
+ # Override define() and timer() methods
+ #
+ def define(self, (win, bounds)):
+ self = StripChart.define(self, (win, bounds, 128))
+ self.sampling = 0
+ self.rate = 3
+ self.enable(0)
+ return self
+ #
+ def timer(self):
+ if self.sampling:
+ chunk = audio.wait_recording()
+ self.sampling = 0
+ nums = audio.chr2num(chunk)
+ ampl = max(abs(min(nums)), abs(max(nums)))
+ self.append(ampl)
+ if self.enabled and not self.sampling:
+ audio.setrate(self.rate)
+ size = Rates[self.rate]/10
+ size = size/48*48
+ audio.start_recording(size)
+ self.sampling = 1
+ if self.sampling:
+ self.win.settimer(1)
+ #
+ # New methods: start() and stop()
+ #
+ def stop(self):
+ if self.sampling:
+ chunk = audio.stop_recording()
+ self.sampling = 0
+ self.enable(0)
+ #
+ def start(self):
+ self.enable(1)
+ self.timer()
diff --git a/Lib/stdwin/StripChart.py b/Lib/stdwin/StripChart.py
new file mode 100755
index 0000000..2021cc4
--- /dev/null
+++ b/Lib/stdwin/StripChart.py
@@ -0,0 +1,67 @@
+# Module 'StripChart'
+
+
+import rect
+from Buttons import *
+from Resize import *
+
+
+class StripChart() = LabelAppearance(), NoReactivity(), NoResize():
+ #
+ def define(self, (win, bounds, scale)):
+ self.init_appearance(win, bounds)
+ self.init_reactivity()
+ self.init_resize()
+ self.ydata = []
+ self.scale = scale
+ self.resetbounds()
+ return self
+ #
+ def setbounds(self, bounds):
+ LabelAppearance.setbounds(self, bounds)
+ self.resetbounds()
+ #
+ def resetbounds(self):
+ (left, top), (right, bottom) = self.bounds
+ self.width = right-left
+ self.height = bottom-top
+ excess = len(self.ydata) - self.width
+ if excess > 0:
+ del self.ydata[:excess]
+ elif excess < 0:
+ while len(self.ydata) < self.width:
+ self.ydata.insert(0, 0)
+ #
+ def append(self, y):
+ self.ydata.append(y)
+ excess = len(self.ydata) - self.width
+ if excess > 0:
+ del self.ydata[:excess]
+ if not self.limbo:
+ self.win.scroll(self.bounds, (-excess, 0))
+ if not self.limbo:
+ (left, top), (right, bottom) = self.bounds
+ i = len(self.ydata)
+ area = (left+i-1, top), (left+i, bottom)
+ self.draw(self.win.begindrawing(), area)
+ #
+ def draw(self, (d, area)):
+ self.limbo = 0
+ area = rect.intersect(area, self.bounds)
+ if area = rect.empty:
+ return
+ d.cliprect(area)
+ d.erase(self.bounds)
+ (a_left, a_top), (a_right, a_bottom) = area
+ (left, top), (right, bottom) = self.bounds
+ height = bottom - top
+ i1 = a_left - left
+ i2 = a_right - left
+ for i in range(max(0, i1), min(len(self.ydata), i2)):
+ split = bottom-self.ydata[i]*height/self.scale
+ d.paint((left+i, split), (left+i+1, bottom))
+ if not self.enabled:
+ self.flipenable(d)
+ if self.hilited:
+ self.fliphilite(d)
+ d.noclip()
diff --git a/Lib/stdwin/VUMeter.py b/Lib/stdwin/VUMeter.py
new file mode 100755
index 0000000..65c018b
--- /dev/null
+++ b/Lib/stdwin/VUMeter.py
@@ -0,0 +1,46 @@
+# Module VUMeter
+
+import audio
+from StripChart import StripChart
+
+K = 1024
+Rates = [0, 32*K, 16*K, 8*K]
+
+class VUMeter() = StripChart():
+ #
+ # Override define() and timer() methods
+ #
+ def define(self, (win, bounds)):
+ self = StripChart.define(self, (win, bounds, 128))
+ self.sampling = 0
+ self.rate = 3
+ self.enable(0)
+ return self
+ #
+ def timer(self):
+ if self.sampling:
+ chunk = audio.wait_recording()
+ self.sampling = 0
+ nums = audio.chr2num(chunk)
+ ampl = max(abs(min(nums)), abs(max(nums)))
+ self.append(ampl)
+ if self.enabled and not self.sampling:
+ audio.setrate(self.rate)
+ size = Rates[self.rate]/10
+ size = size/48*48
+ audio.start_recording(size)
+ self.sampling = 1
+ if self.sampling:
+ self.win.settimer(1)
+ #
+ # New methods: start() and stop()
+ #
+ def stop(self):
+ if self.sampling:
+ chunk = audio.stop_recording()
+ self.sampling = 0
+ self.enable(0)
+ #
+ def start(self):
+ self.enable(1)
+ self.timer()