Jump to content
IGNORED

POKEY question - Distortion 12 "Donkey Kong" bass.


Recommended Posts

Ok, here's the situation:

 

I have volunteered to do the music for an Atari 7800 release called "Bentley Bear: Crystal Quest". It's been about 25 years since I last hacked together POKEY chipmusic, and I found a few nice bits of info, shown below:

 

http://www.ionpool.net/arcade/atari_docs/pokey_datasheet.pdf

(Page 9 has frequency values for Distortion 10)

 

http://www.atarimagazines.com/compute/issue34/112_1_16-BIT_ATARI_MUSIC.php

(Info about 16-bit music using distortion 10)

 

While this is all very useful, I have found that I am relying increasingly on a technique I nicknamed the "Donkey Kong" bass, when I used to do POKEY music back in the 1980's (after the Atari XL "Donkey Kong" game whose "How High Can You Get?" music used this technique). Basically, it means using certain frequencies in Distortion #12 to get the lower bass notes, and extend into the lower octave not possible with Distortion 10, while staying in 8-bit mode. It seems that only values which are evenly divisible by 3 will access these timbres. Some of these values also seem to silence the sound channel.

 

The problem is, the high end of this range is out of tune with the values in the above two resources. Specifically, using the value of 131 in AUDF0 with distortion 12 produces a G note, but it's out of tune (in BASIC, you would do SOUND 0,131,12,volume). The question is, is there a formula that I can use which will retune the distortion 10 values to match these distortion 12 timbres? My project requires that each channel be dedicated to a particular distortion setting.

  • Like 1
Link to comment
Share on other sites

1. If you can spare 2 voices, you can tune the bass with 16-bits.

2. Rapidly alternating two close pitches produces the illusion of a middle pitch.

3. Change to a faster clock (15K->64K) and see if you can move the pitches down the scale where you have finer control.

Link to comment
Share on other sites

I may use 16 bits for some tunes, but a lot of the tunes will require 3 voices (voice 0 is for game sounds only) so I will need to be staying in 8-bit mode for these. How exactly does the faster clock rate (15K - 64K) work? Still trying to remember all this AUDCTL stuff, it's been awhile.

Link to comment
Share on other sites

Can you use a tracker like RMT or TMC2? They both have builtin frequency tables for distortion 10 and 12 waveforms. You can hear how the effective frequency of distortion 12 waveforms jumps all over the place by typing this in BASIC:

 

FOR T=0 TO 255:SOUND 0,T,12,10:FOR D=0 TO 99:NEXT D:NEXT T

 

The tables put all of the out of order frequencies into a sane order. Nevertheless, POKEY in 8-bit mode is always going to be out-of-tune to various degrees especially for small periods. You could switch to 16-bit mode but then you lose channels. I think CMC gives you the option to have one 16-bit channel and two 8-bit channels.

 

Trevin Beattie has a good summary of AUDCTL. Of course phaeron's Altirra Hardware Reference Manual is indispensable.

Link to comment
Share on other sites

Distortion 12 samples from the 4-bit noise generator, which has a period of 15 bits with the pattern 000111011001010. The 64KHz clock has a period of 28 cycles, which is relatively prime with 15, so all 15 bits of the pattern will be used in various orders except when the period is a multiple of 3 or 5, where the value in the SOUND command is one less than the period. A period divisible by 15 would always sample the same bit and give constant output (silence). For a period divisible by 3, a 5-bit pattern will result, so for period 132 the NTSC frequency is 63920.4 / (132 * 5) = 96.9Hz at distortion 12, compared to 242.1Hz for distortion 10.

 

Note that there are three possible 5-bit patterns depending on the current timing offset of the audio channel, so the timbre will vary.

Edited by phaeron
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Can you use a tracker like RMT or TMC2? They both have builtin frequency tables for distortion 10 and 12 waveforms. You can hear how the effective frequency of distortion 12 waveforms jumps all over the place by typing this in BASIC:

 

Unfortunately, using RMT or another tracker isn't an option. There isn't enough room in the game code for the music in those formats or for the player code. Basically, I'm going to be coding the music the old-fashioned way: by coding the frequency data and note duration for each sound channel. Basically, for each tune there is a table for notes for each channel, followed by a table of note durations.

 

In most cases, we're using three sound channels (2 if using 16-bit mode), the 4th channel has been reserved for game sounds. But basically, all sound data for each channel is on the same distortion setting. Wherever silence is needed, we'll be using a zero value for distortion 10, or one of those multiple of 15 values for distortion 12. The duration is measured in jiffies (1/50 PAL, 1/60 NTSC), and there is an indexed volume decay for each note played.

 

So ideally, the frequency data table for distortion 12, and for that matter any other distortions, in both 8 and 16-bit modes, would well come in handy. Would any of these tracking programs like RMT or similar, have such documentation showing the proper frequency settings for each note?

 

Distortion 12 samples from the 4-bit noise generator, which has a period of 15 bits with the pattern 000111011001010. The 64KHz clock has a period of 28 cycles, which is relatively prime with 15, so all 15 bits of the pattern will be used in various orders except when the period is a multiple of 3 or 5, where the value in the SOUND command is one less than the period. A period divisible by 15 would always sample the same bit and give constant output (silence). For a period divisible by 3, a 5-bit pattern will result, so for period 132 the NTSC frequency is 63920.4 / (132 * 5) = 96.9Hz at distortion 12, compared to 242.1Hz for distortion 10.

 

Note that there are three possible 5-bit patterns depending on the current timing offset of the audio channel, so the timbre will vary.

 

Thanks for the explanation of the differing timbres. I had always wondered why the sound varied. I would of course be using differing timbres, depending on the tune. Do these timbres also occur in distortion 12 when using 16-bit mode, by combining two sound channels?

Link to comment
Share on other sites

Thanks for the explanation of the differing timbres. I had always wondered why the sound varied. I would of course be using differing timbres, depending on the tune. Do these timbres also occur in distortion 12 when using 16-bit mode, by combining two sound channels?

 

Yes, they would. Which waveform you get depends on the pitch in cycles, mod 15, and when you switch the period of the timer. 16-bit would produce the same result assuming you used values that produced exactly the same period as in 8-bit mode; just one cycle off, though, and you get a different result.

Link to comment
Share on other sites

RMT's tables are in rmtplayr.a65 in the zip file.

 

They look like this:

 

frqtabbass1
dta $BF,$B6,$AA,$A1,$98,$8F,$89,$80,$F2,$E6,$DA,$CE,$BF,$B6,$AA,$A1
dta $98,$8F,$89,$80,$7A,$71,$6B,$65,$5F,$5C,$56,$50,$4D,$47,$44,$3E
dta $3C,$38,$35,$32,$2F,$2D,$2A,$28,$25,$23,$21,$1F,$1D,$1C,$1A,$18
dta $17,$16,$14,$13,$12,$11,$10,$0F,$0E,$0D,$0C,$0B,$0A,$09,$08,$07
frqtabbass2
dta $FF,$F1,$E4,$D8,$CA,$C0,$B5,$AB,$A2,$99,$8E,$87,$7F,$79,$73,$70
dta $66,$61,$5A,$55,$52,$4B,$48,$43,$3F,$3C,$39,$37,$33,$30,$2D,$2A
dta $28,$25,$24,$21,$1F,$1E,$1C,$1B,$19,$17,$16,$15,$13,$12,$11,$10
dta $0F,$0E,$0D,$0C,$0B,$0A,$09,$08,$07,$06,$05,$04,$03,$02,$01,$00

 

What's cool (and I didn't realize this til just now) is that these two tables produce different timbres even when keeping distortion 12 for each and without any fancy timing.

 

Here's a quick example I coded up:

 

pokey.zip

 

It plays a scale with freqtabbass2 with the background set to purple, then it plays a scale with freqtabbass1 with the background set to red.

 

There are also tables for 16-bit mode in rmtplayr.a65 as well.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
  • 2 years later...

Hi. I am building a synthesizer based on a microcontroller and multiple pokey chips.

I have noticed this timing-related behaviour - the tone depends on the moment of change.

When using distortion 12 (AUDC1 = 0xCF) I am getting "tone or no tone" with AUDF1 = 64.

Why is it so? ((64+1) * 28) mod 15 is 5, so if the pattern is 00011 10110 01010, there are 5 possible sequences - 010, 001, 010, 111, 100. In case of sequence 111 there is no sound. Am I correct?

 

Is there a way to get in sync with (or reset) the timer driving shift register?

 

 

Btw. why "distortion 10" (AUDCn = 0xA*) is named "distortion"? Isn't it a clear tone?

Edited by Silent
Link to comment
Share on other sites

"Distortion" is a misnomer, from the old Atari BASIC days. I suppose a better term would be "timbre", but I've always just went with "distortion".

 

As for the tones ... Distortion 12b (as I termed it) are those sounds where (freq+1) mod 3 = 0 ... it also works on tones where (freq+1) mod 5 = 0, although intermittently. Any other tones where (freq+1) mod 3 and (freq+1) mod 5 are nonzero, will produce buzzy tones (what I have termed Distortion 12a).

 

However ... there are those ones where (freq+1) mod 15 = 0 ... that is, where both 3 and 5 can divide into the frequency. In those cases, there will be no sound. The prime example of this is where freq=14 ... so, if in BASIC, you did this:

 

SOUND 1,14,12,10

 

You would have silence. In doing music on the Atari, I have found it helpful to put 14's into the routine anytime I wanted in introduce a rest into the musical piece when using distortion 12.

  • Like 1
Link to comment
Share on other sites

Incidentally, I did up a table of POKEY note settings, for both 8-bit and 16-bit mode ... for distortions 2 (triangle wave), 10 (square wave), 12a and 12b (saw wave) ... you can find it here:

 

http://atariage.com/forums/topic/216807-complete-pokey-note-table-for-all-distortion-settings/?hl=%2Bpokey+%2Bdistortion+%2Btable&do=findComment&comment=3162749

 

This may be of some use to you. I am going to go through it at some stage and add 15KHz mode settings.

Link to comment
Share on other sites

Thank for your reply!

 

I still have a problem with synchronization. When (freq+1) is divisible by 3 or 5 I am getting different timbers with the same settings. As phaeron wrote, it depends on timing (when the AUDCn/AUDFn was set). How to get in sync so I can get the same timber every time?

Is there a "magic sequence" to reset all counters? How do you control it in your program?

Link to comment
Share on other sites

Distortion, noise, timbre - it's all sort of wrong.

 

It's an LFSR which operates at the base frequency that the voice does (1.79 MHz, 64 KHz or 16 KHz). When the voice's timer counts down (the AUDF value), you have certain actions:

- if it's "pure tone" the voice output simply alternates between off and on.

- if it's LFSR noise/poly, there's an XOR between the on/off contition and whatever on/off (1 or 0) that the LFSR is providing at that time (verification needed that it's an XOR operation).

 

The reason you sometimes total silence is due to a coincidence where the AUDF period happens to coincide with the LFSR being at the same period in it's sequence when sampled.

The pure tone, I think the reason there is that you are only sampling 0 and 1 from the LFSR each time, never a mixture which is what's required for poly noise.

 

The number of samples provided by each poly type depends on it's bit length. AUDC type 8 "noise" can be 17 bits so gives 2^17 - 1 then repeats. If AUDCTL is set such that the 9 bit poly is used instead then it's only 511 samples which is a much quicker repetition and heading towards machine sound rather than noise.

 

 

There is a reset sequence. The STIMER register resets all voices but this is usually undesirable as it creates unwanted clicks when more than one sound is playing.

There are other tricks though to guarantee relationship between a voice and the selected poly counter, there's other threads around about it.

Edited by Rybags
Link to comment
Share on other sites

On the 2600, Atari's engineers allowed the LFSR's to be clocked by the channel divisor, so you always got the same sequence, but at different speeds. With Pokey, they discovered that sub-sampling a common set of fixed-speed LFSR registers usually produced acceptable results and saved space on the chip.

 

The down side is that cycle counting is the only way to use some settings. Once Pokey is released from reset (SKCTL=xxxxxx00) the shift registers are running and the state you land on depends on the cycle. Certain cycle alignments combined with certain dividers will return patterns specific to the beginning cycle. Other divisors will produce sequences that do not depend on the starting cycle (or at least sequences which sound the same even if they're not hitting the same states). You can get the CPU aligned by using WSYNC on real hardware, cycle counters on custom hardware, or reset one of the Pokeys prior to setting up a critical sound.

 

You can see this if you drew out the LFSR sequences and then mapped every n-th state. You'd find some settings that resulted in the same state every time, or a tight looping sequence.

  • Like 1
Link to comment
Share on other sites

The description of the POKEY output path in my Hardware Manual is still a bit text heavy. This diagram in Atari's Hardware Manual is still the best description I know of (as opposed to their distortion chart, which didn't make much sense):

 

post-16457-0-04453600-1453078117_thumb.png

 

There is an error in this diagram, though. It shows the high-pass XOR being switched out, but in reality it is always in the audio path and high-pass is disabled by forcing the flip-flop to 1 instead, which inverts the output state.

 

The 4, 9, and 17-bit noise generators are sampled. This means that every period, one bit from the noise pattern is selected and stretched until the next period. The 5-bit generator goes through the clocking path and is used to make the period irregular instead of being sampled directly.

 

STIMER + SKCTL is enough to completely reset the entire POKEY audio path to a deterministic state. However, the audio channels differ in their distortion output because they're clocked at the same time but receive noise with different delays.

 

  • Like 1
Link to comment
Share on other sites

(A little off topic, but I just had an idea)...

 

If the upper 3 bits are un-used when in 4 bit DAC mode, then why couldn't we build a small circuit that decodes AUDCx registers, and if bit 4 is set for volume only mode, apply the upper 3 bits to a resistor network like the lower 4 are? Connect that to the audio output pin. Would not that give 7 bit resolution instead of 4?

 

This should easily fit on a small board that goes under PoKey.

 

Yeah, I know. Stack, stack stack. FIFO, TK-II, etc.

  • Like 1
Link to comment
Share on other sites

That'd work, not sure if forced volume is a simple DC offset that's easily achieved with a resistor ladder though. From memory I've sampled it and it looks pretty linear.

Would need to be tunable in some way though such that you can get it to fit in with what the normal audio circuit is generating.

 

Maybe the best solution would be to do it as an addition to an existing Covox project. Have the normal 8-bit outputs it provides as well as the Pokey enhanced ones.

  • Like 2
Link to comment
Share on other sites

I have managed to get the (almost) stable tones. In some special cases I am still getting 2 options, but looks like proper reset sequence (when cycles are not counted) does the job. My current sequence is:

SKCTL = 0

AUDF0 = 1

AUDF1 = 1

STIMER = 1

AUDF0 = xx

AUDF1 = yy

SKCTL = 3

 

I have also noticed that setting the register (CS0=L, CS1=H during 1 clock cycle, both edges) does not take an effect when the value was not changed.

For example when using unstable tones - tone changes after first write and another write does not change it. Writing something different then the previous value takes an effect and the tone is "random" (if unstable).

However, the older chip revision which comes from 5200 board (CO12294-03) acts differently. Every write takes an effect and the Synthpopalooza's table for distortion 12b ("smooth", divisible by 3) is not stable (at least in my case; same setup, only the chip was replaced). It was stable on CO12249B-01 (from 65XE).

Do you know what are the differences between chip revisions?

post-45052-0-11271400-1453742807_thumb.jpg

  • Like 1
Link to comment
Share on other sites

So are you saying writes on 2 consecutive cycles don't work for the second one if the target is the same?

Possibly the Pokey datasheet can help, check that your relative timings etc. are done right.

 

Remember with AUDF changes, they don't come into effect until the next time the counter has expired and reloaded, unless force reloaded via STIMER.

There is a delay for counter reload which will be different whether the voice is in 8 or 16 bit mode.

With SKCTL=00, I think there might be some required delay to allow the poly counters to drain.

Edited by Rybags
Link to comment
Share on other sites

  • 3 years later...

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...