ASCIIMath creating images

Tuesday, October 16, 2012

DEMAND: Diverse Environments Multichannel Acoustic Noise Database

It's official: our database of recordings with the microphone array described in a previous post is now active and can be found at Licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License, this is a large chunk of data - so much, we are only putting it on the website in one format, a zip file of 16 mono wav files for each environment.  My preferred format would have been to post it as 16-channel wav files (easier to work with in MATLAB, provided you have loads and loads of RAM) but that decision had to be made.

The original design called for 18 recordings, but one of those was too challenging to do proper around Rennes, and two were unsatisfactory after recording.  So, those will be left for v2.0.  Still, this is a far more diverse set that most other databases I know of - and with more channels.

So if you're into multichannel signal processing... have at it!

Tuesday, September 18, 2012

Wireless Serial on a Raspberry Pi

I don't have my Raspberry Pi yet.  RS has informed me of a delay - I guess the good news is I should be getting a Rev. 2 board.  In the mean time, a colleague of mine got his a while ago, but due to lack of time is letting me play with it.  I don't have time either, but I'm not letting me stop that!

So the first thing I did, not wanting to mess around with swapping monitors and keyboards etc..., was to hook up the Rπ to a bluetooth serial adapter I got off DX. ($8.60!, see also here)  It was trivial to hook up to the Rπ, but make sure to hook Vcc up to 3.3V! Otherwise, the TX line will probably output 5V TTL levels that could damage the Rπ input pin.  So, the hookup is, (adapter pin:Rπ pin) VCC: P1-01, GND: P1-06, TXD: P1-10, RXD: P1-08.

Software wise, there is not much to do either.  I left the adapter at 9600 baud; at some point I will send it the magic AT incantation to change that, but at the moment it was simple to just change numbers on the Rπ, all of which can be done on the SD card using another computer running Linux (in other words, the Rπ never needs to be hooked up to a monitor/keyboard).  In the boot partition, change the baudrates for ttyAMA0 to 9600, and in the actual real linux root partition, change the appropriate inittab line.  (details will follow - I don't have the board in front of me)

The biggest problem is the power.  As the Rπ (rev 1) does not have a halt or reset line, the bluetooth adapter will get power at the same time as the Rπ, so you cannot connect to it before the Rπ boots - on the Rev 2 board I think I could hold it in reset state until I've connected the bluetooth so I can monitor all bootup messages.  The other solution would be to give BT adapter its own 3.3V supply but that could also be dangerous for the serial input line of the Rπ.

Monday, September 3, 2012

LASERS! on (virtual) paper

Yay, another journal article! Ok, ok, I'm 8th author (out of 13 - quite the horde) but it's still good (besides, I wasn't able to contribute much after leaving Montreal). Kudos to Philip and his gang.  The paper was published in Analyst, a journal of the Royal Society of Chemistry; the article itself ("Demonstration of a plasmonic thermocycler for the amplification of human androgen receptor DNA") can be found here.  For reference this was the project I was playing with when I wrote this post.

In related news, the ICASSP 2012 paper (mentioned in this post) is finally in IEEE Xplore.  That took a while.  Now back to research to write a paper on my current research!

Thursday, August 30, 2012

Panasonic HHC Schematics by Tony Duell

(TL;DR version: the scans are here)

Some years ago, I picked up a Panasonic HHC, having had an interest in the small hand-held BASIC computers for a while.  As it turns out, the HHC does not use basic at all, and is by default not really "open" in any way - there was a BASIC ROM available, but generally the thing was used as a specialized calculator with custom ROMs.  Still, It's a cute little machine with the interesting feature of using a 6502 inside, and it came with a printer that uses regular paper, and even the internal batteries still work.

Recently, there was a discussion about it on the Classiccmp mailing list, and Tony Duell - known for his classic computer electronics acumen if not his take-no-prisoners approach to typing emails - mentioned that he had traced out the circuits of this little machine.  This got me (and several others) interested, and he offered to make these available to the general public if someone would scan them and place them somewhere on the web.  The physical pieces of paper from Tony were scanned by Dave Colver, who in turn sent me the images.  I did a bit of cleaning up (nothing more than adjusting levels to remove some JPG compression artifacts) and collated them into a PDF document and you can download them from here: Panasonic HHC RL-H1400 Schematics.

Unfortunately, my HHC is at this moment a couple of thousand kilometers away, in a box at a friend's house in Pointe-Claire, Canada.  However, once I live in a place where I have a workshop again, I will mess around with it, for sure.  Dumping the ROMs would be a good start!

Wednesday, August 22, 2012

Real life interference again, of the best kind

A short time ago, life has become quite overwhelming, but in a good way.   To announce the reason, I sent a little bit of creative writing to my friends; I'll post it here with the personally identifying information masked out.


     A child process with PID "------ ------ Thiemann" has been successfully
     spawned.  While the process is not yet ready for completely standalone 
     deployment, it operates within all expected parameters.
     On --- -- Aug 2012 --:-- CEST, a child process was successfully spawned
     from two parent processes.  The new process was given a PID of "------
     ------ Thiemann".  All parameters are within design specifications, as
     are the parameters of the parent processes.  Note that the new process
     is not functioning as a completely independent unit yet, but relies on
     I/O processing by the parent processes; in particular, the flushed 
     output functionality is not yet present, and instead uses buffered
     output where the buffers are emptied by the parent processes.  Input
     is taken exclusively from one of the parent processes.  Furthermore,
     the self-diagnosis functionality is currently limited to a one-bit sonic
     indicator; if this indicator is activated, it is left to the parent 
     processes to determine if I/O needs to be serviced or if the current
     operating environment is incompatible.
     When not performing I/O, the new process spends a considerable amount 
     of time in the sleep state.  A visualization of the process is appended
     to the report, showing the interaction of the new process with its
     parent processes.
     As of yet, no bugs have been found in the system that merit intervention
     by either the parent processes or the operating system.  However, it is
     expected as the process interacts with the greater system environment,
     some abnormal processing states may occur, but it is expected that the
     self-repair functions will be fully functional by that time.

I know the "thing to do" these days is to have a facebook page, twitter account, email address, etc. for a new kid set up.  Well, this kid's information will be off the net for as long as possible, until he is capable of understanding and deciding for himself.  But watch out world once he gets his hands on a soldering iron and/or a compiler!

Tuesday, July 24, 2012

Simple multithreading using clone()

For a bit of hacking I want to do, I need to implement concurrency between two processes sharing the same memory.  So I looked into how to do it (this is all under Linux). My first stab was to look at the old SYSV shared memory interface - but that was kind of ugly, then I looked at pthreads and thought the same. Isn't there a simple way to do fork() without splitting the memory?

Turns out, Linux does have such a mechanism, in the clone() function call. However, there are some pitfalls that one needs to be aware of. Let's see the code first, though.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/sched.h>

Pretty standard stuff, but note the last one: it's important to pick that rather than <sched.h> (as the man page claims), since otherwise you don't have the necessary constants defined!
Next, we need some memory in global space:
#define STACKSIZE 256
int globalint;
char stack[STACKSIZE];
The lone int is the only memory that I'm using to communicate between the threads for now. The stack however, is only used by the child thread/process. It is visible to the parent, but it's not easy (or reliable) to use it to communicate with the child. Now let's define the code for the child process.
int secondp()
  int i;

  for (i=0; i<1000; i++) {
    globalint = i;
  return 0;
Simple enough: every 60 ms, set the global variable to the value of of the local one being incremented. Note I am NOT "incrementing" the global, since that would be a read-write operation, which gets computer science people all excited in multiprogramming situations! (Or it did, 70 or so years ago.)
Now let's have the main program.
int main()
  int i, j, sppid;

  for (i=0; i<STACKSIZE; i++) stack[i] = 0x55;
I initialize the stack so I can observe what happened to it during execution, filling it with a simple 010101... pattern. Next, the interesting bit.
  sppid = clone( secondp, &stack[STACKSIZE], CLONE_VM, NULL );
  if (sppid==-1) {
    printf("clone error.\n");
  printf("clone pid 0x%08x\n", sppid );
The first line creates the child process, given the pointer to the function as the first argument. The second argument is what that process gets as a stack - but note that the pointer points to the TOP of the stack! This is x86 specific and MAY (or may not) be different on other architectures (ARM? amd64?).
The third argument, the options, is what creates the magic to make this shared memory scheme work. Without it, clone() behaves more like fork(), giving the child a copy (-on-write) of the parent memory space, which is exactly what I don't want. Other options allow you to copy or share specific elements, like the file I/O table etc. Read the documentation. Lastly, the following arguments are passed to the child function - useful in many instances, but not used here.
I finish up the program with code that actually demonstrates that things are happening as expected:
  for (i=0; i<10; i++) {
    printf("%d\n", globalint);

  for (i=0; i<16; i++) {
    printf( "%04x :", i<<4 );
    for (j=0; j<16; j++) {
      printf( " %02x", stack[j+(i<<4)]&(0xff) );
    printf( "\n" );

  return 0;
So, for 10 seconds, the value of the global integer is printed; after that, I dump the stack in a hexdump fashion. This is what I get on my Ubuntu Netbook:
clone pid 0x000005e3
0000 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0010 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0020 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0030 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0040 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0050 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0060 : 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
0070 : 55 55 55 55 55 55 55 55 55 55 55 55 48 f2 0e 08
0080 : e0 8e 04 08 00 00 00 00 6f 58 08 08 cd 84 05 08
0090 : 08 f2 0e 08 00 00 00 00 55 55 55 55 55 55 55 55
00a0 : 55 55 55 55 55 55 55 55 00 00 00 00 00 87 93 03
00b0 : 55 55 55 55 55 55 55 55 55 55 55 55 03 8f 04 08
00c0 : 60 ea 00 00 55 55 55 55 55 55 55 55 55 55 55 55
00d0 : 55 55 55 55 55 55 55 55 55 55 55 55 a6 00 00 00
00e0 : 55 55 55 55 00 01 00 00 00 00 00 00 2e 96 05 08
00f0 : 00 00 00 00 55 55 55 55 55 55 55 55 55 55 55 55
Clearly, the global int is modified by the child process while being read by the parent. The stack display is interesting, showing clearly how it's being filled towards lower memory. A x86 expert could probably explain clearly what is there and why the stack is not written to contiguously (presumably, some of it is allocated byt never written to).
Thus, the three main things to keep in mind when using clone() are:

  • Make sure you use the right sched.h file.  (You'll notice this at compile time)
  • Choose the proper options to clone()
  • Make sure you know which way the stack grows, and how big it'll get!  If you get this wrong, it'll clobber the parent variables - if you use malloc() instead, you'll get a memory fault (which is preferrable since it's slightly easier to diagnose).

Thursday, July 12, 2012

Journée Science et Musique 2012

A few months ago, I got roped into helping to get the "Journée Science et Musique 2012" event off the ground.  Mostly, my contribution to date has been to be a part of the team wrangling an ugly mess of HTML, PHP, and CSS into shape.  Well, as of yesterday that abomination is live and open to the public.  As we get closer to the date, I'll probably get involved into other parts of the event as well - in fact I have two demos that I'm working on that we might show off at the event.

I'm looking forward to it, it should be a lot of fun.

Saturday, June 16, 2012

Classic Computing Redux

When I accepted my current Postdoc position, knowing it would mean a move from Canada to France, I decided to all but completely dissolve my classic computer collection.  I just kept my Commodore 8-bitters, that are now in boxes at a friend's place in Pointe-Claire, QC.

However, here in Rennes (and probably everywhere else in France) there are a lot of "braderies", basically organized neighborhood garage sales; we have found these to be a great source of things we need.

And sometimes, one sees something that can't just be left.  Like this Commodore 4-op calculator (Model 776M).  For €1.  No, I won't hack it, it's just too damn cute.

Tuesday, May 22, 2012

Some new toys to play with

I have just finished up some work for a major deliverable at work; so I predict I have a little more time to work on more fun things.  In the last few weeks, I had some mail-order toys come in - this weekend I finally had some time to at least test them!

The first item is an Arduino Uno, to replace the Diecimila that got left in Montreal with the Laser projects. It's an Arduino - it works like Arduinos do.

The other thing I got though was a JY-MCU Bluetooth serial adapter, which promises to be a lot of fun to mess with.  First though, I wanted to make sure it works, so I need a simple USB TTL serial interface.  This is where the Arduino comes in handy, although in a slightly unorthodox fashion.

Arduino Uno without the chip but as a USB serial
adapter - however, in this picture I had Rx and Tx swapped
Rather than loading up a sketch that provides another serial port on other pins of the ATmega chip, I simply removed the chip and hooked the Bluetooth adapter up to pins 0 and 1.  So, I used the Arduino Uno board as just the plain USB serial adapter with TTL levels that I need.

With this setup I successfully managed to send data (using my Mac) from BT to USB and back; using screen as a terminal emulator.

I am looking forward to messing with all this again.

View of the labels for the BT adapter.

Other Projects

This being said, other projects are getting back on track, too. The (actually work-related) microphone array will get some well-deserved attention again.  And finally, I have been roped into helping out with the next edition of the Journée « Science & Musique » that is being organized here at IRISA/INRIA Rennes.  For now I am just helping out a little with the website (the old one can be seen here) but probably I'll get more involved with some of the exhibits as well. My atrocious french is a problem, but we'll see what happens.

Sunday, March 11, 2012

Building a Microphone Array

With all the holes drilled, the
microphone support rails are
being assembled here for the
first time.
METISS, the group I'm doing my postdoc with, does a considerable amount of research on signal separation and localization.  Given that I have some experience with hardware, I am now helping soon-to-be-ex Ph.D. student Nobutaka Ito (he should be defending soon!) with some work on a microphone array.  Once everything is finished and tested, we will be going out and doing some recordings as raw data to throw at algorithms.

Post-assembly checking for alignment,
and filing off of sharp corners. 
The support structure
Originally, we planned to to the construction rather ad-hoc with hand tools - but then I discovered that INSA/INRIA has a "Atelier Mechanique" that I can use - a nicely equipped workshop!  (There are a few tools that I'd like to use they don't have, but nothing critical.)
The array configuration is four offset linear strips of microphones, with 5 cm distance between microphones along each strip.  The distance between strips is such that 3 microphones (2 on one strip and one on the adjacent strip) form an equilateral triangle, that is each microphone is 5 cm to all of its immediate neighbors.

The array all wired up to the A/D converter and hooked
up to a laptop.  We are forced to use an older laptop
since the drivers don't work on a modern OS,
and the IT department doesn't install XP on new ones.
Fixing the microphones
One of Emmanuel's parameters for us building the array was that we couldn't affix the microphones (Sony ECM-C10) in a permanent fashion.  As a result, we are using sticky tack (the kind used to put posters on the wall).  This is less than ideal - it appears to hold reasonably well, but is not totally solid.

The A/D converter
The A/D converter we are using is a Inrevium (Tokyo Electron Device?) TD-BD-16ADUSB, in what looks very much like a homebrew enclosure (this may have been built in-house at IRISA before I got here).  We have encountered two problems with the setup: the first is the age of the drivers.  The CD provides drivers for Windows and Linux; however, the Windows drivers only work on XP, and the Linux drivers won't compile for a 3.x kernel.  I have attempted to fix the Linux drivers without success so far; the problem is that the driver uses old-style mutex locking, and I don't know enough about the "modern" locking mechanisms in the Linux kernel to replace those in the driver, nor do I have the time to dig deeply into kernel driver writing to do it properly.  If anyone is interested, there is some info on a different website.
Close-up of the microphone array. Note that the
microphones can be a bit hard to distinguish from
the bolts holing the support together.

For now, we are just using an old Dell laptop provided by the IT department that runs XP.  It works reasonably well, but initial tests show that the occasional packet gets lost (the converter pushes 4 ms of audio over USB per packet), rate of packet loss dependent on sampling rate.  We don't know (yet) if this is due to the speed of the laptop or simply a limitation of the USB bus.

Preliminary Evaluation
Given the construction and method to affix the microphones, the tolerances of the microphone placement is about 2 mm.  We are planning to use the array primarily for (wideband) speech processing, so with a sampling rate of 16 kHz.  With a max frequency of about 7 kHz (I should double check the antialiasing filter characteristics of the A/D converter), those errors should be tolerable.  At 16 kHz sampling rate, we also stop dropping packets from the converter.  However, before we go out and make actual field recordings, everything will be double- and triple-checked.

Update: See this post for the recordings we made with the array.

Sunday, February 5, 2012

Postdoc in Rennes

The INRIA building on the campus of Université de Rennes 1
As of mid-January I am a Postdoctoral Fellow with the METISS group at IRISA (Institut de recherche en informatique et systèmes aléatoires) one of the research institutes of INRIA (Institut national de recherche en informatique et en automatique).  Within the group, I will be working on multi-channel source separation - at the moment I'm working on some enhancements to the FASST package, in part to familiarize myself with the code.

En France
Adjusting to living in France has been taking a significant chunk of my time.  This was to be expected - moving to a different country is never a simple endeavor.  While my nationality makes it easy for me to live in France, relocating family is a bit more difficult.  The paperwork is mostly done now, so soon I should have some time again to spend on things like... Arduinos! FPGAs! MIDI!

For that to happen of course I need my equipment and parts.  That should, along with the rest of our furniture, arrive this week - as I'm writing this, our apartment has just one piece of furniture...