Paul's 220c Log
Minimum viable product
Mon Jun 5 09:33:17 PDT 2017
This weekend I pushed ahead and made a minimum viable product (MVP) of the Spigot Tracker. A project page for Spigot has also been made on my personal website. For preservation purposes, an "outdated-on-arrival" version of the project page can be found on locally here.
A screenshot is shown below:
This version is a function music tracker, with the following features:
- Files can be loaded/saved to runt files (text-based so it can be used with trackers). Key: F/S for load/save
- HJKL movement in pattern window
- insert/remove notes with top row Q-P (like many trackers)
- noteoffs: '!'-key
- remove note: 'x'
- Multiple pages of patterns
- Page sequencer navigation: shift + [H|L]: move left/right, shift + [K|J], go up/down one page.
- shift + x: remove current pattern from page sequencer
- 'n': insert new pattern
- Vertical scrollbars show progress
A few other keybindings for playback include:
- ENTER: play song
- SPACE: play current page
- shift + SPACE: play from current position
I have also made a small demo testing out the tracker, where I transcribed the opening bars of Mendelssohn's Reformation Symphony.
Procedurally generating graphics
Wed May 31 10:06:17 PDT 2017
The mockup from previous weeks has been procedurally drawn using bitmaps and horizontal/vertical line functions.
Writing a few assets
Wed May 24 10:53:59 PDT 2017
The first step in programatically generating the concept art is to decompose the components into small assets that can be "drawn".
Here is a rough draft of the 128x128 glyph sheet I am working, with bits extracted from the concept art:
This will be converted to a pseudo-bitmap array using similar tools from previous.
A small, but important thing: the notes have been changed from a 5x5 font to a 4x5 font to match the number fonts, squishing the "4" in "D#4" to match the "4" everywhere else. The "G" is a bit concerning since it doesn't have a serif-y bit. So that may be subject to change. Luckily there are several 4x5 pixel fonts in the planet for study.
The next step from here is to make tracker data that can be drawn to the screen procedurally: note, channels, patterns, sequences.
Sun May 21 23:50:18 PDT 2017
Here is an updated version of the layout:
A few things were added:
- As was suggested from the class, the "status bar" and sequencer were swapped to separate it from the tracker
- I played around with spacing and changing the number of channels displayed. I ultimately decided on keeping the channel amount the same (5), but centering the note names. This ultimately nixes my original idea of having some sort of instrument number to go along with the notes. Nope. It just looked weird. Keep it simple, stupid. Also, more channels is better than a parameters column.
- Channel symbols on top are binary representations of their number. I like binary.
- Row numbers have been filled in. The number fonts should match the sequencer numbers.
- A row selector was created using the color pink. The current column selected is the navy blue color
In addition to the mockup, I whipped up some boilerplate code for the tracker interface in Spigot. Right now, all it does is display the mockup from above, generated to a RGB C array. In future steps, I'll be needing to break down the mockup into assets.
Runt-IMG, libXM, and Demoscene stuff
Wed May 17 10:09:10 PDT 2017
This past week, I looked into simple ways to convert PNG/raster images to C array data. ImageMagick was close, but it still wasn't exactly what I was looking for. Fortunately, I have written tools in the past that could modified to do the job. My library Runt-img now has a word called img_writec, which will write a C header file instead of a PNG file.
Also related... last week I did some work getting a XM player inside of Sporth
Last week I promised I would share more about Demoscenes and Demoscene culture.
There really is no better introduction than the documentary Art of The Algorithms.
The first 6 minutes or so will give you a pretty good idea.
Demos, in a nutshell, is all about doing as much as possible within the constraints of hardware (back in the days of 8-bit computing... there were many constraints). Most of the time these demos manifested themselves to visuals, but every now and then there are audio-related tricks. The demo cubase64, is an insane demo for the commodore 64 which demonstrates modern DSP effects like phase vocoding and filtering that did not really exist when the original C64 was made.
- Pouet is really the largest collection of demoscene content
- modarchive is the website specifically for module files of various formats (mod, XM, it, etc)
- HVSC is the high voltage sid collection, which is a massive collection of SID files, the music format for the commodore 64 computer
Tracker Concept art
I did some quick concept art for my tracker interface in grafx2. Click on it to see the "zoomed" version (new page):
The main purpose of this was to draw some lines and get a sense of the spacing in the constrained 193x193 pixel space. Squares are used as placeholders for icons and text glyphs, however I'm not entirely satisfied with their alignment. Colors are mostly placeholders, but their relative shading feels close. The bounding box is weird looking as well.
The most unusually thing is the horizontal section with the boxes. That will eventually be the pattern sequencer. As far as trackers go, it is pretty unusual. My thinking is that I will use single-character representations of sequence numbers (ie 0-9 a-z) for a total of 36 patterns.
Hopefully that choice won't suck too much...
This weekend, I will solidify the concept art as well as the keyboard shortcut workflow. Next week, I'll begin coding things up.
Mon May 8 10:03:50 PDT 2017
My efforts this weekend were twofold. First, I took the advice from last time and looked into screencasting. I had done this before on Linux using FFMPEG and JACK, with some scripts. However, I had never done screencasting for graphics-heavy openGL things. I did some playing around, and was unable to get things looking right. I either got buffer overruns, sync issues, or poor video quality. I came to this conclusion:
The more focus a project has on realtime, the more difficult it will be to capture that documentation for archival purposes.
So screen-capturing is taking a back seat for now. I should note that I did have fun working with TTYREC, which was extremly good at recording anything in my tmux session. Will have to investigate how to sync audio with it for capturing live-coding pursuits...
As stated before, I am moving towards building another interface beyond the pbrain-based one that I made. I have decided to build on top of the code I already have and generalize Spigot to be any raster-based clock-driven control signal devices.
Externally, there are seemingly no new features this week. However, Spigot now has a generalized interface for drawing and keyboard navigation, and parses a configuration file written using Runt, a stack-based language of mine. The hope is that adding a language like Runt will allow me to extend Spigot in new an unexpected ways.
Some things I'm thinking about
- DMC, a C64 tracker and the closest thing to what my tracker interface will look like.
- This DMC tutorial.
- Ibniz, a really freakin cool low-level virtual machine for audio/visual programs
Mon May 1 09:51:46 PDT 2017
I modified the graphics code to use openGL pixmaps instead of bitmaps. The modifcation was done in such a way that I could still use the old bitmaps I wrote by hand in C. The functionality has a few weird quirks (just stick to using multiples of 8 for widths), but besides that things work fine. Performance seems to be about the same, which is great.
One of the great advantages of using pixmaps is that you can automatically scale the pixel size, as seen in the picture above. Another nifty thing which I'm not taking advantage of (yet) is the fact that I can any RGB color values I want! The bigger zoom is definitely the aesthetic I was missing.
In addition to making everything look bigger, I also added a few more keyboard shortcuts: up/down with K/J and 'Z" to reset.
I wrote a quick demo patch called "clicks" that further demonstrates the capabilities of the system.
Future thoughts: zoomed-in pixels have reinspired me to continue forward making pixel-based interfaces. I am thinking I will work on making a hackable sequencer/tracker interface designed to output control signals for Sporth.
Porting to OpenGL glBitmaps
Mon Apr 24 09:25:27 PDT 2017
I made some first steps towards getting OpenGL up and running. I ported the glyphs created last week to C code, and set up some boilerplate GLFW OpenGL code based on previous projects. My project now looks like a read-only version of my mockup, able to display whatever the current code is. In addition to that, there is also a "playhead" represented by a box that is able to display the current position.
Next time, I hope to implement the following features:
- HJKL navigation
- space to play/stop
- z to zero out
Tue Apr 18 21:30:09 PDT 2017
I quickly made some mockups showcasing the interface for Spigot:
The core 8x8 symbols I have drawn up are displayed below:
The code I wrote loads this symbol table in memory, and uses it a bitmap font table. The programs can be found here:
You'll notice that there is an extra symbol '?' in the symbol table.. This is an idea I have for implementing coin-toss randomization. This idea comes from a previous notation language I wrote called Prop.
The next steps include:
- Drafting out keyboard shortcuts and control flow
- Converting glyphs into C structs that can be read by the glBitmap OpenGL calls (This takes longer than it should simply because I write these by hand!)
I plan on getting most of this out the way for this weekend.
Spigot: Further experimentation
Sun Apr 16 18:37:38 PDT 2017
I made a simple sporth patch which sonifies the pbrain instruction set in Spigot.
To recall, the core pbrain instruction set minus the pbrain extensions consists of the following:
- +: increment current cell
- -: decrement current cell
- >: move cell pointer right
- <: move cell pointer left
- [: loop start
- ]: loop end
- .: write output (this does nothing)
- ,: read input (in this case, value from Sporth)
Here are some patterns I made:
This patch creates a loop that goes three times. Inside the loop, there are three pings to the output and a mandatory decrement.
This is an infinite loop with a finite inner loop, whose number of repetitions. is determined by an input value from Sporth. The pointer movement in the inner loop is only there to add space.
These are the currently implemented instructions, in order.
Spigot: initial template and concept
Wed Apr 12 10:35:23 PDT 2017
- created codebase and uploaded to gitlab
- quick hack on pbrain using code by Daniel Cristofani
- Concept: runs bf/pbrain code in Sporth using a trigger signal for a virtual CPU clock. Every time the Sporth clock ticks, a CPU instruction is made. The '.' symbol produces a tick, which can then be fed into envelope generators.
Things I am thinking about right now:
- Piet (programming language)