Jump to content
IGNORED

Assembly language sound effects


Asmusr

Recommended Posts

 

I have a similar problem (math on the interval) so I looked at this in detail.

If TOS is just a register as you say,
TOS 4 SRC,
TOS W MOV,
W 4 SRL,
W TOS MOVB,

 

BTW I found that the above did not work for 440Hz. while testing.

Instead E0F as the cmd bytes I got 00F.

I cannot understand why? (I have not doubled check this finding)

 

It seems to work with this change:


 CODE >FCODE ( 0abc -- 0cab) \ version by Farmer Potato Atariage
              TOS 4 SRC,   \ C0AB
              TOS W MOV,   \ DUP
              W 4 SRL,     \ 0C0A
              W TOS SOCB,  \ 0CAB
            NEXT,          
            ENDCODE

Link to comment
Share on other sites

 

 

BTW I found that the above did not work for 440Hz. while testing.

Instead E0F as the cmd bytes I got 00F.

I cannot understand why? (I have not doubled check this finding)

 

It seems to work with this change:


 CODE >FCODE ( 0abc -- 0cab) \ version by Farmer Potato Atariage
              TOS 4 SRC,   \ C0AB
              TOS W MOV,   \ DUP
              W 4 SRL,     \ 0C0A
              W TOS SOCB,  \ 0CAB
            NEXT,          
            ENDCODE

 

That's weird. SOCB is the wrong thing to do (it is bitwise OR). Because TOS already holds C0AB you should get CCAB. Are you sure you didn't make a typo when putting in your machine code? (I saw earlier you were putting in machine code D108 for MOVB W,TOS)

(On a side note, SZCB is next in my bag of tricks after SRC but I couldn't find a way to use it here.)

 

Here's my log of running the version I gave you on Sunday. (under TI FORTH it trashes R8 .)

 

   D586  0B44  src  R4,4                   (24) 
   D588  C204  mov  R4,R8                  (18)  42
   D58A  0948  srl  R8,4                   (24)  66
   D58C  D108  movb R8,R4                  (18)  84
   D58E  045F  b    *R15                   (16)

Here's my working TI FORTH version and test results. Of course TI FORTH doesn't have the TOS optimization, only SP. I have to copy *SP to R1 instead since SRC can't do indirect addressing..

 

CODE XS
SP *? 1 MOV,
1 4 SRC,
1 SP *? MOV,
1 4 SRL,
1 SP *? MOVB,
NEXT,


( Classic99)
   D586  C059  mov  *R9,R1                 (26)  26
   D588  0B41  src  R1,4                   (24)  50
   D58A  C641  mov  R1,*R9                 (30)  80
   D58C  0941  srl  R1,4                   (24) 104
   D58E  D641  movb R1,*R9                 (30) 134
   D590  045F  b    *R15                   (16) 150

( Test)
0ABC XS U.  CAB  ok
00FE XS U.  E0F  ok

( Cycles
Camel FORTH 24 + 18 + 24 + 18
TI FORTH 26 + 24 + 30 + 24 + 30 )

 

 

 

 

I think I need the optimization more than you, since I do this bit twiddling (and its reverse) inside the interrupt routine to interpolate frequencies, but so far you only use it at compile time.

 

I can see how much the TOS optimization is worth in Camel Forth: 4 instructions in 84 cycles, vs 5 instructions in 134 cycles in TI FORTH. An extra MOV to get *SP and 12 cycles each for indirect register access. I didn't count the NEXT,

 

Best,

-Erik

 

Link to comment
Share on other sites

 

That's weird. SOCB is the wrong thing to do (it is bitwise OR). Because TOS already holds C0AB you should get CCAB. Are you sure you didn't make a typo when putting in your machine code? (I saw earlier you were putting in machine code D108 for MOVB W,TOS)

(On a side note, SZCB is next in my bag of tricks after SRC but I couldn't find a way to use it here.)

 

Here's my log of running the version I gave you on Sunday. (under TI FORTH it trashes R8 .)

 

   D586  0B44  src  R4,4                   (24) 
   D588  C204  mov  R4,R8                  (18)  42
   D58A  0948  srl  R8,4                   (24)  66
   D58C  D108  movb R8,R4                  (18)  84
   D58E  045F  b    *R15                   (16)

Here's my working TI FORTH version and test results. Of course TI FORTH doesn't have the TOS optimization, only SP. I have to copy *SP to R1 instead since SRC can't do indirect addressing..

 

CODE XS
SP *? 1 MOV,
1 4 SRC,
1 SP *? MOV,
1 4 SRL,
1 SP *? MOVB,
NEXT,


( Classic99)
   D586  C059  mov  *R9,R1                 (26)  26
   D588  0B41  src  R1,4                   (24)  50
   D58A  C641  mov  R1,*R9                 (30)  80
   D58C  0941  srl  R1,4                   (24) 104
   D58E  D641  movb R1,*R9                 (30) 134
   D590  045F  b    *R15                   (16) 150

( Test)
0ABC XS U.  CAB  ok
00FE XS U.  E0F  ok

( Cycles
Camel FORTH 24 + 18 + 24 + 18
TI FORTH 26 + 24 + 30 + 24 + 30 )

 

 

 

 

I think I need the optimization more than you, since I do this bit twiddling (and its reverse) inside the interrupt routine to interpolate frequencies, but so far you only use it at compile time.

 

I can see how much the TOS optimization is worth in Camel Forth: 4 instructions in 84 cycles, vs 5 instructions in 134 cycles in TI FORTH. An extra MOV to get *SP and 12 cycles each for indirect register access. I didn't count the NEXT,

 

Best,

-Erik

 

 

It's possible that I transcribed the machine code incorrectly. I will double check. I just found out I blew up my multitasker somewhere along the line. So I am running that down.

 

I see the logic of using MOVB, I will have to try it all again.

 

I am not sure why you interpolate frequencies in the interrupt routine, when you know the frequency of each note before hand. But I have not looked at you code beyond a quick scan so what do I know.

 

What do you make of me changing my clock frequencies? :-)

From what I can see using that method my command bytes are only off by 1 or so from your table values at the extremes.

Link to comment
Share on other sites

So after looking at your table I realized I could solve this the other way around.

 

Given f=440 and the correct command byte=>FE, what should f(clk) be?

 

The answer is 111,760 Hz. So I changed that value and my 440 is a real A. And octaves sound more in tune now albeit not musically perfect.

 

So by fudging the clock frequency I get better command byte values.

 

If I am correct your values will generate the tempered scale and mine are the mathematical values, correct at 440Hz and drifting off of musical values at the low and high end.

 

For my technical lexicon consisting of Hz and dB commands this is fine.

For my music player I am going to switch everything to your values.

 

For comparison:

( A+) 93F , ( 110)

( A ) C1F , ( 220)

( A ) E0F , ( 440)

( A ) F07 , ( 880)

( A ) 004 , ( 1760)

 

 

B

 

 

I like the idea of choosing a f(clk) that is a multiple of 440. The important thing is that the periods produced are in neat integer ratios. I notice for the first time that TI's periods for As are not: 3F9, 1FC, FE, 7F, 40.
The period FE produces a frequency 440.3968 Hz, so TI's choice of >3f9 or 109.999 Hz is inferior to using >3F8 or 110.099 Hz. At the other end, 1760 Hz is approximated by >40 or 1747 Hz in the TI table but I would prefer to err sharp with >3F for 1775.57 Hz.
109.999 vs 110.099 -- is it too small to matter? The 3rd harmonic (recall a square wave is composed of only odd harmonics) is 439.996 Hz vs 440.396 Hz. Since we are centered on 440.3968 Hz, the TI (lower) choice should create a beat frequency at 0.4 Hz in the 3rd harmonic when notes with periods 3F9 and FE are played together. Should be detectable by ear. I'm going to check how that sounds on real hardware later on. (Aside: I just got a large pile of SN76496 from China.)
So, I like your As.
There are not "musically perfect" frequencies. It is up the orchestra. Historically, the frequency of A varied quite a bit. That said, in the group I performed with for many years, our piano accompanist had "perfect pitch", was also married to the conductor, and would single out anybody who was singing off pitch.
Also, you are starting with integer frequencies, so in addition to tuning up the As, you could pay similar attention to precision on other notes.
Best,
-Erik
Edited by FarmerPotato
Link to comment
Share on other sites

 

I am not sure why you interpolate frequencies in the interrupt routine, when you know the frequency of each note before hand. But I have not looked at you code beyond a quick scan so what do I know.

 

 

I need to interpolate smoothly between notes, i.e. generate notes that are not in the table. I haven't posted that code yet.

Edited by FarmerPotato
Link to comment
Share on other sites

 

There are not "musically perfect" frequencies. It is up the orchestra. Historically, the frequency of A varied quite a bit. That said, in the group I performed with for many years, our piano accompanist had "perfect pitch", was also married to the conductor, and would single out anybody who was singing off pitch.
Also, you are starting with integer frequencies, so in addition to tuning up the As, you could pay similar attention to precision on other notes.
Best,
-Erik

 

 

Just by way of knowing each other, I can tell you have a solid music background. I spent 20 years or so as a church music director, played in a Classic guitar trio, a Jazz trio with Guitar clarinet and double bass and have produced a number of recordings for others. (none of which have went mainstream) :)

 

So my question was mis-leading in that I was thinking about tempered tuning versus natural tuning. However clearly my goals are much less ambitious than yours regarding the 9919.

 

I sympathize with you working with the accompanist with perfect pitch. I can't imagine how those people work in environments. where A is not 440 :?

Many years ago I worked in a 17 piece big band and we would occasional be booked in halls in rural parts of the country. The hall piano was invariably 1/4 tone flat!.

In those years if you called and asked if the piano was in good condition occasionally the reply was "Oh yes! We just had it painted." :grin:

 

B

Link to comment
Share on other sites

You were correct about the >FCODE word. My finger trouble. I compiled the wrong version in the code. No-conditional compile yet so it's all commenting things out.

 

Thanks again for this "petite" code.

 

B

Link to comment
Share on other sites

Well Erik, now I understand why you use a table of command bytes. It makes transposing so simple!

 

I reworked my music language to use your table and I use indexed addressing to fetch the command bytes a quickly as possible in Forth.

And most importantly I can have the word TRANSPOSE that takes a value from -12 to 12 and adjusts the SEMIS variable.

 

Next I will have to create separate volume , off_time and on_time variables for each of the 3 voices.

 

Very fun stuff.

 

 

 

\ music lexicon to control the TMS9919

INCLUDE DSK1.ASM9900.F

\ TMS9919 is a memory mapped device on the TI-99 @ >8400
\ SND! is in the CAMEL99 Kernel as  : SND!     8400 C! ;

\ frequency code must be ORed with these numbers to create a sound
HEX
  8000 CONSTANT OSC1      A000 CONSTANT OSC2   ( oscillators take 2 nibbles)
  C000 CONSTANT OSC3        E0 CONSTANT OSC4   ( noise takes 1 nibble)

\ Attenuation values are ORed with these values to change volume
( 0= max, 15 = off)
    90 CONSTANT ATT1         B0 CONSTANT ATT2
    D0 CONSTANT ATT3         F0 CONSTANT ATT4  ( OSC4 volume adjust)

DECIMAL
 VARIABLE ON_TIME     \ duration control
 VARIABLE OFF_TIME
 VARIABLE FEEL        \ controls the on/off time ratio
 VARIABLE TEMPO       \ computed "tempo" value
 VARIABLE OSC         \ holds the active OSC value
 VARIABLE ATT         \ holds the active ATTENUATOR value

\ need to create a 32 bit integer. Forth has the words to do it.
\ convert a string to double int.   (32bits)
: >DOUBLE  ( addr len -- d ) 0 0 2SWAP >NUMBER 2DROP ;

\ now we create a double int variable called timebase from primitive words
\ this is the slowest we can play music ie: wholenote=240,000 mS
S" 240000" >DOUBLE  CREATE TIMEBASE SWAP  ,  ,

: ATTENUATE ( n -- ) ATT @ OR SND! ;    \ faster than using DB

: BPM>MS    ( bpm -- ms) \ convert beats per minute to mS
            TIMEBASE 2@  ROT UM/MOD NIP ;   

: WHOLENOTE ( -- mS ) \ using tempo set the bpm for 1 whole note
            TEMPO @ BPM>MS ;

: (PLAY)    ( fcode -- ) OSC @ OR  SPLIT SND! SND! ;  \ turns on note

: MUTE      ( -- ) 15 ATTENUATE ;

: PLAY      ( fcode -- )
\             ?BREAK     \ halts if function 4 pressed
             (PLAY)
             0 ATTENUATE  ON_TIME @ MS
             MUTE        OFF_TIME @ MS  ;

 \ Music needs notes to start and end in different ways.
 \ this word adjust the on:off ratio using n
: EXPRESSION ( note_dur n --)
           OVER SWAP -  TUCK -   ( -- on-ms off-ms )
           1 MAX OFF_TIME !  
           1 MAX ON_TIME ! ; 
                                 \ store times in variables
\ return full duration of current note
: NOTE      ( -- MS ) ON_TIME @ OFF_TIME @ + ;

: DURATION! ( MS -- ) FEEL @ EXPRESSION ;

: 5%       ( -- ) 5 / ;
: 10%      ( n -- n ) 10 / ;
: 20% ( n -- n ) 20 / ;
: 50%       ( N -- N/2)    2/ ;
: %         ( N N2  -- N%) 100 */ ;    \ calculate n2% of n
: 50%+      ( N -- N+50%)  DUP 50% + ; \ dotted notes have 50% more time

: BPM       ( BPM -- )  \ set tempo in beats per minute
            TEMPO !
            WHOLENOTE DURATION! ;

: NORMAL      NOTE 5 % FEEL ! ;
: LEGATO      1 FEEL ! ;         \ notes run together
: STACCATTO   NOTE 11 % FEEL ! ;  \ short notes
: DETACHE     NOTE  7 % FEEL ! ;  \ notes separated

: RIT.     NOTE DUP 20% + DURATION! ;

: 1/1      WHOLENOTE      DURATION! ;
: 1/2      WHOLENOTE 50%  DURATION! ;
: 1/2.     1/2  NOTE 50%+ DURATION! ;
: 1/4      1/2  NOTE 50%  DURATION! ;
: 1/4.     1/4  NOTE 50%+ DURATION! ;
: 1/8      1/4  NOTE 50%  DURATION! ;
: 1/8.     1/8  NOTE 50%+ DURATION! ;
: 1/16     1/8  NOTE 50%  DURATION! ;
: 1/32     1/16 NOTE 50%  DURATION! ;
: REST     NOTE MS ;

\ note object creator
: NOTE:   ( freq -- )
           CREATE    ,    \ Compile into 9919 byte code
           DOES> @ PLAY ; \ run time:  fetch the number, play the note
HEX
: SILENT  ( --)  9F SND!  BF SND!  DF SND!  FF SND! ;
: GEN! ( osc att -- )  ATT !  OSC ! ;
\ sound generator selectors
: GEN1    ( -- )  OSC1  ATT1  GEN! ;
: GEN2    ( -- )  OSC2  ATT2  GEN! ;
: GEN3    ( -- )  OSC3  ATT3  GEN! ;
: GEN4    ( -- )  OSC4  ATT4  GEN! ;

: NOISE   ( n -- ) OSC4 OR  SND! ; \ locked to oscillator #4

\ Correct Tempered tuning values from FARMER Potato (Erik) Atariage.com

CREATE NOTES
 ( A+) 93F , 03C , A38 , 735 , 732 , A2F , ( 110)
 ( D#) F2C , 72A , 128 , D25 , B23 , B21 ,
 ( A ) C1F , 01E , 51C , C1A , 419 , D17 , ( 220)
 ( D#) 816 , 315 , 014 , E12 , D11 , D10 ,
 ( A ) E0F , 00F , 20E , 60D , A0C , E0B , ( 440)
 ( D#) 40B , A0A , 00A , 709 , F08 , 708 ,
 ( A ) F07 , 807 , 107 , B06 , 506 , F05 , ( 880)
 ( D#) A05 , 505 , 005 , C04 , 704 , 304 ,
 ( A ) 004 , C03 , 903 , 503 , 203 , 003 , ( 1760)
 ( D#) D02 , A02 , 802 , 602 , 402 , 202 ,

\ fetch contents of any cell in NOTES
CODE ]NOTE@  ( i -- notes[i]@)
        TOS  1 SLA,               \ shift R1 1 bit left (mult. By 2)
        NOTES (TOS) TOS MOV,      \ fetch contents of ARRAY(TOS) to TOS
	NEXT,
ENDCODE

VARIABLE SEMIS

: TRANSPOSE  ( n -- ) SEMIS ! ;

: ENUM-NOTE: ( n -- )      \ enumerating note creator
            CREATE  DUP , 1+
            DOES> @  SEMIS @ + ]NOTE@ PLAY  ;

\ FREQ  NATURAL    FREQ  ACCIDENTAL    EN-HARMONIC
\ -------------    ----------------   ----------------
  0 ENUM-NOTE: A2     ENUM-NOTE: A2#       : Bb2 A2# ;
    ENUM-NOTE: B2
    ENUM-NOTE: C3     ENUM-NOTE: C#3       : DB3 C#3 ;
    ENUM-NOTE: D3     ENUM-NOTE: D#3       : Eb3 D#3 ;
    ENUM-NOTE: E3
    ENUM-NOTE: F3     ENUM-NOTE: F#3       : Gb3 F#3 ;
    ENUM-NOTE: G3     ENUM-NOTE: G#3       : Ab3 G#3 ;
    ENUM-NOTE: A3     ENUM-NOTE: A#3       : Bb3 A#3 ;
    ENUM-NOTE: B3
    ENUM-NOTE: C4     ENUM-NOTE: C#4       : Db4 C#4 ;
    ENUM-NOTE: D4     ENUM-NOTE: D#4       : Eb4 D#4 ;
    ENUM-NOTE: E4
    ENUM-NOTE: F4     ENUM-NOTE: F#4       : Gb4 F#4 ;
    ENUM-NOTE: G4     ENUM-NOTE: G#4       : Ab4 G#4 ;
    ENUM-NOTE: A4     ENUM-NOTE: A#4       : Bb4 A#4 ;
    ENUM-NOTE: B4
    ENUM-NOTE: C5     ENUM-NOTE: C#5       : Db5 C#5 ;
    ENUM-NOTE: D5     ENUM-NOTE: D#5       : Eb5 D#5 ;
    ENUM-NOTE: E5
    ENUM-NOTE: F5     ENUM-NOTE: F#5       : Gb5 F#5 ;
    ENUM-NOTE: G5     ENUM-NOTE: G#5       : Ab5 G#5 ;
    ENUM-NOTE: A5     ENUM-NOTE: A#5       : Bb5 A#5 ;
    ENUM-NOTE: B5
    ENUM-NOTE: C6
    ENUM-NOTE: C6     ENUM-NOTE: C#6       : Db5 C#5 ;
    ENUM-NOTE: D6     ENUM-NOTE: D#6       : Eb5 D#5 ;
    ENUM-NOTE: E6
    ENUM-NOTE: F6     ENUM-NOTE: F#6       : Gb5 F#5 ;
    ENUM-NOTE: G6     ENUM-NOTE: G#6       : Ab5 G#5 ;
    ENUM-NOTE: A6     ENUM-NOTE: A#6       : Bb5 A#5 ;
    ENUM-NOTE: B6
    ENUM-NOTE: C7     ENUM-NOTE: C#7       : Db5 C#5 ;
    ENUM-NOTE: D7     ENUM-NOTE: D#7       : Eb5 D#5 ;
    ENUM-NOTE: E7
    ENUM-NOTE: F7     ENUM-NOTE: F#7       : Gb5 F#5 ;
    ENUM-NOTE: G7
    DROP

DECIMAL
\ create a tuner that is transpose independant
: TUNER    ( -- ) GEN1   24 ]NOTE@ (PLAY)  2 ATTENUATE ;
: TUNEROFF ( -- ) GEN1 MUTE ;

\ Usage Demonstrations
\ This system makes sense if you understand traditional music notation.
: DMAJOR
        122 BPM NORMAL
        GEN1  1/8  D3 E3  F#3 G3 A3 B3  C#4 1/2. D4
              1/4 REST
              1/8  D4 C#4 B3  A3 G3 F#3 E3  1/1  D3 ;

: CHROMATIC
        100 BPM  NORMAL
        GEN2  1/8 C3 C#3 D3 D#3   1/16 E3 F3 F#3 G3 G#3 A3 A#3 B3
              1/8 C4 C#4 D4 D#4   1/16 E4 F4 F#4 G4 G#4 A4 A#4 B4
        NORMAL 1/4 C5 ;

 

 

  • Like 2
Link to comment
Share on other sites

The other day I noticed that the E/A sound table for A440 implied a SLIGHTLY out of tune A110.

The "Textbook" values for the sound chip are 3F9 and 0FE producing 109.99 and 440.3968 Hz.


If tuning the low A to match, you choose 3F8 to produce 110.1 instead.


What's the difference?


Well, when two notes are played together, and one is out of tune, you hear a beat sensation.

The "beat" is the two frequencies interfering constructively and destructively.


Try this: (in TI BASIC for everyone following at home)


10 CALL SOUND(4000, 109.99, 0, 110.4, 0)

20 GOTO 10


or this:


30 CALL SOUND(4000, 440.3968, 0, 438.67, 0)

40 GOTO 30

RUN 30


It's actually a cool sound effect that you will recognize from Munch Man.


You can hear the beat take place at f1-f2, which is 0.4 Hz in the first example, more like 2 Hz in the second.


A square wave (the kind the 76489 sound chip can generate) is composed of a fundamental frequency plus the odd harmonics at 1/n.

That is, a square wave at 110 contains f=110 plus f=440 at 1/3 or -10dB. (EDIT: no it doesn't, it's at f=330. My article falls apart here.)


Given f=109.99, the third harmonic is at 439.96 (EDIT: no, it's 330), but when playing A440, the closest the sound chip can get is either 438.67 or 440.3968. The chord A110+A440.3968 should give us a chance to hear a beat at 0.4 Hz. It should go away when the low A is tuned to 110.1.


I wonder if you can hear this beat in the 3rd harmonic:


10 CALL SOUND(2000, 109.99, 0, 440.3867, 10)

20 PRINT "BEAT"

30 CALL SOUND(2000, 110.1, 0, 440.3867, 10)

40 PRINT "NO BEAT"

50 GOTO 10


I think I can hear one? I can tell that the low A is moving a tiny bit, but the beat should have a quality like the first example of a 0.4 Hz beat. I think that I hear a beat at about 3 Hz on both of them. Not sure what's up with that.


Caveat: I did these tests on Classic99. I got out a 4A console to test real hardware, but a 4116 memory chip failed spectacularly. I'll write elsewhere of the joy of TDX@R HNRTRTLDNTR and playing B@R W@RR and TH HNV@DDRR.

Edited by FarmerPotato
  • Like 2
Link to comment
Share on other sites

FarmerPotato, on 13 Jun 2018, said:

 

I wonder if you can hear this beat in the 3rd harmonic:

10 CALL SOUND(2000, 109.99, 0, 440.3867, 10)
20 PRINT "BEAT"
30 CALL SOUND(2000, 110.1, 0, 440.3867, 10)
40 PRINT "NO BEAT"
50 GOTO 10

Hi again,

 

I think the answer hear(sic) would most likely be NO!

My observations have shown that TI BASIC doesn't reproduce frequencies with great precision.
This is more evident at higher frequencies.
At a frequency of 2222hz and above, frequencies ramp up only every 44hz or so.
Thusly selecting a frequency of 2225 or 2255 will reproduce the same tone (tested on classic99).

As the frequency selected becomes higher, the spread-out becomes wider.

More specifically, for example 2216 through 2260 return the same tone.

As I recall, at frequencies above the normal human hearing range, only about 12 distinct tones can be produced.

I know this from using a test program to adjust frequencies up or down seamlessly whilst I simultaneously adjusted 567 phase locked loop tone decoders to their center frequencies.

Try this:

100 A=2200
104 FOR S=1 TO 200
106 NEXT S
110 CALL SOUND(-4222,A,0)
120 A=A+1
125 PRINT A
130 GOTO 104

Watch the frequency printout value increase as you listen for frequency changes.

Change the value in line 100 to change the starting frequency.
Change the second value in line 104 to change the delay between sound CALLS.

Edited by HOME AUTOMATION
Link to comment
Share on other sites

FarmerPotato, on 13 Jun 2018, said:

Hi again,

 

I think the answer hear(sic) would most likely be NO!

 

My observations have shown that TI BASIC doesn't reproduce frequencies with great precision.

 

The sound chip has a 10 bit counter value N. It can be from 0 to 1023. The math is: frequency = 111860.8 / N. This number is scaled down from the VDP crystal at 3.57955 MHz.

 

The reproducible values include

 

f=109.3458 Hz at N=1023, the lowest it can go.

f=109.99 Hz at N=1017, the "textbook" (Editor/Assembler) value for low A.

f=110.099 Hz at N=1016, a low A that is adjusted to tune with A440.

f=329.0023 Hz at N=340

f=329.9728 Hz at N=339

f=330.9491 Hz at N=338

f=438.6697 Hz at N=255

f=440.3968 Hz at N=254

 

I haven't checked which way TI BASIC might round the value from CALL SOUND, but I chose my frequency values to match integer values of N.

 

I got the theory wrong before my experiment. Here is the right experiment to do around f=330:

 

10 CALL SOUND(2000, 109.99, 0, 330.9491, 10)
20 PRINT "BEAT"
30 CALL SOUND(2000, 109.99, 0, 329.9728, 10)
40 PRINT "NO BEAT"
50 GOTO 10
Sure enough, there it is. There's the beat!
But it doesn't support my hypothesis that A110 should be retuned to match A440.
Edited by FarmerPotato
  • Like 1
Link to comment
Share on other sites

The sound chip has a 10 bit counter value N. It can be from 0 to 1023. The math is: frequency = 111860.8 / N. This number is scaled down from the VDP crystal at 3.57955 MHz.

 

The reproducible values include

 

f=109.3458 Hz at N=1023, the lowest it can go.

f=109.99 Hz at N=1017, the "textbook" (Editor/Assembler) value for low A.

f=110.099 Hz at N=1016, a low A that is adjusted to tune with A440.

f=329.0023 Hz at N=340

f=329.9728 Hz at N=339

f=330.9491 Hz at N=338

f=438.6697 Hz at N=255

f=440.3968 Hz at N=254

 

I haven't checked which way TI BASIC might round the value from CALL SOUND, but I chose my frequency values to match integer values of N.

While I was aware of the above formula and counter frequency synthesis method, I was somewhat confused about the limitation being confined to BASIC.

 

So in conclusion, I now realize the 10 bit counter is what limits the FM to1024 possible tones.

 

Interesting (par for the course) how TI stuff is so replete with analytical requirements. WoW! What Fun:)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...