« Thread started on: Feb 17th, 2018, 9:23pm »
Another 'Z80 Music' transcription from the early 1980s, but this time I decided to tart it up, as you can see! It took me only half a day to write this program; it is 100% BASIC, compatible with both BB4W and BBCSDL, and not complicated (the source code is available at the group; members only).
it is 100% BASIC, compatible with both BB4W and BBCSDL, and not complicated
I like to think, or at least hope, that publishing these various demo programs motivates people to aspire to writing similar programs themselves - or at least to think about how they might go about it.
As I said, the animated piano keyboard was not complicated, but it did involve a couple of interesting aspects, and there may be some value in me explaining how I approached them.
Drawing the 3D keyboard itself was obviously trivial. All the white keys are identical and are modelled as simple cuboids; there was no need to model the 'cutouts' where the black keys go, because by the magic of 3D rendering the black keys simply occupy the same volume! The black keys themselves are slightly more complicated, because of the slant front face, but nevertheless they only have four more triangles each.
So drawing the keyboard was straightforward, but what about animating it? This is where the first 'trick' came in: I chose the coordinate system and orientation of the keys so that 'y=0, z=0' corresponded to the key's pivot point! Now, animating the key was simply a case of changing its tilt value (pitch if you prefer the aeronautical term) which was a big simplification.
The second issue was: how do I determine what notes are currently playing, so as to animate the keyboard in (approximate) synchronisation with the music? The program knows when the SOUND statements are executed, but the sounds are queued by BBC BASIC and are typically made quite some (variable) time later: this is to ensure that music can be played in strict tempo whilst the BASIC program is off doing other things.
There's no legitimate way of 'peeking' the SOUND queues, so surely it must be impossible to determine what sound is playing 'now'? But in fact it is possible! Firstly, in the absence of any way to interrogate the sound queues, I simply create my own copies in the program: so long as I put a new event into my copy of the queue whenever a SOUND statement places a note into BBC BASIC's queue, the two should remain 'in step'.
Having solved the problem of peeking the queue, all I needed to do is to use ADVAL() to discover how many notes are currently queued on each SOUND channel (ADVAL returns the number of free bytes in the queue, but it's easy to calculate from that the number of queued notes). So by looking in my copy of the queue, at a location depending on the number of queued notes, I could find out what sound is currently being played on that channel!
As is so often the case, coding the program was straightforward but it was necessary to do some preliminary thinking to work out just what it needed to do.