It's now one year since I've started this blog. I haven't done as much blogging as I set out to do, but that was to be expected; overall there are now 27 posts (28 if you count this one), 19 of which have actual technical content. I consider this actually pretty good, for my standards. The trick of course is to make next year better! I'll have to juggle that with my new life in Rennes, but it's a challenge I can rise up to!
Popularity-wise this blog has not done too badly either. Blogger reports about 1864 hits to date; the most popular article being about my Amiga 1000 mod - though if taken together, the SIDschield articles are the main draw (this is counting individual article hits only - blogger can't show tag requests AFAICT). The SIDshield is something I definitively will continue working on, but I think I will focus more on VHDL once I'm in Rennes. I think I will shift my focus on the research and MATLAB related content in the future.
Weirdly, I have only ever received one comment, on Further adventures with Mercurial, which is now effectively out of date (the relevant packages on the latest Ubuntu releases are at sufficiently high versions). It's a pity; any blog writer really likes comments, it makes one feel relevant. :-)
Onwards to the next year of posting!
Sporadic outbursts of things that have to do with research, electronics or coding that may or may not be DSP related.
ASCIIMath creating images
Thursday, December 8, 2011
Saturday, November 26, 2011
Moving my research and projects homepage
As mentioned in a previous post, I am currently finishing up my work at McGill University, and then start a postdoc with the
METISS Speech and audio data modelling and processing group at the Universite de Rennes 1. As a result, I will soon be loosing my webspace at McGill, and had to find a new home for my research descriptions and my other projects. UPDATE: That link is long dead.
I did investigate various paid hosting methods - and for the minimal amount of traffic I have seen on my homepage, even $5/month would seem excessive. One alternative is using Amazon to host it (Amazon S3 would probably work well) - but then I found out that bitbucket can host static websites (and it's free!) Since my website is really only about open projects (such as the SIDshield, VHDL experiments, etc. - much of which ends up on this blog, anyways) it's an appropriate site to have my page hosted there, I think. The only other personal stuff that might need high bandwidth are pictures I like posting - and those I put on Picasa and Panoramio; trip travelogues should go to another blog.
Bitbucket webpage hosting works in a way that I really like. It's all version controlled, of course, using Mercurial - and the server actually just displays the tip of a specific repository. This means I can do all the editing on any computer with a clone of the repository; once I am happy with the changes I'll commit and do a "hg push" to bitbucket. Done. My previous webpage was also version controlled of course (subversion first, then Mercurial), but I had an extra script I needed to execute to push the new version onto the server, using a pile of scp commands. A pain if I did't happen to want to copy the private key to the machine I'm on. UPDATE: yeah, I'm using git now. Like everyone else.
So, I'll try keeping it there for the time being. It supports custom domains, then if I register a domain for myself, I can redirect it there.
I did investigate various paid hosting methods - and for the minimal amount of traffic I have seen on my homepage, even $5/month would seem excessive. One alternative is using Amazon to host it (Amazon S3 would probably work well) - but then I found out that bitbucket can host static websites (and it's free!) Since my website is really only about open projects (such as the SIDshield, VHDL experiments, etc. - much of which ends up on this blog, anyways) it's an appropriate site to have my page hosted there, I think. The only other personal stuff that might need high bandwidth are pictures I like posting - and those I put on Picasa and Panoramio; trip travelogues should go to another blog.
Bitbucket webpage hosting works in a way that I really like. It's all version controlled, of course, using Mercurial - and the server actually just displays the tip of a specific repository. This means I can do all the editing on any computer with a clone of the repository; once I am happy with the changes I'll commit and do a "hg push" to bitbucket. Done. My previous webpage was also version controlled of course (subversion first, then Mercurial), but I had an extra script I needed to execute to push the new version onto the server, using a pile of scp commands. A pain if I did't happen to want to copy the private key to the machine I'm on. UPDATE: yeah, I'm using git now. Like everyone else.
So, I'll try keeping it there for the time being. It supports custom domains, then if I register a domain for myself, I can redirect it there.
Tuesday, November 22, 2011
The MATLAB code for my Thesis
To my shock and surprise, it turns out that someone other than my committee has actually been reading my thesis. In fact, Mr. Gao Ge (高戈) of Wuhan University has been looking into my work in such detail that a typographical mistake in Eq. 5.2 was discovered: it should read
$f_m = \frac{1000}{4.37}(10^{\frac{ERB_m}{21.4}}-1)$
which he discovered by comparing the thesis with my 2007 INTERSPEECH paper. (For those of you for whom the math is not displaying correctly, that's f_m = 1000/4.37 (10^(ERB_m/21.4)-1): the exponentiation is kinda important...) I thank Mr. Gao for his vigilance.
As part of his questions, he has asked if he could see the MATLAB code I used to do my simulations. Now, the code was mostly over a year old, not very clean and distributed all over the file system of my computer, but I decided it's worth the effort to try to collect it all in case someone else wants to continue research in a similar direction. And I finally sat down and did just that, and as of now, you can find it here or here. But no, the code is still not very clean. However, it seems to run - all you need extra AFAIK is the Signal Processing Toolbox. You also need to supply your own mono, 16 kHz sampled wave file, which you need to point to in line 64 of RunThesisCode.m.
I'm putting this code out there under the Creative Commons Attribution 3.0 Unported License, and make absolutely no claim that this code is useable for any purpose whatsoever, nor that it is an accurate representation of what I used to run the tests. However, I hope that the code will be useful to understand the ideas I'm trying to explain in my thesis.
$f_m = \frac{1000}{4.37}(10^{\frac{ERB_m}{21.4}}-1)$
which he discovered by comparing the thesis with my 2007 INTERSPEECH paper. (For those of you for whom the math is not displaying correctly, that's f_m = 1000/4.37 (10^(ERB_m/21.4)-1): the exponentiation is kinda important...) I thank Mr. Gao for his vigilance.
As part of his questions, he has asked if he could see the MATLAB code I used to do my simulations. Now, the code was mostly over a year old, not very clean and distributed all over the file system of my computer, but I decided it's worth the effort to try to collect it all in case someone else wants to continue research in a similar direction. And I finally sat down and did just that, and as of now, you can find it here or here. But no, the code is still not very clean. However, it seems to run - all you need extra AFAIK is the Signal Processing Toolbox. You also need to supply your own mono, 16 kHz sampled wave file, which you need to point to in line 64 of RunThesisCode.m.
I'm putting this code out there under the Creative Commons Attribution 3.0 Unported License, and make absolutely no claim that this code is useable for any purpose whatsoever, nor that it is an accurate representation of what I used to run the tests. However, I hope that the code will be useful to understand the ideas I'm trying to explain in my thesis.
Tuesday, November 15, 2011
Update: Real Life interference
I haven't been updating this blog since Real Life (tm) has this nasty habit of making me too busy to work on fun projects.
The first thing that has taken over my time is that I was recruited into being the co-instructor for the ECSE-436: Signal Processing Hardware course here at McGill. This is actually a fun course to teach: I get to teach the kids all about C programming, actual real-world DSP usage, hardware, fixed-point arithmetic, etc. The final project this year is to implement a simplified voice-band modem (the DSP portion only). Not quite as cool as the projects we have had them do in previous years (when I was a TA for the course in previous years, we had them do wavetable synthesizers, guitar effect boxes and time-scale modification of speech), but due to external factors the schedule got a bit squeezed. Still, I think the students are learning quite a bit, and I know some of them are keen to perhaps study more advanced DSP in the future.
The other major thing is that I have accepted a new job, to start in January. Well, technically, it's a postdoc position - it's like a job, but more work and less pay. Still, I'm looking forward to it as it is with a very good group: the METISS group at IRISA. This of course means moving from Montreal to Rennes, France - not a simple task if you have to move an entire household and sell the house!
And while I did get two papers submitted to ICASSP 2012 (one first-author, the other second author) I am still working on a journal paper. And I really want to get that done before we pack up to move.
I do try to squeeze a little bit of VHDL coding in here and there; as someone on the classiccmp list noted, Xilinx ISE is no longer a horrible mess on Linux, so I did install it on my main work machine (that actually has a decent amount of RAM). So far, I was using it on an old P4 with 1 Gig RAM which was unbearably slow. Or maybe I'm just spoiled.
One of these days I will also program the Arduino a bit again. Real soon now.
The first thing that has taken over my time is that I was recruited into being the co-instructor for the ECSE-436: Signal Processing Hardware course here at McGill. This is actually a fun course to teach: I get to teach the kids all about C programming, actual real-world DSP usage, hardware, fixed-point arithmetic, etc. The final project this year is to implement a simplified voice-band modem (the DSP portion only). Not quite as cool as the projects we have had them do in previous years (when I was a TA for the course in previous years, we had them do wavetable synthesizers, guitar effect boxes and time-scale modification of speech), but due to external factors the schedule got a bit squeezed. Still, I think the students are learning quite a bit, and I know some of them are keen to perhaps study more advanced DSP in the future.
The other major thing is that I have accepted a new job, to start in January. Well, technically, it's a postdoc position - it's like a job, but more work and less pay. Still, I'm looking forward to it as it is with a very good group: the METISS group at IRISA. This of course means moving from Montreal to Rennes, France - not a simple task if you have to move an entire household and sell the house!
And while I did get two papers submitted to ICASSP 2012 (one first-author, the other second author) I am still working on a journal paper. And I really want to get that done before we pack up to move.
I do try to squeeze a little bit of VHDL coding in here and there; as someone on the classiccmp list noted, Xilinx ISE is no longer a horrible mess on Linux, so I did install it on my main work machine (that actually has a decent amount of RAM). So far, I was using it on an old P4 with 1 Gig RAM which was unbearably slow. Or maybe I'm just spoiled.
One of these days I will also program the Arduino a bit again. Real soon now.
Friday, October 7, 2011
Playing with VHDL
On my old website there are two projects using VHDL on a Spartan-3e FPGA. Recently, I decided to get back to playing with that again. The project goal this time was to produce a VGA output - in FPGA circles, this is by now the equivalent of a "Hello, World!" program. Nothing new, but I felt it was important to do from scratch without copying any bits so I see how the whole thing fits together.
The picture shows the board and the VGA connector: with only 4 I/O pins on one connector, I made it a monochrome (green) only interface. The pins used are horizontal sync, vertical sync, and 2 bits of video signal. With a bit of soldering I could make it monochrome grey, or I could add another connector to get more output lines to get real color. For playing with synchronization, the quick and dirty adapter giving 4 intensities of green (well, 3 green plus black) is quite sufficient. (...more...)
| The Spartan 3e "S3E Sample Pack" board, a freebie I picked up a few years back. |
Saturday, September 24, 2011
A progress bar for MATLAB scripts
Here is another helpful little MATLAB script written by Prof. Kabal where I made a small modification. The script is basically a wrapper around MATLAB's waitbar function, displaying a typical progress bar such as pretty much every program in the existence of GUIs has ever had.
Using a single function, you set it up first with
ProgressBar(Frac, Delta, Title)
where Delta or Title are optional: default values are 0.01 and an empty title. Frac is the starting fraction of completion; typically this will be 0.
You update the value with
ProgressBar(Frac)
which will only update the window if the display will change by more than Delta: So, if Delta is 0.05, the display will only be redrawn if it changes the display by more than 5%.
Finally, call the function without arguments to close the pop-out window.
I made a simple modification to check if we really have a screen to display to: if not, the update operation displays a simple percentage on stdout (also controlled by Delta). I made this modification since I tend to run tasks remotely using ssh and screen. I found the code to check for a display here.
Get the script here: ProgressBar.m
Using a single function, you set it up first with
ProgressBar(Frac, Delta, Title)
where Delta or Title are optional: default values are 0.01 and an empty title. Frac is the starting fraction of completion; typically this will be 0.
You update the value with
ProgressBar(Frac)
which will only update the window if the display will change by more than Delta: So, if Delta is 0.05, the display will only be redrawn if it changes the display by more than 5%.
Finally, call the function without arguments to close the pop-out window.
I made a simple modification to check if we really have a screen to display to: if not, the update operation displays a simple percentage on stdout (also controlled by Delta). I made this modification since I tend to run tasks remotely using ssh and screen. I found the code to check for a display here.
Get the script here: ProgressBar.m
Sunday, September 11, 2011
Real-time control of MATLAB using a MIDI controller
UPDATE 28/11/2014: this post is obsolete, I have created a better method and described it here.
Sometimes it's nice to set variables in MATLAB in real-time, using an actual physical knob. Like you can find on a MIDI controller.
MATLAB generally is not geared for real-time data input, and to the best of my knowledge, there is no MIDI library for input. So, I hacked up a shockingly simple way of getting controller status data into MATLAB: a small helper program passing data through the filesystem.
The helper program does very little: listen to the MIDI bus, if a controller message is seen, write it to a file in the /tmp directory. In particular, I name the files /tmp/cc/<number>, where <number> is the controller number. Since controllers can only take values 0–127, the files are one byte long.
The MATLAB side is equally simple. If you want to read controller value x, open /tmp/cc/x and read the first byte. Should the read fail, return-1, : let the calling program figure out what to do in that case (eg. read again or use the old value). The code is simply:
The race condition (MATLAB reading the file while it's being written) also returns-1, given the single-byte length of the file that is sufficient. Again, the calling program should handle it somehow.
The helper program
The actual reading of MIDI messages is messy, platform-dependent code that I'd rather not be writing myself. So instead I use the rtmidi package, developed just on the other side of the McGill campus; it works on Mac, Linux, and Windows. The helper program is a simple modification of the program qmidiin.cpp from the tests directory in the rtmidi distribution.
The code can be compiled the same way the other program in the tests directory are compiled, on my Mac it was g++ -O3 -Wall -I.. -D__MACOSX_CORE__ -o midicctmp midicctmp.cpp Release/RtMidi.o -framework CoreMIDI -framework CoreFoundation -framework CoreAudio. Note that the program will fail if the directory /tmp/cc does not exists; just create it manually, or modify the above code to create it at startup.
I have not yet tested it on Linux, but I see no reason for it to not work. I have an idea for a slightly more fancy event-based method, but that's for another post.
Sometimes it's nice to set variables in MATLAB in real-time, using an actual physical knob. Like you can find on a MIDI controller.
![]() |
| MIDI controller hooked up to my Mac |
The helper program does very little: listen to the MIDI bus, if a controller message is seen, write it to a file in the /tmp directory. In particular, I name the files /tmp/cc/<number>, where <number> is the controller number. Since controllers can only take values 0–127, the files are one byte long.
The MATLAB side is equally simple. If you want to read controller value x, open /tmp/cc/x and read the first byte. Should the read fail, return
function r = getCCval( n )
fname = sprintf( '/tmp/cc/%d', n );
f = fopen( fname, 'r' );
if f<0
r = -1;
return
end
r = fread( f, 1, 'uint8' );
fclose(f);
if isempty(r)
r = -1;
end
end
The race condition (MATLAB reading the file while it's being written) also returns
The helper program
The actual reading of MIDI messages is messy, platform-dependent code that I'd rather not be writing myself. So instead I use the rtmidi package, developed just on the other side of the McGill campus; it works on Mac, Linux, and Windows. The helper program is a simple modification of the program qmidiin.cpp from the tests directory in the rtmidi distribution.
//*****************************************// // midicctmp.cpp by Joachim Thiemann 2011 // modified from // qmidiin.cpp by Gary Scavone, 2003-2004. // // read MIDI queue and create files in // /tmp/cc with controller state // //*****************************************// #include#include #include #include "RtMidi.h" #include #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) #include bool done; static void finish( int ignore ){ done = true; } void usage( void ) { // Error function in case of incorrect command-line // argument specifications. std::cout << "\nusage: midicctmp \n"; std::cout << " where port = the device to use (default = 0).\n\n"; exit( 0 ); } int main( int argc, char *argv[] ) { RtMidiIn *midiin = 0; std::vector message; int nBytes; double stamp; FILE *f; // Minimal command-line check. if ( argc > 2 ) usage(); // RtMidiIn constructor try { midiin = new RtMidiIn(); } catch ( RtError &error ) { error.printMessage(); exit( EXIT_FAILURE ); } // Check available ports vs. specified. unsigned int port = 0; unsigned int nPorts = midiin->getPortCount(); if ( argc == 2 ) port = (unsigned int) atoi( argv[1] ); if ( port >= nPorts ) { delete midiin; std::cout << "Invalid port specifier!\n"; usage(); } try { midiin->openPort( port ); } catch ( RtError &error ) { error.printMessage(); goto cleanup; } // Ignore sysex, timing, or active sensing messages. midiin->ignoreTypes( true, true, true ); // Install an interrupt handler function. done = false; (void) signal(SIGINT, finish); // Periodically check input queue. std::cout << "Reading MIDI from port ... quit with Ctrl-C.\n"; while ( !done ) { stamp = midiin->getMessage( &message ); nBytes = message.size(); if (nBytes==3) { char fn[20]; if ((message[0]>>4)==11) { sprintf(fn,"/tmp/cc/%d",(int)message[1]); f = fopen(fn,"w"); fwrite(&message[2],1,1,f); fclose(f); } } // If queue empty, sleep for 10 milliseconds. if (nBytes==0) SLEEP( 10 ); } // Clean up cleanup: delete midiin; return 0; }
The code can be compiled the same way the other program in the tests directory are compiled, on my Mac it was g++ -O3 -Wall -I.. -D__MACOSX_CORE__ -o midicctmp midicctmp.cpp Release/RtMidi.o -framework CoreMIDI -framework CoreFoundation -framework CoreAudio. Note that the program will fail if the directory /tmp/cc does not exists; just create it manually, or modify the above code to create it at startup.
I have not yet tested it on Linux, but I see no reason for it to not work. I have an idea for a slightly more fancy event-based method, but that's for another post.
Subscribe to:
Posts (Atom)



