Jump to content
  • 0

Synchronized continuous AnalogOut playback on multiple Analog Discovery 2 channels


Guest

Question

Hi,

I am a trying to write a Python script that does synchronous 2-channel playback on an AD2 of arbitrary data that is continuously sent to the device using the FDwfAnalogOutNodePlayData call.

Most of this works; I get gapless playback at a rate of 48 kHz on both channels without issue.

However, I just noticed that the playback doesn't start at the precisely the same instant on both channels, which is what I want to achieve.

My sequence of calls (omitting the FDwfAnalogOut prefix) is:

- Configure both channel's "Carrier" node to Enabled, FUNC.Play, frequency 48000.0 ;
- Feed an initial 4096 samples to both channels using nodePlayData();
- Perform a MasterSet(1, 0), which (if I understand correctly) slaves Channel 2 to Channel 1 for starting purposes;
- Call Configure(0, True) which starts the output on both channels;
- In a loop, repeatedly call nodePlayStatus() and nodePlayData() to keep the samples flowing into the device.

As indicated, this all works except for proper synchronization. Both channels show a nice generated 100 Hz sine which should be identical on both channels, but there is a significant time offset between the two.

If I just configure the channels for FUNC.Sine output, do the MasterSet(1, 0), followed by Configure(0, True), I do see perfectly aligned sines.

The time difference seems to be reproducible, and depends on the sample frequency.

At 48 kHz, it's 4 ms. (~ 200 samples).
At 96 kHz. it's 2 ms. (~ 200 samples)
At 192 kHz, it's 6 ms. (~ 1200 samples)

Any help would be appreciated!

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Right, I got it working in another way, but I'm still not quite sure why the previous code didn't work.

I now set both channels to start from TRIGSRC.PC, I start them, push in some initial data, then trigger them (using FDwfDeviceTriggerPC), followed by the loop. This works, but it's a bit more complicated. Since this is for a demo program I'd like the simplest possible solution, so I still wonder if the sequence in my previous post can be made to work.

Now that I have synchronous output I can do nice things :-)

 

Link to comment
Share on other sites

  • 0

Right, so I got it working without triggering, but now I'm confused about how it can work ... ! ?

My code can be found here. It is built on my "pydwf" package, which is work in progress, but very much a usable and easy-to-use binding to the DWF library already. I'd encourage anyone reading this and interested in controlling the Waveforms devices from Python to have a look.

In the current code, I set CH2 as the master of CH1, then immediately I enable CH1 (and, because of the preceding master, also CH2).

At this point I would assume that both channels are starved for samples, since I have not yet given them anything to play. So they probably output 0, or something.

After that, I enter the while loop, which decides which channel it will give data to next. In the API, there is no call to hand over data to 2 channels simultaneously, so I have to pick a first channel to send a bunch of samples to. Turns out, my selection will currently favor CH2.

Then I hand over a few thousand samples to CH2, and repeat the while loop body. Now, I hand over a few thousand samples to CH1.

So what I don't understand is this: even though the channels have been started, and reporting "triggering" as their status; and I clearly feed channel 2 before channel 1, the samples come out perfectly synchronized.

The only thing I can think of is that internally in the FPGA, the "master" setting fixed the behavior so that the internal state machine now looks at the buffers of BOTH channels to decide if it will output an actual sample or an idle ("no data available") sample. Is that perhaps what is going on here?

Or is there some other clever thing going on that I don't see?

Curious mind wants to know...

 

Edited by reddish
missing piece of sentence
Link to comment
Share on other sites

  • 0

Hi @reddish

Here you have an example for stereo play and record: AnalogOutIn_PlayRecordStereo.py

image.png.7260a3d52ed40706c162a21d4dc5c49a.png

image.thumb.png.38d91bb669de432a115dc87fe1df3ffa.png

For synchronized Wavegen output you can use either channels to be maser or use Configure with -1 to set up master automatically.
dwf.FDwfAnalogOutConfigure(hdwf, c_int(-1), c_int(1))

For triggering various combinations can be used, depending on the requirements. For this purpose the easies is probably triggering the Scope on Wavegen.
dwf.FDwfAnalogInTriggerSourceSet(hdwf, trigsrcAnalogOut1)

Edited by attila
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...