Google App Engine costs the same as any shared hosting

There are many good and bad things about GAE but this issue with the new pricing is just strange in my eyes:

Every paid app must pay google at least $9 each month regardless of usage.

The main awesome thing about GAE has always been the pay-as-you-need pricing model. This concept is completely shattered now for a certain scale of apps. The Python 3 Wall of Shame needed a few extra DB writes to finish the day nicely which would have cost roughly 10 cents a day. But now google will be rounding that up to 30 cents a day.

Apps that grow to use $1 worth of quotas a month are much better off heading to some form of shared hosting for $5.50 a month until they hit that $9 a month necessity. That’s the case with the Python3WOS and another one of my apps. I can’t move the wall of shame as I don’t have the time to do the porting (locked in ಠ_ಠ), but that other app is simple enough. So google will never find out if it could have been an app that’s actually worth $9 monthly.

Youtube going to fullscreen skips bug

Whenever I switch between fullscreen and back in this video http://www.youtube.com/watch?v=lOTPCaItx3w for example – youtube skips 2 seconds forward in time. Even while paused.

I found two relevant issues:

http://www.google.com/support/forum/p/youtube/thread?tid=2960543d59021a08&hl=en

http://www.google.com/support/forum/p/youtube/thread?tid=134f7450b6d08d3c&hl=en

The first one suggests to disable flash’s hardware acceleration which does work (right click the video and then click settings).

But why should we do that?

Also did I mention I dislike losing all the video I buffered in 360p when youtube auto-switches to 480p with fullscreen? I had to manually disable that too.

¯\_(ಠ_ಠ)_/¯

Android API Bugs – AudioRecord

When asking android to record from the mic to a buffer you have to do something like:

mRecorder = new AudioRecord(AudioSource.MIC, RATE, CHANNEL_MODE,
 ENCODING, BUFFER_SIZE);
if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
    // fail and bail
}
mRecorder.startRecording();
bytesRead = mRecorder.read(audioBuffer, offsetInBuffer, readSize);
mRecorder.stop();
mRecorder.release();

Now the bug that drove me mad was that read() returned zero when I left the application (using the home button) and immediately returned to it. Luckily I was toying around with BUFFER_SIZE when I noticed

mRecorder.getState()

failed when BUFFER_SIZE was set to 0×100, I guessed it was too small and indeed one must call getMinBufferSize() to find out the limits of AudioRecord instantiation as documented.

Don’t use getMinBufferSize() + 1 btw as that throws an IllegalArgumentException at AudioRecorder construction:

12-10 21:49:33.359: E/AndroidRuntime(28950): java.lang.IllegalArgumentException: Invalid audio buffer size.

Using something like getMinBufferSize() + 100 does work at first but when you use the home-button to leave and return it causes the read() returning zero bug from time to time. Not always, but from time to time. Also make sure you release() the recorder because forgetting that will also allow you to construct the recorder but reads will fail.

I can’t begin to describe how frustrating finding that bug was.

Now audio programmers should know they’re supposed to read a size that’s a divisor of the buffer size, yes. This doesn’t excuse the API from behaving itself and throwing relevant exceptions and errors that are debuggable and documented. This was SdkLevel 8 btw. Things like this make you feel as though these are the guys that wrote the api:

Eventually the working code will be pushed to the android tuner google code project for your enjoyment.

Duplicating Streams of Audio with Python

This morning I made a python script that uses pyaudio to read from one audio device and pipe to the next, I call it replicate.py.

This is a really old problem for me, ever since I first had 4.1 speakers and winamp only played on the front 2. Nowadays I just want VLC to play on both the TV and the computer speakers without switching between audio output modules in the preferences or fiddling with the default audio output in Windows 7.

PyAudio was really nice and easy to use, I just wish asynch io was added so I could lower the latency a bit as I’m getting 240 ms right now which is very far from perfect.

Pendulums, WebGL and three.js

Here’s the waves pendulum three.js simulation I made.

 So I wanted to simulate a magical pendulum with waves to prove my point that the shapes are the result of a dead simple arithmetic progression. I was almost correct.

After testing, I saw that when the frequency is an arithmetic progression we get the awesome patterns. The problem is that achieving such a feat by modifying the length of the strings alone is a bit harder. Here’s omega, or the angular frequency from hyperphysics:

w = sqrt(g/L)

So all I had to do was choose omegas, increment them and from that calculate the string lengths. I got mixed up and solved the problem in a much more complicated way.

Anyhow, by faking it (choosing my omegas with bogus L’s) I get a prettier result. Headache averted. I’m not sure these swing angles are simple pendulums anyway.

WebGL and three.js are indeed awesome. It does have its gotchas but I was just so impressed with http://lights.elliegoulding.com/ and other things in the three.js gallery. It’s amazing how simple and accessible opengl is now that it’s in the browser. The “hello world” of about 20 lines for a rotating cube was good though I think it should include the WebGL detection in it.

Android api quirk number 5

Wow this is silly.

public void drawRect(float left, float top, float right, float bottom, Paint paint)

Usually it doesn’t matter if top is higher than bottom. Either way a rectangle is drawn.

UNLESS, top is outside of the screen. Then no rectangle is drawn at all.

So you can have rectangles that are partially visible, but only if their top is greater than their bottom.

ZOMG that was a hard bug to figure out….

Python 2/3 and unicode file paths

This bug popped up in a script of mine:

For Python 2:

>>> os.path.abspath('.')
'C:\\Users\\yuv\\Desktop\\YuvDesktop\\??????'
>>> os.path.abspath(u'.')
u'C:\\Users\\yuv\\Desktop\\YuvDesktop\\\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5'

For Python 3:

>>> os.path.abspath('.')
'C:\\Users\\yuv\\Desktop\\YuvDesktop\\\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5'
>>> os.path.abspath(b'.')
b'C:\\Users\\yuv\\Desktop\\YuvDesktop\\??????'

That odd set of question marks is a completely useless and invalid path in case you were wondering. The windows cmd prompt sometimes has question marks that aren’t garbage, but I assure you, these are useless and wrong question marks.

The solution is to always use unicode strings with path functions. A bit of a pain. Am I the only one who thinks this is failing silently? I’ll file it in the bug tracker and we’ll see.