Monday, December 20, 2010

Google Voice Callback v0.7 is out!

This one has been long in coming; I was occupied with some real life tasks (good luck to me on my graduate school applications, everyone!) Anyways, v0.7 is out:

  • turn off callback completely for certain weekdays and hours (see Quiet Hour in setting)
  • can now call your own GV number
  • bug fixes

The major change is the "Quiet Hour" feature, which is among the number one asked: turn off callback completely for certain time (such as any time other than Monday-Friday, 7am-8pm).

(Those of you who like to play around with your phone probably already implemented this feature on your own with Tasker/Locale. This feature is simply here since perhaps some of you don't want to pay for an extra app to do something as simple as this. I still strongly encourage you to use Tasker/Locale to turn callback on/off based on more complex situations. More features on the plugin is forthcoming, including the ability to change the callback number with the plugin. Stay tuned!)

Happy "callbacking" and happy holidays!

Changes in v0.7.1

fix bug in Quiet Hour

Sunday, August 29, 2010

Google Voice Callback v0.6 is out!

There are lots of changes in this one (though most of them not visible to the end user). So keep the bug report going!

What's new/changed in v0.6:
  • (Experimental) support for auto-answering the callback call. One less click from you! You need enable it in the preferences to use this feature.
  • Better compatibility with the official GV app. To ensure true compatibility, you should set the official GV app's "Making Calls" setting to "Use Google Voice to make all calls". Don't worry, Google Voice Callback still works despite that settings! You should make sure, though, that no other call interceptors are enabled. Otherwise things might not go as expected.
  • Perhaps the most noticeable change: there is a new settings page! The settings pages are now made to be more robust, less mistake-prone, more foolproof, and more reliable.
  • Killed a bunch of bugs/potential bugs.

In v0.6.1:
  • Small bug (FC) fix for phones that does not report their numbers

In v0.6.2:
  • Small bug fix (should affect very few users anyways).


Sunday, August 15, 2010

Google Voice Callback FAQ

Here is a list of frequently asked questions and answers:

Q: What is the differences between your app and the official Google Voice app? Why do I need Google Voice Callback?
A: As its name implies, my app uses callback mechanism, which means it intercepts your outgoing calls, and then it asks Google Voice to call you back so that when you pick up the incoming call from your Google Voice number, you are connected to your original outgoing number. That means you actually never call out; you answer a call from your Google Voice number.
The official Google Voice app, in contrast, calls out, which means it dials another number instead of your original number (some number from the 416 area code) then transfer you to your original number on their (Google's) end. That means you are virtually dialing a number that does not even exist on your phone book.
Is the difference significant? If you want some form of free call, then it is. See questions/answers below.

Friday, August 13, 2010

Google Voice Callback v0.5 is out!

v0.5 contains mainly changes that make Google Voice Callback interacts better with other apps on your phone. The changes are:

  • A plug-in for Locale or Tasker, two very flexible automation apps* for Android. It means that now you can decide whether you use Google Voice Callback based on situations, including but not limited to: hours of the day; days of the week; GPS location; Wifi availability etc. The possibility is limitless!
  • Google Voice Callback now proactively helps to keep your call log clean, by removing the "fake" entries from your Google Voice incoming call and transferring properties such as call length etc. to the real number you actually called.
  • Interact better with Sipdroid (see a separate blog post!): option for auto-answer for the Google Voice incoming call, and option to start Sipdroid when callback.
  • Display the type of phone number (mobile, home, work, etc.) in the pick number screen for setting callback rules.
  • Other fixes to prevent possible crash.

As always, enjoy! If you find the app helpful, donation is always appreciated!

* I apologize that both Locale and Tasker are paid apps. I want to keep Google Voice Callback a simple and small app that does one thing only, and does it well, instead of trying to accomplish too much. Duplicating functionality that another app already does well is not fun...

Make Sipdroid and Google Voice Callback work together

Many of you (including me) use Sipdroid for calling over internet. The setup can be made pretty convenient, but not enough for me! Thankfully Sipdroid is open-source, so I modified Sipdroid to make it work a little better with Google Voice Callback.

DISCLAIMER: this is a purely fun personal project that I did for myself. I made no guarantee of usability or suitability for you! Use at your own risk, and don't complain if it makes your current GV-SIP setup not working, or burns down your house, or causes global warming.

The modified version of Sipdroid is based on an older version, 1.3.7 beta. I have not had the need to update (and got burned once when one update broke the callback mechanism). I may consider update my changes to a newer version of Sipdroid, but don't count on it!

The major changes I made to Sipdroid are:
  • Exposes some internal functions so that Google Voice Callback can start Sipdroid's service on background. You can enable the option to start Sipdroid when callback occurs (in the main setting screen for Google Voice Callback, press Menu -> Preferences).
  • I added an option to auto-answer incoming call from your Google Voice number (and optionally disable ring for such incoming calls). To find the option, open Sipdroid, press Menu -> Settings -> Call Options -> Auto-Answer number / Disable Ring for Auto-Answer.
  • I removed the annoying red LED notification from Sipdroid when network is not available.

You can find the modified version of Sipdroid and the modified source here:

Be warned that the download apk file is signed with my key, which means that you cannot install it on top of existing Sipdroid. You must uninstall Sipdroid from your phone before installing the modified Sipdroid apk.

Friday, June 18, 2010

Calendar Quick Add v0.4.3 is out!

What's new in v0.4.3:

  • (Experimental) support for HTC Sense UI devices (Hero, Incredible, Evo, etc.).

  • Fix the am/pm reversal bug when the hour is 12

  • Allow alternative syntax for time input - now also accepts (i.e. 8.30 is acceptable for 8:30)

If you own a HTC Sense UI device, let me know if everything works well!

Enjoy, as always :)

Thursday, June 17, 2010

Calendar Quick Add v0.4.2 is out!

This is a quick update to be compatible with the newest Android version (2.2 aka Froyo).

Let me know of any problems!


Friday, June 11, 2010

Google Voice Callback v0.4 is out!

What's new?
  • Call logging is back! (It was accidentally removed in the last version)
  • A toggle shortcut to quickly turn callback on/off.
  • Filter rules! See here for detailss.

v0.4.1 has some minor fixes and minor features including
  • A new type of rule that specifically matches US phone numbers.
  • Rules that match using regular expressions

v0.4.2 has some fixes for the Force Closes (FCs) that used to happen when the login info is not correct.

As usual, I can only test the new features as much. Let me know if you ran into problems.


If you appreciate my work, consider donating! Via Paypal below, or by buying the donate version (search Android Market for "Google Voice Callback Donate").

Filter rules in Google Voice Callback

Many of you want finer control on when to use Google Voice to call back. I heard ya! The latest version (v0.4 and above) contains the functionality called "filter rule" that hopefully give a flexible way to control when to use Google Voice callback.

I try to make the framework flexible so that I can add other type of rules (such as time-based, network-type based, etc.) later, so how the filter rules work is perhaps not so straight-forward. No fear! Let's walk through some examples.

Before you start following the examples, make sure that you turn on the option to use filter rules. To do so, go to the Setting page and choose "According rules (needs setup)" under the option "Callback is enabled when...". A new button with text "Configure filter rules" should appear, and from there you can configure the rules!

On to the examples...

Example 1: You want to use Google Voice callback almost all the time except for a few friends. In the past you probably use the "Ask me everytime" option, but that's annoying. Now, in the rule configuration page:

  • You should choose "Use GV callback" for the default action
  • then click "Add new rule" and choose "Exclude rules".
  • All the phone numbers in your phonebook should appear, and just check all the numbers that you don't want to route through Google Voice, then click "Done" in the bottom.
  • That's it!

Example 2: You only want to use Google Voice for a few numbers, and other times you want to call through your cell phone provider's network. No problem! Follow the directions in Example 1, but choose "Do not use GV" as default action and pick the "Include rules"

Example 3: You want to use Google Voice only when calling non-local numbers. Suppose the area code for where you live is 406 (if you are in Montana!). The steps are similar. You would want to set "Use GV callback" as default action, then add a "Pattern rule." In the edit page for the rule, choose "Exclude" as the action, then put in "406*" (without the quotes) as the phone number pattern.
Caveat: The pattern "406*" basically matches any phone number that starts with 406 (like 406-123-4567), so if you have "1-406-123-4567" in your phonebook, the pattern will NOT match. So you might want to create a few more rules for patterns "1-406*", "+1406*" etc. It's a bit cumbersome, but it gets the job done. If you know what regular expressions are, I'll add some regex rules in the future to make this matching less painful. As of version v0.4.1, there is a regex rule option! A working regex to match all number from local code 406 is "\+?1?-?406-.*" (without the quotes).

Enjoy! More types of rules are coming in future versions, but these phone number rules would satisfy a few of you, I hope!

Monday, May 24, 2010

Google Voice Callback Donate app?

Yes, it's a paid app. No, it does not contain more features than the free Google Voice Callback app. The donate and free apps will always be the same as a tribute to the original open-sourced GV app by Evan Charlton.

Why the donate version? Because with just few cents more than a regular cup of Starbuck coffee (or just a fraction of what you may have saved from AT&T, Verizon, etc.), you can make me quite happy :) A college student can always appreciate some extra cash for coffee (and beer for appropriate occasions).

Sunday, May 23, 2010

How to help me debug problems....

I appreciate all your emails reporting problems in my android apps - they are very important for the well-being of the apps! However, some of your emails are really not helpful because there are not enough information for me to figure out what is wrong.

A helpful email should contain at least most of the following:

  • What is your phone - manufacture (i.e. HTC), type (i.e. Hero), and the android version (i.e. 1.6, 2.0, 2.1, or 2.2)
  • Detailed description of what is not working. A simple "it does not work" is not detailed enough, obviously :)
  • Most useful of all, a logcat. It's basically a log of what happened in your phone. The easiest way to get it is to download the "aLogcat" app from the Android Market. Reproduce whatever problem you had, then open the aLogcat app, hit the menu key, and choose "Send."

Happy bug hunting (though I'd prefer you not find any bugs, of course)!

p.s. If you are running Android 2.2 aka Froyo and you have a "Force Close," you can help by just sending the crash report to me by just following the direction from your phone!

Google Voice Callback v0.3 is out!

This version

  • Hopefully fix some of the force close problems.
  • Added a brief first run help screen.

It has limited testing. Please help me test it by emailing me when you run into problems. When you email, give details! A short email like "It doesn't work" is completely useless and it's a waste of my and your time. See here for more details.

If you appreciate my work, consider donating!

Tuesday, May 18, 2010

Google Voice Callback v0.2 is out!

This is a purely bug-fix version. It hopefully fixed the recent login problem (and maybe other small problems.

It has limited testing. Please help me test it by emailing me when you run into problems. When you email, give details! A short email like "It doesn't work" is completely useless and it's a waste of my and your time.

If you appreciate my work, consider donating!

More Update on Google Voice Callback app

Update (5/18): problem fixed (hopefully). See here

Yes, the login problem is confirmed - it now occurs in my own GV account! Rest assured that the fix will come, although I'll need a few more days to finish my paper first.

Be more patient :)

Saturday, May 8, 2010

Update on Google Voice Callback app

Update (5/18): problem fixed (hopefully). See here

I've heard lots of report of the app failing due to Google's API change. I'm sorry if it has affected you, but here are why I'm unable to fix it for the moment:

  • The Google Voice API is not public - that is, Google really does not (yet) intend for outside developer to use the Voice API, and that means it could break anytime without warning.
  • Google might have rolled out some changes, but as typical of Google, it does not roll out change to all its user at once, but instead gradually. My own Google Voice account has not been affected by the change, so I don't know what has been changed. And I have no clue how to fix the problem if I don't know what has been changed.
  • Real life commitment. Sorry I do have a life beside programming - a busy one at that especially near the end of the semester in college.

Just be a bit patient...

Quick note: According to some, this is a temporary problem from Google that has been solved. If Google Voice Callback has worked for you in the past, but stopped working recently, could you give it another try to see if it works now?

Sunday, April 4, 2010

Google Voice Callback does not work, WTF?!?!

Hi there! Some of you reported that Google Voice Callback (occasionally, sometimes, all the times, etc...) does not work. Thanks for your feedback, and I'm sorry that you are having problems!

If you are having problems, please

  • Make sure that you actually have a Google Voice account. Google Voice is currently by invite only, and you must have a Google Voice account to use this app - neither this app nor I can help you with getting a Google Voice account. Please do not contact me about how to get a Google Voice account. I do not work for Google.
  • Check that your login information is correct and your callback number is correct. The callback number is not your GV number, but your cellphone or gizmo5 number.
  • Try using a different kind of network connection, i.e. 2G, 3G or wifi.
  • Try killing Google Voice Callback using a task killer before you start a call. There is a known bug that causes problem especially with the "Ask me everytime" option. Some reports that killing the app before starting a call solves the problem temporarily. I'm looking for a fix but my time for programming recently has been close to zero.
  • Do you occasionally have login problems? That is, does the "Logging in..." notification sometimes stay forever and never actually log you in? Try making the call again! The second time should work, as a temporary workaround.

In sum, I realize that some people are having problems while others have none :) Some problems are known and I'm looking for fixes. Be patient while I deal with some real life commitments - I'll get to those fixes eventually.

If you appreciate my work, consider donating!

Wednesday, March 17, 2010

Google Voice Callback is out!

For a list of changes between versions, see here.
For a list of frequently asked questions (FAQ), see here

I hacked this together for my own use, but perhaps you might find it useful too.

Many thanks to Evan Charlton for the original GV app, which he stated that he is no longer maintaining.

My app does not have most of the functionality of GV which are replaced by the official Google Voice app; instead it does something that is missing from the official Google Voice app: callback.

For those of you using gizmo5+sipdroid, this will come in handy as the calls connected through callback does not have the 3 minutes limit. And for those of you taking advantage of MyFave (or equivalent), this can make sure that you are always talking to your your google voice number!

Several bugs/annoyances from the original GV app are fixed/changed:
* fix problem with gizmo5/sipdroid
* connects only when internet is available
* can ask for every call whether to use GV

Enjoy! Let me know if there are bugs (and the must be! The app is not well tested yet).

If you appreciate my work, consider donating!

Sunday, March 14, 2010

Calendar Quick Add v0.4.1 is out!

This is a minor update, with some bugs fixed and conveniences added.

What's changed in v0.4.1:

  • Recognizes phrases like "next Sunday" and "1pm until 4pm"
  • Ability to add more than one default reminders.
  • The capitalization of the search input is now preserved.
  • A bunch of small bug fixes.

As an appetizer, I shall promise that something nice is coming in the next version. Stay tuned!

Tuesday, March 2, 2010

Calendar Quick Add v0.4 is out!

What's new in v0.4?

  • Voice input
  • A better looking main screen.
  • Revamped help system.
  • Bug fixes.

The voice input is a biggie, as you can now dictate your calendar event to your phone, and make your phone your personal assistant.

Enjoy :)

p.s. screenshot of voice input in action:

Tuesday, February 23, 2010

Calendar Quick Add v0.3 is out!

What's new:
- you can now add a default reminder to the events you added through Calendar Quick Add.

To enable this option, go to Settings, then under the item "Default reminder", enter the minutes you like. You can enter any positive number there. 0 minute does actually trigger a reminder exactly at the event's start time, but Android's default calendar will show that as "0 days".

Let me know if everything works well, and enjoy adding even more events to your calendar!

Saturday, February 13, 2010

Calendar Quick Add v0.2 is out!

v0.2 adds the ability to add homescreen shortcut that directly launches the quick add interface. To use it, add it to your homescreen the usual way: long click on an empty space on your home -> Shortcuts -> Calendar Quick Add.

I received report that Calendar Quick Add works with Nexus One, but not the Quick Search Box integration. I have no way to fix that since I can't afford a Nexus One, and there is no known way to test calendar related function on the emulator.

I have heard reports that Calendar Quick Add works both on the Droid and Nexus One. Let me know if other problems arise.

p.s. For the Quick Search Box integration (a.k.a. adding event from your homescreen) to work, you need to enable Calendar Quick Add to your allowed search item list. See the "First Run Setup" in the help section in the app for instructions.

Friday, February 12, 2010

Adding calendar events to your android phone the easy way

For a list of changes between versions, see here.

If you own an android phone and use the default calendar (which wonderfully syncs with your Google calendar, of course!), you probably know how hard it is to add an event to the calendar.

Once you get to the add new event page, you need to change go through 4 fields separately to set the start and end time - 2 for the date, 2 for the time. And for each of them, you have to deal with the spinners that are highly inefficient for input. Imagine how many button presses you need to do to get the right time and dat? Do these look familiar?

Now imagine if you can just type 8pm mon dinner with kate at apple bee, right at the Quick Search Box on your home screen:

Now you can do it with a new Android application, Calendar Quick Add. You will get this:

Other examples of what you can add:
  • 4pm doctor's appt - Add "doctor's appt" for 4pm today.
  • tomorrow valentine's day - Add "valentine's day" as an all-day event for tomorrow. You can also use "tmr" instead of tomorrow to shorten your typing on the phone!
  • sun 4-7pm mall shopping - Add "mall shopping" to 4pm-7pm the nearest Sunday in the future.

Give Calendar Quick Add a try!

Wednesday, February 10, 2010

Using Microsoft Natural Ergonomic Keyboard 4000 without Microsoft IntelliType

I love my Natural Ergonomic Keyboard 4000, but frankly, I can't say the same for the bundled software and driver, Microsoft IntelliType. For one, Microsoft IntelliType is cumbersome to use and offer far less customization than my imagination would run. The hacks out there to exhort more freedom out of IntelliType (yes, google'em) are just plainly ugly and I'm not even sure about how much more they can acomplish beyond what IntelliType offers. Furthermore, I prefer installing less stuff on my computer, and however powerful my computer is, I also would always appreciate one less service running in the background.

AutoHotKey comes to rescue! For those of you not in the know, AutoHotKey is an amazing macro / hotkey scripting tool on Windows. It's lightweight, portable, and very powerful - albeit with a slightly awkward syntax. The following trick is due to some helpful forum poster at the AutoHotKey forum, adapted by me. The Natural Ergonomic Keyboard 4000 registers itself to the OS as both a keyboard and a Human Interface Device (HID). The former looks to your OS just like your everyman's keyboard, but the latter accounts for the specials keys like favourites, etc., which, you probably know, will not work without the installing Microsoft IntelliType.

But a little AutoHotKey script can teach your OS how to react to the special keys on your keyboard. To use it, download AutoHotKey from its website; grab the script at the end of this post and save it to something like intellitype.ahk, and drag the script (in Windows Explorer) to the AutoHotKey.exe icon to run it.

Of course, the script now just pops up not-so-useful message boxes when you press the favorite keys, but it's the time now to head to the AutoHotKey website and read their tutorial (hint: look for the Run command). You can make those keys do almost anything you want!

And there you go, a solution to unveil all the potential of your Microsoft Natural Ergonomic Keyboard 4000 without even installing Microsoft Intellitype:

OnMessage(0x00FF, "InputMessage")

RegisterHIDDevice(12, 1) ; Register Microsoft Keyboard


; Zoom down
Send, {Ctrl}-

; Zoom up
Send, {Ctrl}+

; All up

; My Favorites
MsgBox Favourite

; Favorites 1
MsgBox Favorites 1
; Favorites 2
MsgBox Favorites 2
; Favorites 3
MsgBox Favorites 3
; Favorites 4
MsgBox Favorites 4
; Favorites 5
MsgBox Favorites 5

Send (

Send )

Send `=

Mem2Hex( pointer, len )
A_FI := A_FormatInteger
SetFormat, Integer, Hex
Loop, %len% {
Hex := *Pointer+0
StringReplace, Hex, Hex, 0x, 0x0
StringRight Hex, Hex, 2
hexDump := hexDump . hex
Pointer ++
SetFormat, Integer, %A_FI%
StringUpper, hexDump, hexDump
Return hexDump

; Keyboards are always Usage 6, Usage Page 1, Mice are Usage 2, Usage Page 1,
; HID devices specify their top level collection in the info block
; local RawDevice,HWND
RIDEV_INPUTSINK := 0x00000100
DetectHiddenWindows, on
HWND := WinExist("ahk_class AutoHotkey ahk_pid " DllCall("GetCurrentProcessId"))
DetectHiddenWindows, off

VarSetCapacity(RawDevice, 12)
NumPut(UsagePage, RawDevice, 0, "UShort")
NumPut(Usage, RawDevice, 2, "UShort")
NumPut(RIDEV_INPUTSINK, RawDevice, 4)
NumPut(HWND, RawDevice, 8)

Res := DllCall("RegisterRawInputDevices", "UInt", &RawDevice, UInt, 1, UInt, 12)
if (Res = 0)
MsgBox, Failed to register for HID Device
InputMessage(wParam, lParam, msg, hwnd)
RID_INPUT := 0x10000003
SizeofRidDeviceInfo := 32
RIDI_DEVICEINFO := 0x2000000b

DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, 0, "UInt *", Size, UInt, 16)
VarSetCapacity(Buffer, Size)
DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, &Buffer, "UInt *", Size, UInt, 16)

Type := NumGet(Buffer, 0 * 4)
Size := NumGet(Buffer, 1 * 4)
Handle := NumGet(Buffer, 2 * 4)

VarSetCapacity(Info, SizeofRidDeviceInfo)
NumPut(SizeofRidDeviceInfo, Info, 0)
Length := SizeofRidDeviceInfo

DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICEINFO, UInt, &Info, "UInt *", SizeofRidDeviceInfo)

VenderID := NumGet(Info, 4 * 2)
Product := NumGet(Info, 4 * 3)

; tooltip %VenderID% %Product%

if (Type = RIM_TYPEHID)
SizeHid := NumGet(Buffer, (16 + 0))
InputCount := NumGet(Buffer, (16 + 4))
Loop %InputCount% {
Addr := &Buffer + 24 + ((A_Index - 1) * SizeHid)
BAddr := &Buffer
Input := Mem2Hex(Addr, SizeHid)
If (IsLabel(Input))
Gosub, %Input%


A post two years too late...

Digging around my computer, the following is what I meant to publish in Aug 2008, as the conclusion to my 3 month long internship at Karlsruhe, Germany:

Where in the world was I?

I know it's absurd to blog about blogging, but here's my rant: as an inherently lazy person I really cannot keep up a blog, especially when I unintentionally became a professional travel information researcher this summer, thus spending most of my internet time on sites like - so here is the excuse for the absence of blogs...

Anyway, as I'm writing this in the Karlsruhe Hbf waiting for my train to Frankfurt airport, my summer extravaganza in Europe is drawing to an end, and as of my last check in Google Earth, I had traveled, point to point between cities, about 1/4 of the Earth's circumference on the train. Where was I?

  • 1st weekend: went nowhere. I did walk around the city of Karlsruhe a little bit, but my first weekend is nevertheless unique, as it's the only weekend which I did not go traveling. ;)

  • 2nd weekend: Strasbourg - close enough to Karlsruhe, thus only a Saturday day trip.

  • 3rd weekend: Köln (or... Cologne).

  • 4th weekend: Had a quick look at Ulm, then spent a night in Lindau am Bodensee, the little island where one can see the Swiss Alps across the lake on a no so cloudy day, and then Neuschwanstein.

  • 5th weekend: Intended to go to München, but miscalculated the time, and ended up spending too much time on the way to München (in Würzburg and Rothenburg ob der Tauber) and had only less than a day in München...

  • 6th weekend: Berlin for a 3-day trip, but still far from long enough...

  • 7th weekend: The weekend for the Heidelberg meeting arranged by DAAD, but I went first to Giessen to visit a physics lab, another program arranged by DAAD. Then on Sunday, took a day trip in Hamburg.

  • 8th weekend: Vienna, but also stopped by about 3 hours in Salzburg on my way there.

  • 9th weekend: A long "weekend" in Italy. Actually stopped by a day in München first (to make up for my short visit the first time), then went to Venice, Florence, and finally Rome.
  • 10th weekend: Recuperating from my trip in Italy, so only took a short day trip south: checked out the so-called highest waterfall in Germany in Triberg, then chilled out in the Bodensee again, but this time in the west side, in Konstanz (Lindau was on the very east). And from Konstanz I took a short trip to Insel Mainau, the Swedish flower island.
  • 11th weekend: Paris. Yet another 3-days-but-far-far-from-enough-weekend-trip.
  • 12th weekend: Day trip to Dresden on Saturday with a short excursion to Leipzig (for Bach, of course), then attended the Volodos concert (Scriabin, Schumann and Liszt) in the Salzburg Festival (in Salzburg, of course!), then went to a nearby lake, Königssee.
  • 13th weekend: Last weekend... went to Salzburg on Friday night yet again for a lieder concert (Brahms Op.32 and Op.33) with Thomas Quastoff and András Schiff, then on Saturday, two quick trips in Aachen (where I brought a prodigious amount of chocolate) and Baden-Baden. On Sunday, walked in Koblenz a little bit, then took a cruise down the Rhine. Then, of course, spent a sleepless night (because of my 7am flight) in the Frankfurt airport.

So, that's as much ground as I could cover in 13 weekends (plus a few weekdays), as much Europe as I could absorb in 3 months, as much money as I could afford in traveling, and certainly as much energy as I could spend before I need a long, restful break of doing nothing to recover from the constant on-the-road-ness. I'm falling in love with Europe, but...

I'm glad to be home again.