Musical Note Duration Conversions

Basic and Machine Language

Moderator: Moderators

User avatar
Gorf
Vic 20 Dabbler
Posts: 92
Joined: Tue Feb 09, 2016 6:55 pm
Website: http://home.macintosh.garden/~europa/
Location: United States
Occupation: Eccentric Musician

Musical Note Duration Conversions

Post by Gorf »

Hello! :D

I was wondering if someone could give me a good guide for musical not duration conversions as I am trying to use my VIC to create some music using POKEs and FOR...NEXT loops.

Thanks! :D
Bobbi
Vic 20 Afficionado
Posts: 355
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: Musical Note Duration Conversions

Post by Bobbi »

I guess I would get out a stop watch and time some FOR loops in BASIC :)
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Re: Musical Note Duration Conversions

Post by Boray »

How about

FOR T=1 TO S/N : NEXT

Where S is playback speed and N is note length, for example 1,2,4 or 8.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Bobbi
Vic 20 Afficionado
Posts: 355
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: Musical Note Duration Conversions

Post by Bobbi »

Or maybe use the VIC's own stopwatch for timing!

10 S=TI
20 FOR I=1TO1000:NEXTI
30 PRINT TI-S
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Musical Note Duration Conversions

Post by Mike »

The main issue with simple FOR...NEXT timing loops, if used for different note durations, is that they don't compensate properly for the time taken the read in the note data, writes to the VIC sound registers and other overhead. Tunes played with this method quite often sound like they're losing the beat.

IMO, it's better to employ a "tracker" approach, using a single time base period. Then, longer notes are achieved by repeating the note value until the desired length is reached. Most simple tunes do not use more than 3 different note lengths, so that should cover most needs. IRQ based players in machine language almost always take the same approach, using the stable IRQ clock for their purpose.

As an example how a music player in BASIC looks like with that method, here's a simple "Happy Birthday" tune:

Code: Select all

1 V=36864:POKEV+14,5:DIMN(8):FORT=0TO8:READN(T):NEXT
2 A$=""+"AAAAA@AA@BBBBBBBB@AAAAAAAA@DDDDDDDD@CCCCCCCCCCCCCCCCC@"
3 A$=A$+"AAAAA@AA@BBBBBBBB@AAAAAAAA@EEEEEEEE@DDDDDDDDDDDDDDDDD@"
4 A$=A$+"AAAAA@AA@HHHHHHHH@FFFFFFFF@DDDDDDDD@CCCCCCCC@BBBBBBBB@"
5 A$=A$+"GGGGG@GG@FFFFFFFF@DDDDDDDD@EEEEEEEE@DDDDDDDDDDDDDDDDD@"
6 FORT=1TOLEN(A$):POKEV+12,N(ASC(MID$(A$,T,1))-64):FORS=1TO30:NEXT:NEXT
7 FORP=-1TO0:GETA$:P=A$="":NEXT
8 DATA 0,170,179,187,191,198,204,207,212
That one uses a rather short time base (see FORS=1TO30:NEXT), because it needs to insert small pauses to properly separate consecutive identical notes.
User avatar
Gorf
Vic 20 Dabbler
Posts: 92
Joined: Tue Feb 09, 2016 6:55 pm
Website: http://home.macintosh.garden/~europa/
Location: United States
Occupation: Eccentric Musician

Re: Musical Note Duration Conversions

Post by Gorf »

Bobbi wrote:Or maybe use the VIC's own stopwatch for timing!

10 S=TI
20 FOR I=1TO1000:NEXTI
30 PRINT TI-S
So, that gives me a value of 73, can you please tell me what I can deduce from that? :D
Boray wrote:How about

FOR T=1 TO S/N : NEXT

Where S is playback speed and N is note length, for example 1,2,4 or 8.
So, am I correct that 1, 2, 4, or 8 are essentially whole, half, quarter, and eighth notes? If so, how do you determine the playback speed? :D
Mike wrote:The main issue with simple FOR...NEXT timing loops, if used for different note durations, is that they don't compensate properly for the time taken the read in the note data, writes to the VIC sound registers and other overhead. Tunes played with this method quite often sound like they're losing the beat.

IMO, it's better to employ a "tracker" approach, using a single time base period. Then, longer notes are achieved by repeating the note value until the desired length is reached. Most simple tunes do not use more than 3 different note lengths, so that should cover most needs. IRQ based players in machine language almost always take the same approach, using the stable IRQ clock for their purpose.

As an example how a music player in BASIC looks like with that method, here's a simple "Happy Birthday" tune:

Code: Select all

1 V=36864:POKEV+14,5:DIMN(8):FORT=0TO8:READN(T):NEXT
2 A$=""+"AAAAA@AA@BBBBBBBB@AAAAAAAA@DDDDDDDD@CCCCCCCCCCCCCCCCC@"
3 A$=A$+"AAAAA@AA@BBBBBBBB@AAAAAAAA@EEEEEEEE@DDDDDDDDDDDDDDDDD@"
4 A$=A$+"AAAAA@AA@HHHHHHHH@FFFFFFFF@DDDDDDDD@CCCCCCCC@BBBBBBBB@"
5 A$=A$+"GGGGG@GG@FFFFFFFF@DDDDDDDD@EEEEEEEE@DDDDDDDDDDDDDDDDD@"
6 FORT=1TOLEN(A$):POKEV+12,N(ASC(MID$(A$,T,1))-64):FORS=1TO30:NEXT:NEXT
7 FORP=-1TO0:GETA$:P=A$="":NEXT
8 DATA 0,170,179,187,191,198,204,207,212
That one uses a rather short time base (see FORS=1TO30:NEXT), because it needs to insert small pauses to properly separate consecutive identical notes.
Ok, I understand what you are saying about FOR...NEXT loops and I have a rudimentary understanding of how trackers work and how they time notes. Can you tell me what lines to change to use different notes and also, can you take advantage of more than one voice using this approach? :D

Thank you all for your help! :mrgreen:
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Musical Note Duration Conversions

Post by Mike »

Gorf wrote:Ok, I understand what you are saying about FOR...NEXT loops and I have a rudimentary understanding of how trackers work and how they time notes. Can you tell me what lines to change to use different notes and also, can you take advantage of more than one voice using this approach? :D
I deliberately left that as exercise for the reader. :P

But really, the note values are contained in the DATAs of line 8 and can be changed as you like. And more than one voice would be done by interleaving the note data in the string, retrieving the register values into two or more variables, and finally updating the VIC registers with the necessary POKEs within the shortest time possible for each time step, so all note changes happen nearly simultaneously - otherwise you *will* hear strange arpeggio-like blips on all note changes.

Anything more complex than that is better done in one of the music trackers available for the VIC-20, like Daniel Kahlin's VIC-TRACKER 2.0.
User avatar
Gorf
Vic 20 Dabbler
Posts: 92
Joined: Tue Feb 09, 2016 6:55 pm
Website: http://home.macintosh.garden/~europa/
Location: United States
Occupation: Eccentric Musician

Re: Musical Note Duration Conversions

Post by Gorf »

Mike wrote:
Gorf wrote:Ok, I understand what you are saying about FOR...NEXT loops and I have a rudimentary understanding of how trackers work and how they time notes. Can you tell me what lines to change to use different notes and also, can you take advantage of more than one voice using this approach? :D
I deliberately left that as exercise for the reader. :P

But really, the note values are contained in the DATAs of line 8 and can be changed as you like. And more than one voice would be done by interleaving the note data in the string, retrieving the register values into two or more variables, and finally updating the VIC registers with the necessary POKEs within the shortest time possible for each time step, so all note changes happen nearly simultaneously - otherwise you *will* hear strange arpeggio-like blips on all note changes.

Anything more complex than that is better done in one of the music trackers available for the VIC-20, like Daniel Kahlin's VIC-TRACKER 2.0.
Ok, thank you. I think that your subroutine will help me in the future. :D
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Musical Note Duration Conversions

Post by Mike »

Just one small addition:
Mike wrote:[...] more than one voice would be done by interleaving the note data in the string, [...]
It is also possible to use an own string for each voice.

That avoids the interleaving, but you have to take a little more oversight that the voices keep in step. You'd then retrieve the register values for all the voices from the same position in two or more strings instead of from two or more consecutive positions in the same one string.

You'll still have to write the registers as fast as possible, like in: POKEV+10,A:POKEV+11,B:POKEV+12,C - with the values in A, B and C retrieved beforehand (say, with A=N(MID$(..)).:B=...:C=...).
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Re: Musical Note Duration Conversions

Post by Boray »

Gorf wrote: So, am I correct that 1, 2, 4, or 8 are essentially whole, half, quarter, and eighth notes? If so, how do you determine the playback speed? :D
Yes. Playback speed is faster the lower the number is and slower the higher the number is.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Bobbi
Vic 20 Afficionado
Posts: 355
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: Musical Note Duration Conversions

Post by Bobbi »

To answer your question about the 'stopwatch' ... TI (and TI$) contain the time since the system started in 60ths of a second.

So your value of 73, corresponds to slightly more than one second (73/60).
User avatar
Gorf
Vic 20 Dabbler
Posts: 92
Joined: Tue Feb 09, 2016 6:55 pm
Website: http://home.macintosh.garden/~europa/
Location: United States
Occupation: Eccentric Musician

Re: Musical Note Duration Conversions

Post by Gorf »

Mike wrote:Just one small addition:
Mike wrote:[...] more than one voice would be done by interleaving the note data in the string, [...]
It is also possible to use an own string for each voice.

That avoids the interleaving, but you have to take a little more oversight that the voices keep in step. You'd then retrieve the register values for all the voices from the same position in two or more strings instead of from two or more consecutive positions in the same one string.

You'll still have to write the registers as fast as possible, like in: POKEV+10,A:POKEV+11,B:POKEV+12,C - with the values in A, B and C retrieved beforehand (say, with A=N(MID$(..)).:B=...:C=...).

Ok, thank you for the tip! :D
User avatar
Gorf
Vic 20 Dabbler
Posts: 92
Joined: Tue Feb 09, 2016 6:55 pm
Website: http://home.macintosh.garden/~europa/
Location: United States
Occupation: Eccentric Musician

Re: Musical Note Duration Conversions

Post by Gorf »

Boray wrote:
Gorf wrote: So, am I correct that 1, 2, 4, or 8 are essentially whole, half, quarter, and eighth notes? If so, how do you determine the playback speed? :D
Yes. Playback speed is faster the lower the number is and slower the higher the number is.
Ok, thank you for clarifying that. :D
Bobbi wrote:To answer your question about the 'stopwatch' ... TI (and TI$) contain the time since the system started in 60ths of a second.

So your value of 73, corresponds to slightly more than one second (73/60).
Which make sense because the 6502's speen on the NTSC VIC-20 is slightly more than 1 MHz, right? :D
Bobbi
Vic 20 Afficionado
Posts: 355
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: Musical Note Duration Conversions

Post by Bobbi »

Which make sense because the 6502's speen on the NTSC VIC-20 is slightly more than 1 MHz, right?
It has more to do with however fast BASIC happens to be when executing a FOR loop.
User avatar
Gorf
Vic 20 Dabbler
Posts: 92
Joined: Tue Feb 09, 2016 6:55 pm
Website: http://home.macintosh.garden/~europa/
Location: United States
Occupation: Eccentric Musician

Re: Musical Note Duration Conversions

Post by Gorf »

Bobbi wrote:
Which make sense because the 6502's speen on the NTSC VIC-20 is slightly more than 1 MHz, right?
It has more to do with however fast BASIC happens to be when executing a FOR loop.
Ok, thanks for the clarification. :D
Post Reply