EEGMIR -- Prototype EEG biofeedback app

eegmir screenshot

This app is in the alpha stage, and currently there is very little documentation beyond the discussions on the OpenEEG mailing list, which I have pasted in below. However, I thought I would give it a page so that people know about its existence. It currently reads data from a file or from the serial port in one of several formats (including both of the modularEEG formats), and it allows display of the analysis as bars. The configuration is very flexible, using Fiview-style filter-specs (using fidlib internally) to determine the analysis driving the bar display. The analysis method gives very fast response, and is documented HERE. Several screens of bars may be set up and switched between. There is some testing code in there for audio feedback too, but this needs a lot more work. Development has stalled on this project for the moment, as I concentrate on other things.

Download joint Linux-Windows release file

I've just got the latest release up here without all the previous versions. (391K)

Documentation from the mailing list

Date: Sun, 9 Feb 2003 14:13:22 +0000
Subject: Prototype real-time app release 0.1.1

Joe Street has been encouraging me to get a move on with writing some
real-time code, and I've made some progress.  I have taken the
approach of creating a prototype rather than trying to do everything
100% correctly first time.  [...]

I have a snapshot up here:

I'm using a ZIP file in order to do joint Linux/Windows releases.
Text files appear in their natural UNIX format, but are duplicated in
Windows CRLF format with a .txt extension for the benefit of Windows
users.  A Windows binary is included, as is the SDL.DLL file.  So,
Windows users have it very easy and just need to run the EXE.  Linux
users may or may not have to rebuild from source, but in any case they
*will* need to install SDL.

In this prototype, you start on page F1 (an error logging screen), and
you switch between pages using the function keys.  You can exit the
app using ESCAPE.  Feel free to resize it -- everything adjusts.

Everything is controlled from the "eegmir.cfg" file.  At the moment
there is only a bar-display coded up.  However, it is very flexible,
as it is specified in the config file using Fiview filter
descriptions.  So, you can design your filters with Fiview, and then
build an EEG bar-display from them.

The filtering is done with my heterodyne technique (which gives
continuous outputs rather than oscillating ones), so you just need to
select the bar centre-frequency and a low-pass filter that describes
the required response around that centre frequency.  So the line:

  filter 10, LpBu4/=2;

specifies a filter between 8Hz and 12Hz, since the low-pass filter
width is 2Hz.  (The = flag is my new notation for the old fiview -a
auto-adjust option -- basically, it just makes sure the filter gives
its 50% response point at exactly 2Hz; I need to do a fiview release
with these changes in, but not right now ...).

The output of that filter drives the spots on the display, and the
signal is passed through a further smoothing filter to drive the bars
themselves.  This is another low-pass filter.  I reckon LpBe2 filters
are good for this, but you can use any filter you wish, or even 'x 1'
for no filter at all.

You can define different bar charts in the .cfg file for each of the
F-keys from F2 to F10 if you wish, and switch between them.  The
current bar-chart display is just something I knocked up quickly to
test it.  I should really try to make a nice Mind-Mirror emulation, or
experiment with exponential or linear sets.  Anyway, if anyone designs
any nice bar-charts, they just need to post the config files.

Incidentally, I used Jack Spaar's code for doing serial input on
Windows.  I did try to use the OpenEEGLib code, but it was going to be
too much work to strip it down to what I actually needed (as well as
converting C++ -> C), so I took the easy option.

As I have taken the shortest route, vast chunks of the code may need
to be rewritten or reorganized at a later stage.  For example, all the
planning that Dave, Andreas, etc have been putting in to the
OpenEEGLib is to avoid this kind of massive refactoring.  Still, in
the interests of testing ideas and getting something working in the
form of a prototype, I think this is okay.

Also, I have to say that SDL is great -- it "just works".  After
testing on Linux, I just needed to fix one typo I introduced into the
Win serial code, and it built and ran fine right away.  (I tested on
Win98SE as that's all I have here).

I've also set up scripts now using the MinGW cross-compiler so that I
can build the complete release ZIP (including Windows executables)
just with one command from Linux.  This means I can make releases
fairly often.

Right now, I want to put in the features that Joe is after, plus any
other ideas that come to me -- that is the main priority.  However, I
also wanted to get the code and executables out there so that other
people can play around with it if they want to.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Date: Wed, 12 Feb 2003 00:59:33 +0000
Subject: EEGMIR 0.1.2

I've put up version 0.1.2:

I've fixed most of the bugs people mentioned (but not the 1-channel
crashing bug), and set up a nice Mind Mirror emulation on F2, along
with 'file' input (as an alternative to serial input).  Also Jim
Meissner format files can be read in (and Jim-M could probably even
run it on his old hardware).

The config file format has changed a little, so any old config files
probably won't work without modifications.  See the new config file
for examples of how to set up running from a file.

There are now also settings you can change on the bar display page.
They work very similarly to BWView -- i.e. press a letter to select
which one you want to change, and then use digits to access preset
values, or +/- keys to change in smaller steps.  '=' is the same as
'+'.  The bar display only has two settings at the moment, but other
displays are likely to have a lot more.

Sometime I should document all this, but there seems little point when
it's all changing so quick.

Also, (Joe) the signal display colours have now been corrected so that
the fill-in colour is not too bright.  Actually, I copied the wrong
colour value from BWView, so that explains why it looked wrong.

Next job is a display to show how much jitter we are getting on the
incoming data, and then some audio output code.  (The jitter
information is necessary in order to see how much it is necessary to
delay the data feeding to the audio code in order to have a clean
output -- although I could try it both ways).

Running the Windows version under emulation in Win4Lin, I can get it
to drop dead with an error whilst running -- seemingly because it
overloads.  This could be because of the emulation, though.  However,
if anyone has problems like this, let me know.

I may need to think more about optimising things and prioritising the
threads if we start running into trouble.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Date: Tue, 18 Feb 2003 01:58:50 +0000
Subject: EEGMIR 0.1.4 release

The latest version of my prototype biofeedback app for Windows and
Linux is available here:

Major changes since the previous version include:

- Jitter and sampling-rate measurement screen on F12 (by default, see
  config file)

- Changes to avoid trouble with the event queue overflowing

- 'jm2' and 'jm4' formats are now called 'jim-m', with 'chan' values
  of 2 and 4

The jitter measurement screen on F12 shows two lines wrapping around
in columns -- one is the estimated actual time that the sample was
generated, and the second is the time it actually arrived.  The area
between these two lines is filled in yellow.  If there is a delay
somewhere in the system, then a bunch of samples arrives late, which
looks like a step on the display.  If sync is lost, then you get red
lines as well.

At the top is reported the measured sample rate (i.e. the sample rate
measured using the computer's clock) along with the theoretical rate
you put in the config file, then the maximum and average jitter in ms.
(I typically get 257.14Hz for the measured sampling rate from my

The whole display will be nonsense for the first few seconds as the
internal buffers fill up with good data from the EEG device.  After
that point it should look like a load of little steps, the smaller the
steps the better.  (Note: you need to press F12 to get it to redraw).

Running on Linux on a dodgy Celeron-900 box and using the irqtune
setup that Andreas suggested a long time back, I get 9ms average
jitter (25ms max) whilst running the Mind Mirror screen.  If I drag
the windows around (filled drag, which blocks the interrupts with my
chipset on this version of X-Windows), I start getting red lines.

Running on Windows (Win98SE), though, the result is quite spectacular.
With the Mind Mirror display running, I get 1ms average jitter (11ms
max).  The yellow line is barely visible.  There has to be something
very right going on here.  Maybe the way SDL hooks into Windows gives
it some advantages it doesn't get on Linux.

By doing random things on Windows I could get some big steps to appear
(e.g. 100-200ms delays), but I couldn't get it to lose sync.

Incidentally, I've made full use of the packet counter in the
modularEEG format now, and it will fill in error samples for any that
are missing.  This means that the timing display is not in any way
upset by packet or sync loss.

For the next version, I'm considering trying the serial port code in
the audio handler, on the basis that this is likely to be called with
a higher priority.  This may get around some of the 100-200ms delays
on Windows, although we'd lose the 1ms jitter level.  It is worth a
try anyway.

The event queue overflows were reported by Jack Spaar on his very fast
machine, which seem to make no sense to me, but I had also seen them
running on Win4Lin (Windows emulated on top of Linux).  So, I've put
some code in to handle these more nicely.  You'll see messages on F1
if a TICK event ever has to be dropped.  (Also, remember that you can
page up and down the event history on F1 using PageUp/PageDn/etc)

That's it for now --


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Date: Fri, 28 Feb 2003 21:40:21 +0000
Subject: EEGMIR 0.1.5 release

The latest version of my prototype biofeedback app for Windows and
Linux is available here:

There is nothing too amazing on the outside for people who are hoping
for new features, but I've sorted out a lot of stuff on the inside.
This is still very much a prototype, and you'll probably have to
fiddle with some config values to tune it to your system.

- Audio output is now working, with some FM output to prove it works

- Serial reads can now be done either in their own thread or from the
  audio thread.

I had to do a lot of head-scratching to figure out how to get the
three clocks synchronized (computer clock, EEG device clock, and audio
sample clock) especially considering the only available cross-checks
between these clocks may be inaccurate (e.g. processing delays may
mean we handle an incoming packet late, or an outgoing audio block
late), but this is sorted now, I think, and any clock drift is handled

Things you may want to tune in the config file:

  buf 1024;
  rate 44100;

The 'buf' setting should be a power of two and gives the audio block
size in samples.  1024 is 1024/44100*1000 == 23.2ms blocks.  512
(12ms) doesn't quite work on my Linux machine.  On Windows (W98SE) I
had to up it to 2048 to get smooth audio output.

  port COM1 57600;
  fmt modEEG;
  rate 256;
  chan 2;

You may want to try it with 'audio-sync' either present or commented
out.  Without it, serial reads are done from their own thread.  With
it, they are done along with the audio processing.  In theory audio
should get higher priority than anything else, but it doesn't look
like that's always the case.  Maybe it's worth trying both ways.
Probably without is better on Windows.

  fps 20;

You might want to change the FPS (frames per second) of the displays
if the load is too much.

  test-fmsig 50ms 1000+500/100;

This is the audio page (on F11).  At the moment there is only some
testing code generating FM audio output.  This uses EEG channels 1 and
2 to drive sine-wave oscillators on the left and right stereo outputs.
The centre frequency is 1000Hz here, with frequencies ranging between
1000-500 and 1000+500 (i.e. 500Hz to 1500Hz).  The volume level here
is 100 (meaning 100%).

The ms figure tells the audio code how far back in time to look for
the data samples to output.  You can set this to 0ms if you like, but
then every single little delay in the system will show up as
disruption in your FM audio output.  The idea is to find some delay
value that the jitter rarely exceeds (see F12 screen for jitter

If you're using a 2048-sample audio buffer and 'audio-sync' set, then
you'd need to set it to 100ms or so.  Probably it would be a good idea
to get rid of audio-sync, though, in that case.

The FM code does interpolation between the incoming samples, so it
should be pretty smooth.  However, listening to this for too long was
giving me a headache and I was glad to turn it off -- you can comment
it out in the config file.  However, it does prove that it is working.
I hope to add other audio options and more flexibility in future in
the audio output, for example a hb2.mp3 style output, or maybe a
simple amplitude-modulated noise output.

I don't know if this FM output accurately reproduces the result Joe
Street has achieved through hardware -- perhaps he can tell me if it
needs correcting in any way.

So, no big new features, but I've sorted a few things out.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Date: Tue, 11 Mar 2003 22:59:22 +0000

I've put a new release up on my site, with only minor changes:

The main difference is that there is a new option in the [win-dev]
section, called 'rawdump', which is commented out at the moment.  If
you uncomment it, all the data received whilst the program is running
will be written to a file called 'dump.raw'.  You can replay it again
using the 'file' options from before.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Date: Tue, 15 Apr 2003 17:42:28 +0100
Subject: Re: [Openeeg-list] hi

amyl wrote:
> thanks for the advice! I'm really impressed with your progams: EEGMIR,
> FIVIEW, BWVIEW. I've been interested in using the modular EEG as an EOG and
> pipeing realtime data through fiview using this filter:
> fiview 256 -i LpBe8/25, LpBu8/25
> And displaying it in eegmir (which I must add is really impressive
> especially with the sounds); is this possible, and how do you pipe data
> through fiview?

Sorry for the delay in replying -- I've been away for a few days, and
now I'm down with 'flu, which isn't helping.

Fiview is just for designing the filters.  If you actually want to put
data through the filters, you'd need to compile the example code
generated (i.e. write your own program).

However, eegmir uses fiview filters internally, so you can use your
filters there.  You'll need to look at the eegmir.cfg file.  For
example, you could create a special bar display that shows the input
signal passed through your filters.  For example, using something like

  filter 0, LpBe8/25;


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Date: Thu, 24 Apr 2003 10:19:39 +0100
Subject: EEGMIR and BWView updates for new firmware

I've released new versions of EEGMIR and BWView on my website:

The updates are just to support the new modularEEG packet format, as
output by the firmware that Andreas plans to release shortly.

For EEGMIR, the format-handler "modEEG" now expects the new packet
format -- "modEEGold" is available for handling the old format.

For BWView, the format-handler "mod/<rate>" now expects the new packet
format -- "mod0/<rate>" is provided to handle old-style files.

I've tested these with my own modularEEG device, and everything seems
to be working fine, but if anyone else has problems (once Andreas has
released the firmware), please let me know.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Subject: [Openeeg-list] Testing viability of OpenEEG server ideas with EEGMIR
Date: Tue Dec 30 01:19:42 2003

I know I am supposed to be studying, but I've made some changes to
EEGMIR just to test the idea of passing data over TCP/IP.  These only
work on Linux for the moment (I'm not set up for Windows cross-
compilation and testing on this laptop yet, and my previous main
machine died):

I've added client code to EEGMIR which connects to an "OpenEEG server"
as specified in Rudi's draft, and displays the resulting data stream
just the same as it does any other EEG data stream.  To set this up,
just put "server localhost;" in the [unix-dev] section of the config
file (instead of all the serial settings or whatever).  See the *.cfg
files provided for examples.  Connecting to other machines than
localhost should also work, but I haven't tested that.

I've also added some really minimal "OpenEEG server" code to EEGMIR to
test the other side.  If you start it as "eegmir -S", it runs as a
server without the GUI, using "eegmir-server.cfg" as its config file.
All the display-related stuff is ignored in the config file, but the
device section is used to set up a device as normal (either a file or
a serial port).  The data from this device is then made available to a
client connecting on port 8336 via EDF as spec'd in the draft.

When I say the server is minimal, I mean it -- it only handles one
client for one session, and it only understands two of the commands
Rudi put in the draft, i.e. "GetEDFHeader" and "SendSamples".  It also
fakes most of the EDF info instead of filling in proper values.  This
is all that is needed to test the connection, though.

I'm sending through the error information in channel 0 of the EDF
file.  Because error information only requires one bit per sample (I'm
using bit 0), I've called the channel 'OpenEEG flags', allowing the
possibility of using the other bits for other things.  This is all
open for discussion and change, though -- I set this up just for

Unfortunately I don't have my modularEEG device with me right now due
to moving, but I have tested reading data from a file with the server
(eegmir -S), and sending it via TCP/IP to the client (eegmir) and
displaying it there, and it works well.  The jitter is low.  It would
be much more interesting to see how it copes when the server is
reading live data from the serial port, though.

Perhaps someone using Linux can test it.  (You just need to edit
eegmir-server.cfg to comment out the existing [unix-dev] section and
uncomment a section that reads data from the serial port instead, with
whichever protocol (P2/P3) you are using).

It would be interesting to compare the F12 displays to get an idea of
how much (if any) jitters and delays are added due to the
server->client connection (i.e. try it with EEGMIR as it is normally
configured reading from the serial port, then try it with the server
reading the serial port, and the GUI side of EEGMIR reading from the

But anyway -- things seem promising so far.


UAZU-Up- These pages and files, including applets and artwork, are Copyright (c) 1997-2019 Jim Peters unless otherwise stated. Please contact me if you'd like to use anything not explicitly released, or if you have something interesting to discuss.