Friday, April 22, 2011

DrumLine

I decided to forge ahead with the drum line app.  I've got it to the point where things are working from a programmatic standpoint.  The sequencer object reads in the score.  The score consists of measures.  Measures consist of notes.  Measures & notes can be instantiated and added to the score, which is then passed to the sequencer for playing the actual drum line.

The notes right now are limited to drum track samples.  I've got it in mind to expand this to allow any kind of sounds / voices.  But, drum samples are relatively easy to get going.  We'll see how things progress.

The things to do list currently consists of:
  • Create a UI for the sequencer for playing
  • Create an Editor
  • Allow storing / loading of previous compositions
  • Allow importing / exporting of compositions
  • Observe memory usage effects resulting from samples.  Will I need to down sample?
Need to do some experimentation yet, however, to make sure that the Android device is capable of handling this.  As mentioned in a previous post, there are some issues with latency and audio.  Things work fine on my quad-core desktop at up to 160 bpm (haven't messed around too much with that -- but 160-180 is the top end I want to target).... but will they push my HTC Incredible or Nook Color to the limit?  I've got today off so I plan on doing some testing and coding to see where it brings me.

Portal 2

Just completed Portal 2 single player.  Now I can go back to being productive.  Kinda.  Stayed up till around 2am playing it so I'm a bit zoned out at the moment. :P

Sunday, April 17, 2011

Android Market stats

I thought it would be interesting to share this. It's a rendering of what I see in the Developer Console on the Android Market for my app. Unfortunately, an interactive graphic does not show up in that rendering -- at the top in that blank area you see is a Flash graph showing the trending of downloads for an app. It currently states that my app has 254 or so downloads. This conflicts with the market dashboard indicating that value is actually 341. I've noticed a discrepancy between those two values, and although there is info that states the data is updated on a daily basis it doesn't appear to happen that frequently. It looks to be more like one or two days between updates.

Here are some interesting tidbits from that data:

  • There are only 9 installations that utilize something other than Android 2.1 or 2.2.
  • The top three devices that installed it were Motorola Droid X, Samsung Galaxy S, and the HTC Incredible.
  • The top three countries are US, UK, and India. I was surprised that India was #3. It's followed closely by Australia.

Saturday, April 16, 2011

Android Audio bites

Today I thought it would be fun to throw together a Drumkit Soundboard. I was at work the other day and it occurred to me that doing something like this would be really simple and result in something that would be relatively cool.

I've got a program on my desktop named Guitar Pro which is really cool for learning and playing along with songs. It employs something that the company terms "Realistic Sound Engine". What this boils down to is real-world samples of instruments that can be played back at real-time. (OBSERVATION: The Guitar Pro site shows an iPad and iPod, but curiously no Android device... The reasons will become apparent below.)

I took that and created a drum track with the simple drum samples I wanted: snare, bass, high hat, and cymbal. I exported the result and pulled it into open source audio editor Audacity. From there, created individual samples and stored them off as OGG files. I fired up Eclipse and created a libgdx based project called DrumkitSoundboard. After looking up some API calls and creating a really uber-simple quadrant based UI (each quadrant of the screen corresponding to one sound sample), I had the rudiments of my soundboard going. This is where the problem cropped up.

The problem -- the audio on my HTC Incredible lagged to the point of unusability. There is something on the order of 100ms+ gap between the time the user hits the screen to the point that the sample hits the speaker. If you are trying to maintain any kind of rhythm, you are going to be severely messed up trying to play it... I know I was.

As a result, I posted a query on the Bad Logic Games forum about this to see if anyone has run into a similar issue. It turns out that audio latency has been identified as a problem since as early as 2009. The issue is logged here. There are several music app developers that would *love* to port their stuff from the iPhone/iPod to Android, but can't because of this problem with high-latency of real-time sound. Ugh! That royally sucks. ...and also probably explains why there's no Android app from the guys at Guitar Pro.

For fun, I cracked open the Android Market and downloaded a drum kit soundboard I found there (Hit it!). Turns out it has the same lag issue I experienced. Nice.

Needless to say, this put the kibosh on my own drum kit idea. At best, I could create an audio composer of sorts... Where instead of making things interactive, you could create a drum track. For fun, I did this programmatically to see what the result was. With a target tempo of 120 bpm, playing drum samples at an eighth note beat (bass+hihat, hihat, snare+hihat, hihat, repeat ad infinitum) it worked... Mostly. There were times where you could tell it got off the beat by a perceptible amount. Another: Ugh!

I dunno, I think I'd be ultimately disappointed in the result. Still, it would be kinda fun to allow people to compose simple drum lines. Imagine doing that and then hooking up your Android phone to your car stereo... I've already got the name of the app in mind: MasterBeater. :)

Thursday, April 14, 2011

Project hosting

Some guys from work and I are collaborating on Android projects. Mostly to learn from each other as we go along. Initially we opted for using Project Locker for our project hosting. But, that's a bit on the constrained side. You are limited to 3 collaborators and 300MB for your projects and I believe something like only 3 projects. I did some investigating and decided to switch over to Assembla. There you have unlimited projects, 2GB of project space, and up to 10 collaborators on a team. You also can have 'private' (commercial) repos. Not too shabby. Ideally, it'd be best to host our own stuff, but I'm lazy and didn't feel like leaving up a box 24/7.

On the repo side of things we're using Git. I'm still getting my head wrapped around the way that it works, but so far have been okay with it. There's a bunch of stuff you need to get set up beforehand, though, so it definitely has a learning curve (and I'm still on the rising slope in that respect.) Here's some Windows config stuff I recently sent out to the team to give them a leg up on things. Share and Enjoy.

All--

Here's some help with getting Git up and running under Windows. If you run into problems, let me know and I'll see what I can do to help.

Tools you need to set up Git and repo access under Windows:

SSH agent:
http://the.earth.li/~sgtatham/putty/latest/x86/putty.zip

msysgit:
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.4-preview20110204.exe

TortoiseGit:
http://code.google.com/p/tortoisegit/

Extract the putty files to a directory. Run PuttyGen. You'll use this for generating a private & public key that is required for checking files to the host server. Give it a key comment... I use tim@MY_MACHINE. Save the .ppk off. Don't bother saving the public key off -- if you ever need it in the future, just run PuttyGen and load in your .ppk file to get a copy. Copy & paste the public key -- you'll be using this on Assembla.

The Git Repo hosting is on Assembla.com. You'll need to register there to access the space that I've created for the Pazaak game.

For adding SSH keys:
1) Login
2) Click on "Profile"
3) Scroll down and add a key under the Git repo

If you want to create a project space for yourself:
1) Login
2) Click on "Spaces"
3) Click on "Create a new space"
4) Click on "See all workspace configurations"
5) Click on "Select" next to "Free Git Repository - Unlimited commercial uers" (sic)
6) Give it a name
7) Click on "Create the Space"

Git on Windows

When prompted, tell it you want to use plink. Plink is part of the putty.zip file above.

1) Download & install the msysgit preview.
2) Download & install TortoiseGIT
3) Use TortoiseGIT to create a local repo
4) On Assembla, click on the space you are interested in
5) Reference the Git URL for that space from within Tortoise
6) Do a pull from the server repo to your local repo and you should be good to go (right-click on the dir, TortoiseGit > Pull etc.)
7) In Eclipse, just do an Import... > From Existing Projects


Uber nerds unite!

I'm proud to say that if you put in the search term "uber nerd" in the Android Market, the single result you'll get is my app. Just doing my part to help out all those folk building up their old school nerd-cred. Heh! :)

Memory Leak plugged

Alright. I got it fixed. Wahoo.

As mentioned in my previous post, I was noticing that several objects seemed to hang around across screen orientation changes (ie. going from landscape <--> portrait mode). I went back to square one with the original code that I derived my slide rule app from and discovered that *it* also had the memory leak. It didn't exhibit the same issues as my app, however, because it was using way less memory -- all it did was draw a stinking little icon to the screen.

So, I started tracing things which led me to a class based on a Thread object. It turns out that this guy had some references to a Context object. Yesterday I had read several articles that mentioned keeping references to Context when there is a screen change leads to bad juju. Beyond that -- the orientation causes the Activity to be killed, but if there is a reference somewhere to a Context, the old object doesn't disappear. After a bit, this adds up and eventually you have no more memory that can be allocated.

I updated the Thread such that when it needed to be destroyed, it got rid of its references to the Context (and another object it was referencing... just to be safe.) Further, it turned out that the View that presents the graphics was causing the Thread itself to hang around. I had to get rid of that reference as well to shake loose the Thread.

After making those updates and using the DDMS to dump the heap, I still saw that the 3 primary objects in the App (the Thread, the View, and the Activity) were ratcheting up. HOWEVER, this time around forcing the Garbage Collector to execute caused those bad boys to drop back down to 1 each -- which is what I desired. Wahoo! Problem solved!

If you are a visual person, here are some screen shots that highlight the general approach I took in debugging things.



Wednesday, April 13, 2011

Worse than a running faucet

Well, I don't have a solution yet, but I've learned a bit about how to detect memory leaks. I've verified that I do indeed have one. Here are some quick steps for detecting leaks in your Android app:

1) Install the Eclipse Memory Analyzer. You can do this from the "Install New Software..." option in Eclipse.

2) Set up your application in Debug mode.

3) Download your application to your device or emulator.

4) From the DDMS perspective, highlight your app.

5) Click on the "Dump HPROF File" button.

6) After the HPROF viewer comes up, select the Histogram button.

7) In the regex field, enter part of the name of your app to filter things out.

From there you can see how many objects are available. In my case, I have a class that is called Panel. There should be only one instance of this panel present. After performing several orientation changes (landscape <--> portrait), the number of panels ratchets up... once for each change.

So, now it's a matter of figuring out why. What I've done so far is to strip all graphics and graphics threads out of my app. The problem still occurs. Need to spend some more time on this to figure what's not being released and causing this issue. We'll see where this leads....

Memory Leak woes

I was demoing my Slide Rule to a guy at work yesterday and came across a Force Close. It turns out that my app has a memory leak in it. To replicate: go from landscape to portait and back again several times. Eventually, the app will crash because it runs out of memory.

So, over the lunch hour I read up on handling memory leaks and detecting them. Turns out you can use the Heap profile in DDMS. I'll post details after work today. Hopefully I can get this problem cleaned up tonight and return to my libgdx & OpenGL ES studies.

Tuesday, April 12, 2011

OpenGL ES

Currently working my way through libgdx and OpenGL ES

--tim

Sunday, April 10, 2011

Achievement Unlocked: libgdx Bouncing Sprite

I'm looking at doing development using the libgdx Game Development Framework for Android. It's pretty slick in that you can run things on your desktop before having to worry about deploying them to the target Android device. That, of course, is just the tip of the iceberg... it provides a whole bunch of stuff you need for doing audio, graphics, etc.

I'm running through the initial tutorials and am up to the projection-viewport-camera tutorial, tweaking things as I try things out. I'm thinking it would be a good exercise to port my Slide Rule to utilize libgdx.

Here are a couple of screenshots of my bouncing sprite.

I guess you can buy these things new.

Heh.

Saturday, April 9, 2011

Now it's just time to sit back and wait for the accolades

Got my Slide Rule app uploaded to the Android Market. Now all I have to do is sit back and wait for the accolades to come rolling in.

...

(cue: crickets chirping)

...

Anyway, I learned a bunch of stuff and now it's off to working on my next app.

Slide Rule release

I spent a bunch of time last weekend writing a Slide Rule app. Today I'm in the middle of releasing that to the Android Market.

I couldn't sleep last night, so one other thing I did was to update SwiFTP so that it works in full-screen for my Nook Color. I sent an e-mail to the original developer and now have write access to that project. I submitted my updates for that today. Might be interesting to support that and work on issues that people have logged against it.