VISUAL HASHMARKS ON THE GUI FOR EACH RECORDED NOTE: a new feature for the open-source project The Amanuensis: Automated Songwriting and Recording
Repository
https://github.com/to-the-sun/amanuensis
The Amanuensis is an automated songwriting and recording system aimed at ridding the process of anything left-brained, so one need never leave a creative, spontaneous and improvisational state of mind, from the inception of the song until its final master. The program will construct a cohesive song structure, using the best of what you give it, looping around you and growing in real-time as you play. All you have to do is jam and fully written songs will flow out behind you wherever you go.
If you're interested in trying it out, please get a hold of me! Playtesters wanted!
New Features
- What feature(s) did you add?
In this update a step has been taken towards my ideal vision of the system as a sort of videogame, like Guitar Hero, with interactive visual cues to guide you as you play. Hashmarks now appear on each track at the exact positions of the recorded notes that lie within them.
These are essentially "higher scoring" moments that the player can aim for as the play bar moves along, as not only does the system take into account how rhythmic your playing is based on your past playing, but also based on what's already been recorded.
It is not necessarily ideal to spend too much time staring at the screen aiming for these marks, as to be in the right flow with the music usually means paying attention only to your auditory sense and that can be done just as easily with eyes closed, but these marks do give a much better sense of what's going on in the track. This is especially helpful when utilizing the latest new feature, individual note deletion. So while on an editing run, you may not be playing anything at all, but now can see exactly which note it is that will be removed when you hit the hotkey (being that it will always be the one that the play bar has just passed).
- How did you implement it/them?
If you're not familiar, Max is a visual language and textual representations like those shown for each commit on Github aren't particularly comprehensible to humans. You won't find any of the commenting there either. Therefore, I will do my best to present the work done in images instead. Read the comments there to get an idea of how the code works. I'll try to keep my description here about the process of writing that code.
These are the primary commits involved:
Although it would probably be more efficient to use JavaScript in jsui
to create the illustrative spans and their markers, dynamic scripting is easier and seems to be working so I chose to stick with that for the time being. The primary work involved in this feature update with the creation of a new patcher called draw_beats
.
draw_beats
in track.maxpat
The task required careful consideration of the best way to assemble a list of all of the cues currently recorded in the song. Dumping the entire seq~
is something that should be avoided at all costs, so it was settled upon to assemble a separate coll
using the individual add
messages as they originally come in for the seq~
. Dumping coll A_tracks
to get all the current spans is still necessary however.
It was important to consider that spans could be removed or have their endpoints altered at any point after the cues being initially assembled (and also that cues are placed before the span has even finished recording) so it was necessary to compare each of the cues with its span to make sure it lies within it. A new and potentially consolidated list is then assembled each time.
It became apparent that far too many hashmarks were being placed and subsequently realized that the assemblage of ---beats
would need to occur elsewhere, as if it was happening with the rest of draw_beats
the effect would be multiplied 16 times, once for each track. So the code was moved next to the seq~
object itself, in midipalette
.
midipalette
of organism.maxpat
Although I could see through print
ing the issue described in commit #2, on-screen no actual lines were being placed. It was determined that, since the span panel
s themselves were also being drawn upon the trigger from r ---draw_spans
, they were covering up the live.line
s, so it was necessary to avoid this race by ordering the execution explicitly.
you can see draw_beats
here in its larger context in track.maxpat
Cleanup and commenting
Thanks for the contribution, @to-the-sun!
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Hey @to-the-sun
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!