Jump to content

Photo

Assembly language sound effects

Assembly Sound

38 replies to this topic

#26 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 637 posts
  • Location:The Great White North

Posted Tue Jun 5, 2018 8:51 PM

 

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



#27 FarmerPotato OFFLINE  

FarmerPotato

    Star Raider

  • 93 posts
  • Location:Austin, TX

Posted Wed Jun 6, 2018 3:12 PM

 

 

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

 



#28 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 637 posts
  • Location:The Great White North

Posted Wed Jun 6, 2018 3:41 PM

 

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.



#29 FarmerPotato OFFLINE  

FarmerPotato

    Star Raider

  • 93 posts
  • Location:Austin, TX

Posted Wed Jun 6, 2018 4:37 PM

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, Wed Jun 6, 2018 4:48 PM.


#30 FarmerPotato OFFLINE  

FarmerPotato

    Star Raider

  • 93 posts
  • Location:Austin, TX

Posted Wed Jun 6, 2018 5:02 PM

 

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, Wed Jun 6, 2018 5:03 PM.


#31 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 637 posts
  • Location:The Great White North

Posted Wed Jun 6, 2018 6:06 PM

 

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

 

Oh, so you implement a portmanteau (sliding note effect) I guess.



#32 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 637 posts
  • Location:The Great White North

Posted Wed Jun 6, 2018 6:21 PM

 

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



#33 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 637 posts
  • Location:The Great White North

Posted Wed Jun 6, 2018 6:55 PM

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



#34 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 637 posts
  • Location:The Great White North

Posted Thu Jun 7, 2018 10:22 AM

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.

 

Spoiler


#35 FarmerPotato OFFLINE  

FarmerPotato

    Star Raider

  • 93 posts
  • Location:Austin, TX

Posted Wed Jun 13, 2018 2:12 AM

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, Wed Jun 13, 2018 2:23 AM.


#36 HOME AUTOMATION OFFLINE  

HOME AUTOMATION

    Star Raider

  • 58 posts

Posted Wed Jun 13, 2018 7:52 AM

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, Wed Jun 13, 2018 8:13 AM.


#37 FarmerPotato OFFLINE  

FarmerPotato

    Star Raider

  • 93 posts
  • Location:Austin, TX

Posted Wed Jun 13, 2018 9:05 AM

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, Wed Jun 13, 2018 9:10 AM.


#38 HOME AUTOMATION OFFLINE  

HOME AUTOMATION

    Star Raider

  • 58 posts

Posted Wed Jun 13, 2018 10:44 AM

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:)



#39 OLD CS1 OFFLINE  

OLD CS1

    Quadrunner

  • 5,360 posts
  • Technology Samurai
  • Location:Tallahassee, FL

Posted Wed Jun 13, 2018 1:47 PM

Sounds like 4A Flyer.







Also tagged with one or more of these keywords: Assembly, Sound

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users