Geoff Groberg

Currently browsing creative code

Teaching Interactive Digital Media

Allison Kleinman, Blake Behrens, Caroline Lewis, Charlotte Sullivan, Ciara Appelbaum, Elise Dean, Emily Eisert (not pictured), Emma Lang, Heather Wiley, Isabella Zhang, Janelle Thomas, Katie Dickens, Lily Walter, Melissa Farley, Shannon Kuehn

During Spring semester 2017, I taught a course in Interactive Digital Media at Wake Forest University. This was my class. 15 journalism minors, all of them girls. Not sure how that happened, but yes, it was fun.

The class introduced the basics of digital media use in journalistic style stories. We learned the fundamentals of photoshop, digital audio, video, and tools for creating interactive web media, like Knight Lab and WordPress. Here are a few stories my students created:

Winston-Salem’s Food Insecurity Dilemma

UpDog Kombucha: WFU Student Entrepreneurs’ Health Drink Is An Instant Success

At Wake Forest University, Latin Isn’t Dead. It’s Immortal.

I man-spreaded everywhere for a week and I’ve never felt more confident

Wise Man Brews Change in Downtown Winston-Salem

The Silence of War

The Silence of War is a transmedia storytelling project about a small group of African American Vietnam Veterans from rural Eastern North Carolina. Their stories are told through interviews, photos, videos and other media.

The project was created by faculty and students at Wake Forest University. I was a co-director and also led the web development and design.

The technical side of things

One of the fun things about the project for me was creating the web framework. It’s a single-page application designed for the presentation of rich media. And it’s based entirely on front-end technologies: HTML5, CSS, and Javascript. It was refreshing since I usually do a lot of backend programming.

The framework is built for storytelling. Stories are created with a series of slides that contain all kinds of rich media. Video, audio, images, text, gradients, and more can be layered in interesting ways and navigated with smooth transitions in between. There are lots of interesting techniques I used to help with things like positioning text, creating rich full-screen backgrounds (including video backgrounds), overlaying transparent vignettes and gradients, and creating smooth background audio transitions.

In order to deal with all of the large video files and other media I created a custom lazy-loader in javascript. The lazy-loader basically downloads large media files just before they are needed, rather than trying to download everything at once. It looks ahead to see what slides the viewer can potentially view next and downloads only the media for those.

Building the framework gave me some new ideas and changed the way I think about storytelling on the web. Background audio is especially interesting to me in this type of application and I’m planning on doing more with it in the future.

View the The Silence of War.

A Custom MVC Framework

As a grad student, I discovered that the systems designed for student equipment reservations were not very good, and way too expensive. So I built EQ Checkout.

I debated whether to use an off-the-shelf framework, like Laravel, Django, or Rails. But in the end, nerd that I am, I built my own framework. It’s based in PHP and inspired by various things I’ve seen in other frameworks. It’s simple, easy to deploy to an inexpensive LAMP stack, and cleanly separates MVC code.

Some Interesting Things About the Framework


The framework has a database abstraction layer, so it can use MySQL, PostgreSQL, and other DBs. But I chose to use SQLite for this app. WHY?! Why would an experienced web developer use SQLite for an application that’s designed to scale? It’s super fast. It’s easy to deploy. It’s stable. And for other reasons.


EQ Checkout is a multi-tenant application. Using SQLite made it trivial to silo off data for each tenant. They each get their own, completely separate database. Easy to do, easy to maintain and make backups.

You might be concerned about high traffic and concurrency, but it’s not an issue with an app like this. Since each tenant has their own, separate database, each database has a relatively small number of users. Even if a tenant had 1000 times the number of users this app was designed for, concurrency still probably wouldn’t be an issue. And there would be other issues that came into play long before SQLite became the bottleneck.

An ActiveRecord-ish Model

I like short, efficient bits of code. Here are some examples of how the Models work in my framework:

Get a list of users:
$users = user::getList(); // returns an array of user objects

Get a user with a specific email address:
$user = user::get("WHERE `email` = ''");

Save a model (in this case a “reservation”):
$result = $reservation->save();

Delete a model:
$result = $reservation->delete();

You can also specify model relationships, like hasMany and hasManyThru. For example, a user can have many reservations. And a user also can have various roles, thru the userRole model:
public $_hasMany = array("reservation");
public $_hasManyThru = array(array("role", "userRole"));

There is also a simple way to define validations for each model. In this example, a user must have a name, and the name must be at least 2 words. (So “Bono” and “Sting” unfortunately can’t register as users.) Also, in this case, email is required, must be a valid email address, and must be unique (but case insensitive):
public $_validations = array(
"name" => array("required", "minWords,2"),
"email" => array("required", "email", "unique,CI"),

Of course there’s a lot more to the framework: a router with some sensible defaults, lots of convention of configuration, basically a lot of ideas I stole from Rails.

I have mixed feelings about the wisdom of creating your own framework, vs using an existing one. In this case, it worked pretty well. But moving forward, I’m interested in getting better with Rails. There are pros and cons of course. One good thing about using Rails, Django, or Laravel is that they come with so many features. And one bad thing is that they come with so many features.

EQ Checkout

EQ Checkout is a web application for inventory management. I designed it with Universities in mind, but it can work for any organization. There are a lot of university departments (and other organizations) that have equipment that they checkout to their users. EQ Checkout allows their users to make reservations online and helps administrators manage the equipment.

The application is a multi-tenant application. When a new organization signs up they create a subdomain ( and that becomes the URL that is used to make reservations, checkout equipment, and manage inventory and users. Each organization gets their own database and preferences.

I actually built a custom MVC framework for this application.

You can learn more about EQ Checkout here.


Transcribe is a web app I built while working for the Lee Library. It’s been one of the more rewarding apps I’ve built because it’s a crowd-sourcing application that continues to be used.

What does it do?

Transcribe was built for Special Collections. They have a lot of old books and manuscripts that are not available electronically. Transcribe allows students to help get these documents transcribed, making them searchable and much more available for research and scholarship.

How does it work?

It’s an application that employs crowd-sourcing. A student logs in and grabs a “task,” in this case usually a single page to be transcribed. The application also allows for transcribing time-based media (video and audio).

Each task gets completed twice, by different people. So for every page, there will be two transcriptions. The two transcriptions are then “diffed,” highlighting any discrepancies between the two.

At this point, a new task is made available to a reviewer. The reviewer can quickly see highlighted discrepancies and choose between them, along with making any other changes. The reviewer can also easily point and click to add XML tags, identifying people, places, and dates, for example, to make the document more searchable.

Rather than using a textarea tag, we used HTML5’s contenteditable attribute. This allowed us to style transcribed text in ways that wouldn’t have been possible using a textarea. Another interesting UI/UX feature is that the transcription interface can be toggled by the user to be side-by-side or up-down.

After all pages in a project have been transcribed, reviewed, and tagged, the application compiles them into an XML file (adhering to the TEI Lite standard) that the library can use to make the document electronically available and searchable. I built the application in 2014 and I’m happy to see that as of 2017 it is very much alive and being used to make rare documents more available.

I was the lead developer on Transcribe and I worked closely with the fantastic Grant Zabriskie for front-end design.

Final Limit

Final Limit is an audio effects processing plugin. It’s a “limiter” designed to be the final element in your signal chain. It brings the overall volume up, without distorting. (Unless you want a bit of distortion, which it also provides.) I created the plugin using SonicBirth.

How it works

The main slider increases the gain of the input signal which is then processed with a compression algorithm I designed. Any leftover peaks are attenuated using a shaper function curve. There are also options for EQ, attack and release characteristics, and maximum output level.

The user interface is inspired by an old Ensoniq synth I used to own. I avoided naming the limiter’s attack and release characteristics with technical numbers and labels (like milliseconds). Instead the controls are labelled with fun/zany titles like “Dog Slow” and “Burnt Toast.” They sound funny, but the idea is that they actually describe the sound better than a label like “80ms.” The UI was also designed with the idea of minimizing visual feedback. All too often audio engineers make adjustments based on what they see (like the curve of an EQ) instead of what they actually hear.

You can download it here. It runs on OS X as an AudioUnits plugin, but unfortunately it is 32 bit only because sonic birth doesn’t allow exporting 64 bit plugins. It won’t run in hosts that are 64 bit applications.