February 8th, 2008

rain

(no subject)

A post for programmers who are being frustrated with bad documentation - Google didn't help me, but once it indexes this it might help someone else. In programming audio in the latest DirectX "hey it's Monday again, let's make everything work another new totally different way" upgrade to audio functionality, there is a function
HRESULT IXACTWave::SetPitch(XACTPITCH pitch)
About which the documentation says "The value of pitch may be between XACTPITCH_MIN (-1200) and XACTPITCH_MAX (1200), which is approximately one semitone."

Now the astute amongst you might realise that already this is annoying and ambiguous - what is approximately one semitone? The distance between -1200 and 1200, which is 2400, or a distance of 1200? Also, what the hell, when you're changing pitch by playing the sample at a different frequency you can easily go up and down by a whole octave by doubling or halving the frequency, why are you limiting me to a semitone? Well, thankfully, the answer to "which of these" is "no, it is neither of those things that could possibly be meant by that sentence."

Instead, a pitch of 1200 is approximately one octave above 0, and each 100 pitch is a semitone. So you can in fact go up and down by an octave, like you should be able to (though really there's no reason for it to disallow going two octaves if you want to, even though it'd sound crap) as well as pitching to nearby notes easily. It's a bit strange to have SetPitch operating on a linear scale like this since the change of frequency is an exponential scale, which conversion must presumably be going on behind the scenes in a manner that would be entirely unnecessary for my purposes since I could precalculate the desired frequencies, but oh well, at least it works and does what I need it to do.

Another malfunctioning function is
HRESULT IXACTWave::Stop(DWORD flags)
which "returns S_OK if successful, otherwise an error code." Except no it doesn't - if you use IXACTWaveBank::Play to start a sound, and then call Stop on the output IXACTWave pointer immediately afterwards, it returns S_OK but the wave does not in fact stop, which is horrible if the wave was set to loop indefinitely. However, you can call Destroy on the output wave object which will reliably stop it. I have no idea what's going on behind the scenes there, or whether one needs to call Destroy on every output wave pointer out of a wavebank.Play call to avoid memory leaks, because the documentation is fucking awful. Hooray.

In other good design news, installing Linux Ubuntu, the "user-friendly" desktop Linux. Step 1: graphical installer. Very posh and Windows-like. Here's a dialog box, fill it in. Here's another one to select your timezone. Oh you don't want to be able to click 'next' do you? Well good luck with that, Mr "only 800x600 screen" (or less, as, say, on an Eee machine), because that button is way off the bottom of the screen where you can't get it unless you know some arcane key-mouse combinations to work around it. This has been a known and potentially-easily-fixed issue for about two years. Oh Lunix nerds, you are so good at user interfaces.

And further on the audio front, is there really no preexisting function to make a segment of a wave file loop smoothly? It's getting to the point that I'm considering writing my own command-line wave file editor to perform the following operations:
  1. Find the zero-crossings in the same direction nearest to the given boundaries. (Existing software does this one.)
  2. Find the volume 'cone' in the selection and normalise it to a volume 'cylinder'.
  3. Also normalise into the same volume cylinder a small section out of the wave before the selected block, into a spare area.
  4. Cross-fade the spare block onto the end of the target block.
  5. Set loop point markers in the wav file at the ends of the target block. (One of the two pieces of software I tried can do this step.)
Hopefully this way I can make instrument notes where I can control the duration and volume of the note and it doesn't sound like a midi file.
rain

(no subject)

I went out to buy some printer paper, and on the way home passed a shop I have passed many times. It invariably has a sign outside advertising 25kg of potatoes for about 5 quid - I don't even know if that's a good price, but I'm always a bit tempted to buy them anyway, until I remember how far uphill it is to my house, and I walk past. Today, however, the door was open, so I peered in to see what else was in the shop. It was full of strange wonders, so I went in and purchased some.

One I purchased was a bottle of "MIGHTY MALT", whose ingredients appeared to be an approximation of "beer that didn't get fermented". It turns out unexpectedly that this drink was pretty nice.

Another purchased one is "Jamaican IRISH MOSS (Carageenan) vanilla flavoured drink", a strange can of nominal drink. To give you an idea of how 'drink' it was, it took about twenty minutes to pour into a glass. I suspect it's supposed to be like a protein shake or something, because it was utterly vile in that sort of way.

There were also several sorts of ginger-based cake that I could eat, one of which I bought but have not yet tried, the big bags of spices that I love this sort of shop for (twenty times a supermarket refill's size for close to the same price), a jar of unrefined palm oil which is a horrific glowing orange colour, a tin of some sort of leaves in brine that sounded like it'll taste like chili leaves (which are nice, like peppery spinach), "fufu flour" which I think is plantains, and a huge bag of cassava flour (unless that one's plantains and fufu is cassava). I didn't buy the huge bag because, like the potatoes, 15kg uphill made it less tempting than it would otherwise have been, but really, crazy flours that I've not seen before! Horrible things in tins and jars! I can never resist these temptations.

Also, Lunix drivers suck. Two possible drivers to pick from for my wireless card; the default one works for about 5 minutes then dies and requires a full reboot, the other option, after being a pain in the arse to install, also doesn't work at all. Working solution - installing the Windows driver inside ndiswrapper so Lunix can understand it. Apparently the drivers that don't work have been works in progress for about three years.