How to succed in coding optimized programs.

Most people cant be race-car drivers, yet they can drive a car. Same goes for programmers, most optimization of the code is today done by the compiler. So there is seldom any need to manually optimize loops or fiddle with the small things. This however does not excuse giving up optimization or making your program to work as snappy as possible. Here are a few steps, I will explain them after but these are good to copy paste into your word-document, print and put near your computer.

  1. Choose the correct algorithms for the problem you are solving.
  2. Write readable functional and documented code
  3. Test (on the hardware you are gonna run it on)
  4. Analyze the test’s and find the weak-spots.

Choose the correct algorithms for the problem you are solving.
This might seem obvious, but it’s not and it is the step you’re gonna correct most of the time. There are in normal software development to many variables to keep track on to choose the correct algorithm the first time. This does not mean you’re a bad developer. It’s just life.

Write readable functional and documented code.
In this step, don’t pre-optimize, don’t write hard to read code just because you can or want to show off how smart you are to the few other that could be reading the code you write. The longer it takes to understand the code you are writing, the longer it will take to fix bugs, and the slower bug fixes and new features will come to the user of your program. Now who do you really care about? think about it! Why document you ask? well, because if you write in plain English (or whatever your preferred tongue is) you explain what the code is supposed to do, if someone finds out that it doesn’t do as described the bug is probably there. Coders who say “all you have to do is read the code” has it all wrong. Think about it like a destination and driving instructions”. If you only get the instructions like this: “take a left, walk 2 houses, take a right ….” without the destination clear someone who knows the destination and how to read and write instructions wont be able to fully understand.

Test (on the hardware you are gonna run it on)
You probably have a decent to really fast computer. Do your users have that? do they need to? If you’re writing for a microprocessor or mobile-phone or similar. there is one thing I can tell you, DON’T TRUST EMULATORS. There is always small but crucial differences on running on your computer or on the actual device. It could be they way you’re holding it, the way it reads from file-system. What I’m telling you is that there is no substitute for testing it on the hardware the costumer is gonna use your program on. The sooner you test it on hardware the sooner you’re gonna find the things about your program that sucks, and you’re able to fix them. The sooner the better!

Analyze the test’s and find the weak-spots.
Did you choose the correct algorithm to solve your problem? is there a performance bottleneck somewhere that you didn’t thing of? Fix it.

Most importantly do this for every feature added. If your writing something for a platform other then the one you are writing code on, test on hardware as often and as soon as possible or you will fail.

This was a nice little Saturday morning rant. I should do this more often, I was actually angry while typing. And I borrowed a lot of the language from a book I’m going to review in a little while!

How I made a twitterbot for fun and profit! part 2

Back to the bot. The twitter-bot. The Lars Ulrich twitter-bot. The Lars Ulrich swearing twitter-bot. He’s up and running, spreading obscenities all over the internets. Check him out at http://twitter.com/i_am_larsulrich

The engine I was planning on using didn’t do what I  wanted it to do (search) so I went with twitter4j and processing (processing to the rescue).

There are a lot of other bot’s you could build for example a “silent bob” bot, that twitters silent comments beavis or butthead bot’s that search for bad words and replies to those twitters in a “huh huh huh you say *”

I’ve included the source of the bot down after the jump for you to build further on if you want to, the whole shebang is also available here for you to download: i_am_larsulrich.zip

Continue reading

Idea for a new VST, a little helper for creating melodies.

Yes yes yo.

I had  this idea when traveling to work. The train was super crowded and that got me thinking of circuit bending. A lot of the devices I’ve bent have a “press only one key to play a melody that you probably heard a gazillion times before”  that combined with me reading up on Arnold Schoenberg’s 12 tone matrix melody composer thing gave me a new idea! What if you could type in a couple of notes that you know are in a good scale, or fits your mood. Then press a key on your keyboard or similar to add play these in order. And if you make the VST output MIDI then you could connect it to any VSTi and have it play the sound’s of your liking. You could even record the output and edit it. I was thinking that this would be a nice little tool for creating melodies (which I suck at programming in) but editing or fiddling them out is much easier for me.

Perhaps I’ll do this and put it up on http://www.shuriken.se one of these days, it will mostly be UI work though, which I find a bit tedious to program in VST GUI.  Thought’s ideas suggestions are welcome.  Name suggestions also.

Decompression glitches for sound generation.

The art of using compression glitches as visual tools for creating art has been around a some time now. Datamoshing yields many hits, as do glitch. But how could you apply the same effects to audio and get more interesting results then we have to day with the mp3 FFT artifact?

That question was thrown out in a conversation between me and Rosa late one night at Norbergfestivalen. I recently met her when we carpooled to the festival. Anyways, she’s writing her doctorate about these things and that was one of the questions she was thinking about. To bad she addressed that to me, because I started thinking about it also.

I’ve gone through and tried a few things, but none of them sounded very good. Basic RLE decoding of data to a waveform. Fourier compression data corruption test’s. Packaging raw data in a zip-file, change the contest of the zip data, and then re-import the raw-data.   None of these where very interesting, but they are easy to do without any programming. I also listened to the scratched mp3-cd’s I have in my car. Where the most interesting effects where a sort of LP-like stuttering. But not interesting enough.

So what to do to make things a little more interesting? Well one has to look at the problem from another angle I suppose.

I have to create a compression-algorithm that makes more sense to break. Sounds stupid? I guess, but if we cant be stupid for the sake of art or comedy when are we allowed to be stupid?

Right. I came up with a modified RLE-algorithm. It’s pretty basic. waveforms are 2D, and the next sample can move up, down, or not move at all. With that you can compress your data with information on where to move for the next sample, and if there is a pattern to it it’s easy to find and repeat. A triangle example follows the data could be: “move up 1 step for every sample 127 times”.

This can also make for seriously fun glitches if you edit the compressed data, or as nice samples if you  just randomly generate the compressed data.

As you can see below  the implementation is very naive, there are no key frames, the comparison algorithm works by stripping away data (converting from double to float). One could also implement a better RLE that finds patterns. None of this however was very important for me when I wanted to test this idea.

There are a few parameters I’ve been toying around with on a few different wav files. These have yielded results that I’m mildly satisfied with. I don’t know what my expectations where when I started out on this journey, but there has been some success.

I tried it out on a few different sounds, the result’s are a little longer and they don’t share parameters:

trumpet.wav
trumpet_glitched

bicycle_bell
bicycle_bell_glitched

rusty
rusty_glitched

scream_females.wav
scream_females_glitched

I’ve toyed with the parameters in injectErrors() function. as you can se from the commented out code there are a few different things to play with when trying out the algorithm.

Where to go now?

Well I don’t know, perhaps wrap this in a standalone program, look more into other compression techniques  to try out, make a VST out of it. Maybe I’ll just leave it. Possibly I’ll try to make some nice noise songs with this as either a generation device or as an effect on noisy samples. Most possibly I’ll let it mutate itself over time, feeding the same sample back over and over and over and over. Maybe one should try and apply this to MIDI note data. That could be awesome.

#include "stdafx.h"
#include "wav.h"
#include "wav_save.h"
#include  

SoundDataStruct* p_wav;

void compressWaveform()
{
int i;

//first run is to change everything to relative path's
double oldData = p_wav->dataP[0];
p_wav->dataRLEWP[0] = p_wav->dataP[0];
for (i = 1; i < p_wav->length; i++)
{
p_wav->dataRLEWP[i] = oldData - p_wav->dataP[i];
oldData = p_wav->dataP[i];
}

p_wav->keyframedata = (keyFrameStruct*)malloc(sizeof(keyFrameStruct)*(p_wav->length/100));

//add keyframes
int pos=0;
for (i = 1; i < p_wav->length; i+=100)
{
p_wav->keyframedata[pos].data=p_wav->dataP[i];
p_wav->keyframedata[pos].position =i;
pos++;
}
//now we RLE Encode it for real.
int writeplace=0;
for (i = 0; i < p_wav->length; i++)
{
int runLength = 1;
while( i+1 < p_wav->length && (float)p_wav->dataRLEWP[i] == (float)p_wav->dataRLEWP[i+1] ) {
runLength++;
i++;
}
p_wav->dataRLEP[writeplace]=runLength;
writeplace++;
p_wav->dataRLEP[writeplace]=p_wav->dataRLEWP[i];
writeplace++;

}
p_wav->RLELengthP = writeplace;

printf("compression is %d \n",p_wav->length-p_wav->RLELengthP);
}

double clamp(double in)
{
if(in>1.0)
return 1.0;

else if(in<-1.0)
return -1.0;

else return in;
}

void decompressWaveform()
{
int i,x;
int writeplace =0;
int newLength=0;

//find length for the new sample.
for (i = 0; i < p_wav->RLELengthP; i+=2)
newLength+=p_wav->dataRLEP[i];

printf("newLength % = %d \n ",newLength);
p_wav->dataU = (double *)malloc(sizeof(double)*newLength);
p_wav->dataRLEWU = (double *)malloc(sizeof(double)*newLength);

//undo RLE Encoding
for (i = 0; i < p_wav->RLELengthP; i+=2)
{
for(x=0;x<(int)p_wav->dataRLEP[i];x++)
{
p_wav->dataRLEWU[writeplace] = p_wav->dataRLEP[i+1];
writeplace++;
}

}
p_wav->RLEWLengthU = writeplace;
//undo RLEW Encoding
int pos=0;
p_wav->dataU[0]= p_wav->dataRLEWU[0];
for (i = 1; i < p_wav->RLEWLengthU; i++)
{
p_wav->dataU[i] = p_wav->dataU[i-1]+p_wav->dataRLEWU[i];
p_wav->dataU[i] = clamp(p_wav->dataU[i]);
}

}

void compareWaveforms()
{
int i;
if(p_wav->length != p_wav->RLEWLengthU)
{
printf("data not equal\n");
printf("%d\n",p_wav->length);
printf("%d\n",p_wav->RLEWLengthU);

}
for (i = 0; i < p_wav->RLEWLengthU; i++)
{
if(i>p_wav->length)
break;
if(i>p_wav->RLEWLengthU)
break;
}

}
void injectErrors()
{
int i=0;
//randomizing number of repeat's
for (i = 0; i < p_wav->RLELengthP; i+=2)
{
if(rand()%200==1)
{
p_wav->dataRLEP[i]=(rand()%512)+1024;
//         p_wav->dataRLEP[i] -= ((double) (rand() / (double)RAND_MAX)*0.4f)-0.2f;
p_wav->dataRLEP[i] -= ((double) (rand() / (double)RAND_MAX));
}
}
//randomizing data to repeat
for (i = 1; i < p_wav->RLELengthP; i+=2)
{
if(rand()%4000==1)
{
//p_wav->dataRLEP[i] -= ((double) (rand() / (double)RAND_MAX)*0.4f)-0.2f;
}
}
}

void savewav()
{

float calculatedlengthofnewsample = float(p_wav->RLEWLengthU)/44100.0;

Init_save(calculatedlengthofnewsample+1.0);

int i;
for ( i=0; i
RLEWLengthU; i+=1 )
{

SaveWavData(i, p_wav->dataU[i] );
}
Do("temporary.wav"); //save might crash if called to many times
freemeData();
//---------- end render block
}
int _tmain(int argc, _TCHAR* argv[])
{

srand( 1234 );

/* get input wav */
p_wav = (SoundDataStruct*)malloc(sizeof(SoundDataStruct));

wav_init( "bicycle_bell.wav", p_wav );

compressWaveform();
decompressWaveform();
compareWaveforms();

/* the fun begins here*/
injectErrors();
decompressWaveform();
compareWaveforms();

/* save wav */
savewav();

return 0;
}