Spring Synth Update

Tue, 02 Feb 2010

A few new bits for the spring synth.

  • Event plugins (so keyboard input is optional)
  • MIDI support (an "Event plugin" which uses Jack)
  • Lua 5.1 (no longer an external dependency too, so it is easier to compile)
  • Visualisation plugins (so the OpenGL stuff is optional)
  • Cleaned up a whole lot of build stuff to make it easier to build

I compiled it for an N900, and it works. Hopefully with all the changes I made before, it will nearly compile out of the box (just have to disable some of the plugins). If you attempt this, then bear in mind that you will want to simplify the models you are using.

Get spring synth version 0.2 (C code, 253 KB, GPL3) and be frustrated that it still doesn't have any cool examples.

Is changing your PIN a good idea?

Thu, 21 Jan 2010

I read an article about a recent wave of card skimming attacks. The bit I found interesting was this bit:

NSW fraud squad head Detective Superintendent Colin Dyson:

"There is sometimes a lag between PINs being compromised and used," he said. "If someone whose details are skimmed changes their PIN quickly, the data can be useless to the criminal."

Now if my understanding of bank card security is correct, then changing your PIN will do absolutely nothing, and if your card has been skimmed, then you will want to speak to the bank. Of course, it is quite possible that I'm not quite with the times, and it is sound advice, so here goes with my explanation of how I think it works:

  1. You put your card into the ATM
  2. You type in your PIN
  3. The ATM reads the magnetic stripe on the card and reads:
    • The card number
    • Expiration date
    • A random number (a nonce)
    • Your "PIN offset"
  4. The ATM then takes most of the data it read (but not the PIN offset) and sends it to a special secure cryptoprocessor.
  5. The cryptoprocessor encrypts the data using 3DES, and a very secret "master PIN", known only to the bank.
  6. The encrypted data (longer than 4 digits) is converted into your card's "natural PIN" (4 digits), by a fairly straightforward process.
  7. The resulting "natural PIN" is output from the secure cryptoprocessor to the less secure innards of the ATM.
  8. The "PIN offset" is added to the "natural PIN" (without doing carries, so 2468 + 2468 = 4826)
  9. This number is compared to the number you typed into the ATM, if it matches you are authenticated.

When you go to an ATM and change your PIN, you are just changing the PIN offset, your cards natural PIN doesn't change, and you could even do it at home if you had a magnet and a steady hand :-). If your current PIN is 1234, and you want to change it to 2222, then you read the PIN offset on your card (lets say it was 6789) and (without carry) subtract the new PIN (6789 - 2222 = 4567) and add the old PIN (4567 + 1234 = 5791). Write this number as the PIN offset and you are done.

So, in the scenario that you have your card skimmed, then the attacker knows what PIN you typed in, and what the PIN offset was. When they reproduce the card, it will have the PIN offset from before you changed your PIN, so they can just use your old PIN.

So it is possible that they have changed how it all works. Or maybe just a slight change (e.g. store the nonce at the bank also, change it when the PIN changes, and check that it matches when authenticating). However, this slight change actually changes a whole lot of the security model, because in my model all authentication is done inside the ATM. I can't imagine that making this change would be easy.

Spring Synth

Wed, 23 Dec 2009

It has been a while. I've been working on something quite fun, it is a physical modelling synth. It is a bit bigger than the usual hackish programs I put up here, and ties lots of different things together. I wouldn't say it is ready for primetime yet, but it is at a stage where it is fun to use.

Screenshot

So it is an audio synth with a 3d wireframe view of the model it is synthesizing. So this particular model sounds like this:

Download (42KB)

To drive it, you create a lua script which builds up the model, saying where to put points, how heavy they are and how the points join together. The joins are all springs, with a fairly simple model. The lua script can also define events, at the moment I bind these to keypresses, so you might have something like this:

function event.key_a(s)
    apply_force_set(s, "hit_me", 0.0, 0.0, -250.0);
end

Which applies a force of 250 units, in some particular direction (either down or up I suspect) to all of the points that have been labeled "hit_me" whenever the "a" key is pressed.

As a heads up, don't use models/scripts from people you don't trust, they are programs in their own right and can do bad stuff like deleting files.

Any springs that are labeled as "air" are used for getting sound out of the model. Since I don't model actual air, I can't model a real microphone. The raw signal is the total displacement of all the springs labeled "air". This is then filtered and limited a bit to allow you to make pretty much anything and get useful sound out of it without having to tweak numbers. However, if you have a loud thing and a soft thing, then the soft thing probably won't be audible. This layer is all a bit of a hack.

So, there was the OpenGL wireframe for output, but you might also want to be able to hear what is going on. I've been a bit busy here too, and made 3 dynamically loadable output plugins. Firstly, it can output a wave file using libsndfile. Then it can also output over PulseAudio. Then it can also output over Jack. Having written these three plugins, I must say that I do like these APIs. They were quite pleasant for what I wanted to do.

The source code ( is all C (except for the demo lua file) and GPL3. It should compile cleanly, but given that is has a few dependencies you might need to poke it a bit. There is a readme which tells you what packages you need, and how to drive it.

Embedding Python

Sun, 04 Oct 2009

A quick pointer for anyone who is embedding python into a C application. I found that the useful looking example code didn't work as described. When I ran it I would get:

$ ./call multiply multiply 3 2
ImportError: No module named multiply
Failed to load "multiply"

Even though I could run:

$ python
>>> import multiply
>>> multiply.multiply(3, 2)
Will compute 3 times 2
Result of call: 6

The problem is that sys.path is different between the two environments. In the C code, it doesn't include the current directory. You can fix this easily:

Py_Initialize();
PyObject *psyspath = PySys_GetObject("path");
PyList_Insert(psyspath, 0, PyString_FromString(""));

Hoepfully this will be helpful to someone.

I haven't finished the application that is actually using this (I'll post it when done). But I'm not crazily impressed by the Python C-API. A few examples:

  • The fact that I'm writing this post (maybe it is something different in the Ubuntu python distribution)
  • Not enough consts: Both PyImport_ImportModuleLevel() and PyImport_ImportModuleEx() take "char *name" as a parameter. If they do modify the values pointed to, then it isn't documented how. If they don't, then they should be marked const.
  • Inconsistent naming: PyImport_Cleanup() is documented as "For internal use only". Nearly every other internal function (like _PyImport_Init) has a name starting with an underscore.
  • python-config: It would be much better to use pkg-config like every other library. It would also be nice not to add all sorts of flags which have nothing to do with compiling applications that use this library. For example, the --cflags option adds "-g -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing" - none of which should be needed. Also, running "python-config --cflags --ldflags" silently ignores the "--ldflags" option.
  • Bug reporting non-obvious. The number 1 hit on google for me for "python-config cflags" is the bug report for the previous point. Maybe I'm dumb, but I can't see any way of commenting on this page, to help out.

I'd like it if things got more pleasant from here, but I'm not holding my breath.

Street View Car

Thu, 18 Jun 2009

Google street view car taking a picture of itself:

Is that the camera man's legs hanging out?

I'm not a big user of street view, so maybe this is more common than I realise. On the other hand, it did make me realise how cool it is that it works so well everywhere else.

Pulse Density Modulation

Mon, 11 May 2009

This is a bit of experimental code for working with sounds in the PDM domain. The simple explaination of what that is would probably be these pictures:

Input signal:

A sine wave

Converted to PDM (the three lines are independent, I wrapped it to avoid horizontal scrolling), oversampling 32 times:

A sine wave in PDM form

So as the waveform goes up, the PDM version gets darker, and when the waveform goes down, the PDM gets lighter. This is not quite the same as PWM, as we don't have a specific time window which we try to encode, and so we generally have more transitions from on to off in a time period.

People generally seem to pass the PDM signal to an amplifier, which then spits out a bigger version of the signal, which is then low pass filtered to get back to something resembling the original. This is a simple way to build a D/A converter, and they can be quite cheap, efficient and I believe also sound good.

I thought it would be interesting to do some processing on the signal while it is still in the PDM domain. So, I built a quick test application for taking a wave-file, putting it into PDM domain, doing something to it, and then returning it to PCM and spitting out another wave file.

Things which are trivial in PCM domain (like adjusting the volume) are a bit more involved for a PDM signal. This is (a simplified form of) the code I used:

for (int i = 0; i < get_length(this_channel); i++) {
  this_bit = get_bit(i);

  if (this_bit) error += VOLUME_FACTOR;
  else          error -= VOLUME_FACTOR;

  if (error > 0)   this_value = 0;
  else (error < 0) this_value = 1;

  if (this_value) error += 1;
  else            error -= 1;

  set_bit(this_channel, i, this_value);
}

Whereas for PCM, you would write something like:

for (int i = 0; i < get_length(this_channel); i++) {
  this_value = get_value(i);
  set_value(this_channel, i, this_value * VOLUME_FACTOR);
}

However, this also means that it isn't as obvious when we are going to clip. In PCM, you know you have clipped if the value ends up out of the range you are working in. But here, we are always working with 0 and 1, and there is no way we can get a -1 or a 2. If you drive it too hard, the output will still clip, but it just won't be as obvious that it will clip until you do the conversion back to PCM.

So what the included code does is:

  1. Split the input signal into high frequencies (> 2KHz) and low frequencies.
  2. Put the low frequency signal into PDM domain.
  3. Drive the low frequency signal using code like the code above, where VOLUME_FACTOR is big enough to make it clip frequently.
  4. Mix together the high frequencies, some clean lows and some distorted lows.

And it can transform something like this into something like this. Even though it destroys the bass drum (in a cool way), the filtering makes it one of the subtler things I've put up here :)

The code isn't written for speed. On the other hand, you should look at some of the hacks used to get the filters right. I use a stack of 1st order IIR filters to do the low pass filter. Then for the high pass, I delay it by a magic number and subtract this from the original. From what I understand, this shouldn't work very well thanks to the phase response of the IIR... but in practice it seems to work (just don't change the frequency without retuning the cutoff).

The C, GPL3 code.

New Toy

Mon, 23 Feb 2009

I got a new toy last week. Today I discovered that the colours on it match the ubuntu palette.

7x7 Cube Ubuntu Logo

I thought my computer was being sluggish, and I didn't know why. It turned out that it was just my left mouse button dying, and hence the computer seemed unresponsive.

Now I have the left/right buttons switched, and for some reason, it is putting my mind into "whacky input mode", and I keep on thinking the keyboard is dvorak.

For the cube, it is pretty much the same as any other > 3x3 rubik's cube, except bigger and more awesome. With the larger cubes, if you solve them the way I do (and I think most other people do) you get parity issues, where you get really close to the end, and then realise that some pieces are out of place and if you just use the set of moves you have been using, then you won't be able to fix them. Up until a few days ago, my solution had been to scramble the cube and try again.

Wikipedia originally made me think that it wouldn't have parity issues:

Because the centers, middle edges and corners can be treated as equivalent to a 3x3x3 cube, the parity errors sometimes seen on the 4x4x4 and 6x6x6 cannot occur on the 7x7x7 unless the cube has been tampered with.

But it was just referring to the parity issue you get with the even sized cubes that you don't discover until the very end. With the 5x5 and 7x7, you realise there is a parity problem a bit sooner, but it is still there. My first solve I got lucky and had no parity problems, which confirmed my misreading of wikipedia. The second time around, I had a double parity problem, which made me think that I should get a method for deterministically fixing the parity problems (which I have now).

I have a square-1 puzzle which I've solved once. Unfortunately my algorithm wasn't general enough to work all the time, and I don't have a good sense for probabilities on those puzzles, so I don't know what the chances of it working are (my guess would be 1/8 or 1/16). I think my big problem with the square-1 is that it is difficult to remember the state of the puzzle before you do a move sequence, so you can work out what has changed. Even notating a move sequence is difficult. (though I don't understand the notation people use for rubik's cubes either).

Glitch Repairing

Sat, 21 Feb 2009

I was recently given the task of cleaning up some audio tracks that were recorded on a setup where there were word clock synchronisation issues between two of the boxes in the recording chain. The glitches looked a bit like this:

Waveform for a glitch

And they were very frequent (about 1 a second, but sometimes more or less, sometimes two within a few samples of each other).

I wrote a program that would fix them automatically, it was written fairly quickly, and fairly experimentally (I didn't know exactly which approach would be best for fixing them, so I tried several, and hacked lots of methods to see if they could be improved). As a result, the code isn't particularly nice to follow, but it is farily short, and gives a nice starting point if you have a similar problem.

The basic approach was to look at windows of samples, and calculate some statistics about them (e.g. mean and variance) then calculate those same statistics, but with the very middle sample ignored. If the statistics for these two windows were too different, then the middle sample is declared to be a possible glitch and given some sort of score for how wrong the stats were.

Then, all the possible glitches are filtered somehow, to get rid of some of the common cases for false positives. For me, this was somewhere in the middle still, there were still some glitches that were missed, and lots of false positives in noisy sounds (like 'esses'). I did experiment with an 'ess' detection thing, but the repairing was so subtle, I turned it off in order to fix as many glitches as possible, since they were very noticable.

Repairing was done by just taking the mean of the adjacent samples. This was fine, but I'm guessing if the glitches were longer than 1 sample, then this would sound bad.

Get the GPL3 C Code for it. Should compile without anything fancier than gcc and make.

Tetroids

Mon, 13 Oct 2008

Screenshot

This is a game I made last week. It mixes together three different video games into one. It is actually quite fun to play, which is something that surprised me. The interaction of tetris and asteroids adds a whole lot to the asteroids game (and basically destroys the tetris game). While you are out shooting and dodging asteroids, you can build a safe haven out of the tetris blocks that have fallen, so you can get yourself into a safer area when there are lots of asteroids around. But you can't just camp there the whole game, or else the tetris blocks will reach the top of the screen.

I think I'm a big fan of games where you can do some sort of construction, even if it is as basic as shooting out a hole in a stack of tetris blocks and calling it a bunker. That part of me makes me want to call myself creative, but then when I look at the people that you would typically call creative (i.e. the artsie types), I don't see many similarities.

The code is C code (GPL3), it uses SDL for graphics and input. There is even a precompiled linux (x86) binary in there (but there is also a working makefile). Theoretically it should compile and run in Windows. I tried and failed (you might think that a compiler with the year 2005 in its name would be able to compile C99 code, but you would be wrong) and don't really have enough access to Windows machines or desire to fiddle with them in order to get a Windows binary. I'd be happy to host it though if someone makes one (send me the files you used to build it too, since that sort of thing is useful).

Finally, press Escape to exit, I never got around to listening to the window manager events.

Paint Filtering

Sun, 07 Sep 2008


This is another non-linear audio filter. The idea is that you take the original signal (which is a line of zero thickness in a time-amplitude scale) and trace over it with a thick elliptical brush. This gives an area which follows the shape of the line, but some of the little kinks will be taken out, and the peaks will be rounded. We then have to convert this area into a line, this is done by just taking a point in time and finding the average of the minimum and maximum amplitudes for that time. There are other ways of doing this step which will give different results, but I used this one because it is simple.

In my mind, I was expecting it to be a sort of low-pass filter, as the high frequency stuff would be blurred out by the "brush". What actually happened was that it has more of a comb-filter like effect. If you run it on pink noise you get a frequency response curve that looks like this:

Filtered pink noise spectrum

(without filtering, this wouldn't have all the bumps in it).

Since the filter isn't linear, you can't generalise and say it will have a comb filter effect for all input signals, but for the stuff I've tried it on, it generally gives a comb filter like effect. On more aggressive settings, certain notes will sound much louder than other notes. I've chosen two examples that I'd think are usable, and while they are quite obvious, they aren't so aggressive as to add the really noticable loud notes:

Original signal, Paint Filtered 1, Paint Filtered 2.

Get the source (C, GPL3, includes makefile, and is a little bit dumb in one spot where instead of using a circular buffer I shift every value in a buffer across a spot).

 

About

I'm a nerd living in Sydney. This is a place where I can write stuff about my interests and not care that no one else is reading.

I like music, maths, programming, pretty pictures, filters and other good things.

(more info)

It should be fairly obvious that this isn't connected to my employer at all.

Email me (not a catchpa)

Email policy

Subscribe

RSS Feed RSS

Get an aggregator

Liferea (Linux)

Vienna (OSX)

Feedreader (Windows)

Google Reader (Web based)

I've only used Liferea, so I can't vouch for the other ones.

About this site

This site runs a (modified) version of blosxom.

The host is GeekISP, and they seem to do an excellent job.