Skip to content

Bear Stearns Bravo

Album artwork (a floating CD-ROM jewel case) for Empire Sunrise: Music for Bear Stearns Bravo

Empire Sunrise:
Music for Bear Stearns Bravo
Available on BravoNET for $5

If you’ve experienced Bear Stearns Bravo, you may have wondered about the music: synthesized yet expressive, and reminiscent of games of the FMV era. I think the key is a choice we made early in the game’s development: to compose the music almost entirely for a 4 MB wavetable synthesizer from 1996, the Yamaha S-YXG50.

When released, Yamaha XG synths were some of the most powerful tools available for computer musicians, particularly the SW1000XG sound card. Although now considered obsolete, there is still an active XG community. A few features, often missing from modern samplers, remain useful:

Diagram of Yamaha XG parameters (source: Sound on Sound)

Diagram of Yamaha XG parameters (source: Sound on Sound)

  • Filters: no need to insert a plugin — every channel has a low-pass filter with Resonance and Cutoff controls
  • Vibrato: instead of riding the Modulation wheel through a phrase, there are Vibrato Rate and Vibrato Delay controls to add feeling — automatically!
  • Expression: to give legato phrases their shape there’s an Expression control, freeing up Volume control for what it was intended (balance within the overall mix)

The track used in the trailer, Move Objects and People, has examples of the Vibrato and Expression controls (guitar and saxophone) and Filter controls (bass and arpeggios)

Harnessing the full power of the S-YXG50 would not be possible without some great software, some new, some old:

Screenshot of XGedit95 configuration for Move Objects and People

Screenshot of XGedit95 configuration for Move Objects and People

  • XGedit95: its primary function is to save and recall XG synth configurations — it also provides interfaces to features only accessible with SysEx (System Exclusive) messages, including the ADSR envelope, reverb, chorus, and special effects
  • SAVIHost: a standalone VSTi (virtual instrument) host (used to host the S-YXG50)
  • Cakewalk SONAR: a MIDI sequencer (for recording and playing back notes)
  • LoopBe1/LoopBe30 (a Windows 7 compatible replacement for MIDI Yoke): allows for virtual MIDI routing (used to connect all of the above together)

Categories: Composing.


Screenshot of the CANYON.MID simulator

The CANYON.MID simulator

Want to relive the moment you first heard the dulcet FM synthesizer tones of the Yamaha OPL3 on your fancy new multimedia computer with Windows 3.1? Take a Trip Through the Grand Canyon again at!

Special thanks to:

Categories: Composing.

Credit Cards in Forgery

My pull request was accepted, so random credit card type and number generation is now available in the Forgery gem!

# => "Visa"

# => "4539750423451972"

Forgery(:credit_card).number(:type => 'Visa', :length => 13)
# => "4556180133982"

A few interesting things I picked up along the way:

Photograph of Hans Peter Luhn, 1952

Hans Peter Luhn, responsible for at least one number in your wallet

  • The anatomy of a credit card number (validation of credit card numbers always seemed like magic to me, but not any longer!):


    • 6011 — the IIN or prefix — these belong to different card issuers (for example, this is a Discover Card)
    • 47543247114 — the account number — normally assigned by the issuer to an individual customer, Forgery creates this at random
    • 0 — the check digit — a checksum from the Luhn algorithm
  • This was my first experience writing comments for machine-generated documentation (RDoc). I think it looks great, and could prove very useful on other projects.
  • I learned that one of my go-to Ruby methods for test automation, choice, has been deprecated. Thankfully, it was simply renamed to sample, which is available in backports.
  • This was my first experience with RSpec, too. I like it — it seems very similar to Test::Unit (which I’m more familiar with), but with a more human-readable syntax. As a result, you end up with more meaningful tests and test failures, because behaviors are being defined instead of functions.

Finally, big props to Graham King and Celestino Gomes, whose knowledge and code I borrowed heavily from.

Categories: Development, Testing.

Tags: , ,

CAST 2011 Presentation: Intro to Sinatra

The Sinatra logo (a fedora)

When I attended CAST 2011 this year, I was given a really neat opportunity: to present! I selected Sinatra as my topic, for a few reasons:

  • Its low barrier to entry (easy to learn and free)
  • I had a few interesting experiences with Sinatra to share
  • I wanted to demonstrate that testers could write useful code that wasn’t automation

The presentation (in 3 parts) went something like this:

#1: What’s Sinatra?

Since the audience was potentially a mix of coders, non-coders, etc., I wanted to lay some groundwork, including:

  • What’s a DSL?
  • What’s a web application, exactly?
  • Why Ruby: its readability, the robust native string manipulation library, how regular expressions are tightly integrated, the vast repository of helpful gems
The Final Countown by Europe album cover

An early idea was to play “Final Countdown” while coding

#2: Live demo

Next, I gave a live coding demonstration (I’ve since been told that I was…brave for trying this). There were four distinct steps:

  1. A static response (essentially, the example on the Sinatra home page)
  2. A dynamic response
  3. A dynamic view (ERB)
  4. Dynamic data (JSON)

#3: Examples

I shared 3 examples where Sinatra saved the day:

  1. An e-commerce payment gateway that we had to work with was in many respects a “black box”, and it was drastically limiting our ability to test. We understood how the requests and responses worked well enough to build a replica in Sinatra, however, giving us the testability features we needed, including:

    • Logging
    • Recall of past transactions
    • “Magic” functionality (ex. getting any gift certificate amount you wanted)
    • Error simulations (ex. internal server errors, connection timeouts, etc.)
  2. The diverse set of tools used by my team at Interactive Partners led to an unfortunate case of information siloing, but thankfully they all had APIs, so a Sinatra application named iP Relay was created to help “glue” them all together, for example:

    When David, one of our developers, does a deployment using Capistrano:
    > cap deploy
    Our faithful chat servant Botsworth announces it to the team:
    Botsworth: David Stamm deployed 3.16.1 (023c968) to SHO production

    Or, when he makes a commit with a message in this format (with the square brackets at the end):
    Bug #1941 (a bug that will live in infamy) — Fixed incorrect link URL. [bug: 1941, status: resolved]
    A screenshot of the "Testing Test"

    Screenshot of the "Testing Test"

    The following actions are carried out in our bug tracker, Bugzilla:
    Add comment to bug #1941, change status to “RESOLVED”.
  3. When hiring, without access to old bug reports or test plans, it was difficult to evaluate how well candidates could find and report on bugs, so a Sinatra application named Testing Test was created to help test the testers. The person we ended up hiring found all of the bugs we intended to be in there, and even some we didn’t!


Finally, the slides shown to the audience, for your viewing pleasure:

Categories: Testing.

Tags: , , ,