Jumping right back in where I left off, I’ve managed to fix the issues I was having with my previous attempt at implementing playback functionality. More than that, though, I realised a bigger problem with the code as it was. There was a serious lack of object-oriented programming. Inspired by my previous ventures into incorporating these principles and techniques into my previous work, I decided it’s about time to up the standards of my code and OOP-ify it (no, that’s not a word).
To start down this path, I thought of how my code would best translate to a more object-oriented approach. I would need to define a class, so I mulled upon what my class would be, and how I would use it. I thought about things such as defining a drawing as a class, and giving it functions such as adding a point and playing through its audiovisuals. In this instance the fields of the class would be things like number of ‘notes’, and I would essentially be transforming my entire project into one big class with different methods. While this may have worked, I decided to opt for a somewhat simpler route.
I decided to define a ‘note’ as a class. A note, in the context of my project, is both the visual point on the canvas created by the presence of a bright enough light source, and the audio note representation which is generated from this. Thinking of what fields the class would require then, I declared variables for the x and y coordinates, amplitude and colour. I also included a size field, however in the screenshot above I have hard coded the value 10 as the stroke weight of the drawn point, something which I have since changed to use this variable. The constructor of this class is quite simple, simple accepting parameters for the x and y coordinates of the note and setting the corresponding fields to these values. The colour is currently still set to black for testing, however this is likely to change. As it was before, the amplitude of the sound is set to the x coordinate of the drawn point, however as I have said before I’m still looking at ways to change this up so the sound is more intuitively and evidently linked with the appearance of the visuals. In terms of functionality, the note class needed to do two things – draw a point to the screen while the user was drawing, and play a note while playback is happening, along with in some way altering the point that was drawn. To accomplish this I created two class methods named drawCircle and play. The first of these methods takes functionality that was previously found in the main section of code, setting the stroke colour and weight before plotting a point at the x and y coordinates of the note object. The play function is used to hold some of the code for the playback functionality, and simultaneously plays a note using the SoundCipher library and changes the colour of the note object to be red.
In the main loop of the sketch, I have now included a for loop which, every frame, will iterate through the ArrayList of notes and call the drawCircle method of each note object in the list. This is to ensure that each note gets drawn to the screen every frame, and prevents overlapping problems I was having when I was manually re-drawing the circles in the play method, where notes in the background would get briefly redrawn over those in the front when they were played. This could be seen as a valid way for the notes to work, as it would ensure the currently played note is always seen, however it often produced a jarring visual effect which was aesthetically displeasing.
The lightDraw function has been accordingly updated. Since the actual drawing of the points has been moved to a method in the note class, the lightDraw function now adds a new note to the notes list (rather than a vector as it did before) and then calls the drawCircle method of the last note in the list (the one that was just added). This method is called here as well as in the main draw loop, because I found when just leaving the notes to be drawn at the next frame, sometimes the drawing on the screen would noticeably lag behind the movement of the light source, which led to a less intuitive feeling interaction.
That brings me to the newly-revamped and functional playback code. While not massively different from the way it was before in what it does, it differs slightly in the way that it goes about looping through the notes. Firstly, I have declared a new integer variable (not seen here) called index. The function checks whether this index value is greater than the size of the notes ArrayList. If so, the index is returned to its default value of 0 and the playback is stopped. Then the function checks whether the notes list has any data in it (better safe than sorry), and if it does a temporary note object is created and assigned the data of the note object located in the ArrayList at the position defined by the index variable. The play method of this note object is then called, which causes the sound to be played and the changing of colour of the point on the screen. Whereas before this series of events (without the inclusion of the note class) happened in a for-loop, I found that this was causing the playback to occur all at once, rather than at a reasonable tempo. I therefore have now created a timing function to space out the playback of each note. This is called each frame that the playback function is running, and checks using another new variable (again not shown here) simply named ‘time’ whether a specific amount of time has passed since the last note was played. If it has, the time variable is set to the current time, essentially setting this timer back to zero, and the index is incremented to allow the next note in the list to be played by the playback function. This new technique of cycling through the list of notes has solved the issue I was having, and the playback now happens as I intended, note-by-note.
I am pleased I have been able to fix the problems with the playback functionality, and although the moving of some of the functions of the project into their own class hasn’t visually, to the outsider, changed how the sketch works, I am confident that it will enable me to more easily proceed with the project and make important changes which I would like to make. I intend to revamp the visual design of the work, before looking to gather some user feedback for the project in the hopes of getting closer to a final version.