Close

int bird1, bird2; int stone = 1; bird1 = bird2 = stone;

A project log for FATCAT: Altoids Tin Mod Tracker

A drum machine, base synth and arpeggiator that fits in your pocket. User interface inspired by classic mod tracker software.

dejan-risticDejan Ristic 10/09/2018 at 11:100 Comments

Was there ever a time when people actually threw stones at birds? Who does that? 

In a recent log I wrote about how I've had to make some difficult sacrifices of wavetable data in order to accommodate the gradually increasing size of the code. In the end, that left me with just the kick wavetable for the drumkit, which I then used as a component in recreating the snare sound. 

So in this case the idiom would be "killing two drums with one kick" I guess. And since this project is in large part an exercise in making the most out of limited resources, I've tried to exploit any opportunity to apply that principle throughout the project. In this log I'll cover how those opportunities presented themselves, and what effect they've had on FATCATs design.

The pin header and the potentially awesome third bird

As already mentioned in the project details, FATCATs  pinheader serves a dual function as both a patchbay for musical improvisation and as an ISP interface for the MCU. Boom, two birds down! 

I'll probably write a log exclusively about the patchbay function in the future as there's some interesting stuff going on there, but here I'll just mention a possible third use for the pin header. I'll be rambling a bit at first but I'll get to the point eventually.

FATCATs perhaps most glaring musical limitation is that it can only hold one single song, consisting of eight patterns. And apart from possibly using the ISP interface for saving/loading the song data to a PC, it's basically a closed system.   

However, you could think of the problem in a different way: Maybe FATCAT isn't a device for storing songs on; Maybe the device itself is the song. If you view it as a gradually evolving canvas intended for repeatedly being painted over, the song size is a feature as much as it is a limitation. I guess that sounds a bit grandiose, but the point I was getting to is that it's also a very cheap canvas. If you want to start working on a brand new song but still hang on to your old one, just build one more device. Heck, build ten! 

And that finally brings me back to my original subject: Lets say you have a couple of the things--each with its own patchbay--then why not connect them to each other? Well, no reason at all. Actually it would be a great way of getting a third function out of the pin header. That's your third bird right there!

EDIT: Well, it's really an extension of the second function so maybe two of the birds are conjoined twins or something. But I'm still counting them as three damn it!

I remember the idea being in the back of my mind earlier, but for some reason it didn't really strike me as awesome until the last couple of days. 

I haven't actually tried doing this yet, as I haven't had time to build a second prototype device, but I see no reason why this feature wouldn't work using the current hardware design and firmware (version 0.8). The patchbay includes a ground pin and the playback engine is completely agnostic about where the patchbay gets its signals from.

Of course there won't be any way of synchronizing the tempo of patched together devices, which means music playback would be a more or less unorganized affair. It might still sound cool though--or be a total mess--I've really no idea at this point. Having the devices establishing a master-slave relationship and syncing up would be the next logical step though, if one would want to take this function to the next level. I haven't really thought about how I would go about implementing that feature yet, or how hard it would be, or how much the code would grow. I am sure it would require time consuming code rewrites. And also there's very little flash left to work with as is.

The next target of opportunity would be daisychaining three (or more) devices. That'd be real easy. It'd require little more than having the patchbay extend two more steps to the right on the PCB, in order to add a second ground pin to it. However, I'm not sure how useful that feature would be without tempo sync, or at all really. I'd expect it to sound pretty chaotic.

EDIT: Two devices actually seems like the perfect amount, when thinking about it. Then you'd be the DJ and the two FATCATs your solid-state turntables, to butcher another metaphor for a change. You'd switch your records/patterns with one hand on the L and R buttons of each device and mix it up by patching in some new effects now and then. Wow, that concept sounds pretty amazing now while still safe and snug in dreamy theory-land. Let's see how it turns out when put to practice.

In any case: Tempo sync is an intriguing concept, but I'll have to put it at the very bottom of the to-do list nevertheless. But I'll try out the dual-device patching thing as soon as I can, and do a report on the results.

GPIO ins & outs

This one I'll just mention in passing for now, but I'm sure I'll get back to it in more detail at some point. All GPIO pins except for the two dedicated to driving the speaker (and the "reset" pin), are used for both reading inputs as well as for controlling the display elements. In this metaphor each pin would be a stone and... well, you get the rest. Just felt I had to mention this one given the subject matter for this log. 

Of course all inputs has to be read by polling now. And you have to switch back and forth between that and controlling the display, while not letting that whole dance interfere with the stuff the playback engine's doing. Not like in the old proto-FATCAT days when life used to be simple and I could just rely on pin interrupts. But that's the price you pay if you want to be a cold-blooded double bird-murderer.

The user interface design

A general rule I had when designing the UI, was for there to be only one single way of performing any specific task, even if that meant structuring the UI in slightly unconventional ways. This was in part a measure in avoiding any unnecessary bloating of the code. But it also serves to reduce the number of UI modes that the user needs to distinguish between, which ultimately should make the UI easier to learn and to operate. Several UI design choices where directed by that rule, and in the next section I'll cover one of those.

It's playback time!

Tip: Have a look at the user operations flowchart in "project files" before reading this section.

FATCAT doesn't provide any way of playing a song as a predetermined sequence of the song patterns. During playback (PLAY mode) the current pattern simply loops endlessly until the user switches to another one by pressing L or R. Patterns can be switched at any point in the loop, and switching back and forth between two adjacent patterns mid-loop is encouraged as a technique for creating improvised variations of the original song. 

Of course there also needs to be a way of selecting which specific pattern to edit. The conventional method would be to simply have a specific option in the MENU mode which would turn the display into an integer spinner for selecting the next pattern to edit. But when you think about it, PLAY already kindof is that. It just happens to also play back the the pattern corresponding to the currently selected value. And that's actually what you'd want anyway. What you don't want, is to have to remember what the loops corresponding to each pattern number sounds like, when selecting which one to edit next. 

PLAY mode also has a feature for playing a solo of any of the three tracks. Pressing E during playback advances you to the next solo state. 

When cycling through rows in the editing modes, the device will normally output the audio of all instrument notes on the currently selected row, regardless of which track is currently targeted by the editor. This is often what you want the device to do. But when editing a very busy pattern that feature can sometimes be a source of confusion, despite the fact that the LED indicates the row note state of the track being edited. Because of this, it's useful to have an option for only monitoring the audio of that specific track.

Again, the proper method for selecting that option is by using the PLAY mode, since it already has a function for cycling between solo states. If play mode is exited while in a solo state, that will carry over into Row Edit mode. The function also serves as a way to select different track than whichever one was active before entering PLAY.  In this case however, separate menu items for selecting tracks are necessary,  since you want to retain the option for editing while monitoring the audio of all tracks.

Discussions