wavesynth: program decoding

This commit is contained in:
Sebastien Bourdeauducq 2015-03-15 18:05:03 +01:00
parent 327448977c
commit 1d0fde7f13
1 changed files with 131 additions and 16 deletions

View File

@ -25,7 +25,7 @@ class SplinePhase:
def set_coefficients(self, c): def set_coefficients(self, c):
self.c = self.c[0:1] + c[1:] self.c = self.c[0:1] + c[1:]
self.c0 = self.c[0] self.c0 = c[0]
def clear(self): def clear(self):
self.c[0] = 0.0 self.c[0] = 0.0
@ -55,21 +55,136 @@ class Wave:
return self.bias.next() + self.dds.next() return self.bias.next() + self.dds.next()
if __name__ == "__main__": class TriggerError(Exception):
pass
class Synthesizer:
def __init__(self, nchannels, program):
self.channels = [Wave() for _ in range(nchannels)]
self.program = program
# line_iter is None: "wait for segment selection" state
# otherwise: iterator on the current position in the segment
self.line_iter = None
def trigger(self, selection=None):
if selection is None:
if self.line_iter is None:
raise TriggerError
else:
if self.line_iter is not None:
raise TriggerError
self.line_iter = iter(self.program[selection])
r = [[] for _ in self.channels]
while True:
line = next(self.line_iter)
if line["dac_divider"] != 1:
raise NotImplementedError
for channel, channel_data in zip(self.channels,
line["channel_data"]):
if "bias" in channel_data:
channel.bias.set_coefficients(channel_data["bias"])
if "dds" in channel_data:
channel.dds.amplitude.set_coefficients(
channel_data["dds"]["amplitude"])
channel.dds.phase.set_coefficients(
channel_data["dds"]["phase"])
if channel_data["dds"]["clear"]:
channel.dds.phase.clear()
for channel, rc in zip(self.channels, r):
for i in range(line["duration"]):
rc.append(channel.next())
if line["wait_trigger"] and line["jump"]:
raise ValueError("Line cannot both jump and wait for trigger")
if line["wait_trigger"]:
return r
if line["jump"]:
self.line_iter = None
return r
def main():
program = [
[
# segment 0
{
# line 0
"dac_divider": 1,
"duration": 100,
"channel_data": [
{
# channel 0
"dds": {"amplitude": [0.0, 0.0, 0.01],
"phase": [0.0, 0.0, 0.0005],
"clear": False}
}
],
"wait_trigger": False,
"jump": False
},
{
# line 1
"dac_divider": 1,
"duration": 100,
"channel_data": [
{
# channel 0
"dds": {"amplitude": [49.5, 1.0, -0.01],
"phase": [0.0, 0.05, 0.0005],
"clear": False}
}
],
"wait_trigger": False,
"jump": True
},
],
[
# segment 1
{
# line 2
"dac_divider": 1,
"duration": 100,
"channel_data": [
{
# channel 0
"dds": {"amplitude": [100.0, 0.0, -0.01],
"phase": [0.0, 0.1, -0.0005],
"clear": False}
}
],
"wait_trigger": False,
"jump": False
},
{
# line 3
"dac_divider": 1,
"duration": 100,
"channel_data": [
{
# channel 0
"dds": {"amplitude": [50.5, -1.0, 0.01],
"phase": [0.0, 100.05, -0.0005],
"clear": False}
}
],
"wait_trigger": False,
"jump": True
}
]
]
x = list(range(400)) x = list(range(400))
w = Wave() s = Synthesizer(1, program)
w.dds.amplitude.set_coefficients([0.0, 0.0, 0.01])
w.dds.phase.set_coefficients([0.0, 0.0, 0.0005])
y = [w.next() for i in range(100)]
w.dds.amplitude.set_coefficients([49.5, 1.0, -0.01])
y += [w.next() for i in range(100)]
w.dds.phase.set_coefficients([0.0, 0.1, -0.0005])
y += [w.next() for i in range(100)]
w.dds.amplitude.set_coefficients([50.5, -1.0, 0.01])
y += [w.next() for i in range(100)]
r = s.trigger(0)
y = r[0]
r = s.trigger(1)
y += r[0]
cairoplot.scatter_plot("plot.png", [x, y]) cairoplot.scatter_plot("plot.png", [x, y])
if __name__ == "__main__":
main()