About half a year ago I was looking for a reliable metronome app for Android. I fiddled with the code of Bad Metronome and Android UI design to learn more. The result is a simple spike of a metronome app for Android. The source code meanwhile made it as »Classical Metronome« to Github. It should build natively on any Android device using Android IDE.
I’m currently experimenting with the code of Bad Metronome. Since I’m developing natively on a tablet, I need to create the UI by manually editing the XML files, without the support of a user inteface designer tool. Which turned out to be a rather time consuming task. Here are a couple of hints.
Dynamic distribution of widgets
I just wanted to stack three UI elements one above another. I’m using one of the most basic layouts, the LinearLayout in vertical direction. To distribute the widgets equally over the available height, regardless of the screen’s size (handset, tablet), I added empty views above, below, and between the widgets with only the following attributes:
One of the three widgets is a TextView. The amount of lines changes during runtime from one up to three. This means the other user interface elements are repositioned while the user interacts with the app. Fortunately, the TextView provides attributes for the amount of minimum and maximum lines:
Icons for ToggleButton
The ToggleButton supports different icons depending on its state. Those can be changed using a selector:
The content of the selctor file may contain the following lines, where the icons name are just files within the resource folders:
Auch in Unicode gibt es mehrere Möglichkeiten, diakritische Zeichen darzustellen. Stark vereinfacht ausgedrückt kann ein Zeichen als selbstständiges Zeichen (»Ich bin ein Ä«, Normalization Form C, abgekürzt NFC) oder als zusammengesetztes Zeichen (»Ich bin ein A mit zwei Punkten darüber«, Normalization Form D, abgekürzt NFD) ausgedrückt werden.
Ich nutze ein Python-Skript auf Mac OS X, um automatisiert aus Dateinamen Tags für Ogg-Vorbis-Dateien zu generieren. Im Dateinamen von OS X liegen die diakritischen Zeichen als NFD vor. Um die Zeichenkette in NFC zu überführen, nutze ich folgenden Aufruf:
filenameNFC = unicodedata.normalize("NFC", filenameNFD.decode("utf-8"))
On my hard drive a couple of wav recordings of classical concerts are waiting eagerly being split into the individual pieces and to be saved as ogg respectively mp3 files.
I’m using Audacity for the task, a famous open source audio editing software.
The tasks requires the following steps:
- Remove audio in front of the first piece.
- Remove audio past the final applause of the audience.
- Fade out the applause.
- Normalize both channels independently due to mike differences.
- Add silence between the pieces.
- Fade in the hum caused by the audience in front of each piece.
- Fade out the hum at the end of each piece.
- Create text markers for each piece containing the name of the compser, the name of the piece and the like.
- Let Audacity do the job by splitting and exporting the audio material based on the text markers.
I searched a possibility to ease steps 5 through 7. I found a code snippet by edgar-rft. He politely granted the permission to reuse the Nyquist plugin code, so I slightly modified it to get my job done.
Installation and Usage
- Download dual-fade.ny.zip and extract it.
- Move the resulting file dual-fade.ny to the plug-ins folder of your Audacity installation.
- (Re)start Audacity and load some audio data.
- Select some of the audio.
- From the menu effects, choose the command »Dual-Fade«.
That’s it. The first third of the selected audio will be faded out, the second third will appear as silence, and the last third will be faded in. The complete fade follows a three-stage envelope with linear segments (using pwl, »piece-wise linear functions«):
BTW: I also found the Fade+ plugin by Steve Daulton which uses bezier curves to apply some smoother fading curves instead of the usual linear one. In case you do not only want to fade noise but real audio pieces, I’d recommend to check whether it gives you pleasant results.
One use case of the recently purchased slate was to take notes, e.g. during conferences or while reading a book. It turned out that the on-screen keyboard of the pad does not serve much better than the mini keyboard of the N900 (which is very useful compared to its size BTW). So I ordered the dock for the Transformer to turn it into a netbook of 1320 grams.
10 people, two public transport tickets – we did a marvellous spring hiking trip from Calmbach to Pforzheim. That’s the viewpoint at Büchenbronner Höhe:
I find wild boars interesting, but I’m not really interested that they come that close – at least not somewhere in the woods. Fortunately this one was enclosed in a compound :) :
Almost everything on the way already was in the OSM database, so I only recorded stuff for minor edits. I used MoNav on the N900 for routing, track logging and note taking. Additionally I played with OsmAnd on the tablet every now and then. It provids tons of great features. The disadvantage is that it features tons of configurations options to cope with :) .
BTW: Thanks, Miro, for organizing the trip – I know you are reading this :) .
I bought an Adroid device a couple of days ago. It’s not that I really need it, but I was interested in learning more concerning the platform and developing software for it.
I’m not sure what I will be working on. Maybe I’ll work on some stuff for Android, continue coding spoken turn instructions for MoNav, or do some spontaneous stuff with some other participants.
About two weeks ago I blogged about my first attempts to teach MoNav to provide speech output. While everything worked well on my desktop machines, MoNav did tend to crash every now and then on the N900, rendering it pretty useless for the intended use.
As debugging was a bit difficult, I have just rewritten a suspicious part of the code. Et voilà, a test drive through the city of Karlsruhe the past evening was of great joy and pleasure.
The speech output still is not mass compliant, though. MoNav is too verbose, instructions are spoken too late, and MoNav needs too long to detect that the vehicle left the precomputed route. But that’s just tedious work in progress to be done during the next weeks and months.
And though I’m complaining, do not forget that MoNav in its current state actually is capable to guide you to your destination, while I’m pleased with what I achieved during the past weeks.
I’ll continue the work on speech output for car drivers before I’ll dive into making it compliant with the needs of cyclists.
- hg clone https://code.google.com/p/monav/ monav-permaroute
- cd monav-permaroute
- hg update permaroute
- qmake monavclient.pro
- (/Developer/QtSDK/Desktop/Qt/474/gcc/bin/qmake monavclient.pro on Mac OS X)
The above lines are not intended for end users. It’s for all those openstreetmap addicts who are interested to follow the current development of MoNav.
In the last posting I mentioned that I made the routes in MoNav more persistent:
As a consequence, I’ve just written some code that detects whether the vehicle is still “on track”. The route only gets recalculated in case the vehicle left it for more than x meters. This makes the route much more persistent and will cause far less headache than the previous approach.
Since the GPS position is always a bit inaccurate, it will almost never be exactly on the computed route. Instead, it will aberrate a bit from it. What you want to achieve is to detect whether the current position still is either near the route, e.g. left or right of it, no more than x meters away and still in direction to the planned target, or in the opposite direction.
A couple of months ago I opened a branch named »ui-ng« in MoNav‘s repository to develop a new user interface. Meanwhile this branch became a playground for several hacks, and some of them are just spikes to check out whether some ideas work or not.
I denied to work on speech output this spring, as I knew this would become a rather lengthy task. But it was obvious that I won’t resist the temptation during the cold and dark winter months. So I added the first code to generate spoken turn instructions recently. It is an ugly hack, just to determine what was possible. The code as found in the »ui-ng« repo works, well, at least a bit. The instructions are far away from being useful, except for lonesome crossings or roundabouts without other crossings nearby.
I’m using prerecorded samples for now, as the current open source speech synthesis systems did not show the results I desired. OTOH, this means I cannot generate instructions with dynamic contents like distances or street names. Additionally, those samples currently are included in the application binary, which will pollute the memory of handset devices as soon I’ll add further localized samples (currently speech is available in german and english language only).
The main issue is that MoNav recalculates the route each time a GPS position update is received – which means each second on the N900. As the GPS position always is a bit inaccurate, MoNav will speak »Please turn right« when you pass, for example, a gas station and the GPS position is off the road by a couple of meters.
As a consequence, I’ve just written some code that detects whether the vehicle is still “on track”. The route only gets recalculated in case the vehicle left it for more than x meters. This makes the route much more persistent and will cause far less headache than the previous approach. As this happened just a couple of minutes ago, the code is not in the repo yet.
There’s still a lot of work to do, and I’m curious whether I’ll stay motivated enough to do all of the work ahead. On the other hand it’s just plain fun to explore the secrets of a usable routing application.
So stay tuned. The next week(s) will show whether I’ll »head straightforward« :) .
The last two days I’ve worked on a first translation system for MoNav. Thanks to Qt4 it was just simple, and admittedly I copied over some lines of code from one of my other projects, Gebabbel.
MoNav checks the user’s system for a locale string, searches for a matching translation file, and if available, it gets loaded. Currently, the translation files are included in the binary, so we do not need to care about install paths and the like. As soon we have some translations available, they will be removed from the binary and installed as separate files to save some memory.
This also means we are in desparate need of translators for the upcoming releases. Do you want MoNav to appear in your mother tongue, maybe Russian, Chinese, or Bamanankan? As no programming skills are required to create a translation, do not hesitate to contact us.
Today my way led from Darmstadt to Aschaffenburg, where I visited some relatives and friends. MoNav did a very good job guiding me. As it chose a route which led along major roads, I set a via point in Messel, and got really great results.
The trip info page I recently introduced was very helpful. Well, it’s like a progress bar on computers. It does neither shorten the remaining distance, nor does it beam you to the destination. But anyway, it’s very useful to have some figures right at your fingertips during the tour, so you know whether you should hurry or you can enjoy a short rest.
The trip was about 50 kilometers which I planned to cope with in 2 hours. Though the terrain is completely flat, some head wind caused an average speed of 20 km/h only – I needed 30 minutes more as I planned.
Once again, I really enjoyed to have MoNav’s excellent offline routing available during the trip. Before I used MoNav, I spent hours in front of my computer to prepare a trip. Today, I just check what MoNav suggests before I leave and help it with some via points – that’s it. An issue of minutes, not hours.
I’d like to thank all Co-Mappers who contributed the data I used during today’s trip. Thanks girls and guys.
¹ According to
Though I’m currently rewriting the user interface of MoNav, I’m still missing some features while being on the road. During a trip, I want to see information about the remaining route distance, the distance and time already traveled, and as a cyclist who sometimes crosses hilly regions, I found some altitude information very useful. Obviously some volunteer is needed to write the code to accomplish that. Waiting for someone else is a valid option, but I know it’s much better to get things done™ :) .
I pushed the first code to the central repository a couple of minutes ago. It’s not polished yet, and the user interface requires some more dedication. I’d also like to add a display of the average speed, but this required some redesign of the track logger code first.
Frankly, it’s a great joy and pleasure to contribute to MoNav. I’d like to thank its creator and maintainer, Christian Vetter, for the great work he put into it. The use of Qt for the backend and the frontend code. The uber fast routing engine. The use of OSM data for routing and the fast address search. And last but not least for his openness when it comes to new ideas and changes. Oh, and did I mention MoNav ran on the N900 out of the box from the first day I tried it :) ?
I’d also like to thank James Hollingshead who wrote the first ready to use vector renderer for MoNav. Though it still shows some minor glitches and is missing rendering of street names, it currently serves us very well for displaying offline vector map data.
Enough rant for now. The code is written, and I better should go to bed :) .
The recent 0.3 release of MoNav provides a useful interface, which allows to invoke all features directly from its main window. It’s a great, both finger as well as user friendly interface, especially on mobile devices such as the Nokia N900. The downside is that it does not conform to the look and feel of the other applications of a given platform.
Christian Vetter, the inventor and maintainer of MoNav, just announced the release of MoNav 0.3. Finally the improvements and new features developed during the last weeks and months are available as precompiled installers. Here’s a copy of the original posting:
The highlights of this release are:
- UI Overhaul, take a look at the screenshots
- Offline vector renderer: QTileRenderer
- Better handling of map data and map modules: It is now very easy to switch between routing ( motorcar, bicycle, pedestrian ) and rendering modes ( online, offline vector… ).
- Full Maemo support
- Track logging
- PBF support: 10 times faster OpenStreetMap data parsing!
- Console version of the preprocessor
- Improved import of OpenStreetMap data: surface, smoothness, barriers, …
- And many more
Of course MoNav still delivers blazingly fast routing, even for huge
graphs on mobile devices.
- Client binaries for Windows32, Ubuntu 32/64 and Maemo
- Map packages for most countries: pedestrian, motorcar and bicycle routing; online and offline vector rendering.
We are still looking for contributors in the following areas:
- GUI design
- Address Lookup ( Karlsruhe Schema, novel approaches … )
- Binary package maintenance for various systems / distributions
- Usability tests and improvements
- New features
- Of course other contributions are always welcome If you believe you can contribute and are interested in joining the development team please let us know.
Please note that this project is under active development and while
considered stable may still contain serious bugs.
Comments, bug reports and suggestions are welcome and can be filed under 
 MoNav Homepage: http://code.google.com/p/monav/
 MoNav at OpenStreetMap Wiki: http://wiki.openstreetmap.org/wiki/MoNav
 MoNav Downloads: http://monav.openstreetmap.de/
 MoNav Screenshots: http://code.google.com/p/monav/#Screenshots
 QTile Renderer: http://code.google.com/p/monav/wiki/QTileRenderer
 PBF at OpenStreetMap wiki: http://wiki.openstreetmap.org/wiki/PBF_Format
 MoNav mailing list: http://groups.google.com/group/monav-discuss
 MoNav developer mailing list: http://groups.google.com/group/monav-dev
 MoNav bug tracker: http://code.google.com/p/monav/issues/list
My last black forest trip by bike led me through Baden-Baden, and MoNav created an interesting route, avoiding the best one. At home, I figured out that bollards caused the weird behaviour. Actually MoNav didn’t route across nodes with any barrier tag applied.
I checked the code of the preprocessor, and allowing bikes to cross bollards was just simple. However, the preprocessed bicycle maps available for download all were of less use.
Some script currently recomputes all maps. For each region provided, you’ll only find one zip package instead of three. The zip file contains the following data:
- Address search.
- Online tiles (Mapnik style, internet connection required).
- Fast offline vector rendering (due to early code, no streetnames rendered still).
- Car routing.
- Bicycle routing.
- Pedestrian routing.
In case you do not need all of the routing data, just remove the folder you do not need after extraction. I hope these data sets will serve cyclists and pedestrians better than the previous ones.
The installer contains experiental software, as I applied some quick and dirty hacks to get it compiled. It is thus not intended to be used by end users. As I’m rarely booting into Redmond OS, some developer who is savvy enough to maintain the NSIS installer is required to update the package every now and then. Contributors are always welcome!