Hard to believe this baby’s finally done!
As I mentioned in my final proposal, I picked this song for its melody, lyrics, and structure. I didn’t delve too deeply into what it means to me, so it feels appropriate to do that now. Though I didn’t grow up hearing Como Nossos Pais a lot, I rediscovered it and fell in love with it earlier this year, back when I was still working in an office. Suddenly the lyrics clicked with me, and the bass line and vocals mesmerized me. I must’ve listened to it on repeat for the entirety of my subway ride home at least three days in a row. All that love really prepared me for this project. I must have listened to the first verse, if not the whole song, some 200 times in the last month. You would think I’d be sick of it by now, but I’m not — it still gives me goosebumps almost every time.
I decided to do an “interactive lyric video” because I’ve always really liked lyric videos, but just making an animation without interactivity would be missing out on the possibilities of p5js (since it’d be a lot simpler to just make it on video/animation software to if interactivity weren’t a factor). I also realized that the graphics might help an audience who isn’t familiar with the song or its historical context to understand, even if not fully or even consciously, some of its deeper meaning. Maybe you don’t really understand the political context of a military dictatorship declaring war on political art, but seeing handcuffs around a singer’s wrists might give you a sense of wrongness that gets the point across.
My first steps in the process were translating the song’s lyrics, deciding on the graphics, and creating timestamps. I made a spreadsheet to keep track of everything in one place, which in the beginning looked like this:
I split the verses into different lines (called “screen” on the spreadsheet) and laid them out on Illustrator, each on one artboard. I did both versions at the same time, so I could quickly see where the graphics would fit on the screen. To get the stop motion-y effect, I exported those artboards to Photoshop and used a warp grid to distort the letters ever so slightly (manually, while watching a lot of YouTube videos to keep my brain from going numb). Those warped versions became the second frame for each GIF, toggling back and forth for movement. Initially, each line would be one GIF, for a total of 16 — but since I had problems getting them to show properly in the code, I broke them up into smaller chunks (naming those with the letters on the third column, to keep track). With that separation, the total number of lyric GIFs for each version was 84. It’s a lot, but it worked — and since I’d already made the timestamps for each line, it wasn’t that much extra work (just a lot of exporting on Photoshop).
For the first code test, I had the lyrics and splash screen as functions, declaring a variable songStart which was called when the song plays, keeping track of the milliseconds; then, inside my lyrics function, another variable t would subtract songStart from the current milliseconds so that the lyrics would always play properly (whether you click play the moment the sketch starts playing, or if you wait a long time). Here’s the version of the code from that first run, with a test graphic in the beginning so I could see if the layers would work well. You may notice the GIFs look a little wonky; sometimes they only flash a frame for a split second before switching to the next frame. That’s because I didn’t take the frame duration (which was 400ms) into account when writing my timestamps; you can see up in the spreadsheet, for example, the number 15, 1025, 5021, and so on, are not divisible by 400, leaving those tiny gaps between frames. I wanted them to be smooth as butter, so I went back to the spreadsheet and rounded those timestamps to the nearest 400. On my second test, it looked perfect, so I went ahead and added the English version, copying and pasting the same function but changing some of the timestamps to account for a better flow in some of the translated lines.
For the graphics, I originally wanted to make some simply decorative and only 5 interactive (saving the latter for the most meaningful lines). To make the decorative ones more interesting, they would be animated — I was envisioning them as one continuous line being drawn on the screen. In testing my first GIF, I ran into the same problem I had with the lyrics earlier; they just wouldn’t sync well, leaving chunks of the GIF empty at random times. This was a blessing in disguise, because it made me change my approach entirely to something I think worked a lot more elegantly: all graphics had to be static until interaction, and because of that, all graphics had to be interactive, since there wasn’t a good way to differentiate between the two types anymore. I went back and rethought each graphic; the change forced me to be a lot more purposeful about what I was putting on the screen. As an example, my original thought for “Our idols are still the same” was just to have portraits of “old school cool people”, but now these portraits had to change, and in a contextually meaningful way.
With the graphics redone, I imported them using the same function logic as the lyrics. This failed pretty miserably, since the graphics just piled on top of each other instead of replacing each other. I asked Scott for help, who said this would be easier if the graphics were a class instead of a function. We tried a few things, but nothing worked until I went ahead and changed lyrics and graphics to be classes. I believe this was the version I presented in our final class, with the graphics actually embedded into the lyrics classes.
For the final adjustments, I went back to make everything its own class, including the splash screen. I added pseudocode and tidied up as much as I could. The new features I added, based on the presentation feedback, were a hotspots function, which changes the cursor around the clickable areas, and a more explicit explanation (including a clickable example) of the interactivity on the splash screen. I also added a back button so you can go back to change your selection mid-song if you want to. Those extra features went mostly smoothly, until I made the horrible mistake of naming my back button png “back”, which ended up breaking the entire code for about half an hour until I could figure out what the issue was. When I renamed it “backbutton” it worked fine — I guess p5js just wanted to give me one last heart attack before the end of the semester.
The last step, of course, was to write up this documentation, so I could link it in the final code and close the loop. I couldn’t be more pleased with the end result — it accomplished everything I wanted it to, pretty much the way I wanted to. If I could make the graphics appear on the screen in that continuous line animated format, it would be pretty great; but that would also mean redrawing them in a different style, and by now I’ve grown attached to them as they look. I’m glad I was able to devote so much time to something I truly care about, which now holds a whole new special meaning to me.
My deep thanks to my professor Scott Fitzgerald for teaching me everything I know about p5js; to my husband David Solo for cracking my back after long hours hunched over my laptop; to Brazilian artists for creating beauty despite the state of things then, now, and always.
- Song: written by Belchior. The version used was recorded by Elis Regina for her studio album, Falso Brilhante. Lyrics translated by me.
- Font: Turbinado from Adobe Fonts.
- Color palette: made on Coolors.
- Splash page text: adapted from Cultura Genial.
- Image references:
- Record player
- Singer and handcuffs
- Corner and Brazilian cop
- Men standing and hugging, women standing and kissing