RE: [buildcheapeeg] RE: Software (was ElectricGuru)

From: John Morrison (jmorrison_at_ahc.net.au)
Date: 2002-01-21 09:13:58


-----Original Message-----
From: Rob Sacks [mailto:editor_at_realization.org]

Dear John,
Don't you just hate getting Dear John letters. :-)
Thanks for the kind words about ElectricGuru and for
understanding my reluctance to use it for the basis for
further development.
I've written QUICK programs before and I"D HATE anyone to actually see them.
:-)

You make some excellent suggestions. Before I respond
to them, let me say that in my opinion, the most important
thing that can be done at this stage, to make good software,
is look at existing feedback programs and use them as
starting points to design the screens and other user features
of our new software.
I agree how about we start a new thread and ask WHAT people what the
software to do.
I'm not real familiar with what is out there so maybe a list of links would
help us.
Correlate the results and start from there?

In other words, we should be thinking about the functional
specs from the viewpoint of the user, because they tell us
what accomodations and allowances must be built into the
program so it can do what it will eventually be required
to do. Or, to put it more simply, we should decide first
what the program will be, before we decide how to build
it. The easiest way to figure out what the program will be
is to design the interface from the standpoint of the user.
And the easiest way to make that design is by drawing
the screens and menus.
For example, do we like the method used by Waveware to
input feedback protocols? Can we design something
better? Etc.

YES I agree it is after all the user that will decide if the program is a
hit or a flop.
BUT if be break the program up as I've stated further on we can give the
user what they want and still work on the "guts" of the program.

Somebody may be tempted to object at this point: but
we don't have to plan carefully, because we will make
the software so it can be modified and extended. To
which I reply: yes, of course we will do everything
possible to write software that can be modified in
the future as easily as possible, but this is not a substitute
for planning as thoroughly as possible in advance. In
fact, the two things go together. The best way to promote
maximum future extensibility, is to define the
future needs as concretely as possible in advance.
VERY true if we design a good "User" interface and good internal interfaces
extending the design becomes VERY easy.

One of our members here volunteered last year to
coordinate a project to solicit comments about the user
interface from experienced feedback practioners, but
if anything has come of that yet, I'm not aware of it.
OK so who ever that was can you please give us a report?

I'm a great believer in the crayon school of
spec'ing: draw the screens and menus.
No I prefer coloured pencils. :-)

> We make the software modular. This way we can link in
> whatever "Modules" are required for a particular
> purpose. .... ECG's and such have already been discussed
> so why not allow for that in the software.

I agree that this should be our goal. It is also our most
difficult design problem. How can we make a program
that allows other programmers, in the future, to take
the source code and add new types of machines to it?

It's a difficult problem because when somebody adds a new
type of machine, he or she will have to add new code for
every single functional machine-specific part of the
program.
One way is to break the design into 3 parts.
Each of the 3 sections would include it's own user interface so the user
could alter the settings manually.
But would also have a program interface so that other modules (i.e.
biofeedback interface) could modify it programmatically.
Also each stage would contain a library of functions that could be used to
do common functions.

1. Input (The hardware interface)
- Each type of hardware (i.e. eeg, ECG, whatever) would give the system the
same interface and signals so further stages can be written without regard
for the type of hardware
2. Processing
- This is where we place all the digital filters and "fancy stuff" (Sorry
technical term there) :-)
- Digital triggers could be placed here too. (i.e. a module that will send
a signal back when a certain wave form is present)
3. User Interface
- The pretty graphics that everyone loves and wants.
- It would consist of an umbrella interface that give the user access to all
of the modules (All levels).
- The user would select the "User Interface" module he wants (eg Standard
EEG) and go from there
o This would be where it's all tied together. It chooses the input, the
processing to be done and how to display it. Which should be very easy with
well defined interfaces.
o How about a user interface that compresses the data and sends it real time
to someone else on the net (Maybe your doctor) :-) It's possible.
Now let's suppose, after the EEG part of the program
is complete, that somebody wants to add support for
an ECG machine. Every single part of my functional
breakdown (except the last) has to be changed.
Not at all the input side would have to be added to (a new ECG module).
Processing may need some additions unless the filters are flexible enough to
handle both types.
And the user interface would get an addition of an ECG monitor.
BUT........... from then on different ECG machines could be added wit only a
change in the input stage
User Interface modules could be written that take both ECG and EEG inputs
for biofeedback purposes.

In other words, there's no easy or natural way to divide this
program into modules that allows additional modules to
be *added* when new types of machines are added. Instead,
pre-existing modules will need to be modified. Or the
equivalent of a whole new program must be added. If you
have to add a whole second set of everything I just specified,
in what sense are you modifying anything? You're not
modifying anything; you're writing a second program. (Of
course if the two machines communicate simultaneously
through the same port, the port-reading code has to be
integral, and some low-level code like the FFT routines
can service both the original code and the new code,
but these two things are a small portion of the program,
and the significance of the first one is that it cannot be
done in a modular way.)
It's the tying together that I'm looking for. A new TYPE of device will
require additions in all 3 layers but after that new user interfaces or
devices of the same sort can be added with minimal or no changes to the
other layers.

Alternatively, the program could be written as a sort of
interpreter that allows support for new machines to be
specified in a sort of program-specific data format. This
second suggestion would be quite technically demanding
and probably not worth the effort.
Interpreters are too slow for what we want. But things like digital filters
could be parametised so that they can be used over a wide range of uses.

If somebody can think of an easy or natural way to divide
this type of program into modules that allow new types of
machines to be easily added, I'd like to hear it. I've been
thinking about this for a year now without much success.
See above!
(By the way, if we write a good program, it will
not "belong" to the hardware designed by this group,
any more than Linux belongs to any particular brand
of computer.)
If this all gets up and going we should start a new sourceforge project as
you say it is really a separate part of the project with it's own problems
and problems.

> Anyone can added their own modules to the user interface

It's useful to examine the way that this is currently
implemented by Brainmaster. Brainmaster publishes
a DLL that is a sort of mathematical server. The DLL
parses the incoming data from the EEG machine,
decomposes it with FFT and filters, and makes it available
to the user program. The user then writes everything else.
This would be easy for us to imitate. But does it allow
the user to add a module to the existing interface? No; it
allows the user to write a whole separate interface.
This really covers level 1 & 2 in the design above. We split what they have
into the RAW DATA (1. input) then run it through filters (2. Processing) to
give us the data for the user interface.

If we examine the interface of an existing program such as
Waveware (particularly the protocol-design screens) it
becomes apparent that it's really rather difficult to allow
a user to *add* something to an *existing* interface.
Never seen the program so I can't comment. It isn't easy to building a
cheap EEG machine either. :-)

The one thing that *is* easy to add is the *reward*
portion of the interface... the sounds that the user
listens to, or the game that the user plays, etc. But
precisely because this is easy to do, we don't have
to worry about it too much.
But if we think beyond a simple User program. Why not make it possible to
have a module that acts as a trigger the "reward/game" program sets up one
or more of these triggers as it's input so there is NO reason for the
programmer to worry about HOW to analyse the input just what to do when it
happens. :-)

(I keep stressing the protocol-input screens because they
embody the whole functionality of the program. Can
The user train on phase coherence or on reduced
variance? Does a successful epoch affect something in
a game or does it play a major chord from an oboe?
All this is implied and embodied in the protocol-input
screens.)

> How about a user program that Bi-audio sounds
> that response to your current brain waves?

Sure.

> Use JAVA for the output and user interfaces.

If anybody wants to write Java, great, go ahead.
Personally, I'm only interested in writing software
that is as excellent as possible from the standpoint
of the user. To me, the user is God. That means
I want maximum artistic control and speed, and
I want to write a program that can be used by as
many people as possible.

That leads me to the usual tools used by most
commercial publishers: C++, native code, the
most widely-used operating system, etc. Bottom line:
if I write more code of this kind, I prefer to write
in C++ for Windows and DirectX. Of
course every module that can be portable, should
be made portable.

I'm not saying this is right and Java is
wrong; it's what I would want to do personally.

If anybody else wants to write in Java, that's
fine, I wouldn't try to discourage them.

OK I can see your point I program in either and C++ defiantly can produce
faster code.
Why I say Java should be considered is that it is portable with out
recompiling. There are a lot of Linux users out there and it is growing.
If we ignore them I believe it would be a mistake.
Also as Linux runs on low end platforms the experimenters out there could
set up an old 486 as there "MIND MACHINE" with the software instead of there
main machine.
Lastly it is an easier language to understand an program in so we would be
allowing access to the system for more users.

Best regards,

Rob

In my view the first 2 things we should do are
1. Work out WHAT people want the software to show them (User Interface).
2. Work out the architecture we will employ for the engine (Input,
Processing) Libraries to be created and of course interfaces to design to
link the whole together.
Lets get the show on the road! :-)
John



This archive was generated by hypermail 2.1.4 : 2002-07-27 12:28:36 BST