COMPLICATION 1 - HAS A BIT OF FLOATING POINT MATH
This adjusts the songs duration for each note by an adjustment factor involving both the number of quarter notes per minute and the relative frequency of the note. There is a calculation involved:
535500 / Q / RF
This converts each of those numbers to floating point and then converts the answer back to an integer, loping off any fractional part. That integer result will multiply the duration of the note, which begins as the number of eighth notes but is scaled by the calculated factor which I approximate to be anywhere from 22 to 95. That adjusted duration is the counter for an outer loop, while the relative frequency itself is the count for the inner loop.
I guess the calculation above is determining the proper adjustment of the duration of the outer loop to achieve the number of eighth notes. It takes the time in the inner loop (relative frequency) and the desired duration in fractions of a second for an eighth note to decide how many outer loops produces that duration.
Relative frequencies run from a F which the program claims is 83.1Hz - but that is between E flat and E on the real musical scale. The program's F note has a relative value of 213. The program supports a range of over four octaves to a note whose relative value is 51. That places the high note at approximately 340 Hz which is almost F in the octave containing a piano middle C.
FIGURING OUT TIMING WITHOUT RUNNING ON A REAL 1130
I don't have a running 1130 at the moment while I work on the demo programs at home. However, I have a way to figure out how to get the tones correct.
I stopped the program on the simulator and observed it using a tight loop with a somewhat inefficient inner loop consisting of:
MDM (MDX L with no index register) to bump the value of the DO loop counter by 1
NO-OP to burn one cycle fruitlessly
LD L to grab the DO loop counter
S L to subtract the end count of the DO loop (the relative frequency)
BSC L to branch back to the loop while the ACC is negative
This takes approximately 53.5 microseconds on the initial model of the 1130 (3.6 us memory cycle time) and thus 213 loops matches the low F and 51 loops matches the highest note. When the inner loop changes, it decrements the counter of the outer loop (using a similar set of instructions) and then reloads the inner loop back to its initial value of 1.
Thus I can achieve the proper timing even though my testing will be on the IBM 1130 simulator which runs much, much too fast compared to a real 1130.
WILL USE SCALED INTEGER MATH TO HANDLE THE ADJUSTMENT FORMULA
By scaling up the values appropriately before all the divisions I can have enough precision to produce the same non-fractional part of the answer without having to implement floating point arithmetic. For example, when I divide the initial constant 535500 by the quarter notes per minute value, I will get both a quotient and a remainder. I can multiply that by 8 and still fit in a single word (16 bit integer). Then I can divide that by the relative frequency and gain multiply the result as long as it won't overflow. The final answer can be divided by the scaling I applied to get an integer result.
No comments:
Post a Comment