Error when ringbuffer size isn't a multiple of bytes/sample

Post Reply
michaelrepucci
Posts: 13
Joined: Thu Aug 11, 2011 9:44 pm
Location: NYC

Error when ringbuffer size isn't a multiple of bytes/sample

Post by michaelrepucci »

I'm getting a strange bug when using the Labview_DLL.dll in my C++ program. I setup my program according to the instructions http://www.biosemi.com/faq/make_own_acq ... ftware.htm, and I'm using the Labview_DLL.dll obtained from the current download of the "USB driver Windows (32bit)" from http://www.biosemi.com/download.htm, as directed in this previous discussion: viewtopic.php?t=600.

When I use the recommended ringbuffer size of 2^25=33554432, and speed mode 4 on an Mk2 box, I get erroneous data in some of the (for me unused) EEG channels and all of the EX channels every 29747 samples. However, data continues to be collected without error, and the synchronization word is always present, exactly where it is expected.

If, instead, I make the ringbuffer size a multiple of the number of bytes per sample, this problem goes away. That is, with speed mode 4 I need to use n*282*4, with speed mode 5 I need to use m*154*4, etc, where n or m are some large number such that the ringbuffer size is close to 2^25. I didn't see this problem mentioned in any of the documentation on how to use the Labview_DLL.dll, nor in the forums, though I may have overlooked it. I believe this to be a bug in the Labview_DLL.dll, and just wanted to share my experience so that other users may avoid this problem in the future.

pmac
Posts: 70
Joined: Thu Jan 21, 2010 2:51 pm
Location: Canada

Post by pmac »

Hi Michael,

Since Actiview, by default, uses a 33554432 byte buffer and seems to be working for many users, I would doubt that there's a problem with
this size.

With buffer size 33554432 and speed mode 4 the buffer holds 29746 packets of 282 words plus 236 words of the 29747th packet. The I/O
system then wraps back to the start of the buffer and puts the rest of the 29747th packet there, overwriting some of the first packet.

Check that your modular arithmetic for indexing is correct and also that you don't look at words beyond the index value returned by
READ_POINTER - the index returned is rarely on a packet boundary.

Regards,
Paul

michaelrepucci
Posts: 13
Joined: Thu Aug 11, 2011 9:44 pm
Location: NYC

Post by michaelrepucci »

Hi Paul,

I too have been able to use ActiView to obtain uncontaminated data, so I was surprised by this error. However, it's worth noting that the DLL that I'm using, and the one that ActiView uses are different.

That being said, I wish I could share my code, but unfortunately cannot (company restriction). I've checked and rechecked the code, with special attention to the modular arithmetic, and can't find an error. Moreover, I would expect an error in modular arithmetic to create a problem in finding the next synchronization word, but that doesn't happen. That is, if my modular arithmetic were wrong, so that I was occasionally off by n bytes in a sample, I wouldn't expect to be properly aligned with the next synchronization word, but in fact I am.

As for the value returned by READ_POINTER, it is in bytes, so I divide it by sizeof(int)=4 to give me the index into the ringbuffer (which is an array of ints). I always look only at full samples of words (i.e., 282) between my last read pointer value (which of course starts its life at 0) and the latest read pointer, ignoring any partially written sample.

I'll keep investigating, but if you have any further thoughts how this could happen, please let me know.

pmac
Posts: 70
Joined: Thu Jan 21, 2010 2:51 pm
Location: Canada

Post by pmac »

Hi Michael,

The DLL with Actiview and the DLL in the driver package should be interchangable - I believe the Actiview download package has been
updated since you reported the different versions.

You might try replacing your Actiview's DLL with the one you are using for development to build some confidence that the DLL is working correctly.

Regards,
Paul

michaelrepucci
Posts: 13
Joined: Thu Aug 11, 2011 9:44 pm
Location: NYC

Post by michaelrepucci »

Paul, my huge apologies! It seems like the sleep deprivation of being a new dad (less than 3 weeks now) is in fact affecting my code. I hope you didn't waste too much time on my query, but I thank you sincerely for trying.

FYI, my modular arithmetic was fine, so I didn't lose synchronization. But when I was accessing items in the ringbuffer, I was inadvertently using indices that did exceed the ringbuffer array, as they were composed from my last read pointer plus various offsets (to index the start of EEG or EX channels). For some reason, Visual Studio didn't catch this, as it normally does, and simply allowed me to access this unrelated memory. Ooops.

Post Reply