From CSWiki
Revision as of 17:47, 30 December 2010 by Leachman (talk | contribs) (How do I play PPR?)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Sam's Final Project: PLOrk PLOrk Revolution

A 2-player typical PPR setup.

What is PPR?

PPR is an interactive multiplayer drum machine. Using PSX controllers and DDR pads as input devices, players can toy with individual beats and melodies through the built-in sampler. Once they've found a cool pattern, pressing start will record the sound and time for each input note. Pressing start again stops recording and transmit the musical data over to the host computer, which cleans up the timing and plays it along with a bass loop.

To see it in action, check out this demo video

How do I play PPR?

Download the code here.

Unfortunately for the end-user, PSX-USB adapters, and even PSX controllers themselves, do not have a standardized interface. Not only are buttons mapped differently, some adapters may interpret the arrows as a directional-pad, requiring a completely different way of interpreting the HID signals (and making simultaneous L + R impossible on a DDR pad). While this is bad enough on its own, the piratic nature of PSX-USB adapters makes them very prone to shorts, as one of my adapters experienced.

In short, you probably should take the video as evidence that it worked at one point and not attempt to get it working on your computer.

If you simply must try this out, run on each client computer and run and on a computer with decent speakers. If you have more than one person playing, duplicate and rename to for each client. (You'll also have to change Machine.add("controller") inside it as well.) Make sure each controller-player pair is operating over a unique port.

Keep in mind that you can always run PPR on a single computer.

What's Up With...

Offbeat patterns? Every recorded pattern starts on the downbeat of a measure. There's simply no way to distinguish offbeat patterns without transmitting the pulse across the network, which I don't want to get into. The way around this is to hit L1 on the downbeat of the first measure of a recording when don't want to start sounds on the downbeat. This is what I do in the video. L1 is mapped to a null sound, so everything else acts like normal, but no sound is played.

Array-Out-of-Bounds Errors? Loops are limited to 48 notes. I hope this wasn't really your problem.

Error Correction? So hitting beats exactly where you want them is hard. It's hard for drummers in real life, and it's hard for me (and I play a hella lot of music videogames). What I've done for loops is snap each note to the nearest sixteenth or quarter-triplet. This actually works pretty well, and is the only reason the constant sixteenths in the video sound good at all. (Even so, I had to practice this and slow down the tempo at bit.) However, I never intended loops to be longer than two measures, so there's no error correction afterwards.

The original project idea? I originally intended to create a H-O-R-S-E-like videogame. During coding, I found it exceedingly difficult to quantify deviations from proper rhythms. As a result, I scrapped a good deal of code and began to rethink error correction. Though this original technical problem was overcome (as evidenced by the functional error-correction), I began to rethink how this project would work. The game would have a steep learning curve, few others would be dorky enough to play it, and at this point, I only had one functioning USB-PSX adapter. After finishing the current implementation of PPR, I decided I was really happy with what it could do. It integrates the main features of the proposal, including live HID control, error correction, multiplayer support, and a recording function, but strips it of its competitive aspect in favor of collaborative one.

If you're still not convinced that this is a better project, an implementation of the original idea would require a few simple modifications.

  • 1. Create a new shred ("") with four matrices, aiHits1[], aiHits2[], aiRhythms1[], and aiRhythms2[]
  • 2. Add code to and to transfer the contents of the corrected matrices for each player to (code should be very similar to that used to transfer the data from controller to player)
  • 3. Compare the two matrices. If the loop input by Player 2 is 90% similar, start a new round. Otherwise, Player 1 gets the point.
  • 4. In the next round, Player 2 inputs his/her loop first, and Player 1 attempts to match it.

The current implementation should allow players enough time to listen to the loop and toy around with their own samplers before attempting to match it.


Sam Leachman
Princeton University, Chemistry
Class of 2009