Friday, 15 September 2006

Direct Shit

MSDN says: Building DirectMusic Projects
Projects need to include the Dmusici.h header file, which contains declarations for the DirectMusic performance layer.

Yeah! Once in a lifetime, Microsoft did something easy to use and clearly explained! Let's download the tiny SDK and just do it!

#include <Dmusici.h>

int main(int argc, char *argv[])
{
  return 0;
}

Here's the result:

warning: "MAKEFOURCC" redefined
warning: this is the location of the previous definition
error: declaration of `WLOOP _DMUS_REGION::WLOOP[1]'
error: changes meaning of `WLOOP' from `typedef struct _rloop WLOOP'
make.exe: *** [main.o] Error 1

Well.. GG! I'm tired after ONE line of code!

Ok, forget 'bout DirectMusic.

Redo from start - Multithreading in C++ && OO

The Win32 API for threading have been designed for C, therefore they don't fit very well the use inside classes. In highest-level languages (such as Java), threading is implementable simply extending the Thread class and overriding the run() method. In C++, things are slighly more complex, expecially because it is impossible to reach classes methods from an isolated static function.

So, it is necessary... once again... pull up socks and use the _beginthreadex API.


class Threader
{
  public:

  // this is the method called by main
  static unsigned __stdcall ThreadStaticEntryPoint(void * pThis)
  {
    Threader * pthX = (Threader *) pThis;
    pthX -> EntryPoint();
  }

  // this is the real thread method
  void EntryPoint()
  {
    // put thread's job here
  }
};

int main() {

  unsigned int uiThread1ID;

  // let's call thread. the NULL are useful parameters, but not obbligatory
  HANDLE hth1 = (HANDLE)_beginthreadex( NULL, 0, Threader::ThreadStaticEntryPoint, NULL, NULL, &uiThread1ID );

}


You can find an excellent and more extended explanation on Code Project.

Don't forget to include process.h!

Thursday, 14 September 2006

Parallel port and Win32

The more we progress, the more simple things get complex.

Kind of entropy, I suppose.

Once upon a time, there was the parallel port: an easy and powerful alternative to the serial port, useful for interfacing with external devices.

The arrival multiprogramming brought the abstraction of the port; after that, for some reason, in the Windows environment the access became a taboo.

What about free parallel programming in 2006? Introducing the inpout32.dll!

Developed by Logix4u.net, it's a free library for free kernel mode access to the parallel port in Windows 98/ME/NT/2000/XP. This library give access to two basic functions: Inp32 and Out32, to get and put bits onto the port.

You can find several example codes around the internet; the DLL is very efficent and can be imported with pratically every language known!

A little step behind

For anyone interested into Powerglove hacking, here follow the hardware modifications required.

The idea is to modify the 7-poles connector of the glove to became a standard parallel interface.
You can achieve this by soldering the wires as described in the scheme on the right. As you can see, the glove's circuitry requires an external +5V alimentation that is NOT provided by the parallel port.

You can obtain it from the PS2 keyboard connector, or from the floppy drive power chord. The glove I bought on eBay was previously modified for PC use, so I restored the connections. The original owner did the soldering directly on the board of the glove itself, using the parallel port cables to bring the +5V directly on the circuit. Check out the picture!

On the other side, I soldered the three wires at the port as described, and the fourth to the +5V power supply.

That's it! Ready to rumble!!

Tuesday, 12 September 2006

Multithreading in C++

The Powerglove periodically squeezes out its datas. One way to keep the informations up-to-date is to delegate the readings of its status to a separate thread, which stores data in a circular buffer. This can be achieved with the multithreading tecnique: one process but more than one separate, and virtually parallel, thread of execution. It's gonna be my "producer".

The "consumer" will be the main procedure, which will obtain the deglitched coordinates with specifically concurrent methods. I'm wondering if a separate thread for the MIDI could be useful.

Btw, for anyone who'd like to write multithreaded classes, here's my snippet:


void threadFunc() {
  // actual thread routines
}

void launcher()
{
  // you can pass useful parameters to the thread using this variable
  long * param;

  // the "threadID" variable will contain the reference of the created thread
  DWORD threadID;

  // the NULL and the zeros are additional features of the syscall
  // check out references for further info
  // they're not needed for a simple thread creation
  HANDLE ret = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadFunc, param, 0, &threadID);
}

Saturday, 9 September 2006

Powerglove as MIDI device


A second attempt. This time I gave more throttle via scheduler: the latency is really better now!

Priorities in Win32

I found that increasing process priority is a nice (asd) way to improve performances of my Powerglove, expecially on less powerful machines.

The glove itself produces trains of data at ~500hz: casts ten bytes and then waits 2ms. Too bad, I couldn't leave the scheduler the privilege to subtract more time.

What follows is a short C function to change priority of the running process:


void prioritizza(DWORD value) {
// PID of this process
int processID = GetCurrentProcessId();

// handler of this process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processID);

// actually sets priority
SetPriorityClass(hProcess, value);
};


Remember to include "windows.h" , for many structures and constants are defined there.

In the end, as values, I used the constant HIGH_PRIORITY_CLASS. Here follow the constants you could use in your own programs:
  • IDLE_PRIORITY_CLASS
  • BELOW_NORMAL_PRIORITY_CLASS
  • NORMAL_PRIORITY_CLASS
  • ABOVE_NORMAL_PRIORITY_CLASS
  • HIGH_PRIORITY_CLASS
  • REALTIME_PRIORITY_CLASS
As you could imagine, they are ordered by increasing performance.

Tuesday, 5 September 2006

Using Powerglove as MIDI controller?

I modified a Powerglove to use it on PC via parallel port; using C++ I programmed it for translating the detected spatial coordinates into MIDI messages. Now I'm gonna optimize the software in order to play synth with my band Simmetry.

As you can see from the footages, my software suffers latency. Maybe it's due to the low-level MIDI programming, instead using DirectX, and the error correction routines which waste several milliseconds.